Salome HOME
Management of 3D surf voronoi for Gauss
[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 MemArray<int>;
40 template class MemArray<double>;
41 template class DataArrayTemplate<int>;
42 template class DataArrayTemplate<double>;
43
44 template<int SPACEDIM>
45 void DataArrayDouble::findCommonTuplesAlg(const double *bbox, int nbNodes, int limitNodeId, double prec, DataArrayInt *c, DataArrayInt *cI) const
46 {
47   const double *coordsPtr=getConstPointer();
48   BBTreePts<SPACEDIM,int> myTree(bbox,0,0,nbNodes,prec);
49   std::vector<bool> isDone(nbNodes);
50   for(int i=0;i<nbNodes;i++)
51     {
52       if(!isDone[i])
53         {
54           std::vector<int> intersectingElems;
55           myTree.getElementsAroundPoint(coordsPtr+i*SPACEDIM,intersectingElems);
56           if(intersectingElems.size()>1)
57             {
58               std::vector<int> commonNodes;
59               for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
60                 if(*it!=i)
61                   if(*it>=limitNodeId)
62                     {
63                       commonNodes.push_back(*it);
64                       isDone[*it]=true;
65                     }
66               if(!commonNodes.empty())
67                 {
68                   cI->pushBackSilent(cI->back()+(int)commonNodes.size()+1);
69                   c->pushBackSilent(i);
70                   c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
71                 }
72             }
73         }
74     }
75 }
76
77 template<int SPACEDIM>
78 void DataArrayDouble::FindTupleIdsNearTuplesAlg(const BBTreePts<SPACEDIM,int>& myTree, const double *pos, int nbOfTuples, double eps,
79                                                 DataArrayInt *c, DataArrayInt *cI)
80 {
81   for(int i=0;i<nbOfTuples;i++)
82     {
83       std::vector<int> intersectingElems;
84       myTree.getElementsAroundPoint(pos+i*SPACEDIM,intersectingElems);
85       std::vector<int> commonNodes;
86       for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
87         commonNodes.push_back(*it);
88       cI->pushBackSilent(cI->back()+(int)commonNodes.size());
89       c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
90     }
91 }
92
93 template<int SPACEDIM>
94 void DataArrayDouble::FindClosestTupleIdAlg(const BBTreePts<SPACEDIM,int>& myTree, double dist, const double *pos, int nbOfTuples, const double *thisPt, int thisNbOfTuples, int *res)
95 {
96   double distOpt(dist);
97   const double *p(pos);
98   int *r(res);
99   for(int i=0;i<nbOfTuples;i++,p+=SPACEDIM,r++)
100     {
101       while(true)
102         {
103           int elem=-1;
104           double ret=myTree.getElementsAroundPoint2(p,distOpt,elem);
105           if(ret!=std::numeric_limits<double>::max())
106             {
107               distOpt=std::max(ret,1e-4);
108               *r=elem;
109               break;
110             }
111           else
112             { distOpt=2*distOpt; continue; }
113         }
114     }
115 }
116
117 int DataArray::EffectiveCircPerm(int nbOfShift, int nbOfTuples)
118 {
119   if(nbOfTuples<=0)
120     throw INTERP_KERNEL::Exception("DataArray::EffectiveCircPerm : number of tuples is expected to be > 0 !");
121   if(nbOfShift>=0)
122     {
123       return nbOfShift%nbOfTuples;
124     }
125   else
126     {
127       int tmp(-nbOfShift);
128       tmp=tmp%nbOfTuples;
129       return nbOfTuples-tmp;
130     }
131 }
132
133 std::size_t DataArray::getHeapMemorySizeWithoutChildren() const
134 {
135   std::size_t sz1=_name.capacity();
136   std::size_t sz2=_info_on_compo.capacity();
137   std::size_t sz3=0;
138   for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
139     sz3+=(*it).capacity();
140   return sz1+sz2+sz3;
141 }
142
143 std::vector<const BigMemoryObject *> DataArray::getDirectChildrenWithNull() const
144 {
145   return std::vector<const BigMemoryObject *>();
146 }
147
148 /*!
149  * Sets the attribute \a _name of \a this array.
150  * See \ref MEDCouplingArrayBasicsName "DataArrays infos" for more information.
151  *  \param [in] name - new array name
152  */
153 void DataArray::setName(const std::string& name)
154 {
155   _name=name;
156 }
157
158 /*!
159  * Copies textual data from an \a other DataArray. The copied data are
160  * - the name attribute,
161  * - the information of components.
162  *
163  * For more information on these data see \ref MEDCouplingArrayBasicsName "DataArrays infos".
164  *
165  *  \param [in] other - another instance of DataArray to copy the textual data from.
166  *  \throw If number of components of \a this array differs from that of the \a other.
167  */
168 void DataArray::copyStringInfoFrom(const DataArray& other)
169 {
170   if(_info_on_compo.size()!=other._info_on_compo.size())
171     throw INTERP_KERNEL::Exception("Size of arrays mismatches on copyStringInfoFrom !");
172   _name=other._name;
173   _info_on_compo=other._info_on_compo;
174 }
175
176 void DataArray::copyPartOfStringInfoFrom(const DataArray& other, const std::vector<int>& compoIds)
177 {
178   int nbOfCompoOth=other.getNumberOfComponents();
179   std::size_t newNbOfCompo=compoIds.size();
180   for(std::size_t i=0;i<newNbOfCompo;i++)
181     if(compoIds[i]>=nbOfCompoOth || compoIds[i]<0)
182       {
183         std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompoOth << ")";
184         throw INTERP_KERNEL::Exception(oss.str().c_str());
185       }
186   for(std::size_t i=0;i<newNbOfCompo;i++)
187     setInfoOnComponent((int)i,other.getInfoOnComponent(compoIds[i]));
188 }
189
190 void DataArray::copyPartOfStringInfoFrom2(const std::vector<int>& compoIds, const DataArray& other)
191 {
192   int nbOfCompo=getNumberOfComponents();
193   std::size_t partOfCompoToSet=compoIds.size();
194   if((int)partOfCompoToSet!=other.getNumberOfComponents())
195     throw INTERP_KERNEL::Exception("Given compoIds has not the same size as number of components of given array !");
196   for(std::size_t i=0;i<partOfCompoToSet;i++)
197     if(compoIds[i]>=nbOfCompo || compoIds[i]<0)
198       {
199         std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompo << ")";
200         throw INTERP_KERNEL::Exception(oss.str().c_str());
201       }
202   for(std::size_t i=0;i<partOfCompoToSet;i++)
203     setInfoOnComponent(compoIds[i],other.getInfoOnComponent((int)i));
204 }
205
206 bool DataArray::areInfoEqualsIfNotWhy(const DataArray& other, std::string& reason) const
207 {
208   std::ostringstream oss;
209   if(_name!=other._name)
210     {
211       oss << "Names DataArray mismatch : this name=\"" << _name << " other name=\"" << other._name << "\" !";
212       reason=oss.str();
213       return false;
214     }
215   if(_info_on_compo!=other._info_on_compo)
216     {
217       oss << "Components DataArray mismatch : \nThis components=";
218       for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
219         oss << "\"" << *it << "\",";
220       oss << "\nOther components=";
221       for(std::vector<std::string>::const_iterator it=other._info_on_compo.begin();it!=other._info_on_compo.end();it++)
222         oss << "\"" << *it << "\",";
223       reason=oss.str();
224       return false;
225     }
226   return true;
227 }
228
229 /*!
230  * Compares textual information of \a this DataArray with that of an \a other one.
231  * The compared data are
232  * - the name attribute,
233  * - the information of components.
234  *
235  * For more information on these data see \ref MEDCouplingArrayBasicsName "DataArrays infos".
236  *  \param [in] other - another instance of DataArray to compare the textual data of.
237  *  \return bool - \a true if the textual information is same, \a false else.
238  */
239 bool DataArray::areInfoEquals(const DataArray& other) const
240 {
241   std::string tmp;
242   return areInfoEqualsIfNotWhy(other,tmp);
243 }
244
245 void DataArray::reprWithoutNameStream(std::ostream& stream) const
246 {
247   stream << "Number of components : "<< getNumberOfComponents() << "\n";
248   stream << "Info of these components : ";
249   for(std::vector<std::string>::const_iterator iter=_info_on_compo.begin();iter!=_info_on_compo.end();iter++)
250     stream << "\"" << *iter << "\"   ";
251   stream << "\n";
252 }
253
254 std::string DataArray::cppRepr(const std::string& varName) const
255 {
256   std::ostringstream ret;
257   reprCppStream(varName,ret);
258   return ret.str();
259 }
260
261 /*!
262  * Sets information on all components. To know more on format of this information
263  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
264  *  \param [in] info - a vector of strings.
265  *  \throw If size of \a info differs from the number of components of \a this.
266  */
267 void DataArray::setInfoOnComponents(const std::vector<std::string>& info)
268 {
269   if(getNumberOfComponents()!=(int)info.size())
270     {
271       std::ostringstream oss; oss << "DataArray::setInfoOnComponents : input is of size " << info.size() << " whereas number of components is equal to " << getNumberOfComponents() << " !";
272       throw INTERP_KERNEL::Exception(oss.str().c_str());
273     }
274   _info_on_compo=info;
275 }
276
277 /*!
278  * This method is only a dispatcher towards DataArrayDouble::setPartOfValues3, DataArrayInt::setPartOfValues3, DataArrayChar::setPartOfValues3 depending on the true
279  * type of \a this and \a aBase.
280  *
281  * \throw If \a aBase and \a this do not have the same type.
282  *
283  * \sa DataArrayDouble::setPartOfValues3, DataArrayInt::setPartOfValues3, DataArrayChar::setPartOfValues3.
284  */
285 void DataArray::setPartOfValuesBase3(const DataArray *aBase, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
286 {
287   if(!aBase)
288     throw INTERP_KERNEL::Exception("DataArray::setPartOfValuesBase3 : input aBase object is NULL !");
289   DataArrayDouble *this1(dynamic_cast<DataArrayDouble *>(this));
290   DataArrayInt *this2(dynamic_cast<DataArrayInt *>(this));
291   DataArrayChar *this3(dynamic_cast<DataArrayChar *>(this));
292   const DataArrayDouble *a1(dynamic_cast<const DataArrayDouble *>(aBase));
293   const DataArrayInt *a2(dynamic_cast<const DataArrayInt *>(aBase));
294   const DataArrayChar *a3(dynamic_cast<const DataArrayChar *>(aBase));
295   if(this1 && a1)
296     {
297       this1->setPartOfValues3(a1,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
298       return ;
299     }
300   if(this2 && a2)
301     {
302       this2->setPartOfValues3(a2,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
303       return ;
304     }
305   if(this3 && a3)
306     {
307       this3->setPartOfValues3(a3,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
308       return ;
309     }
310   throw INTERP_KERNEL::Exception("DataArray::setPartOfValuesBase3 : input aBase object and this do not have the same type !");
311 }
312
313 std::vector<std::string> DataArray::getVarsOnComponent() const
314 {
315   int nbOfCompo=(int)_info_on_compo.size();
316   std::vector<std::string> ret(nbOfCompo);
317   for(int i=0;i<nbOfCompo;i++)
318     ret[i]=getVarOnComponent(i);
319   return ret;
320 }
321
322 std::vector<std::string> DataArray::getUnitsOnComponent() const
323 {
324   int nbOfCompo=(int)_info_on_compo.size();
325   std::vector<std::string> ret(nbOfCompo);
326   for(int i=0;i<nbOfCompo;i++)
327     ret[i]=getUnitOnComponent(i);
328   return ret;
329 }
330
331 /*!
332  * Returns information on a component specified by an index.
333  * To know more on format of this information
334  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
335  *  \param [in] i - the index (zero based) of the component of interest.
336  *  \return std::string - a string containing the information on \a i-th component.
337  *  \throw If \a i is not a valid component index.
338  */
339 std::string DataArray::getInfoOnComponent(int i) const
340 {
341   if(i<(int)_info_on_compo.size() && i>=0)
342     return _info_on_compo[i];
343   else
344     {
345       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();
346       throw INTERP_KERNEL::Exception(oss.str().c_str());
347     }
348 }
349
350 /*!
351  * Returns the var part of the full information of the \a i-th component.
352  * For example, if \c getInfoOnComponent(0) returns "SIGXY [N/m^2]", then
353  * \c getVarOnComponent(0) returns "SIGXY".
354  * If a unit part of information is not detected by presence of
355  * two square brackets, then the full information is returned.
356  * To read more about the component information format, see
357  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
358  *  \param [in] i - the index (zero based) of the component of interest.
359  *  \return std::string - a string containing the var information, or the full info.
360  *  \throw If \a i is not a valid component index.
361  */
362 std::string DataArray::getVarOnComponent(int i) const
363 {
364   if(i<(int)_info_on_compo.size() && i>=0)
365     {
366       return GetVarNameFromInfo(_info_on_compo[i]);
367     }
368   else
369     {
370       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();
371       throw INTERP_KERNEL::Exception(oss.str().c_str());
372     }
373 }
374
375 /*!
376  * Returns the unit part of the full information of the \a i-th component.
377  * For example, if \c getInfoOnComponent(0) returns "SIGXY [ N/m^2]", then
378  * \c getUnitOnComponent(0) returns " N/m^2".
379  * If a unit part of information is not detected by presence of
380  * two square brackets, then an empty string is returned.
381  * To read more about the component information format, see
382  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
383  *  \param [in] i - the index (zero based) of the component of interest.
384  *  \return std::string - a string containing the unit information, if any, or "".
385  *  \throw If \a i is not a valid component index.
386  */
387 std::string DataArray::getUnitOnComponent(int i) const
388 {
389   if(i<(int)_info_on_compo.size() && i>=0)
390     {
391       return GetUnitFromInfo(_info_on_compo[i]);
392     }
393   else
394     {
395       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();
396       throw INTERP_KERNEL::Exception(oss.str().c_str());
397     }
398 }
399
400 /*!
401  * Returns the var part of the full component information.
402  * For example, if \a info == "SIGXY [N/m^2]", then this method returns "SIGXY".
403  * If a unit part of information is not detected by presence of
404  * two square brackets, then the whole \a info is returned.
405  * To read more about the component information format, see
406  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
407  *  \param [in] info - the full component information.
408  *  \return std::string - a string containing only var information, or the \a info.
409  */
410 std::string DataArray::GetVarNameFromInfo(const std::string& info)
411 {
412   std::size_t p1=info.find_last_of('[');
413   std::size_t p2=info.find_last_of(']');
414   if(p1==std::string::npos || p2==std::string::npos)
415     return info;
416   if(p1>p2)
417     return info;
418   if(p1==0)
419     return std::string();
420   std::size_t p3=info.find_last_not_of(' ',p1-1);
421   return info.substr(0,p3+1);
422 }
423
424 /*!
425  * Returns the unit part of the full component information.
426  * For example, if \a info == "SIGXY [ N/m^2]", then this method returns " N/m^2".
427  * If a unit part of information is not detected by presence of
428  * two square brackets, then an empty string is returned.
429  * To read more about the component information format, see
430  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
431  *  \param [in] info - the full component information.
432  *  \return std::string - a string containing only unit information, if any, or "".
433  */
434 std::string DataArray::GetUnitFromInfo(const std::string& info)
435 {
436   std::size_t p1=info.find_last_of('[');
437   std::size_t p2=info.find_last_of(']');
438   if(p1==std::string::npos || p2==std::string::npos)
439     return std::string();
440   if(p1>p2)
441     return std::string();
442   return info.substr(p1+1,p2-p1-1);
443 }
444
445 /*!
446  * This method put in info format the result of the merge of \a var and \a unit.
447  * The standard format for that is "var [unit]".
448  * Inversely you can retrieve the var part or the unit part of info string using resp. GetVarNameFromInfo and GetUnitFromInfo.
449  */
450 std::string DataArray::BuildInfoFromVarAndUnit(const std::string& var, const std::string& unit)
451 {
452   std::ostringstream oss;
453   oss << var << " [" << unit << "]";
454   return oss.str();
455 }
456
457 std::string DataArray::GetAxisTypeRepr(MEDCouplingAxisType at)
458 {
459   switch(at)
460     {
461     case AX_CART:
462       return std::string("AX_CART");
463     case AX_CYL:
464       return std::string("AX_CYL");
465     case AX_SPHER:
466       return std::string("AX_SPHER");
467     default:
468       throw INTERP_KERNEL::Exception("DataArray::GetAxisTypeRepr : unrecognized axis type enum !");
469     }
470 }
471
472 /*!
473  * Returns a new DataArray by concatenating all given arrays, so that (1) the number
474  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
475  * the number of component in the result array is same as that of each of given arrays.
476  * Info on components is copied from the first of the given arrays. Number of components
477  * in the given arrays must be  the same.
478  *  \param [in] arrs - a sequence of arrays to include in the result array. All arrays must have the same type.
479  *  \return DataArray * - the new instance of DataArray (that can be either DataArrayInt, DataArrayDouble, DataArrayChar).
480  *          The caller is to delete this result array using decrRef() as it is no more
481  *          needed.
482  *  \throw If all arrays within \a arrs are NULL.
483  *  \throw If all not null arrays in \a arrs have not the same type.
484  *  \throw If getNumberOfComponents() of arrays within \a arrs.
485  */
486 DataArray *DataArray::Aggregate(const std::vector<const DataArray *>& arrs)
487 {
488   std::vector<const DataArray *> arr2;
489   for(std::vector<const DataArray *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
490     if(*it)
491       arr2.push_back(*it);
492   if(arr2.empty())
493     throw INTERP_KERNEL::Exception("DataArray::Aggregate : only null instance in input vector !");
494   std::vector<const DataArrayDouble *> arrd;
495   std::vector<const DataArrayInt *> arri;
496   std::vector<const DataArrayChar *> arrc;
497   for(std::vector<const DataArray *>::const_iterator it=arr2.begin();it!=arr2.end();it++)
498     {
499       const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(*it);
500       if(a)
501         { arrd.push_back(a); continue; }
502       const DataArrayInt *b=dynamic_cast<const DataArrayInt *>(*it);
503       if(b)
504         { arri.push_back(b); continue; }
505       const DataArrayChar *c=dynamic_cast<const DataArrayChar *>(*it);
506       if(c)
507         { arrc.push_back(c); continue; }
508       throw INTERP_KERNEL::Exception("DataArray::Aggregate : presence of not null instance in inuput that is not in [DataArrayDouble, DataArrayInt, DataArrayChar] !");
509     }
510   if(arr2.size()==arrd.size())
511     return DataArrayDouble::Aggregate(arrd);
512   if(arr2.size()==arri.size())
513     return DataArrayInt::Aggregate(arri);
514   if(arr2.size()==arrc.size())
515     return DataArrayChar::Aggregate(arrc);
516   throw INTERP_KERNEL::Exception("DataArray::Aggregate : all input arrays must have the same type !");
517 }
518
519 /*!
520  * Sets information on a component specified by an index.
521  * To know more on format of this information
522  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
523  *  \warning Don't pass NULL as \a info!
524  *  \param [in] i - the index (zero based) of the component of interest.
525  *  \param [in] info - the string containing the information.
526  *  \throw If \a i is not a valid component index.
527  */
528 void DataArray::setInfoOnComponent(int i, const std::string& info)
529 {
530   if(i<(int)_info_on_compo.size() && i>=0)
531     _info_on_compo[i]=info;
532   else
533     {
534       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();
535       throw INTERP_KERNEL::Exception(oss.str().c_str());
536     }
537 }
538
539 /*!
540  * Sets information on all components. This method can change number of components
541  * at certain conditions; if the conditions are not respected, an exception is thrown.
542  * The number of components can be changed in \a this only if \a this is not allocated.
543  * The condition of number of components must not be changed.
544  *
545  * To know more on format of the component information see
546  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
547  *  \param [in] info - a vector of component infos.
548  *  \throw If \a this->getNumberOfComponents() != \a info.size() && \a this->isAllocated()
549  */
550 void DataArray::setInfoAndChangeNbOfCompo(const std::vector<std::string>& info)
551 {
552   if(getNumberOfComponents()!=(int)info.size())
553     {
554       if(!isAllocated())
555         _info_on_compo=info;
556       else
557         {
558           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 !";
559           throw INTERP_KERNEL::Exception(oss.str().c_str());
560         }
561     }
562   else
563     _info_on_compo=info;
564 }
565
566 void DataArray::checkNbOfTuples(int nbOfTuples, const std::string& msg) const
567 {
568   if(getNumberOfTuples()!=nbOfTuples)
569     {
570       std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " <<  nbOfTuples << " having " << getNumberOfTuples() << " !";
571       throw INTERP_KERNEL::Exception(oss.str().c_str());
572     }
573 }
574
575 void DataArray::checkNbOfComps(int nbOfCompo, const std::string& msg) const
576 {
577   if(getNumberOfComponents()!=nbOfCompo)
578     {
579       std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << nbOfCompo << " having " << getNumberOfComponents() << " !";
580       throw INTERP_KERNEL::Exception(oss.str().c_str());
581     }
582 }
583
584 void DataArray::checkNbOfElems(std::size_t nbOfElems, const std::string& msg) const
585 {
586   if(getNbOfElems()!=nbOfElems)
587     {
588       std::ostringstream oss; oss << msg << " : mismatch number of elems : Expected " << nbOfElems << " having " << getNbOfElems() << " !";
589       throw INTERP_KERNEL::Exception(oss.str().c_str());
590     }
591 }
592
593 void DataArray::checkNbOfTuplesAndComp(const DataArray& other, const std::string& msg) const
594 {
595   if(getNumberOfTuples()!=other.getNumberOfTuples())
596     {
597       std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " <<  other.getNumberOfTuples() << " having " << getNumberOfTuples() << " !";
598       throw INTERP_KERNEL::Exception(oss.str().c_str());
599     }
600   if(getNumberOfComponents()!=other.getNumberOfComponents())
601     {
602       std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << other.getNumberOfComponents() << " having " << getNumberOfComponents() << " !";
603       throw INTERP_KERNEL::Exception(oss.str().c_str());
604     }
605 }
606
607 void DataArray::checkNbOfTuplesAndComp(int nbOfTuples, int nbOfCompo, const std::string& msg) const
608 {
609   checkNbOfTuples(nbOfTuples,msg);
610   checkNbOfComps(nbOfCompo,msg);
611 }
612
613 /*!
614  * Simply this method checks that \b value is in [0,\b ref).
615  */
616 void DataArray::CheckValueInRange(int ref, int value, const std::string& msg)
617 {
618   if(value<0 || value>=ref)
619     {
620       std::ostringstream oss; oss << "DataArray::CheckValueInRange : " << msg  << " ! Expected in range [0," << ref << "[ having " << value << " !";
621       throw INTERP_KERNEL::Exception(oss.str().c_str());
622     }
623 }
624
625 /*!
626  * This method checks that [\b start, \b end) is compliant with ref length \b value.
627  * typicaly start in [0,\b value) and end in [0,\b value). If value==start and start==end, it is supported.
628  */
629 void DataArray::CheckValueInRangeEx(int value, int start, int end, const std::string& msg)
630 {
631   if(start<0 || start>=value)
632     {
633       if(value!=start || end!=start)
634         {
635           std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg  << " ! Expected start " << start << " of input range, in [0," << value << "[ !";
636           throw INTERP_KERNEL::Exception(oss.str().c_str());
637         }
638     }
639   if(end<0 || end>value)
640     {
641       std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg  << " ! Expected end " << end << " of input range, in [0," << value << "] !";
642       throw INTERP_KERNEL::Exception(oss.str().c_str());
643     }
644 }
645
646 void DataArray::CheckClosingParInRange(int ref, int value, const std::string& msg)
647 {
648   if(value<0 || value>ref)
649     {
650       std::ostringstream oss; oss << "DataArray::CheckClosingParInRange : " << msg  << " ! Expected input range in [0," << ref << "] having closing open parenthesis " << value << " !";
651       throw INTERP_KERNEL::Exception(oss.str().c_str());
652     }
653 }
654
655 /*!
656  * 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, 
657  * typically it is a whole slice of tuples of DataArray or cells, nodes of a mesh...
658  *
659  * The input \a sliceId should be an id in [0, \a nbOfSlices) that specifies the slice of work.
660  *
661  * \param [in] start - the start of the input slice of the whole work to perform splitted into slices.
662  * \param [in] stop - the stop of the input slice of the whole work to perform splitted into slices.
663  * \param [in] step - the step (that can be <0) of the input slice of the whole work to perform splitted into slices.
664  * \param [in] sliceId - the slice id considered
665  * \param [in] nbOfSlices - the number of slices (typically the number of cores on which the work is expected to be sliced)
666  * \param [out] startSlice - the start of the slice considered
667  * \param [out] stopSlice - the stop of the slice consided
668  * 
669  * \throw If \a step == 0
670  * \throw If \a nbOfSlices not > 0
671  * \throw If \a sliceId not in [0,nbOfSlices)
672  */
673 void DataArray::GetSlice(int start, int stop, int step, int sliceId, int nbOfSlices, int& startSlice, int& stopSlice)
674 {
675   if(nbOfSlices<=0)
676     {
677       std::ostringstream oss; oss << "DataArray::GetSlice : nbOfSlices (" << nbOfSlices << ") must be > 0 !";
678       throw INTERP_KERNEL::Exception(oss.str().c_str());
679     }
680   if(sliceId<0 || sliceId>=nbOfSlices)
681     {
682       std::ostringstream oss; oss << "DataArray::GetSlice : sliceId (" << nbOfSlices << ") must be in [0 , nbOfSlices (" << nbOfSlices << ") ) !";
683       throw INTERP_KERNEL::Exception(oss.str().c_str());
684     }
685   int nbElems=GetNumberOfItemGivenBESRelative(start,stop,step,"DataArray::GetSlice");
686   int minNbOfElemsPerSlice=nbElems/nbOfSlices;
687   startSlice=start+minNbOfElemsPerSlice*step*sliceId;
688   if(sliceId<nbOfSlices-1)
689     stopSlice=start+minNbOfElemsPerSlice*step*(sliceId+1);
690   else
691     stopSlice=stop;
692 }
693
694 int DataArray::GetNumberOfItemGivenBES(int begin, int end, int step, const std::string& msg)
695 {
696   if(end<begin)
697     {
698       std::ostringstream oss; oss << msg << " : end before begin !";
699       throw INTERP_KERNEL::Exception(oss.str().c_str());
700     }
701   if(end==begin)
702     return 0;
703   if(step<=0)
704     {
705       std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
706       throw INTERP_KERNEL::Exception(oss.str().c_str());
707     }
708   return (end-1-begin)/step+1;
709 }
710
711 int DataArray::GetNumberOfItemGivenBESRelative(int begin, int end, int step, const std::string& msg)
712 {
713   if(step==0)
714     throw INTERP_KERNEL::Exception("DataArray::GetNumberOfItemGivenBES : step=0 is not allowed !");
715   if(end<begin && step>0)
716     {
717       std::ostringstream oss; oss << msg << " : end before begin whereas step is positive !";
718       throw INTERP_KERNEL::Exception(oss.str().c_str());
719     }
720   if(begin<end && step<0)
721     {
722       std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
723       throw INTERP_KERNEL::Exception(oss.str().c_str());
724     }
725   if(begin!=end)
726     return (std::max(begin,end)-1-std::min(begin,end))/std::abs(step)+1;
727   else
728     return 0;
729 }
730
731 int DataArray::GetPosOfItemGivenBESRelativeNoThrow(int value, int begin, int end, int step)
732 {
733   if(step!=0)
734     {
735       if(step>0)
736         {
737           if(begin<=value && value<end)
738             {
739               if((value-begin)%step==0)
740                 return (value-begin)/step;
741               else
742                 return -1;
743             }
744           else
745             return -1;
746         }
747       else
748         {
749           if(begin>=value && value>end)
750             {
751               if((begin-value)%(-step)==0)
752                 return (begin-value)/(-step);
753               else
754                 return -1;
755             }
756           else
757             return -1;
758         }
759     }
760   else
761     return -1;
762 }
763
764 /*!
765  * Returns a new instance of DataArrayDouble. The caller is to delete this array
766  * using decrRef() as it is no more needed. 
767  */
768 DataArrayDouble *DataArrayDouble::New()
769 {
770   return new DataArrayDouble;
771 }
772
773 /*!
774  * Returns the only one value in \a this, if and only if number of elements
775  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
776  *  \return double - the sole value stored in \a this array.
777  *  \throw If at least one of conditions stated above is not fulfilled.
778  */
779 double DataArrayDouble::doubleValue() const
780 {
781   if(isAllocated())
782     {
783       if(getNbOfElems()==1)
784         {
785           return *getConstPointer();
786         }
787       else
788         throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is allocated but number of elements is not equal to 1 !");
789     }
790   else
791     throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is not allocated !");
792 }
793
794 /*!
795  * Returns a full copy of \a this. For more info on copying data arrays see
796  * \ref MEDCouplingArrayBasicsCopyDeep.
797  *  \return DataArrayDouble * - a new instance of DataArrayDouble. The caller is to
798  *          delete this array using decrRef() as it is no more needed. 
799  */
800 DataArrayDouble *DataArrayDouble::deepCopy() const
801 {
802   return new DataArrayDouble(*this);
803 }
804
805 /*!
806  * Returns either a \a deep or \a shallow copy of this array. For more info see
807  * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
808  *  \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
809  *  \return DataArrayDouble * - either a new instance of DataArrayDouble (if \a dCpy
810  *          == \a true) or \a this instance (if \a dCpy == \a false).
811  */
812 DataArrayDouble *DataArrayDouble::performCopyOrIncrRef(bool dCpy) const
813 {
814   if(dCpy)
815     return deepCopy();
816   else
817     {
818       incrRef();
819       return const_cast<DataArrayDouble *>(this);
820     }
821 }
822
823 /*!
824  * Assign zero to all values in \a this array. To know more on filling arrays see
825  * \ref MEDCouplingArrayFill.
826  * \throw If \a this is not allocated.
827  */
828 void DataArrayDouble::fillWithZero()
829 {
830   fillWithValue(0.);
831 }
832
833 /*!
834  * Set all values in \a this array so that the i-th element equals to \a init + i
835  * (i starts from zero). To know more on filling arrays see \ref MEDCouplingArrayFill.
836  *  \param [in] init - value to assign to the first element of array.
837  *  \throw If \a this->getNumberOfComponents() != 1
838  *  \throw If \a this is not allocated.
839  */
840 void DataArrayDouble::iota(double init)
841 {
842   checkAllocated();
843   if(getNumberOfComponents()!=1)
844     throw INTERP_KERNEL::Exception("DataArrayDouble::iota : works only for arrays with only one component, you can call 'rearrange' method before !");
845   double *ptr=getPointer();
846   int ntuples=getNumberOfTuples();
847   for(int i=0;i<ntuples;i++)
848     ptr[i]=init+double(i);
849   declareAsNew();
850 }
851
852 /*!
853  * Checks if all values in \a this array are equal to \a val at precision \a eps.
854  *  \param [in] val - value to check equality of array values to.
855  *  \param [in] eps - precision to check the equality.
856  *  \return bool - \a true if all values are in range (_val_ - _eps_; _val_ + _eps_),
857  *                 \a false else.
858  *  \throw If \a this->getNumberOfComponents() != 1
859  *  \throw If \a this is not allocated.
860  */
861 bool DataArrayDouble::isUniform(double val, double eps) const
862 {
863   checkAllocated();
864   if(getNumberOfComponents()!=1)
865     throw INTERP_KERNEL::Exception("DataArrayDouble::isUniform : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
866   int nbOfTuples=getNumberOfTuples();
867   const double *w=getConstPointer();
868   const double *end2=w+nbOfTuples;
869   const double vmin=val-eps;
870   const double vmax=val+eps;
871   for(;w!=end2;w++)
872     if(*w<vmin || *w>vmax)
873       return false;
874   return true;
875 }
876
877 /*!
878  * Checks that \a this array is consistently **increasing** or **decreasing** in value,
879  * with at least absolute difference value of |\a eps| at each step.
880  * If not an exception is thrown.
881  *  \param [in] increasing - if \a true, the array values should be increasing.
882  *  \param [in] eps - minimal absolute difference between the neighbor values at which 
883  *                    the values are considered different.
884  *  \throw If sequence of values is not strictly monotonic in agreement with \a
885  *         increasing arg.
886  *  \throw If \a this->getNumberOfComponents() != 1.
887  *  \throw If \a this is not allocated.
888  */
889 void DataArrayDouble::checkMonotonic(bool increasing, double eps) const
890 {
891   if(!isMonotonic(increasing,eps))
892     {
893       if (increasing)
894         throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not INCREASING monotonic !");
895       else
896         throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not DECREASING monotonic !");
897     }
898 }
899
900 /*!
901  * Checks that \a this array is consistently **increasing** or **decreasing** in value,
902  * with at least absolute difference value of |\a eps| at each step.
903  *  \param [in] increasing - if \a true, array values should be increasing.
904  *  \param [in] eps - minimal absolute difference between the neighbor values at which 
905  *                    the values are considered different.
906  *  \return bool - \a true if values change in accordance with \a increasing arg.
907  *  \throw If \a this->getNumberOfComponents() != 1.
908  *  \throw If \a this is not allocated.
909  */
910 bool DataArrayDouble::isMonotonic(bool increasing, double eps) const
911 {
912   checkAllocated();
913   if(getNumberOfComponents()!=1)
914     throw INTERP_KERNEL::Exception("DataArrayDouble::isMonotonic : only supported with 'this' array with ONE component !");
915   int nbOfElements=getNumberOfTuples();
916   const double *ptr=getConstPointer();
917   if(nbOfElements==0)
918     return true;
919   double ref=ptr[0];
920   double absEps=fabs(eps);
921   if(increasing)
922     {
923       for(int i=1;i<nbOfElements;i++)
924         {
925           if(ptr[i]<(ref+absEps))
926             return false;
927           ref=ptr[i];
928         }
929       return true;
930     }
931   else
932     {
933       for(int i=1;i<nbOfElements;i++)
934         {
935           if(ptr[i]>(ref-absEps))
936             return false;
937           ref=ptr[i];
938         }
939       return true;
940     }
941 }
942
943 /*!
944  * Returns a textual and human readable representation of \a this instance of
945  * DataArrayDouble. This text is shown when a DataArrayDouble is printed in Python.
946  * \return std::string - text describing \a this DataArrayDouble.
947  *
948  * \sa reprNotTooLong, reprZip
949  */
950 std::string DataArrayDouble::repr() const
951 {
952   std::ostringstream ret;
953   reprStream(ret);
954   return ret.str();
955 }
956
957 std::string DataArrayDouble::reprZip() const
958 {
959   std::ostringstream ret;
960   reprZipStream(ret);
961   return ret.str();
962 }
963
964 /*!
965  * This method is close to repr method except that when \a this has more than 1000 tuples, all tuples are not
966  * printed out to avoid to consume too much space in interpretor.
967  * \sa repr
968  */
969 std::string DataArrayDouble::reprNotTooLong() const
970 {
971   std::ostringstream ret;
972   reprNotTooLongStream(ret);
973   return ret.str();
974 }
975
976 void DataArrayDouble::writeVTK(std::ostream& ofs, int indent, const std::string& nameInFile, DataArrayByte *byteArr) const
977 {
978   static const char SPACE[4]={' ',' ',' ',' '};
979   checkAllocated();
980   std::string idt(indent,' ');
981   ofs.precision(17);
982   ofs << idt << "<DataArray type=\"Float32\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
983   //
984   bool areAllEmpty(true);
985   for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
986     if(!(*it).empty())
987       areAllEmpty=false;
988   if(!areAllEmpty)
989     for(std::size_t i=0;i<_info_on_compo.size();i++)
990       ofs << " ComponentName" << i << "=\"" << _info_on_compo[i] << "\"";
991   //
992   if(byteArr)
993     {
994       ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
995       INTERP_KERNEL::AutoPtr<float> tmp(new float[getNbOfElems()]);
996       float *pt(tmp);
997       // to make Visual C++ happy : instead of std::copy(begin(),end(),(float *)tmp);
998       for(const double *src=begin();src!=end();src++,pt++)
999         *pt=float(*src);
1000       const char *data(reinterpret_cast<const char *>((float *)tmp));
1001       std::size_t sz(getNbOfElems()*sizeof(float));
1002       byteArr->insertAtTheEnd(data,data+sz);
1003       byteArr->insertAtTheEnd(SPACE,SPACE+4);
1004     }
1005   else
1006     {
1007       ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
1008       std::copy(begin(),end(),std::ostream_iterator<double>(ofs," "));
1009     }
1010   ofs << std::endl << idt << "</DataArray>\n";
1011 }
1012
1013 void DataArrayDouble::reprStream(std::ostream& stream) const
1014 {
1015   stream << "Name of double array : \"" << _name << "\"\n";
1016   reprWithoutNameStream(stream);
1017 }
1018
1019 void DataArrayDouble::reprZipStream(std::ostream& stream) const
1020 {
1021   stream << "Name of double array : \"" << _name << "\"\n";
1022   reprZipWithoutNameStream(stream);
1023 }
1024
1025 void DataArrayDouble::reprNotTooLongStream(std::ostream& stream) const
1026 {
1027   stream << "Name of double array : \"" << _name << "\"\n";
1028   reprNotTooLongWithoutNameStream(stream);
1029 }
1030
1031 void DataArrayDouble::reprWithoutNameStream(std::ostream& stream) const
1032 {
1033   DataArray::reprWithoutNameStream(stream);
1034   stream.precision(17);
1035   _mem.repr(getNumberOfComponents(),stream);
1036 }
1037
1038 void DataArrayDouble::reprZipWithoutNameStream(std::ostream& stream) const
1039 {
1040   DataArray::reprWithoutNameStream(stream);
1041   stream.precision(17);
1042   _mem.reprZip(getNumberOfComponents(),stream);
1043 }
1044
1045 void DataArrayDouble::reprNotTooLongWithoutNameStream(std::ostream& stream) const
1046 {
1047   DataArray::reprWithoutNameStream(stream);
1048   stream.precision(17);
1049   _mem.reprNotTooLong(getNumberOfComponents(),stream);
1050 }
1051
1052 void DataArrayDouble::reprCppStream(const std::string& varName, std::ostream& stream) const
1053 {
1054   int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
1055   const double *data=getConstPointer();
1056   stream.precision(17);
1057   stream << "DataArrayDouble *" << varName << "=DataArrayDouble::New();" << std::endl;
1058   if(nbTuples*nbComp>=1)
1059     {
1060       stream << "const double " << varName << "Data[" << nbTuples*nbComp << "]={";
1061       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<double>(stream,","));
1062       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
1063       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
1064     }
1065   else
1066     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
1067   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
1068 }
1069
1070 /*!
1071  * Method that gives a quick overvien of \a this for python.
1072  */
1073 void DataArrayDouble::reprQuickOverview(std::ostream& stream) const
1074 {
1075   static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
1076   stream << "DataArrayDouble C++ instance at " << this << ". ";
1077   if(isAllocated())
1078     {
1079       int nbOfCompo=(int)_info_on_compo.size();
1080       if(nbOfCompo>=1)
1081         {
1082           int nbOfTuples=getNumberOfTuples();
1083           stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
1084           reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
1085         }
1086       else
1087         stream << "Number of components : 0.";
1088     }
1089   else
1090     stream << "*** No data allocated ****";
1091 }
1092
1093 void DataArrayDouble::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
1094 {
1095   const double *data=begin();
1096   int nbOfTuples=getNumberOfTuples();
1097   int nbOfCompo=(int)_info_on_compo.size();
1098   std::ostringstream oss2; oss2 << "[";
1099   oss2.precision(17);
1100   std::string oss2Str(oss2.str());
1101   bool isFinished=true;
1102   for(int i=0;i<nbOfTuples && isFinished;i++)
1103     {
1104       if(nbOfCompo>1)
1105         {
1106           oss2 << "(";
1107           for(int j=0;j<nbOfCompo;j++,data++)
1108             {
1109               oss2 << *data;
1110               if(j!=nbOfCompo-1) oss2 << ", ";
1111             }
1112           oss2 << ")";
1113         }
1114       else
1115         oss2 << *data++;
1116       if(i!=nbOfTuples-1) oss2 << ", ";
1117       std::string oss3Str(oss2.str());
1118       if(oss3Str.length()<maxNbOfByteInRepr)
1119         oss2Str=oss3Str;
1120       else
1121         isFinished=false;
1122     }
1123   stream << oss2Str;
1124   if(!isFinished)
1125     stream << "... ";
1126   stream << "]";
1127 }
1128
1129 /*!
1130  * Equivalent to DataArrayDouble::isEqual except that if false the reason of
1131  * mismatch is given.
1132  * 
1133  * \param [in] other the instance to be compared with \a this
1134  * \param [in] prec the precision to compare numeric data of the arrays.
1135  * \param [out] reason In case of inequality returns the reason.
1136  * \sa DataArrayDouble::isEqual
1137  */
1138 bool DataArrayDouble::isEqualIfNotWhy(const DataArrayDouble& other, double prec, std::string& reason) const
1139 {
1140   if(!areInfoEqualsIfNotWhy(other,reason))
1141     return false;
1142   return _mem.isEqual(other._mem,prec,reason);
1143 }
1144
1145 /*!
1146  * Checks if \a this and another DataArrayDouble are fully equal. For more info see
1147  * \ref MEDCouplingArrayBasicsCompare.
1148  *  \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1149  *  \param [in] prec - precision value to compare numeric data of the arrays.
1150  *  \return bool - \a true if the two arrays are equal, \a false else.
1151  */
1152 bool DataArrayDouble::isEqual(const DataArrayDouble& other, double prec) const
1153 {
1154   std::string tmp;
1155   return isEqualIfNotWhy(other,prec,tmp);
1156 }
1157
1158 /*!
1159  * Checks if values of \a this and another DataArrayDouble are equal. For more info see
1160  * \ref MEDCouplingArrayBasicsCompare.
1161  *  \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1162  *  \param [in] prec - precision value to compare numeric data of the arrays.
1163  *  \return bool - \a true if the values of two arrays are equal, \a false else.
1164  */
1165 bool DataArrayDouble::isEqualWithoutConsideringStr(const DataArrayDouble& other, double prec) const
1166 {
1167   std::string tmp;
1168   return _mem.isEqual(other._mem,prec,tmp);
1169 }
1170
1171 /*!
1172  * Creates a new DataArrayInt and assigns all (textual and numerical) data of \a this
1173  * array to the new one.
1174  *  \return DataArrayInt * - the new instance of DataArrayInt.
1175  */
1176 DataArrayInt *DataArrayDouble::convertToIntArr() const
1177 {
1178   DataArrayInt *ret=DataArrayInt::New();
1179   ret->alloc(getNumberOfTuples(),getNumberOfComponents());
1180   int *dest=ret->getPointer();
1181   // to make Visual C++ happy : instead of std::size_t nbOfVals=getNbOfElems(); std::copy(src,src+nbOfVals,dest);
1182   for(const double *src=begin();src!=end();src++,dest++)
1183     *dest=(int)*src;
1184   ret->copyStringInfoFrom(*this);
1185   return ret;
1186 }
1187
1188 /*!
1189  * Returns a new DataArrayDouble holding the same values as \a this array but differently
1190  * arranged in memory. If \a this array holds 2 components of 3 values:
1191  * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
1192  * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
1193  *  \warning Do not confuse this method with transpose()!
1194  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1195  *          is to delete using decrRef() as it is no more needed.
1196  *  \throw If \a this is not allocated.
1197  */
1198 DataArrayDouble *DataArrayDouble::fromNoInterlace() const
1199 {
1200   if(_mem.isNull())
1201     throw INTERP_KERNEL::Exception("DataArrayDouble::fromNoInterlace : Not defined array !");
1202   double *tab=_mem.fromNoInterlace(getNumberOfComponents());
1203   DataArrayDouble *ret=DataArrayDouble::New();
1204   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
1205   return ret;
1206 }
1207
1208 /*!
1209  * Returns a new DataArrayDouble holding the same values as \a this array but differently
1210  * arranged in memory. If \a this array holds 2 components of 3 values:
1211  * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
1212  * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
1213  *  \warning Do not confuse this method with transpose()!
1214  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1215  *          is to delete using decrRef() as it is no more needed.
1216  *  \throw If \a this is not allocated.
1217  */
1218 DataArrayDouble *DataArrayDouble::toNoInterlace() const
1219 {
1220   if(_mem.isNull())
1221     throw INTERP_KERNEL::Exception("DataArrayDouble::toNoInterlace : Not defined array !");
1222   double *tab=_mem.toNoInterlace(getNumberOfComponents());
1223   DataArrayDouble *ret=DataArrayDouble::New();
1224   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
1225   return ret;
1226 }
1227
1228 /*!
1229  * Appends components of another array to components of \a this one, tuple by tuple.
1230  * So that the number of tuples of \a this array remains the same and the number of 
1231  * components increases.
1232  *  \param [in] other - the DataArrayDouble to append to \a this one.
1233  *  \throw If \a this is not allocated.
1234  *  \throw If \a this and \a other arrays have different number of tuples.
1235  *
1236  *  \if ENABLE_EXAMPLES
1237  *  \ref cpp_mcdataarraydouble_meldwith "Here is a C++ example".
1238  *
1239  *  \ref py_mcdataarraydouble_meldwith "Here is a Python example".
1240  *  \endif
1241  */
1242 void DataArrayDouble::meldWith(const DataArrayDouble *other)
1243 {
1244   checkAllocated();
1245   other->checkAllocated();
1246   int nbOfTuples=getNumberOfTuples();
1247   if(nbOfTuples!=other->getNumberOfTuples())
1248     throw INTERP_KERNEL::Exception("DataArrayDouble::meldWith : mismatch of number of tuples !");
1249   int nbOfComp1=getNumberOfComponents();
1250   int nbOfComp2=other->getNumberOfComponents();
1251   double *newArr=(double *)malloc((nbOfTuples*(nbOfComp1+nbOfComp2))*sizeof(double));
1252   double *w=newArr;
1253   const double *inp1=getConstPointer();
1254   const double *inp2=other->getConstPointer();
1255   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
1256     {
1257       w=std::copy(inp1,inp1+nbOfComp1,w);
1258       w=std::copy(inp2,inp2+nbOfComp2,w);
1259     }
1260   useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
1261   std::vector<int> compIds(nbOfComp2);
1262   for(int i=0;i<nbOfComp2;i++)
1263     compIds[i]=nbOfComp1+i;
1264   copyPartOfStringInfoFrom2(compIds,*other);
1265 }
1266
1267 /*!
1268  * This method checks that all tuples in \a other are in \a this.
1269  * If true, the output param \a tupleIds contains the tuples ids of \a this that correspond to tupes in \a this.
1270  * 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.
1271  *
1272  * \param [in] other - the array having the same number of components than \a this.
1273  * \param [out] tupleIds - the tuple ids containing the same number of tuples than \a other has.
1274  * \sa DataArrayDouble::findCommonTuples
1275  */
1276 bool DataArrayDouble::areIncludedInMe(const DataArrayDouble *other, double prec, DataArrayInt *&tupleIds) const
1277 {
1278   if(!other)
1279     throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : input array is NULL !");
1280   checkAllocated(); other->checkAllocated();
1281   if(getNumberOfComponents()!=other->getNumberOfComponents())
1282     throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : the number of components does not match !");
1283   MCAuto<DataArrayDouble> a=DataArrayDouble::Aggregate(this,other);
1284   DataArrayInt *c=0,*ci=0;
1285   a->findCommonTuples(prec,getNumberOfTuples(),c,ci);
1286   MCAuto<DataArrayInt> cSafe(c),ciSafe(ci);
1287   int newNbOfTuples=-1;
1288   MCAuto<DataArrayInt> ids=DataArrayInt::ConvertIndexArrayToO2N(a->getNumberOfTuples(),c->begin(),ci->begin(),ci->end(),newNbOfTuples);
1289   MCAuto<DataArrayInt> ret1=ids->selectByTupleIdSafeSlice(getNumberOfTuples(),a->getNumberOfTuples(),1);
1290   tupleIds=ret1.retn();
1291   return newNbOfTuples==getNumberOfTuples();
1292 }
1293
1294 /*!
1295  * Searches for tuples coincident within \a prec tolerance. Each tuple is considered
1296  * as coordinates of a point in getNumberOfComponents()-dimensional space. The
1297  * distance separating two points is computed with the infinite norm.
1298  *
1299  * Indices of coincident tuples are stored in output arrays.
1300  * A pair of arrays (\a comm, \a commIndex) is called "Surjective Format 2".
1301  *
1302  * This method is typically used by MEDCouplingPointSet::findCommonNodes() and
1303  * MEDCouplingUMesh::mergeNodes().
1304  *  \param [in] prec - minimal absolute distance between two tuples (infinite norm) at which they are
1305  *              considered not coincident.
1306  *  \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
1307  *              tuples have id strictly lower than \a limitTupleId then they are not returned.
1308  *  \param [out] comm - the array holding ids (== indices) of coincident tuples. 
1309  *               \a comm->getNumberOfComponents() == 1. 
1310  *               \a comm->getNumberOfTuples() == \a commIndex->back().
1311  *  \param [out] commIndex - the array dividing all indices stored in \a comm into
1312  *               groups of (indices of) coincident tuples. Its every value is a tuple
1313  *               index where a next group of tuples begins. For example the second
1314  *               group of tuples in \a comm is described by following range of indices:
1315  *               [ \a commIndex[1], \a commIndex[2] ). \a commIndex->getNumberOfTuples()-1
1316  *               gives the number of groups of coincident tuples.
1317  *  \throw If \a this is not allocated.
1318  *  \throw If the number of components is not in [1,2,3,4].
1319  *
1320  *  \if ENABLE_EXAMPLES
1321  *  \ref cpp_mcdataarraydouble_findcommontuples "Here is a C++ example".
1322  *
1323  *  \ref py_mcdataarraydouble_findcommontuples  "Here is a Python example".
1324  *  \endif
1325  *  \sa DataArrayInt::ConvertIndexArrayToO2N(), DataArrayDouble::areIncludedInMe
1326  */
1327 void DataArrayDouble::findCommonTuples(double prec, int limitTupleId, DataArrayInt *&comm, DataArrayInt *&commIndex) const
1328 {
1329   checkAllocated();
1330   int nbOfCompo=getNumberOfComponents();
1331   if ((nbOfCompo<1) || (nbOfCompo>4)) //test before work
1332     throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : Unexpected spacedim of coords. Must be 1, 2, 3 or 4.");
1333
1334   int nbOfTuples=getNumberOfTuples();
1335   //
1336   MCAuto<DataArrayInt> c(DataArrayInt::New()),cI(DataArrayInt::New()); c->alloc(0,1); cI->pushBackSilent(0);
1337   switch(nbOfCompo)
1338   {
1339     case 4:
1340       findCommonTuplesAlg<4>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1341       break;
1342     case 3:
1343       findCommonTuplesAlg<3>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1344       break;
1345     case 2:
1346       findCommonTuplesAlg<2>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1347       break;
1348     case 1:
1349       findCommonTuplesAlg<1>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1350       break;
1351     default:
1352       throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : nb of components managed are 1,2,3 and 4 ! not implemented for other number of components !");
1353   }
1354   comm=c.retn();
1355   commIndex=cI.retn();
1356 }
1357
1358 /*!
1359  * 
1360  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayDouble instance.
1361  *             \a nbTimes  should be at least equal to 1.
1362  * \return a newly allocated DataArrayDouble having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
1363  * \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.
1364  */
1365 DataArrayDouble *DataArrayDouble::duplicateEachTupleNTimes(int nbTimes) const
1366 {
1367   checkAllocated();
1368   if(getNumberOfComponents()!=1)
1369     throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : this should have only one component !");
1370   if(nbTimes<1)
1371     throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : nb times should be >= 1 !");
1372   int nbTuples=getNumberOfTuples();
1373   const double *inPtr=getConstPointer();
1374   MCAuto<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbTimes*nbTuples,1);
1375   double *retPtr=ret->getPointer();
1376   for(int i=0;i<nbTuples;i++,inPtr++)
1377     {
1378       double val=*inPtr;
1379       for(int j=0;j<nbTimes;j++,retPtr++)
1380         *retPtr=val;
1381     }
1382   ret->copyStringInfoFrom(*this);
1383   return ret.retn();
1384 }
1385
1386 /*!
1387  * This methods returns the minimal distance between the two set of points \a this and \a other.
1388  * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
1389  * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
1390  *
1391  * \param [out] thisTupleId the tuple id in \a this corresponding to the returned minimal distance
1392  * \param [out] otherTupleId the tuple id in \a other corresponding to the returned minimal distance
1393  * \return the minimal distance between the two set of points \a this and \a other.
1394  * \sa DataArrayDouble::findClosestTupleId
1395  */
1396 double DataArrayDouble::minimalDistanceTo(const DataArrayDouble *other, int& thisTupleId, int& otherTupleId) const
1397 {
1398   MCAuto<DataArrayInt> part1=findClosestTupleId(other);
1399   int nbOfCompo(getNumberOfComponents());
1400   int otherNbTuples(other->getNumberOfTuples());
1401   const double *thisPt(begin()),*otherPt(other->begin());
1402   const int *part1Pt(part1->begin());
1403   double ret=std::numeric_limits<double>::max();
1404   for(int i=0;i<otherNbTuples;i++,part1Pt++,otherPt+=nbOfCompo)
1405     {
1406       double tmp(0.);
1407       for(int j=0;j<nbOfCompo;j++)
1408         tmp+=(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j])*(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j]);
1409       if(tmp<ret)
1410         { ret=tmp; thisTupleId=*part1Pt; otherTupleId=i; }
1411     }
1412   return sqrt(ret);
1413 }
1414
1415 /*!
1416  * This methods returns for each tuple in \a other which tuple in \a this is the closest.
1417  * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
1418  * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
1419  *
1420  * \return a newly allocated (new object to be dealt by the caller) DataArrayInt having \c other->getNumberOfTuples() tuples and one components.
1421  * \sa DataArrayDouble::minimalDistanceTo
1422  */
1423 DataArrayInt *DataArrayDouble::findClosestTupleId(const DataArrayDouble *other) const
1424 {
1425   if(!other)
1426     throw INTERP_KERNEL::Exception("DataArrayDouble::findClosestTupleId : other instance is NULL !");
1427   checkAllocated(); other->checkAllocated();
1428   int nbOfCompo=getNumberOfComponents();
1429   if(nbOfCompo!=other->getNumberOfComponents())
1430     {
1431       std::ostringstream oss; oss << "DataArrayDouble::findClosestTupleId : number of components in this is " << nbOfCompo;
1432       oss << ", whereas number of components in other is " << other->getNumberOfComponents() << "! Should be equal !";
1433       throw INTERP_KERNEL::Exception(oss.str().c_str());
1434     }
1435   int nbOfTuples=other->getNumberOfTuples();
1436   int thisNbOfTuples=getNumberOfTuples();
1437   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuples,1);
1438   double bounds[6];
1439   getMinMaxPerComponent(bounds);
1440   switch(nbOfCompo)
1441   {
1442     case 3:
1443       {
1444         double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2])),zDelta(fabs(bounds[5]-bounds[4]));
1445         double delta=std::max(xDelta,yDelta); delta=std::max(delta,zDelta);
1446         double characSize=pow((delta*delta*delta)/((double)thisNbOfTuples),1./3.);
1447         BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1448         FindClosestTupleIdAlg<3>(myTree,3.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1449         break;
1450       }
1451     case 2:
1452       {
1453         double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2]));
1454         double delta=std::max(xDelta,yDelta);
1455         double characSize=sqrt(delta/(double)thisNbOfTuples);
1456         BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1457         FindClosestTupleIdAlg<2>(myTree,2.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1458         break;
1459       }
1460     case 1:
1461       {
1462         double characSize=fabs(bounds[1]-bounds[0])/thisNbOfTuples;
1463         BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1464         FindClosestTupleIdAlg<1>(myTree,1.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1465         break;
1466       }
1467     default:
1468       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for findClosestTupleId. Must be 1, 2 or 3.");
1469   }
1470   return ret.retn();
1471 }
1472
1473 /*!
1474  * This method expects that \a this and \a otherBBoxFrmt arrays are bounding box arrays ( as the output of MEDCouplingPointSet::getBoundingBoxForBBTree method ).
1475  * 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
1476  * how many bounding boxes in \a otherBBoxFrmt.
1477  * So, this method expects that \a this and \a otherBBoxFrmt have the same number of components.
1478  *
1479  * \param [in] otherBBoxFrmt - It is an array .
1480  * \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.
1481  * \sa MEDCouplingPointSet::getBoundingBoxForBBTree
1482  * \throw If \a this and \a otherBBoxFrmt have not the same number of components.
1483  * \throw If \a this and \a otherBBoxFrmt number of components is not even (BBox format).
1484  */
1485 DataArrayInt *DataArrayDouble::computeNbOfInteractionsWith(const DataArrayDouble *otherBBoxFrmt, double eps) const
1486 {
1487   if(!otherBBoxFrmt)
1488     throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : input array is NULL !");
1489   if(!isAllocated() || !otherBBoxFrmt->isAllocated())
1490     throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : this and input array must be allocated !");
1491   int nbOfComp(getNumberOfComponents()),nbOfTuples(getNumberOfTuples());
1492   if(nbOfComp!=otherBBoxFrmt->getNumberOfComponents())
1493     {
1494       std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : this number of components (" << nbOfComp << ") must be equal to the number of components of input array (" << otherBBoxFrmt->getNumberOfComponents() << ") !";
1495       throw INTERP_KERNEL::Exception(oss.str().c_str());
1496     }
1497   if(nbOfComp%2!=0)
1498     {
1499       std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : Number of components (" << nbOfComp << ") is not even ! It should be to be compatible with bbox format !";
1500       throw INTERP_KERNEL::Exception(oss.str().c_str());
1501     }
1502   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbOfTuples,1);
1503   const double *thisBBPtr(begin());
1504   int *retPtr(ret->getPointer());
1505   switch(nbOfComp/2)
1506   {
1507     case 3:
1508       {
1509         BBTree<3,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
1510         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
1511           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
1512         break;
1513       }
1514     case 2:
1515       {
1516         BBTree<2,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
1517         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
1518           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
1519         break;
1520       }
1521     case 1:
1522       {
1523         BBTree<1,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
1524         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
1525           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
1526         break;
1527       }
1528     default:
1529       throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : space dimension supported are [1,2,3] !");
1530   }
1531
1532   return ret.retn();
1533 }
1534
1535 /*!
1536  * Returns a copy of \a this array by excluding coincident tuples. Each tuple is
1537  * considered as coordinates of a point in getNumberOfComponents()-dimensional
1538  * space. The distance between tuples is computed using norm2. If several tuples are
1539  * not far each from other than \a prec, only one of them remains in the result
1540  * array. The order of tuples in the result array is same as in \a this one except
1541  * that coincident tuples are excluded.
1542  *  \param [in] prec - minimal absolute distance between two tuples at which they are
1543  *              considered not coincident.
1544  *  \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
1545  *              tuples have id strictly lower than \a limitTupleId then they are not excluded.
1546  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1547  *          is to delete using decrRef() as it is no more needed.
1548  *  \throw If \a this is not allocated.
1549  *  \throw If the number of components is not in [1,2,3,4].
1550  *
1551  *  \if ENABLE_EXAMPLES
1552  *  \ref py_mcdataarraydouble_getdifferentvalues "Here is a Python example".
1553  *  \endif
1554  */
1555 DataArrayDouble *DataArrayDouble::getDifferentValues(double prec, int limitTupleId) const
1556 {
1557   checkAllocated();
1558   DataArrayInt *c0=0,*cI0=0;
1559   findCommonTuples(prec,limitTupleId,c0,cI0);
1560   MCAuto<DataArrayInt> c(c0),cI(cI0);
1561   int newNbOfTuples=-1;
1562   MCAuto<DataArrayInt> o2n=DataArrayInt::ConvertIndexArrayToO2N(getNumberOfTuples(),c0->begin(),cI0->begin(),cI0->end(),newNbOfTuples);
1563   return renumberAndReduce(o2n->getConstPointer(),newNbOfTuples);
1564 }
1565
1566 /*!
1567  * Copy all components in a specified order from another DataArrayDouble.
1568  * Both numerical and textual data is copied. The number of tuples in \a this and
1569  * the other array can be different.
1570  *  \param [in] a - the array to copy data from.
1571  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
1572  *              to be copied.
1573  *  \throw If \a a is NULL.
1574  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
1575  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
1576  *
1577  *  \if ENABLE_EXAMPLES
1578  *  \ref py_mcdataarraydouble_setselectedcomponents "Here is a Python example".
1579  *  \endif
1580  */
1581 void DataArrayDouble::setSelectedComponents(const DataArrayDouble *a, const std::vector<int>& compoIds)
1582 {
1583   if(!a)
1584     throw INTERP_KERNEL::Exception("DataArrayDouble::setSelectedComponents : input DataArrayDouble is NULL !");
1585   checkAllocated();
1586   copyPartOfStringInfoFrom2(compoIds,*a);
1587   std::size_t partOfCompoSz=compoIds.size();
1588   int nbOfCompo=getNumberOfComponents();
1589   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
1590   const double *ac=a->getConstPointer();
1591   double *nc=getPointer();
1592   for(int i=0;i<nbOfTuples;i++)
1593     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
1594       nc[nbOfCompo*i+compoIds[j]]=*ac;
1595 }
1596
1597 void DataArrayDouble::SetArrayIn(DataArrayDouble *newArray, DataArrayDouble* &arrayToSet)
1598 {
1599   if(newArray!=arrayToSet)
1600     {
1601       if(arrayToSet)
1602         arrayToSet->decrRef();
1603       arrayToSet=newArray;
1604       if(arrayToSet)
1605         arrayToSet->incrRef();
1606     }
1607 }
1608
1609 void DataArrayDouble::aggregate(const DataArrayDouble *other)
1610 {
1611   if(!other)
1612     throw INTERP_KERNEL::Exception("DataArrayDouble::aggregate : null pointer !");
1613   if(getNumberOfComponents()!=other->getNumberOfComponents())
1614     throw INTERP_KERNEL::Exception("DataArrayDouble::aggregate : mismatch number of components !");
1615   _mem.insertAtTheEnd(other->begin(),other->end());
1616 }
1617
1618 /*!
1619  * Checks if 0.0 value is present in \a this array. If it is the case, an exception
1620  * is thrown.
1621  * \throw If zero is found in \a this array.
1622  */
1623 void DataArrayDouble::checkNoNullValues() const
1624 {
1625   const double *tmp=getConstPointer();
1626   std::size_t nbOfElems=getNbOfElems();
1627   const double *where=std::find(tmp,tmp+nbOfElems,0.);
1628   if(where!=tmp+nbOfElems)
1629     throw INTERP_KERNEL::Exception("A value 0.0 have been detected !");
1630 }
1631
1632 /*!
1633  * Computes minimal and maximal value in each component. An output array is filled
1634  * with \c 2 * \a this->getNumberOfComponents() values, so the caller is to allocate
1635  * enough memory before calling this method.
1636  *  \param [out] bounds - array of size at least 2 *\a this->getNumberOfComponents().
1637  *               It is filled as follows:<br>
1638  *               \a bounds[0] = \c min_of_component_0 <br>
1639  *               \a bounds[1] = \c max_of_component_0 <br>
1640  *               \a bounds[2] = \c min_of_component_1 <br>
1641  *               \a bounds[3] = \c max_of_component_1 <br>
1642  *               ...
1643  */
1644 void DataArrayDouble::getMinMaxPerComponent(double *bounds) const
1645 {
1646   checkAllocated();
1647   int dim=getNumberOfComponents();
1648   for (int idim=0; idim<dim; idim++)
1649     {
1650       bounds[idim*2]=std::numeric_limits<double>::max();
1651       bounds[idim*2+1]=-std::numeric_limits<double>::max();
1652     } 
1653   const double *ptr=getConstPointer();
1654   int nbOfTuples=getNumberOfTuples();
1655   for(int i=0;i<nbOfTuples;i++)
1656     {
1657       for(int idim=0;idim<dim;idim++)
1658         {
1659           if(bounds[idim*2]>ptr[i*dim+idim])
1660             {
1661               bounds[idim*2]=ptr[i*dim+idim];
1662             }
1663           if(bounds[idim*2+1]<ptr[i*dim+idim])
1664             {
1665               bounds[idim*2+1]=ptr[i*dim+idim];
1666             }
1667         }
1668     }
1669 }
1670
1671 /*!
1672  * This method retrieves a newly allocated DataArrayDouble instance having same number of tuples than \a this and twice number of components than \a this
1673  * to store both the min and max per component of each tuples. 
1674  * \param [in] epsilon the width of the bbox (identical in each direction) - 0.0 by default
1675  *
1676  * \return a newly created DataArrayDouble instance having \c this->getNumberOfTuples() tuples and 2 * \c this->getNumberOfComponent() components
1677  *
1678  * \throw If \a this is not allocated yet.
1679  */
1680 DataArrayDouble *DataArrayDouble::computeBBoxPerTuple(double epsilon) const
1681 {
1682   checkAllocated();
1683   const double *dataPtr=getConstPointer();
1684   int nbOfCompo=getNumberOfComponents();
1685   int nbTuples=getNumberOfTuples();
1686   MCAuto<DataArrayDouble> bbox=DataArrayDouble::New();
1687   bbox->alloc(nbTuples,2*nbOfCompo);
1688   double *bboxPtr=bbox->getPointer();
1689   for(int i=0;i<nbTuples;i++)
1690     {
1691       for(int j=0;j<nbOfCompo;j++)
1692         {
1693           bboxPtr[2*nbOfCompo*i+2*j]=dataPtr[nbOfCompo*i+j]-epsilon;
1694           bboxPtr[2*nbOfCompo*i+2*j+1]=dataPtr[nbOfCompo*i+j]+epsilon;
1695         }
1696     }
1697   return bbox.retn();
1698 }
1699
1700 /*!
1701  * For each tuples **t** in \a other, this method retrieves tuples in \a this that are equal to **t**.
1702  * Two tuples are considered equal if the euclidian distance between the two tuples is lower than \a eps.
1703  * 
1704  * \param [in] other a DataArrayDouble having same number of components than \a this.
1705  * \param [in] eps absolute precision representing distance (using infinite norm) between 2 tuples behind which 2 tuples are considered equal.
1706  * \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.
1707  *             \a cI allows to extract information in \a c.
1708  * \param [out] cI is an indirection array that allows to extract the data contained in \a c.
1709  *
1710  * \throw In case of:
1711  *  - \a this is not allocated
1712  *  - \a other is not allocated or null
1713  *  - \a this and \a other do not have the same number of components
1714  *  - if number of components of \a this is not in [1,2,3]
1715  *
1716  * \sa MEDCouplingPointSet::getNodeIdsNearPoints, DataArrayDouble::getDifferentValues
1717  */
1718 void DataArrayDouble::computeTupleIdsNearTuples(const DataArrayDouble *other, double eps, DataArrayInt *& c, DataArrayInt *& cI) const
1719 {
1720   if(!other)
1721     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : input pointer other is null !");
1722   checkAllocated();
1723   other->checkAllocated();
1724   int nbOfCompo=getNumberOfComponents();
1725   int otherNbOfCompo=other->getNumberOfComponents();
1726   if(nbOfCompo!=otherNbOfCompo)
1727     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : number of components should be equal between this and other !");
1728   int nbOfTuplesOther=other->getNumberOfTuples();
1729   MCAuto<DataArrayInt> cArr(DataArrayInt::New()),cIArr(DataArrayInt::New()); cArr->alloc(0,1); cIArr->pushBackSilent(0);
1730   switch(nbOfCompo)
1731   {
1732     case 3:
1733       {
1734         BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
1735         FindTupleIdsNearTuplesAlg<3>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
1736         break;
1737       }
1738     case 2:
1739       {
1740         BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
1741         FindTupleIdsNearTuplesAlg<2>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
1742         break;
1743       }
1744     case 1:
1745       {
1746         BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
1747         FindTupleIdsNearTuplesAlg<1>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
1748         break;
1749       }
1750     default:
1751       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for computeTupleIdsNearTuples. Must be 1, 2 or 3.");
1752   }
1753   c=cArr.retn(); cI=cIArr.retn();
1754 }
1755
1756 /*!
1757  * 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
1758  * around origin of 'radius' 1.
1759  * 
1760  * \param [in] eps absolute epsilon. under that value of delta between max and min no scale is performed.
1761  */
1762 void DataArrayDouble::recenterForMaxPrecision(double eps)
1763 {
1764   checkAllocated();
1765   int dim=getNumberOfComponents();
1766   std::vector<double> bounds(2*dim);
1767   getMinMaxPerComponent(&bounds[0]);
1768   for(int i=0;i<dim;i++)
1769     {
1770       double delta=bounds[2*i+1]-bounds[2*i];
1771       double offset=(bounds[2*i]+bounds[2*i+1])/2.;
1772       if(delta>eps)
1773         applyLin(1./delta,-offset/delta,i);
1774       else
1775         applyLin(1.,-offset,i);
1776     }
1777 }
1778
1779 /*!
1780  * Returns the maximal value and all its locations within \a this one-dimensional array.
1781  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
1782  *               tuples holding the maximal value. The caller is to delete it using
1783  *               decrRef() as it is no more needed.
1784  *  \return double - the maximal value among all values of \a this array.
1785  *  \throw If \a this->getNumberOfComponents() != 1
1786  *  \throw If \a this->getNumberOfTuples() < 1
1787  */
1788 double DataArrayDouble::getMaxValue2(DataArrayInt*& tupleIds) const
1789 {
1790   int tmp;
1791   tupleIds=0;
1792   double ret=getMaxValue(tmp);
1793   tupleIds=findIdsInRange(ret,ret);
1794   return ret;
1795 }
1796
1797 /*!
1798  * Returns the minimal value and all its locations within \a this one-dimensional array.
1799  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
1800  *               tuples holding the minimal value. The caller is to delete it using
1801  *               decrRef() as it is no more needed.
1802  *  \return double - the minimal value among all values of \a this array.
1803  *  \throw If \a this->getNumberOfComponents() != 1
1804  *  \throw If \a this->getNumberOfTuples() < 1
1805  */
1806 double DataArrayDouble::getMinValue2(DataArrayInt*& tupleIds) const
1807 {
1808   int tmp;
1809   tupleIds=0;
1810   double ret=getMinValue(tmp);
1811   tupleIds=findIdsInRange(ret,ret);
1812   return ret;
1813 }
1814
1815 /*!
1816  * 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.
1817  * This method only works for single component array.
1818  *
1819  * \return a value in [ 0, \c this->getNumberOfTuples() )
1820  *
1821  * \throw If \a this is not allocated
1822  *
1823  */
1824 int DataArrayDouble::count(double value, double eps) const
1825 {
1826   int ret=0;
1827   checkAllocated();
1828   if(getNumberOfComponents()!=1)
1829     throw INTERP_KERNEL::Exception("DataArrayDouble::count : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
1830   const double *vals=begin();
1831   int nbOfTuples=getNumberOfTuples();
1832   for(int i=0;i<nbOfTuples;i++,vals++)
1833     if(fabs(*vals-value)<=eps)
1834       ret++;
1835   return ret;
1836 }
1837
1838 /*!
1839  * Returns the average value of \a this one-dimensional array.
1840  *  \return double - the average value over all values of \a this array.
1841  *  \throw If \a this->getNumberOfComponents() != 1
1842  *  \throw If \a this->getNumberOfTuples() < 1
1843  */
1844 double DataArrayDouble::getAverageValue() const
1845 {
1846   if(getNumberOfComponents()!=1)
1847     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
1848   int nbOfTuples=getNumberOfTuples();
1849   if(nbOfTuples<=0)
1850     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : array exists but number of tuples must be > 0 !");
1851   const double *vals=getConstPointer();
1852   double ret=std::accumulate(vals,vals+nbOfTuples,0.);
1853   return ret/nbOfTuples;
1854 }
1855
1856 /*!
1857  * Returns the Euclidean norm of the vector defined by \a this array.
1858  *  \return double - the value of the Euclidean norm, i.e.
1859  *          the square root of the inner product of vector.
1860  *  \throw If \a this is not allocated.
1861  */
1862 double DataArrayDouble::norm2() const
1863 {
1864   checkAllocated();
1865   double ret=0.;
1866   std::size_t nbOfElems=getNbOfElems();
1867   const double *pt=getConstPointer();
1868   for(std::size_t i=0;i<nbOfElems;i++,pt++)
1869     ret+=(*pt)*(*pt);
1870   return sqrt(ret);
1871 }
1872
1873 /*!
1874  * Returns the maximum norm of the vector defined by \a this array.
1875  * This method works even if the number of components is diferent from one.
1876  * If the number of elements in \a this is 0, -1. is returned.
1877  *  \return double - the value of the maximum norm, i.e.
1878  *          the maximal absolute value among values of \a this array (whatever its number of components).
1879  *  \throw If \a this is not allocated.
1880  */
1881 double DataArrayDouble::normMax() const
1882 {
1883   checkAllocated();
1884   double ret(-1.);
1885   std::size_t nbOfElems(getNbOfElems());
1886   const double *pt(getConstPointer());
1887   for(std::size_t i=0;i<nbOfElems;i++,pt++)
1888     {
1889       double val(std::abs(*pt));
1890       if(val>ret)
1891         ret=val;
1892     }
1893   return ret;
1894 }
1895
1896 /*!
1897  * Returns the minimum norm (absolute value) of the vector defined by \a this array.
1898  * This method works even if the number of components is diferent from one.
1899  * If the number of elements in \a this is 0, std::numeric_limits<double>::max() is returned.
1900  *  \return double - the value of the minimum norm, i.e.
1901  *          the minimal absolute value among values of \a this array (whatever its number of components).
1902  *  \throw If \a this is not allocated.
1903  */
1904 double DataArrayDouble::normMin() const
1905 {
1906   checkAllocated();
1907   double ret(std::numeric_limits<double>::max());
1908   std::size_t nbOfElems(getNbOfElems());
1909   const double *pt(getConstPointer());
1910   for(std::size_t i=0;i<nbOfElems;i++,pt++)
1911     {
1912       double val(std::abs(*pt));
1913       if(val<ret)
1914         ret=val;
1915     }
1916   return ret;
1917 }
1918
1919 /*!
1920  * Accumulates values of each component of \a this array.
1921  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
1922  *         by the caller, that is filled by this method with sum value for each
1923  *         component.
1924  *  \throw If \a this is not allocated.
1925  */
1926 void DataArrayDouble::accumulate(double *res) const
1927 {
1928   checkAllocated();
1929   const double *ptr=getConstPointer();
1930   int nbTuple=getNumberOfTuples();
1931   int nbComps=getNumberOfComponents();
1932   std::fill(res,res+nbComps,0.);
1933   for(int i=0;i<nbTuple;i++)
1934     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<double>());
1935 }
1936
1937 /*!
1938  * This method returns the min distance from an external tuple defined by [ \a tupleBg , \a tupleEnd ) to \a this and
1939  * the first tuple in \a this that matches the returned distance. If there is no tuples in \a this an exception will be thrown.
1940  *
1941  *
1942  * \a this is expected to be allocated and expected to have a number of components equal to the distance from \a tupleBg to
1943  * \a tupleEnd. If not an exception will be thrown.
1944  *
1945  * \param [in] tupleBg start pointer (included) of input external tuple
1946  * \param [in] tupleEnd end pointer (not included) of input external tuple
1947  * \param [out] tupleId the tuple id in \a this that matches the min of distance between \a this and input external tuple
1948  * \return the min distance.
1949  * \sa MEDCouplingUMesh::distanceToPoint
1950  */
1951 double DataArrayDouble::distanceToTuple(const double *tupleBg, const double *tupleEnd, int& tupleId) const
1952 {
1953   checkAllocated();
1954   int nbTuple=getNumberOfTuples();
1955   int nbComps=getNumberOfComponents();
1956   if(nbComps!=(int)std::distance(tupleBg,tupleEnd))
1957     { 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()); }
1958   if(nbTuple==0)
1959     throw INTERP_KERNEL::Exception("DataArrayDouble::distanceToTuple : no tuple in this ! No distance to compute !");
1960   double ret0=std::numeric_limits<double>::max();
1961   tupleId=-1;
1962   const double *work=getConstPointer();
1963   for(int i=0;i<nbTuple;i++)
1964     {
1965       double val=0.;
1966       for(int j=0;j<nbComps;j++,work++) 
1967         val+=(*work-tupleBg[j])*((*work-tupleBg[j]));
1968       if(val>=ret0)
1969         continue;
1970       else
1971         { ret0=val; tupleId=i; }
1972     }
1973   return sqrt(ret0);
1974 }
1975
1976 /*!
1977  * Accumulate values of the given component of \a this array.
1978  *  \param [in] compId - the index of the component of interest.
1979  *  \return double - a sum value of \a compId-th component.
1980  *  \throw If \a this is not allocated.
1981  *  \throw If \a the condition ( 0 <= \a compId < \a this->getNumberOfComponents() ) is
1982  *         not respected.
1983  */
1984 double DataArrayDouble::accumulate(int compId) const
1985 {
1986   checkAllocated();
1987   const double *ptr=getConstPointer();
1988   int nbTuple=getNumberOfTuples();
1989   int nbComps=getNumberOfComponents();
1990   if(compId<0 || compId>=nbComps)
1991     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulate : Invalid compId specified : No such nb of components !");
1992   double ret=0.;
1993   for(int i=0;i<nbTuple;i++)
1994     ret+=ptr[i*nbComps+compId];
1995   return ret;
1996 }
1997
1998 /*!
1999  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
2000  * The returned array will have same number of components than \a this and number of tuples equal to
2001  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
2002  *
2003  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
2004  * 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.
2005  *
2006  * \param [in] bgOfIndex - begin (included) of the input index array.
2007  * \param [in] endOfIndex - end (excluded) of the input index array.
2008  * \return DataArrayDouble * - the new instance having the same number of components than \a this.
2009  * 
2010  * \throw If bgOfIndex or end is NULL.
2011  * \throw If input index array is not ascendingly sorted.
2012  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
2013  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
2014  */
2015 DataArrayDouble *DataArrayDouble::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
2016 {
2017   if(!bgOfIndex || !endOfIndex)
2018     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : input pointer NULL !");
2019   checkAllocated();
2020   int nbCompo=getNumberOfComponents();
2021   int nbOfTuples=getNumberOfTuples();
2022   int sz=(int)std::distance(bgOfIndex,endOfIndex);
2023   if(sz<1)
2024     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : invalid size of input index array !");
2025   sz--;
2026   MCAuto<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(sz,nbCompo);
2027   const int *w=bgOfIndex;
2028   if(*w<0 || *w>=nbOfTuples)
2029     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
2030   const double *srcPt=begin()+(*w)*nbCompo;
2031   double *tmp=ret->getPointer();
2032   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
2033     {
2034       std::fill(tmp,tmp+nbCompo,0.);
2035       if(w[1]>=w[0])
2036         {
2037           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
2038             {
2039               if(j>=0 && j<nbOfTuples)
2040                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<double>());
2041               else
2042                 {
2043                   std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
2044                   throw INTERP_KERNEL::Exception(oss.str().c_str());
2045                 }
2046             }
2047         }
2048       else
2049         {
2050           std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
2051           throw INTERP_KERNEL::Exception(oss.str().c_str());
2052         }
2053     }
2054   ret->copyStringInfoFrom(*this);
2055   return ret.retn();
2056 }
2057
2058 /*!
2059  * Converts each 2D point defined by the tuple of \a this array from the Polar to the
2060  * Cartesian coordinate system. The two components of the tuple of \a this array are 
2061  * considered to contain (1) radius and (2) angle of the point in the Polar CS.
2062  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
2063  *          contains X and Y coordinates of the point in the Cartesian CS. The caller
2064  *          is to delete this array using decrRef() as it is no more needed. The array
2065  *          does not contain any textual info on components.
2066  *  \throw If \a this->getNumberOfComponents() != 2.
2067  * \sa fromCartToPolar
2068  */
2069 DataArrayDouble *DataArrayDouble::fromPolarToCart() const
2070 {
2071   checkAllocated();
2072   int nbOfComp(getNumberOfComponents());
2073   if(nbOfComp!=2)
2074     throw INTERP_KERNEL::Exception("DataArrayDouble::fromPolarToCart : must be an array with exactly 2 components !");
2075   int nbOfTuple(getNumberOfTuples());
2076   DataArrayDouble *ret(DataArrayDouble::New());
2077   ret->alloc(nbOfTuple,2);
2078   double *w(ret->getPointer());
2079   const double *wIn(getConstPointer());
2080   for(int i=0;i<nbOfTuple;i++,w+=2,wIn+=2)
2081     {
2082       w[0]=wIn[0]*cos(wIn[1]);
2083       w[1]=wIn[0]*sin(wIn[1]);
2084     }
2085   return ret;
2086 }
2087
2088 /*!
2089  * Converts each 3D point defined by the tuple of \a this array from the Cylindrical to
2090  * the Cartesian coordinate system. The three components of the tuple of \a this array 
2091  * are considered to contain (1) radius, (2) azimuth and (3) altitude of the point in
2092  * the Cylindrical CS.
2093  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
2094  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
2095  *          on the third component is copied from \a this array. The caller
2096  *          is to delete this array using decrRef() as it is no more needed. 
2097  *  \throw If \a this->getNumberOfComponents() != 3.
2098  * \sa fromCartToCyl
2099  */
2100 DataArrayDouble *DataArrayDouble::fromCylToCart() const
2101 {
2102   checkAllocated();
2103   int nbOfComp(getNumberOfComponents());
2104   if(nbOfComp!=3)
2105     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCylToCart : must be an array with exactly 3 components !");
2106   int nbOfTuple(getNumberOfTuples());
2107   DataArrayDouble *ret(DataArrayDouble::New());
2108   ret->alloc(getNumberOfTuples(),3);
2109   double *w(ret->getPointer());
2110   const double *wIn(getConstPointer());
2111   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
2112     {
2113       w[0]=wIn[0]*cos(wIn[1]);
2114       w[1]=wIn[0]*sin(wIn[1]);
2115       w[2]=wIn[2];
2116     }
2117   ret->setInfoOnComponent(2,getInfoOnComponent(2));
2118   return ret;
2119 }
2120
2121 /*!
2122  * Converts each 3D point defined by the tuple of \a this array from the Spherical to
2123  * the Cartesian coordinate system. The three components of the tuple of \a this array 
2124  * are considered to contain (1) radius, (2) polar angle and (3) azimuthal angle of the
2125  * point in the Cylindrical CS.
2126  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
2127  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
2128  *          on the third component is copied from \a this array. The caller
2129  *          is to delete this array using decrRef() as it is no more needed.
2130  *  \throw If \a this->getNumberOfComponents() != 3.
2131  * \sa fromCartToSpher
2132  */
2133 DataArrayDouble *DataArrayDouble::fromSpherToCart() const
2134 {
2135   checkAllocated();
2136   int nbOfComp(getNumberOfComponents());
2137   if(nbOfComp!=3)
2138     throw INTERP_KERNEL::Exception("DataArrayDouble::fromSpherToCart : must be an array with exactly 3 components !");
2139   int nbOfTuple(getNumberOfTuples());
2140   DataArrayDouble *ret(DataArrayDouble::New());
2141   ret->alloc(getNumberOfTuples(),3);
2142   double *w(ret->getPointer());
2143   const double *wIn(getConstPointer());
2144   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
2145     {
2146       w[0]=wIn[0]*cos(wIn[2])*sin(wIn[1]);
2147       w[1]=wIn[0]*sin(wIn[2])*sin(wIn[1]);
2148       w[2]=wIn[0]*cos(wIn[1]);
2149     }
2150   return ret;
2151 }
2152
2153 /*!
2154  * 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.
2155  * 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.
2156  * If \a at equals to AX_CYL the returned array will be the result of operation cylindric to cartesian of \a this...
2157  *
2158  * \param [in] atOfThis - The axis type of \a this.
2159  * \return DataArrayDouble * - the new instance of DataArrayDouble (that must be dealed by caller) containing the result of the cartesianizification of \a this.
2160  */
2161 DataArrayDouble *DataArrayDouble::cartesianize(MEDCouplingAxisType atOfThis) const
2162 {
2163   checkAllocated();
2164   int nbOfComp(getNumberOfComponents());
2165   MCAuto<DataArrayDouble> ret;
2166   switch(atOfThis)
2167     {
2168     case AX_CART:
2169       ret=deepCopy();
2170     case AX_CYL:
2171       if(nbOfComp==3)
2172         {
2173           ret=fromCylToCart();
2174           break;
2175         }
2176       if(nbOfComp==2)
2177         {
2178           ret=fromPolarToCart();
2179           break;
2180         }
2181       else
2182         throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : For AX_CYL, number of components must be in [2,3] !");
2183     case AX_SPHER:
2184       if(nbOfComp==3)
2185         {
2186           ret=fromSpherToCart();
2187           break;
2188         }
2189       if(nbOfComp==2)
2190         {
2191           ret=fromPolarToCart();
2192           break;
2193         }
2194       else
2195         throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : For AX_CYL, number of components must be in [2,3] !");
2196     default:
2197       throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : not recognized axis type ! Only AX_CART, AX_CYL and AX_SPHER supported !");
2198     }
2199   ret->copyStringInfoFrom(*this);
2200   return ret.retn();
2201 }
2202
2203 /*!
2204  * This method returns a newly created array to be deallocated that contains the result of conversion from cartesian to polar.
2205  * This method expects that \a this has exactly 2 components.
2206  * \sa fromPolarToCart
2207  */
2208 DataArrayDouble *DataArrayDouble::fromCartToPolar() const
2209 {
2210   MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2211   checkAllocated();
2212   int nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2213   if(nbOfComp!=2)
2214     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToPolar : must be an array with exactly 2 components !");
2215   ret->alloc(nbTuples,2);
2216   double *retPtr(ret->getPointer());
2217   const double *ptr(begin());
2218   for(int i=0;i<nbTuples;i++,ptr+=2,retPtr+=2)
2219     {
2220       retPtr[0]=sqrt(ptr[0]*ptr[0]+ptr[1]*ptr[1]);
2221       retPtr[1]=atan2(ptr[1],ptr[0]);
2222     }
2223   return ret.retn();
2224 }
2225
2226 /*!
2227  * This method returns a newly created array to be deallocated that contains the result of conversion from cartesian to cylindrical.
2228  * This method expects that \a this has exactly 3 components.
2229  * \sa fromCylToCart
2230  */
2231 DataArrayDouble *DataArrayDouble::fromCartToCyl() const
2232 {
2233   MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2234   checkAllocated();
2235   int nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2236   if(nbOfComp!=3)
2237     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCyl : must be an array with exactly 3 components !");
2238   ret->alloc(nbTuples,3);
2239   double *retPtr(ret->getPointer());
2240   const double *ptr(begin());
2241   for(int i=0;i<nbTuples;i++,ptr+=3,retPtr+=3)
2242     {
2243       retPtr[0]=sqrt(ptr[0]*ptr[0]+ptr[1]*ptr[1]);
2244       retPtr[1]=atan2(ptr[1],ptr[0]);
2245       retPtr[2]=ptr[2];
2246     }
2247   return ret.retn();
2248 }
2249
2250 /*!
2251  * This method returns a newly created array to be deallocated that contains the result of conversion from cartesian to spherical coordinates.
2252  * \sa fromSpherToCart
2253  */
2254 DataArrayDouble *DataArrayDouble::fromCartToSpher() const
2255 {
2256   MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2257   checkAllocated();
2258   int nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2259   if(nbOfComp!=3)
2260     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToSpher : must be an array with exactly 3 components !");
2261   ret->alloc(nbTuples,3);
2262   double *retPtr(ret->getPointer());
2263   const double *ptr(begin());
2264   for(int i=0;i<nbTuples;i++,ptr+=3,retPtr+=3)
2265     {
2266       retPtr[0]=sqrt(ptr[0]*ptr[0]+ptr[1]*ptr[1]+ptr[2]*ptr[2]);
2267       retPtr[1]=acos(ptr[2]/retPtr[0]);
2268       retPtr[2]=atan2(ptr[1],ptr[0]);
2269     }
2270   return ret.retn();
2271 }
2272
2273 /*!
2274  * 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.
2275  * This method expects that \a this has exactly 3 components.
2276  * \sa MEDCouplingFieldDouble::computeVectorFieldCyl
2277  */
2278 DataArrayDouble *DataArrayDouble::fromCartToCylGiven(const DataArrayDouble *coords, const double center[3], const double vect[3]) const
2279 {
2280   if(!coords)
2281     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : input coords are NULL !");
2282   MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2283   checkAllocated(); coords->checkAllocated();
2284   int nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2285   if(nbOfComp!=3)
2286     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : must be an array with exactly 3 components !");
2287   if(coords->getNumberOfComponents()!=3)
2288     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : coords array must have exactly 3 components !");
2289   if(coords->getNumberOfTuples()!=nbTuples)
2290     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : coords array must have the same number of tuples !");
2291   ret->alloc(nbTuples,nbOfComp);
2292   double magOfVect(sqrt(vect[0]*vect[0]+vect[1]*vect[1]+vect[2]*vect[2]));
2293   if(magOfVect<1e-12)
2294     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : magnitude of vect is too low !");
2295   double Ur[3],Uteta[3],Uz[3],*retPtr(ret->getPointer());
2296   const double *coo(coords->begin()),*vectField(begin());
2297   std::transform(vect,vect+3,Uz,std::bind2nd(std::multiplies<double>(),1./magOfVect));
2298   for(int i=0;i<nbTuples;i++,vectField+=3,retPtr+=3,coo+=3)
2299     {
2300       std::transform(coo,coo+3,center,Ur,std::minus<double>());
2301       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];
2302       double magOfTeta(sqrt(Uteta[0]*Uteta[0]+Uteta[1]*Uteta[1]+Uteta[2]*Uteta[2]));
2303       std::transform(Uteta,Uteta+3,Uteta,std::bind2nd(std::multiplies<double>(),1./magOfTeta));
2304       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];
2305       retPtr[0]=Ur[0]*vectField[0]+Ur[1]*vectField[1]+Ur[2]*vectField[2];
2306       retPtr[1]=Uteta[0]*vectField[0]+Uteta[1]*vectField[1]+Uteta[2]*vectField[2];
2307       retPtr[2]=Uz[0]*vectField[0]+Uz[1]*vectField[1]+Uz[2]*vectField[2];
2308     }
2309   ret->copyStringInfoFrom(*this);
2310   return ret.retn();
2311 }
2312
2313 /*!
2314  * Computes the doubly contracted product of every tensor defined by the tuple of \a this
2315  * array contating 6 components.
2316  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
2317  *          is calculated from the tuple <em>(t)</em> of \a this array as follows:
2318  *          \f$ t[0]^2+t[1]^2+t[2]^2+2*t[3]^2+2*t[4]^2+2*t[5]^2\f$.
2319  *         The caller is to delete this result array using decrRef() as it is no more needed. 
2320  *  \throw If \a this->getNumberOfComponents() != 6.
2321  */
2322 DataArrayDouble *DataArrayDouble::doublyContractedProduct() const
2323 {
2324   checkAllocated();
2325   int nbOfComp(getNumberOfComponents());
2326   if(nbOfComp!=6)
2327     throw INTERP_KERNEL::Exception("DataArrayDouble::doublyContractedProduct : must be an array with exactly 6 components !");
2328   DataArrayDouble *ret=DataArrayDouble::New();
2329   int nbOfTuple=getNumberOfTuples();
2330   ret->alloc(nbOfTuple,1);
2331   const double *src=getConstPointer();
2332   double *dest=ret->getPointer();
2333   for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
2334     *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];
2335   return ret;
2336 }
2337
2338 /*!
2339  * Computes the determinant of every square matrix defined by the tuple of \a this
2340  * array, which contains either 4, 6 or 9 components. The case of 6 components
2341  * corresponds to that of the upper triangular matrix.
2342  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
2343  *          is the determinant of matrix of the corresponding tuple of \a this array.
2344  *          The caller is to delete this result array using decrRef() as it is no more
2345  *          needed. 
2346  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2347  */
2348 DataArrayDouble *DataArrayDouble::determinant() const
2349 {
2350   checkAllocated();
2351   DataArrayDouble *ret=DataArrayDouble::New();
2352   int nbOfTuple=getNumberOfTuples();
2353   ret->alloc(nbOfTuple,1);
2354   const double *src=getConstPointer();
2355   double *dest=ret->getPointer();
2356   switch(getNumberOfComponents())
2357   {
2358     case 6:
2359       for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
2360         *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];
2361       return ret;
2362     case 4:
2363       for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
2364         *dest=src[0]*src[3]-src[1]*src[2];
2365       return ret;
2366     case 9:
2367       for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
2368         *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];
2369       return ret;
2370     default:
2371       ret->decrRef();
2372       throw INTERP_KERNEL::Exception("DataArrayDouble::determinant : Invalid number of components ! must be in 4,6,9 !");
2373   }
2374 }
2375
2376 /*!
2377  * Computes 3 eigenvalues of every upper triangular matrix defined by the tuple of
2378  * \a this array, which contains 6 components.
2379  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 3
2380  *          components, whose each tuple contains the eigenvalues of the matrix of
2381  *          corresponding tuple of \a this array. 
2382  *          The caller is to delete this result array using decrRef() as it is no more
2383  *          needed. 
2384  *  \throw If \a this->getNumberOfComponents() != 6.
2385  */
2386 DataArrayDouble *DataArrayDouble::eigenValues() const
2387 {
2388   checkAllocated();
2389   int nbOfComp=getNumberOfComponents();
2390   if(nbOfComp!=6)
2391     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenValues : must be an array with exactly 6 components !");
2392   DataArrayDouble *ret=DataArrayDouble::New();
2393   int nbOfTuple=getNumberOfTuples();
2394   ret->alloc(nbOfTuple,3);
2395   const double *src=getConstPointer();
2396   double *dest=ret->getPointer();
2397   for(int i=0;i<nbOfTuple;i++,dest+=3,src+=6)
2398     INTERP_KERNEL::computeEigenValues6(src,dest);
2399   return ret;
2400 }
2401
2402 /*!
2403  * Computes 3 eigenvectors of every upper triangular matrix defined by the tuple of
2404  * \a this array, which contains 6 components.
2405  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 9
2406  *          components, whose each tuple contains 3 eigenvectors of the matrix of
2407  *          corresponding tuple of \a this array.
2408  *          The caller is to delete this result array using decrRef() as it is no more
2409  *          needed.
2410  *  \throw If \a this->getNumberOfComponents() != 6.
2411  */
2412 DataArrayDouble *DataArrayDouble::eigenVectors() const
2413 {
2414   checkAllocated();
2415   int nbOfComp=getNumberOfComponents();
2416   if(nbOfComp!=6)
2417     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenVectors : must be an array with exactly 6 components !");
2418   DataArrayDouble *ret=DataArrayDouble::New();
2419   int nbOfTuple=getNumberOfTuples();
2420   ret->alloc(nbOfTuple,9);
2421   const double *src=getConstPointer();
2422   double *dest=ret->getPointer();
2423   for(int i=0;i<nbOfTuple;i++,src+=6)
2424     {
2425       double tmp[3];
2426       INTERP_KERNEL::computeEigenValues6(src,tmp);
2427       for(int j=0;j<3;j++,dest+=3)
2428         INTERP_KERNEL::computeEigenVectorForEigenValue6(src,tmp[j],1e-12,dest);
2429     }
2430   return ret;
2431 }
2432
2433 /*!
2434  * Computes the inverse matrix of every matrix defined by the tuple of \a this
2435  * array, which contains either 4, 6 or 9 components. The case of 6 components
2436  * corresponds to that of the upper triangular matrix.
2437  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2438  *          same number of components as \a this one, whose each tuple is the inverse
2439  *          matrix of the matrix of corresponding tuple of \a this array. 
2440  *          The caller is to delete this result array using decrRef() as it is no more
2441  *          needed. 
2442  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2443  */
2444 DataArrayDouble *DataArrayDouble::inverse() const
2445 {
2446   checkAllocated();
2447   int nbOfComp=getNumberOfComponents();
2448   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
2449     throw INTERP_KERNEL::Exception("DataArrayDouble::inversion : must be an array with 4,6 or 9 components !");
2450   DataArrayDouble *ret=DataArrayDouble::New();
2451   int nbOfTuple=getNumberOfTuples();
2452   ret->alloc(nbOfTuple,nbOfComp);
2453   const double *src=getConstPointer();
2454   double *dest=ret->getPointer();
2455   if(nbOfComp==6)
2456     for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
2457       {
2458         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];
2459         dest[0]=(src[1]*src[2]-src[4]*src[4])/det;
2460         dest[1]=(src[0]*src[2]-src[5]*src[5])/det;
2461         dest[2]=(src[0]*src[1]-src[3]*src[3])/det;
2462         dest[3]=(src[5]*src[4]-src[3]*src[2])/det;
2463         dest[4]=(src[5]*src[3]-src[0]*src[4])/det;
2464         dest[5]=(src[3]*src[4]-src[1]*src[5])/det;
2465       }
2466   else if(nbOfComp==4)
2467     for(int i=0;i<nbOfTuple;i++,dest+=4,src+=4)
2468       {
2469         double det=src[0]*src[3]-src[1]*src[2];
2470         dest[0]=src[3]/det;
2471         dest[1]=-src[1]/det;
2472         dest[2]=-src[2]/det;
2473         dest[3]=src[0]/det;
2474       }
2475   else
2476     for(int i=0;i<nbOfTuple;i++,dest+=9,src+=9)
2477       {
2478         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];
2479         dest[0]=(src[4]*src[8]-src[7]*src[5])/det;
2480         dest[1]=(src[7]*src[2]-src[1]*src[8])/det;
2481         dest[2]=(src[1]*src[5]-src[4]*src[2])/det;
2482         dest[3]=(src[6]*src[5]-src[3]*src[8])/det;
2483         dest[4]=(src[0]*src[8]-src[6]*src[2])/det;
2484         dest[5]=(src[2]*src[3]-src[0]*src[5])/det;
2485         dest[6]=(src[3]*src[7]-src[6]*src[4])/det;
2486         dest[7]=(src[6]*src[1]-src[0]*src[7])/det;
2487         dest[8]=(src[0]*src[4]-src[1]*src[3])/det;
2488       }
2489   return ret;
2490 }
2491
2492 /*!
2493  * Computes the trace of every matrix defined by the tuple of \a this
2494  * array, which contains either 4, 6 or 9 components. The case of 6 components
2495  * corresponds to that of the upper triangular matrix.
2496  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 
2497  *          1 component, whose each tuple is the trace of
2498  *          the matrix of corresponding tuple of \a this array. 
2499  *          The caller is to delete this result array using decrRef() as it is no more
2500  *          needed. 
2501  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2502  */
2503 DataArrayDouble *DataArrayDouble::trace() const
2504 {
2505   checkAllocated();
2506   int nbOfComp=getNumberOfComponents();
2507   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
2508     throw INTERP_KERNEL::Exception("DataArrayDouble::trace : must be an array with 4,6 or 9 components !");
2509   DataArrayDouble *ret=DataArrayDouble::New();
2510   int nbOfTuple=getNumberOfTuples();
2511   ret->alloc(nbOfTuple,1);
2512   const double *src=getConstPointer();
2513   double *dest=ret->getPointer();
2514   if(nbOfComp==6)
2515     for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
2516       *dest=src[0]+src[1]+src[2];
2517   else if(nbOfComp==4)
2518     for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
2519       *dest=src[0]+src[3];
2520   else
2521     for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
2522       *dest=src[0]+src[4]+src[8];
2523   return ret;
2524 }
2525
2526 /*!
2527  * Computes the stress deviator tensor of every stress tensor defined by the tuple of
2528  * \a this array, which contains 6 components.
2529  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2530  *          same number of components and tuples as \a this array.
2531  *          The caller is to delete this result array using decrRef() as it is no more
2532  *          needed.
2533  *  \throw If \a this->getNumberOfComponents() != 6.
2534  */
2535 DataArrayDouble *DataArrayDouble::deviator() const
2536 {
2537   checkAllocated();
2538   int nbOfComp=getNumberOfComponents();
2539   if(nbOfComp!=6)
2540     throw INTERP_KERNEL::Exception("DataArrayDouble::deviator : must be an array with exactly 6 components !");
2541   DataArrayDouble *ret=DataArrayDouble::New();
2542   int nbOfTuple=getNumberOfTuples();
2543   ret->alloc(nbOfTuple,6);
2544   const double *src=getConstPointer();
2545   double *dest=ret->getPointer();
2546   for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
2547     {
2548       double tr=(src[0]+src[1]+src[2])/3.;
2549       dest[0]=src[0]-tr;
2550       dest[1]=src[1]-tr;
2551       dest[2]=src[2]-tr;
2552       dest[3]=src[3];
2553       dest[4]=src[4];
2554       dest[5]=src[5];
2555     }
2556   return ret;
2557 }
2558
2559 /*!
2560  * Computes the magnitude of every vector defined by the tuple of
2561  * \a this array.
2562  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2563  *          same number of tuples as \a this array and one component.
2564  *          The caller is to delete this result array using decrRef() as it is no more
2565  *          needed.
2566  *  \throw If \a this is not allocated.
2567  */
2568 DataArrayDouble *DataArrayDouble::magnitude() const
2569 {
2570   checkAllocated();
2571   int nbOfComp=getNumberOfComponents();
2572   DataArrayDouble *ret=DataArrayDouble::New();
2573   int nbOfTuple=getNumberOfTuples();
2574   ret->alloc(nbOfTuple,1);
2575   const double *src=getConstPointer();
2576   double *dest=ret->getPointer();
2577   for(int i=0;i<nbOfTuple;i++,dest++)
2578     {
2579       double sum=0.;
2580       for(int j=0;j<nbOfComp;j++,src++)
2581         sum+=(*src)*(*src);
2582       *dest=sqrt(sum);
2583     }
2584   return ret;
2585 }
2586
2587 /*!
2588  * Computes for each tuple the sum of number of components values in the tuple and return it.
2589  * 
2590  * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2591  *          same number of tuples as \a this array and one component.
2592  *          The caller is to delete this result array using decrRef() as it is no more
2593  *          needed.
2594  *  \throw If \a this is not allocated.
2595  */
2596 DataArrayDouble *DataArrayDouble::sumPerTuple() const
2597 {
2598   checkAllocated();
2599   int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
2600   MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2601   ret->alloc(nbOfTuple,1);
2602   const double *src(getConstPointer());
2603   double *dest(ret->getPointer());
2604   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
2605     *dest=std::accumulate(src,src+nbOfComp,0.);
2606   return ret.retn();
2607 }
2608
2609 /*!
2610  * Computes the maximal value within every tuple of \a this array.
2611  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2612  *          same number of tuples as \a this array and one component.
2613  *          The caller is to delete this result array using decrRef() as it is no more
2614  *          needed.
2615  *  \throw If \a this is not allocated.
2616  *  \sa DataArrayDouble::maxPerTupleWithCompoId
2617  */
2618 DataArrayDouble *DataArrayDouble::maxPerTuple() const
2619 {
2620   checkAllocated();
2621   int nbOfComp=getNumberOfComponents();
2622   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
2623   int nbOfTuple=getNumberOfTuples();
2624   ret->alloc(nbOfTuple,1);
2625   const double *src=getConstPointer();
2626   double *dest=ret->getPointer();
2627   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
2628     *dest=*std::max_element(src,src+nbOfComp);
2629   return ret.retn();
2630 }
2631
2632 /*!
2633  * Computes the maximal value within every tuple of \a this array and it returns the first component
2634  * id for each tuple that corresponds to the maximal value within the tuple.
2635  * 
2636  *  \param [out] compoIdOfMaxPerTuple - the new new instance of DataArrayInt containing the
2637  *          same number of tuples and only one component.
2638  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2639  *          same number of tuples as \a this array and one component.
2640  *          The caller is to delete this result array using decrRef() as it is no more
2641  *          needed.
2642  *  \throw If \a this is not allocated.
2643  *  \sa DataArrayDouble::maxPerTuple
2644  */
2645 DataArrayDouble *DataArrayDouble::maxPerTupleWithCompoId(DataArrayInt* &compoIdOfMaxPerTuple) const
2646 {
2647   checkAllocated();
2648   int nbOfComp=getNumberOfComponents();
2649   MCAuto<DataArrayDouble> ret0=DataArrayDouble::New();
2650   MCAuto<DataArrayInt> ret1=DataArrayInt::New();
2651   int nbOfTuple=getNumberOfTuples();
2652   ret0->alloc(nbOfTuple,1); ret1->alloc(nbOfTuple,1);
2653   const double *src=getConstPointer();
2654   double *dest=ret0->getPointer(); int *dest1=ret1->getPointer();
2655   for(int i=0;i<nbOfTuple;i++,dest++,dest1++,src+=nbOfComp)
2656     {
2657       const double *loc=std::max_element(src,src+nbOfComp);
2658       *dest=*loc;
2659       *dest1=(int)std::distance(src,loc);
2660     }
2661   compoIdOfMaxPerTuple=ret1.retn();
2662   return ret0.retn();
2663 }
2664
2665 /*!
2666  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c this->getNumberOfTuples() tuples.
2667  * \n This returned array contains the euclidian distance for each tuple in \a this. 
2668  * \n So the returned array can be seen as a dense symmetrical matrix whose diagonal elements are equal to 0.
2669  * \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)
2670  *
2671  * \warning use this method with care because it can leads to big amount of consumed memory !
2672  * 
2673  * \return A newly allocated (huge) MEDCoupling::DataArrayDouble instance that the caller should deal with.
2674  *
2675  * \throw If \a this is not allocated.
2676  *
2677  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrixWith
2678  */
2679 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrix() const
2680 {
2681   checkAllocated();
2682   int nbOfComp=getNumberOfComponents();
2683   int nbOfTuples=getNumberOfTuples();
2684   const double *inData=getConstPointer();
2685   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
2686   ret->alloc(nbOfTuples*nbOfTuples,1);
2687   double *outData=ret->getPointer();
2688   for(int i=0;i<nbOfTuples;i++)
2689     {
2690       outData[i*nbOfTuples+i]=0.;
2691       for(int j=i+1;j<nbOfTuples;j++)
2692         {
2693           double dist=0.;
2694           for(int k=0;k<nbOfComp;k++)
2695             { double delta=inData[i*nbOfComp+k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
2696           dist=sqrt(dist);
2697           outData[i*nbOfTuples+j]=dist;
2698           outData[j*nbOfTuples+i]=dist;
2699         }
2700     }
2701   return ret.retn();
2702 }
2703
2704 /*!
2705  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c other->getNumberOfTuples() tuples.
2706  * \n This returned array contains the euclidian distance for each tuple in \a other with each tuple in \a this. 
2707  * \n So the returned array can be seen as a dense rectangular matrix with \c other->getNumberOfTuples() rows and \c this->getNumberOfTuples() columns.
2708  * \n Output rectangular matrix is sorted along rows.
2709  * \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)
2710  *
2711  * \warning use this method with care because it can leads to big amount of consumed memory !
2712  * 
2713  * \param [in] other DataArrayDouble instance having same number of components than \a this.
2714  * \return A newly allocated (huge) MEDCoupling::DataArrayDouble instance that the caller should deal with.
2715  *
2716  * \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.
2717  *
2718  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrix
2719  */
2720 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrixWith(const DataArrayDouble *other) const
2721 {
2722   if(!other)
2723     throw INTERP_KERNEL::Exception("DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : input parameter is null !");
2724   checkAllocated();
2725   other->checkAllocated();
2726   int nbOfComp=getNumberOfComponents();
2727   int otherNbOfComp=other->getNumberOfComponents();
2728   if(nbOfComp!=otherNbOfComp)
2729     {
2730       std::ostringstream oss; oss << "DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : this nb of compo=" << nbOfComp << " and other nb of compo=" << otherNbOfComp << ". It should match !";
2731       throw INTERP_KERNEL::Exception(oss.str().c_str());
2732     }
2733   int nbOfTuples=getNumberOfTuples();
2734   int otherNbOfTuples=other->getNumberOfTuples();
2735   const double *inData=getConstPointer();
2736   const double *inDataOther=other->getConstPointer();
2737   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
2738   ret->alloc(otherNbOfTuples*nbOfTuples,1);
2739   double *outData=ret->getPointer();
2740   for(int i=0;i<otherNbOfTuples;i++,inDataOther+=nbOfComp)
2741     {
2742       for(int j=0;j<nbOfTuples;j++)
2743         {
2744           double dist=0.;
2745           for(int k=0;k<nbOfComp;k++)
2746             { double delta=inDataOther[k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
2747           dist=sqrt(dist);
2748           outData[i*nbOfTuples+j]=dist;
2749         }
2750     }
2751   return ret.retn();
2752 }
2753
2754 /*!
2755  * Sorts value within every tuple of \a this array.
2756  *  \param [in] asc - if \a true, the values are sorted in ascending order, else,
2757  *              in descending order.
2758  *  \throw If \a this is not allocated.
2759  */
2760 void DataArrayDouble::sortPerTuple(bool asc)
2761 {
2762   checkAllocated();
2763   double *pt=getPointer();
2764   int nbOfTuple=getNumberOfTuples();
2765   int nbOfComp=getNumberOfComponents();
2766   if(asc)
2767     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
2768       std::sort(pt,pt+nbOfComp);
2769   else
2770     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
2771       std::sort(pt,pt+nbOfComp,std::greater<double>());
2772   declareAsNew();
2773 }
2774
2775 /*!
2776  * Converts every value of \a this array to its absolute value.
2777  * \b WARNING this method is non const. If a new DataArrayDouble instance should be built containing the result of abs DataArrayDouble::computeAbs
2778  * should be called instead.
2779  *
2780  * \throw If \a this is not allocated.
2781  * \sa DataArrayDouble::computeAbs
2782  */
2783 void DataArrayDouble::abs()
2784 {
2785   checkAllocated();
2786   double *ptr(getPointer());
2787   std::size_t nbOfElems(getNbOfElems());
2788   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<double,double>(fabs));
2789   declareAsNew();
2790 }
2791
2792 /*!
2793  * This method builds a new instance of \a this object containing the result of std::abs applied of all elements in \a this.
2794  * This method is a const method (that do not change any values in \a this) contrary to  DataArrayDouble::abs method.
2795  *
2796  * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2797  *         same number of tuples and component as \a this array.
2798  *         The caller is to delete this result array using decrRef() as it is no more
2799  *         needed.
2800  * \throw If \a this is not allocated.
2801  * \sa DataArrayDouble::abs
2802  */
2803 DataArrayDouble *DataArrayDouble::computeAbs() const
2804 {
2805   checkAllocated();
2806   DataArrayDouble *newArr(DataArrayDouble::New());
2807   int nbOfTuples(getNumberOfTuples());
2808   int nbOfComp(getNumberOfComponents());
2809   newArr->alloc(nbOfTuples,nbOfComp);
2810   std::transform(begin(),end(),newArr->getPointer(),std::ptr_fun<double,double>(fabs));
2811   newArr->copyStringInfoFrom(*this);
2812   return newArr;
2813 }
2814
2815 /*!
2816  * Apply a linear function to a given component of \a this array, so that
2817  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
2818  *  \param [in] a - the first coefficient of the function.
2819  *  \param [in] b - the second coefficient of the function.
2820  *  \param [in] compoId - the index of component to modify.
2821  *  \throw If \a this is not allocated, or \a compoId is not in [0,\c this->getNumberOfComponents() ).
2822  */
2823 void DataArrayDouble::applyLin(double a, double b, int compoId)
2824 {
2825   checkAllocated();
2826   double *ptr(getPointer()+compoId);
2827   int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
2828   if(compoId<0 || compoId>=nbOfComp)
2829     {
2830       std::ostringstream oss; oss << "DataArrayDouble::applyLin : The compoId requested (" << compoId << ") is not valid ! Must be in [0," << nbOfComp << ") !";
2831       throw INTERP_KERNEL::Exception(oss.str().c_str());
2832     }
2833   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
2834     *ptr=a*(*ptr)+b;
2835   declareAsNew();
2836 }
2837
2838 /*!
2839  * Apply a linear function to all elements of \a this array, so that
2840  * an element _x_ becomes \f$ a * x + b \f$.
2841  *  \param [in] a - the first coefficient of the function.
2842  *  \param [in] b - the second coefficient of the function.
2843  *  \throw If \a this is not allocated.
2844  */
2845 void DataArrayDouble::applyLin(double a, double b)
2846 {
2847   checkAllocated();
2848   double *ptr=getPointer();
2849   std::size_t nbOfElems=getNbOfElems();
2850   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2851     *ptr=a*(*ptr)+b;
2852   declareAsNew();
2853 }
2854
2855 /*!
2856  * Modify all elements of \a this array, so that
2857  * an element _x_ becomes \f$ numerator / x \f$.
2858  *  \warning If an exception is thrown because of presence of 0.0 element in \a this 
2859  *           array, all elements processed before detection of the zero element remain
2860  *           modified.
2861  *  \param [in] numerator - the numerator used to modify array elements.
2862  *  \throw If \a this is not allocated.
2863  *  \throw If there is an element equal to 0.0 in \a this array.
2864  */
2865 void DataArrayDouble::applyInv(double numerator)
2866 {
2867   checkAllocated();
2868   double *ptr=getPointer();
2869   std::size_t nbOfElems=getNbOfElems();
2870   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2871     {
2872       if(std::abs(*ptr)>std::numeric_limits<double>::min())
2873         {
2874           *ptr=numerator/(*ptr);
2875         }
2876       else
2877         {
2878           std::ostringstream oss; oss << "DataArrayDouble::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
2879           oss << " !";
2880           throw INTERP_KERNEL::Exception(oss.str().c_str());
2881         }
2882     }
2883   declareAsNew();
2884 }
2885
2886 /*!
2887  * Returns a full copy of \a this array except that sign of all elements is reversed.
2888  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2889  *          same number of tuples and component as \a this array.
2890  *          The caller is to delete this result array using decrRef() as it is no more
2891  *          needed.
2892  *  \throw If \a this is not allocated.
2893  */
2894 DataArrayDouble *DataArrayDouble::negate() const
2895 {
2896   checkAllocated();
2897   DataArrayDouble *newArr=DataArrayDouble::New();
2898   int nbOfTuples=getNumberOfTuples();
2899   int nbOfComp=getNumberOfComponents();
2900   newArr->alloc(nbOfTuples,nbOfComp);
2901   const double *cptr=getConstPointer();
2902   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<double>());
2903   newArr->copyStringInfoFrom(*this);
2904   return newArr;
2905 }
2906
2907 /*!
2908  * Modify all elements of \a this array, so that
2909  * an element _x_ becomes <em> val ^ x </em>. Contrary to DataArrayInt::applyPow
2910  * all values in \a this have to be >= 0 if val is \b not integer.
2911  *  \param [in] val - the value used to apply pow on all array elements.
2912  *  \throw If \a this is not allocated.
2913  *  \warning If an exception is thrown because of presence of 0 element in \a this 
2914  *           array and \a val is \b not integer, all elements processed before detection of the zero element remain
2915  *           modified.
2916  */
2917 void DataArrayDouble::applyPow(double val)
2918 {
2919   checkAllocated();
2920   double *ptr=getPointer();
2921   std::size_t nbOfElems=getNbOfElems();
2922   int val2=(int)val;
2923   bool isInt=((double)val2)==val;
2924   if(!isInt)
2925     {
2926       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2927         {
2928           if(*ptr>=0)
2929             *ptr=pow(*ptr,val);
2930           else
2931             {
2932               std::ostringstream oss; oss << "DataArrayDouble::applyPow (double) : At elem # " << i << " value is " << *ptr << " ! must be >=0. !";
2933               throw INTERP_KERNEL::Exception(oss.str().c_str());
2934             }
2935         }
2936     }
2937   else
2938     {
2939       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2940         *ptr=pow(*ptr,val2);
2941     }
2942   declareAsNew();
2943 }
2944
2945 /*!
2946  * Modify all elements of \a this array, so that
2947  * an element _x_ becomes \f$ val ^ x \f$.
2948  *  \param [in] val - the value used to apply pow on all array elements.
2949  *  \throw If \a this is not allocated.
2950  *  \throw If \a val < 0.
2951  *  \warning If an exception is thrown because of presence of 0 element in \a this 
2952  *           array, all elements processed before detection of the zero element remain
2953  *           modified.
2954  */
2955 void DataArrayDouble::applyRPow(double val)
2956 {
2957   checkAllocated();
2958   if(val<0.)
2959     throw INTERP_KERNEL::Exception("DataArrayDouble::applyRPow : the input value has to be >= 0 !");
2960   double *ptr=getPointer();
2961   std::size_t nbOfElems=getNbOfElems();
2962   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2963     *ptr=pow(val,*ptr);
2964   declareAsNew();
2965 }
2966
2967 /*!
2968  * Returns a new DataArrayDouble created from \a this one by applying \a
2969  * FunctionToEvaluate to every tuple of \a this array. Textual data is not copied.
2970  * For more info see \ref MEDCouplingArrayApplyFunc
2971  *  \param [in] nbOfComp - number of components in the result array.
2972  *  \param [in] func - the \a FunctionToEvaluate declared as 
2973  *              \c bool (*\a func)(\c const \c double *\a pos, \c double *\a res), 
2974  *              where \a pos points to the first component of a tuple of \a this array
2975  *              and \a res points to the first component of a tuple of the result array.
2976  *              Note that length (number of components) of \a pos can differ from
2977  *              that of \a res.
2978  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2979  *          same number of tuples as \a this array.
2980  *          The caller is to delete this result array using decrRef() as it is no more
2981  *          needed.
2982  *  \throw If \a this is not allocated.
2983  *  \throw If \a func returns \a false.
2984  */
2985 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, FunctionToEvaluate func) const
2986 {
2987   checkAllocated();
2988   DataArrayDouble *newArr=DataArrayDouble::New();
2989   int nbOfTuples=getNumberOfTuples();
2990   int oldNbOfComp=getNumberOfComponents();
2991   newArr->alloc(nbOfTuples,nbOfComp);
2992   const double *ptr=getConstPointer();
2993   double *ptrToFill=newArr->getPointer();
2994   for(int i=0;i<nbOfTuples;i++)
2995     {
2996       if(!func(ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp))
2997         {
2998           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
2999           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
3000           oss << ") : Evaluation of function failed !";
3001           newArr->decrRef();
3002           throw INTERP_KERNEL::Exception(oss.str().c_str());
3003         }
3004     }
3005   return newArr;
3006 }
3007
3008 /*!
3009  * Returns a new DataArrayDouble created from \a this one by applying a function to every
3010  * tuple of \a this array. Textual data is not copied.
3011  * For more info see \ref MEDCouplingArrayApplyFunc1.
3012  *  \param [in] nbOfComp - number of components in the result array.
3013  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
3014  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
3015  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
3016  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
3017  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3018  *          same number of tuples as \a this array and \a nbOfComp components.
3019  *          The caller is to delete this result array using decrRef() as it is no more
3020  *          needed.
3021  *  \throw If \a this is not allocated.
3022  *  \throw If computing \a func fails.
3023  */
3024 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, const std::string& func, bool isSafe) const
3025 {
3026   INTERP_KERNEL::ExprParser expr(func);
3027   expr.parse();
3028   std::set<std::string> vars;
3029   expr.getTrueSetOfVars(vars);
3030   std::vector<std::string> varsV(vars.begin(),vars.end());
3031   return applyFuncNamedCompo(nbOfComp,varsV,func,isSafe);
3032 }
3033
3034 /*!
3035  * Returns a new DataArrayDouble created from \a this one by applying a function to every
3036  * tuple of \a this array. Textual data is not copied. This method works by tuples (whatever its size).
3037  * If \a this is a one component array, call applyFuncOnThis instead that performs the same work faster.
3038  *
3039  * For more info see \ref MEDCouplingArrayApplyFunc0.
3040  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
3041  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
3042  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
3043  *                       If false the computation is carried on without any notification. When false the evaluation is a little faster.
3044  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3045  *          same number of tuples and components as \a this array.
3046  *          The caller is to delete this result array using decrRef() as it is no more
3047  *          needed.
3048  *  \sa applyFuncOnThis
3049  *  \throw If \a this is not allocated.
3050  *  \throw If computing \a func fails.
3051  */
3052 DataArrayDouble *DataArrayDouble::applyFunc(const std::string& func, bool isSafe) const
3053 {
3054   int nbOfComp(getNumberOfComponents());
3055   if(nbOfComp<=0)
3056     throw INTERP_KERNEL::Exception("DataArrayDouble::applyFunc : output number of component must be > 0 !");
3057   checkAllocated();
3058   int nbOfTuples(getNumberOfTuples());
3059   MCAuto<DataArrayDouble> newArr(DataArrayDouble::New());
3060   newArr->alloc(nbOfTuples,nbOfComp);
3061   INTERP_KERNEL::ExprParser expr(func);
3062   expr.parse();
3063   std::set<std::string> vars;
3064   expr.getTrueSetOfVars(vars);
3065   if((int)vars.size()>1)
3066     {
3067       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 : ";
3068       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
3069       throw INTERP_KERNEL::Exception(oss.str().c_str());
3070     }
3071   if(vars.empty())
3072     {
3073       expr.prepareFastEvaluator();
3074       newArr->rearrange(1);
3075       newArr->fillWithValue(expr.evaluateDouble());
3076       newArr->rearrange(nbOfComp);
3077       return newArr.retn();
3078     }
3079   std::vector<std::string> vars2(vars.begin(),vars.end());
3080   double buff,*ptrToFill(newArr->getPointer());
3081   const double *ptr(begin());
3082   std::vector<double> stck;
3083   expr.prepareExprEvaluationDouble(vars2,1,1,0,&buff,&buff+1);
3084   expr.prepareFastEvaluator();
3085   if(!isSafe)
3086     {
3087       for(int i=0;i<nbOfTuples;i++)
3088         {
3089           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
3090             {
3091               buff=*ptr;
3092               expr.evaluateDoubleInternal(stck);
3093               *ptrToFill=stck.back();
3094               stck.pop_back();
3095             }
3096         }
3097     }
3098   else
3099     {
3100       for(int i=0;i<nbOfTuples;i++)
3101         {
3102           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
3103             {
3104               buff=*ptr;
3105               try
3106               {
3107                   expr.evaluateDoubleInternalSafe(stck);
3108               }
3109               catch(INTERP_KERNEL::Exception& e)
3110               {
3111                   std::ostringstream oss; oss << "For tuple # " << i << " component # " << iComp << " with value (";
3112                   oss << buff;
3113                   oss << ") : Evaluation of function failed !" << e.what();
3114                   throw INTERP_KERNEL::Exception(oss.str().c_str());
3115               }
3116               *ptrToFill=stck.back();
3117               stck.pop_back();
3118             }
3119         }
3120     }
3121   return newArr.retn();
3122 }
3123
3124 /*!
3125  * This method is a non const method that modify the array in \a this.
3126  * This method only works on one component array. It means that function \a func must
3127  * contain at most one variable.
3128  * This method is a specialization of applyFunc method with one parameter on one component array.
3129  *
3130  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
3131  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
3132  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
3133  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
3134  *
3135  * \sa applyFunc
3136  */
3137 void DataArrayDouble::applyFuncOnThis(const std::string& func, bool isSafe)
3138 {
3139   int nbOfComp(getNumberOfComponents());
3140   if(nbOfComp<=0)
3141     throw INTERP_KERNEL::Exception("DataArrayDouble::applyFuncOnThis : output number of component must be > 0 !");
3142   checkAllocated();
3143   int nbOfTuples(getNumberOfTuples());
3144   INTERP_KERNEL::ExprParser expr(func);
3145   expr.parse();
3146   std::set<std::string> vars;
3147   expr.getTrueSetOfVars(vars);
3148   if((int)vars.size()>1)
3149     {
3150       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 : ";
3151       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
3152       throw INTERP_KERNEL::Exception(oss.str().c_str());
3153     }
3154   if(vars.empty())
3155     {
3156       expr.prepareFastEvaluator();
3157       std::vector<std::string> compInfo(getInfoOnComponents());
3158       rearrange(1);
3159       fillWithValue(expr.evaluateDouble());
3160       rearrange(nbOfComp);
3161       setInfoOnComponents(compInfo);
3162       return ;
3163     }
3164   std::vector<std::string> vars2(vars.begin(),vars.end());
3165   double buff,*ptrToFill(getPointer());
3166   const double *ptr(begin());
3167   std::vector<double> stck;
3168   expr.prepareExprEvaluationDouble(vars2,1,1,0,&buff,&buff+1);
3169   expr.prepareFastEvaluator();
3170   if(!isSafe)
3171     {
3172       for(int i=0;i<nbOfTuples;i++)
3173         {
3174           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
3175             {
3176               buff=*ptr;
3177               expr.evaluateDoubleInternal(stck);
3178               *ptrToFill=stck.back();
3179               stck.pop_back();
3180             }
3181         }
3182     }
3183   else
3184     {
3185       for(int i=0;i<nbOfTuples;i++)
3186         {
3187           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
3188             {
3189               buff=*ptr;
3190               try
3191               {
3192                   expr.evaluateDoubleInternalSafe(stck);
3193               }
3194               catch(INTERP_KERNEL::Exception& e)
3195               {
3196                   std::ostringstream oss; oss << "For tuple # " << i << " component # " << iComp << " with value (";
3197                   oss << buff;
3198                   oss << ") : Evaluation of function failed !" << e.what();
3199                   throw INTERP_KERNEL::Exception(oss.str().c_str());
3200               }
3201               *ptrToFill=stck.back();
3202               stck.pop_back();
3203             }
3204         }
3205     }
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 MEDCouplingArrayApplyFunc2.
3212  *  \param [in] nbOfComp - number of components in the result array.
3213  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
3214  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
3215  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
3216  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
3217  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3218  *          same number of tuples as \a this array.
3219  *          The caller is to delete this result array using decrRef() as it is no more
3220  *          needed.
3221  *  \throw If \a this is not allocated.
3222  *  \throw If \a func contains vars that are not in \a this->getInfoOnComponent().
3223  *  \throw If computing \a func fails.
3224  */
3225 DataArrayDouble *DataArrayDouble::applyFuncCompo(int nbOfComp, const std::string& func, bool isSafe) const
3226 {
3227   return applyFuncNamedCompo(nbOfComp,getVarsOnComponent(),func,isSafe);
3228 }
3229
3230 /*!
3231  * Returns a new DataArrayDouble created from \a this one by applying a function to every
3232  * tuple of \a this array. Textual data is not copied.
3233  * For more info see \ref MEDCouplingArrayApplyFunc3.
3234  *  \param [in] nbOfComp - number of components in the result array.
3235  *  \param [in] varsOrder - sequence of vars defining their order.
3236  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
3237  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
3238  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
3239  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
3240  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3241  *          same number of tuples as \a this array.
3242  *          The caller is to delete this result array using decrRef() as it is no more
3243  *          needed.
3244  *  \throw If \a this is not allocated.
3245  *  \throw If \a func contains vars not in \a varsOrder.
3246  *  \throw If computing \a func fails.
3247  */
3248 DataArrayDouble *DataArrayDouble::applyFuncNamedCompo(int nbOfComp, const std::vector<std::string>& varsOrder, const std::string& func, bool isSafe) const
3249 {
3250   if(nbOfComp<=0)
3251     throw INTERP_KERNEL::Exception("DataArrayDouble::applyFuncNamedCompo : output number of component must be > 0 !");
3252   std::vector<std::string> varsOrder2(varsOrder);
3253   int oldNbOfComp(getNumberOfComponents());
3254   for(int i=(int)varsOrder.size();i<oldNbOfComp;i++)
3255     varsOrder2.push_back(std::string());
3256   checkAllocated();
3257   int nbOfTuples(getNumberOfTuples());
3258   INTERP_KERNEL::ExprParser expr(func);
3259   expr.parse();
3260   std::set<std::string> vars;
3261   expr.getTrueSetOfVars(vars);
3262   if((int)vars.size()>oldNbOfComp)
3263     {
3264       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
3265       oss << vars.size() << " variables : ";
3266       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
3267       throw INTERP_KERNEL::Exception(oss.str().c_str());
3268     }
3269   MCAuto<DataArrayDouble> newArr(DataArrayDouble::New());
3270   newArr->alloc(nbOfTuples,nbOfComp);
3271   INTERP_KERNEL::AutoPtr<double> buff(new double[oldNbOfComp]);
3272   double *buffPtr(buff),*ptrToFill;
3273   std::vector<double> stck;
3274   for(int iComp=0;iComp<nbOfComp;iComp++)
3275     {
3276       expr.prepareExprEvaluationDouble(varsOrder2,oldNbOfComp,nbOfComp,iComp,buffPtr,buffPtr+oldNbOfComp);
3277       expr.prepareFastEvaluator();
3278       const double *ptr(getConstPointer());
3279       ptrToFill=newArr->getPointer()+iComp;
3280       if(!isSafe)
3281         {
3282           for(int i=0;i<nbOfTuples;i++,ptrToFill+=nbOfComp,ptr+=oldNbOfComp)
3283             {
3284               std::copy(ptr,ptr+oldNbOfComp,buffPtr);
3285               expr.evaluateDoubleInternal(stck);
3286               *ptrToFill=stck.back();
3287               stck.pop_back();
3288             }
3289         }
3290       else
3291         {
3292           for(int i=0;i<nbOfTuples;i++,ptrToFill+=nbOfComp,ptr+=oldNbOfComp)
3293             {
3294               std::copy(ptr,ptr+oldNbOfComp,buffPtr);
3295               try
3296               {
3297                   expr.evaluateDoubleInternalSafe(stck);
3298                   *ptrToFill=stck.back();
3299                   stck.pop_back();
3300               }
3301               catch(INTERP_KERNEL::Exception& e)
3302               {
3303                   std::ostringstream oss; oss << "For tuple # " << i << " with value (";
3304                   std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
3305                   oss << ") : Evaluation of function failed !" << e.what();
3306                   throw INTERP_KERNEL::Exception(oss.str().c_str());
3307               }
3308             }
3309         }
3310     }
3311   return newArr.retn();
3312 }
3313
3314 void DataArrayDouble::applyFuncFast32(const std::string& func)
3315 {
3316   checkAllocated();
3317   INTERP_KERNEL::ExprParser expr(func);
3318   expr.parse();
3319   char *funcStr=expr.compileX86();
3320   MYFUNCPTR funcPtr;
3321   *((void **)&funcPtr)=funcStr;//he he...
3322   //
3323   double *ptr=getPointer();
3324   int nbOfComp=getNumberOfComponents();
3325   int nbOfTuples=getNumberOfTuples();
3326   int nbOfElems=nbOfTuples*nbOfComp;
3327   for(int i=0;i<nbOfElems;i++,ptr++)
3328     *ptr=funcPtr(*ptr);
3329   declareAsNew();
3330 }
3331
3332 void DataArrayDouble::applyFuncFast64(const std::string& func)
3333 {
3334   checkAllocated();
3335   INTERP_KERNEL::ExprParser expr(func);
3336   expr.parse();
3337   char *funcStr=expr.compileX86_64();
3338   MYFUNCPTR funcPtr;
3339   *((void **)&funcPtr)=funcStr;//he he...
3340   //
3341   double *ptr=getPointer();
3342   int nbOfComp=getNumberOfComponents();
3343   int nbOfTuples=getNumberOfTuples();
3344   int nbOfElems=nbOfTuples*nbOfComp;
3345   for(int i=0;i<nbOfElems;i++,ptr++)
3346     *ptr=funcPtr(*ptr);
3347   declareAsNew();
3348 }
3349
3350 /*!
3351  * \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.
3352  */
3353 MCAuto<DataArrayDouble> DataArrayDouble::symmetry3DPlane(const double point[3], const double normalVector[3]) const
3354 {
3355   checkAllocated();
3356   if(getNumberOfComponents()!=3)
3357     throw INTERP_KERNEL::Exception("DataArrayDouble::symmetry3DPlane : this is excepted to have 3 components !");
3358   int nbTuples(getNumberOfTuples());
3359   MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
3360   ret->alloc(nbTuples,3);
3361   Symmetry3DPlane(point,normalVector,nbTuples,begin(),ret->getPointer());
3362   return ret;
3363 }
3364
3365 DataArrayDoubleIterator *DataArrayDouble::iterator()
3366 {
3367   return new DataArrayDoubleIterator(this);
3368 }
3369
3370 /*!
3371  * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional
3372  * array whose values are within a given range. Textual data is not copied.
3373  *  \param [in] vmin - a lowest acceptable value (included).
3374  *  \param [in] vmax - a greatest acceptable value (included).
3375  *  \return DataArrayInt * - the new instance of DataArrayInt.
3376  *          The caller is to delete this result array using decrRef() as it is no more
3377  *          needed.
3378  *  \throw If \a this->getNumberOfComponents() != 1.
3379  *
3380  *  \sa DataArrayDouble::findIdsNotInRange
3381  *
3382  *  \if ENABLE_EXAMPLES
3383  *  \ref cpp_mcdataarraydouble_getidsinrange "Here is a C++ example".<br>
3384  *  \ref py_mcdataarraydouble_getidsinrange "Here is a Python example".
3385  *  \endif
3386  */
3387 DataArrayInt *DataArrayDouble::findIdsInRange(double vmin, double vmax) const
3388 {
3389   checkAllocated();
3390   if(getNumberOfComponents()!=1)
3391     throw INTERP_KERNEL::Exception("DataArrayDouble::findIdsInRange : this must have exactly one component !");
3392   const double *cptr(begin());
3393   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
3394   int nbOfTuples(getNumberOfTuples());
3395   for(int i=0;i<nbOfTuples;i++,cptr++)
3396     if(*cptr>=vmin && *cptr<=vmax)
3397       ret->pushBackSilent(i);
3398   return ret.retn();
3399 }
3400
3401 /*!
3402  * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional
3403  * array whose values are not within a given range. Textual data is not copied.
3404  *  \param [in] vmin - a lowest not acceptable value (excluded).
3405  *  \param [in] vmax - a greatest not acceptable value (excluded).
3406  *  \return DataArrayInt * - the new instance of DataArrayInt.
3407  *          The caller is to delete this result array using decrRef() as it is no more
3408  *          needed.
3409  *  \throw If \a this->getNumberOfComponents() != 1.
3410  *
3411  *  \sa DataArrayDouble::findIdsInRange
3412  */
3413 DataArrayInt *DataArrayDouble::findIdsNotInRange(double vmin, double vmax) const
3414 {
3415   checkAllocated();
3416   if(getNumberOfComponents()!=1)
3417     throw INTERP_KERNEL::Exception("DataArrayDouble::findIdsNotInRange : this must have exactly one component !");
3418   const double *cptr(begin());
3419   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
3420   int nbOfTuples(getNumberOfTuples());
3421   for(int i=0;i<nbOfTuples;i++,cptr++)
3422     if(*cptr<vmin || *cptr>vmax)
3423       ret->pushBackSilent(i);
3424   return ret.retn();
3425 }
3426
3427 /*!
3428  * Returns a new DataArrayDouble by concatenating two given arrays, so that (1) the number
3429  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
3430  * the number of component in the result array is same as that of each of given arrays.
3431  * Info on components is copied from the first of the given arrays. Number of components
3432  * in the given arrays must be  the same.
3433  *  \param [in] a1 - an array to include in the result array.
3434  *  \param [in] a2 - another array 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 both \a a1 and \a a2 are NULL.
3439  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
3440  */
3441 DataArrayDouble *DataArrayDouble::Aggregate(const DataArrayDouble *a1, const DataArrayDouble *a2)
3442 {
3443   std::vector<const DataArrayDouble *> tmp(2);
3444   tmp[0]=a1; tmp[1]=a2;
3445   return Aggregate(tmp);
3446 }
3447
3448 /*!
3449  * Returns a new DataArrayDouble by concatenating all given arrays, so that (1) the number
3450  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
3451  * the number of component in the result array is same as that of each of given arrays.
3452  * Info on components is copied from the first of the given arrays. Number of components
3453  * in the given arrays must be  the same.
3454  * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it
3455  * not the object itself.
3456  *  \param [in] arr - a sequence of arrays to include in the result array.
3457  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3458  *          The caller is to delete this result array using decrRef() as it is no more
3459  *          needed.
3460  *  \throw If all arrays within \a arr are NULL.
3461  *  \throw If getNumberOfComponents() of arrays within \a arr.
3462  */
3463 DataArrayDouble *DataArrayDouble::Aggregate(const std::vector<const DataArrayDouble *>& arr)
3464 {
3465   std::vector<const DataArrayDouble *> a;
3466   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
3467     if(*it4)
3468       a.push_back(*it4);
3469   if(a.empty())
3470     throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : input list must contain at least one NON EMPTY DataArrayDouble !");
3471   std::vector<const DataArrayDouble *>::const_iterator it=a.begin();
3472   int nbOfComp=(*it)->getNumberOfComponents();
3473   int nbt=(*it++)->getNumberOfTuples();
3474   for(int i=1;it!=a.end();it++,i++)
3475     {
3476       if((*it)->getNumberOfComponents()!=nbOfComp)
3477         throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : Nb of components mismatch for array aggregation !");
3478       nbt+=(*it)->getNumberOfTuples();
3479     }
3480   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
3481   ret->alloc(nbt,nbOfComp);
3482   double *pt=ret->getPointer();
3483   for(it=a.begin();it!=a.end();it++)
3484     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
3485   ret->copyStringInfoFrom(*(a[0]));
3486   return ret.retn();
3487 }
3488
3489 /*!
3490  * Returns a new DataArrayDouble by aggregating two given arrays, so that (1) the number
3491  * of components in the result array is a sum of the number of components of given arrays
3492  * and (2) the number of tuples in the result array is same as that of each of given
3493  * arrays. In other words the i-th tuple of result array includes all components of
3494  * i-th tuples of all given arrays.
3495  * Number of tuples in the given arrays must be  the same.
3496  *  \param [in] a1 - an array to include in the result array.
3497  *  \param [in] a2 - another array 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 both \a a1 and \a a2 are NULL.
3502  *  \throw If any given array is not allocated.
3503  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3504  */
3505 DataArrayDouble *DataArrayDouble::Meld(const DataArrayDouble *a1, const DataArrayDouble *a2)
3506 {
3507   std::vector<const DataArrayDouble *> arr(2);
3508   arr[0]=a1; arr[1]=a2;
3509   return Meld(arr);
3510 }
3511
3512 /*!
3513  * Returns a new DataArrayDouble by aggregating all given arrays, so that (1) the number
3514  * of components in the result array is a sum of the number of components of given arrays
3515  * and (2) the number of tuples in the result array is same as that of each of given
3516  * arrays. In other words the i-th tuple of result array includes all components of
3517  * i-th tuples of all given arrays.
3518  * Number of tuples in the given arrays must be  the same.
3519  *  \param [in] arr - a sequence of arrays to include in the result array.
3520  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3521  *          The caller is to delete this result array using decrRef() as it is no more
3522  *          needed.
3523  *  \throw If all arrays within \a arr are NULL.
3524  *  \throw If any given array is not allocated.
3525  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
3526  */
3527 DataArrayDouble *DataArrayDouble::Meld(const std::vector<const DataArrayDouble *>& arr)
3528 {
3529   std::vector<const DataArrayDouble *> a;
3530   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
3531     if(*it4)
3532       a.push_back(*it4);
3533   if(a.empty())
3534     throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : input list must contain at least one NON EMPTY DataArrayDouble !");
3535   std::vector<const DataArrayDouble *>::const_iterator it;
3536   for(it=a.begin();it!=a.end();it++)
3537     (*it)->checkAllocated();
3538   it=a.begin();
3539   int nbOfTuples=(*it)->getNumberOfTuples();
3540   std::vector<int> nbc(a.size());
3541   std::vector<const double *> pts(a.size());
3542   nbc[0]=(*it)->getNumberOfComponents();
3543   pts[0]=(*it++)->getConstPointer();
3544   for(int i=1;it!=a.end();it++,i++)
3545     {
3546       if(nbOfTuples!=(*it)->getNumberOfTuples())
3547         throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : mismatch of number of tuples !");
3548       nbc[i]=(*it)->getNumberOfComponents();
3549       pts[i]=(*it)->getConstPointer();
3550     }
3551   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
3552   DataArrayDouble *ret=DataArrayDouble::New();
3553   ret->alloc(nbOfTuples,totalNbOfComp);
3554   double *retPtr=ret->getPointer();
3555   for(int i=0;i<nbOfTuples;i++)
3556     for(int j=0;j<(int)a.size();j++)
3557       {
3558         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
3559         pts[j]+=nbc[j];
3560       }
3561   int k=0;
3562   for(int i=0;i<(int)a.size();i++)
3563     for(int j=0;j<nbc[i];j++,k++)
3564       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j));
3565   return ret;
3566 }
3567
3568 /*!
3569  * Returns a new DataArrayDouble containing a dot product of two given arrays, so that
3570  * the i-th tuple of the result array is a sum of products of j-th components of i-th
3571  * tuples of given arrays (\f$ a_i = \sum_{j=1}^n a1_j * a2_j \f$).
3572  * Info on components and name is copied from the first of the given arrays.
3573  * Number of tuples and components in the given arrays must be the same.
3574  *  \param [in] a1 - a given array.
3575  *  \param [in] a2 - another given array.
3576  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3577  *          The caller is to delete this result array using decrRef() as it is no more
3578  *          needed.
3579  *  \throw If either \a a1 or \a a2 is NULL.
3580  *  \throw If any given array is not allocated.
3581  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3582  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
3583  */
3584 DataArrayDouble *DataArrayDouble::Dot(const DataArrayDouble *a1, const DataArrayDouble *a2)
3585 {
3586   if(!a1 || !a2)
3587     throw INTERP_KERNEL::Exception("DataArrayDouble::Dot : input DataArrayDouble instance is NULL !");
3588   a1->checkAllocated();
3589   a2->checkAllocated();
3590   int nbOfComp=a1->getNumberOfComponents();
3591   if(nbOfComp!=a2->getNumberOfComponents())
3592     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Dot !");
3593   int nbOfTuple=a1->getNumberOfTuples();
3594   if(nbOfTuple!=a2->getNumberOfTuples())
3595     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Dot !");
3596   DataArrayDouble *ret=DataArrayDouble::New();
3597   ret->alloc(nbOfTuple,1);
3598   double *retPtr=ret->getPointer();
3599   const double *a1Ptr=a1->getConstPointer();
3600   const double *a2Ptr=a2->getConstPointer();
3601   for(int i=0;i<nbOfTuple;i++)
3602     {
3603       double sum=0.;
3604       for(int j=0;j<nbOfComp;j++)
3605         sum+=a1Ptr[i*nbOfComp+j]*a2Ptr[i*nbOfComp+j];
3606       retPtr[i]=sum;
3607     }
3608   ret->setInfoOnComponent(0,a1->getInfoOnComponent(0));
3609   ret->setName(a1->getName());
3610   return ret;
3611 }
3612
3613 /*!
3614  * Returns a new DataArrayDouble containing a cross product of two given arrays, so that
3615  * the i-th tuple of the result array contains 3 components of a vector which is a cross
3616  * product of two vectors defined by the i-th tuples of given arrays.
3617  * Info on components is copied from the first of the given arrays.
3618  * Number of tuples in the given arrays must be the same.
3619  * Number of components in the given arrays must be 3.
3620  *  \param [in] a1 - a given array.
3621  *  \param [in] a2 - another given array.
3622  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3623  *          The caller is to delete this result array using decrRef() as it is no more
3624  *          needed.
3625  *  \throw If either \a a1 or \a a2 is NULL.
3626  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3627  *  \throw If \a a1->getNumberOfComponents() != 3
3628  *  \throw If \a a2->getNumberOfComponents() != 3
3629  */
3630 DataArrayDouble *DataArrayDouble::CrossProduct(const DataArrayDouble *a1, const DataArrayDouble *a2)
3631 {
3632   if(!a1 || !a2)
3633     throw INTERP_KERNEL::Exception("DataArrayDouble::CrossProduct : input DataArrayDouble instance is NULL !");
3634   int nbOfComp=a1->getNumberOfComponents();
3635   if(nbOfComp!=a2->getNumberOfComponents())
3636     throw INTERP_KERNEL::Exception("Nb of components mismatch for array crossProduct !");
3637   if(nbOfComp!=3)
3638     throw INTERP_KERNEL::Exception("Nb of components must be equal to 3 for array crossProduct !");
3639   int nbOfTuple=a1->getNumberOfTuples();
3640   if(nbOfTuple!=a2->getNumberOfTuples())
3641     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array crossProduct !");
3642   DataArrayDouble *ret=DataArrayDouble::New();
3643   ret->alloc(nbOfTuple,3);
3644   double *retPtr=ret->getPointer();
3645   const double *a1Ptr=a1->getConstPointer();
3646   const double *a2Ptr=a2->getConstPointer();
3647   for(int i=0;i<nbOfTuple;i++)
3648     {
3649       retPtr[3*i]=a1Ptr[3*i+1]*a2Ptr[3*i+2]-a1Ptr[3*i+2]*a2Ptr[3*i+1];
3650       retPtr[3*i+1]=a1Ptr[3*i+2]*a2Ptr[3*i]-a1Ptr[3*i]*a2Ptr[3*i+2];
3651       retPtr[3*i+2]=a1Ptr[3*i]*a2Ptr[3*i+1]-a1Ptr[3*i+1]*a2Ptr[3*i];
3652     }
3653   ret->copyStringInfoFrom(*a1);
3654   return ret;
3655 }
3656
3657 /*!
3658  * Returns a new DataArrayDouble containing maximal values of two given arrays.
3659  * Info on components is copied from the first of the given arrays.
3660  * Number of tuples and components in the given arrays must be the same.
3661  *  \param [in] a1 - an array to compare values with another one.
3662  *  \param [in] a2 - another array to compare values with the first one.
3663  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3664  *          The caller is to delete this result array using decrRef() as it is no more
3665  *          needed.
3666  *  \throw If either \a a1 or \a a2 is NULL.
3667  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3668  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
3669  */
3670 DataArrayDouble *DataArrayDouble::Max(const DataArrayDouble *a1, const DataArrayDouble *a2)
3671 {
3672   if(!a1 || !a2)
3673     throw INTERP_KERNEL::Exception("DataArrayDouble::Max : input DataArrayDouble instance is NULL !");
3674   int nbOfComp=a1->getNumberOfComponents();
3675   if(nbOfComp!=a2->getNumberOfComponents())
3676     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Max !");
3677   int nbOfTuple=a1->getNumberOfTuples();
3678   if(nbOfTuple!=a2->getNumberOfTuples())
3679     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Max !");
3680   DataArrayDouble *ret=DataArrayDouble::New();
3681   ret->alloc(nbOfTuple,nbOfComp);
3682   double *retPtr=ret->getPointer();
3683   const double *a1Ptr=a1->getConstPointer();
3684   const double *a2Ptr=a2->getConstPointer();
3685   int nbElem=nbOfTuple*nbOfComp;
3686   for(int i=0;i<nbElem;i++)
3687     retPtr[i]=std::max(a1Ptr[i],a2Ptr[i]);
3688   ret->copyStringInfoFrom(*a1);
3689   return ret;
3690 }
3691
3692 /*!
3693  * Returns a new DataArrayDouble containing minimal values of two given arrays.
3694  * Info on components is copied from the first of the given arrays.
3695  * Number of tuples and components in the given arrays must be the same.
3696  *  \param [in] a1 - an array to compare values with another one.
3697  *  \param [in] a2 - another array to compare values with the first one.
3698  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3699  *          The caller is to delete this result array using decrRef() as it is no more
3700  *          needed.
3701  *  \throw If either \a a1 or \a a2 is NULL.
3702  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3703  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
3704  */
3705 DataArrayDouble *DataArrayDouble::Min(const DataArrayDouble *a1, const DataArrayDouble *a2)
3706 {
3707   if(!a1 || !a2)
3708     throw INTERP_KERNEL::Exception("DataArrayDouble::Min : input DataArrayDouble instance is NULL !");
3709   int nbOfComp=a1->getNumberOfComponents();
3710   if(nbOfComp!=a2->getNumberOfComponents())
3711     throw INTERP_KERNEL::Exception("Nb of components mismatch for array min !");
3712   int nbOfTuple=a1->getNumberOfTuples();
3713   if(nbOfTuple!=a2->getNumberOfTuples())
3714     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array min !");
3715   DataArrayDouble *ret=DataArrayDouble::New();
3716   ret->alloc(nbOfTuple,nbOfComp);
3717   double *retPtr=ret->getPointer();
3718   const double *a1Ptr=a1->getConstPointer();
3719   const double *a2Ptr=a2->getConstPointer();
3720   int nbElem=nbOfTuple*nbOfComp;
3721   for(int i=0;i<nbElem;i++)
3722     retPtr[i]=std::min(a1Ptr[i],a2Ptr[i]);
3723   ret->copyStringInfoFrom(*a1);
3724   return ret;
3725 }
3726
3727 /*!
3728  * Returns a new DataArrayDouble that is a sum of two given arrays. There are 3
3729  * valid cases.
3730  * 1.  The arrays have same number of tuples and components. Then each value of
3731  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
3732  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
3733  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
3734  *   component. Then
3735  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
3736  * 3.  The arrays have same number of components and one array, say _a2_, has one
3737  *   tuple. Then
3738  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
3739  *
3740  * Info on components is copied either from the first array (in the first case) or from
3741  * the array with maximal number of elements (getNbOfElems()).
3742  *  \param [in] a1 - an array to sum up.
3743  *  \param [in] a2 - another array to sum up.
3744  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3745  *          The caller is to delete this result array using decrRef() as it is no more
3746  *          needed.
3747  *  \throw If either \a a1 or \a a2 is NULL.
3748  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
3749  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
3750  *         none of them has number of tuples or components equal to 1.
3751  */
3752 DataArrayDouble *DataArrayDouble::Add(const DataArrayDouble *a1, const DataArrayDouble *a2)
3753 {
3754   if(!a1 || !a2)
3755     throw INTERP_KERNEL::Exception("DataArrayDouble::Add : input DataArrayDouble instance is NULL !");
3756   int nbOfTuple=a1->getNumberOfTuples();
3757   int nbOfTuple2=a2->getNumberOfTuples();
3758   int nbOfComp=a1->getNumberOfComponents();
3759   int nbOfComp2=a2->getNumberOfComponents();
3760   MCAuto<DataArrayDouble> ret=0;
3761   if(nbOfTuple==nbOfTuple2)
3762     {
3763       if(nbOfComp==nbOfComp2)
3764         {
3765           ret=DataArrayDouble::New();
3766           ret->alloc(nbOfTuple,nbOfComp);
3767           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<double>());
3768           ret->copyStringInfoFrom(*a1);
3769         }
3770       else
3771         {
3772           int nbOfCompMin,nbOfCompMax;
3773           const DataArrayDouble *aMin, *aMax;
3774           if(nbOfComp>nbOfComp2)
3775             {
3776               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
3777               aMin=a2; aMax=a1;
3778             }
3779           else
3780             {
3781               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
3782               aMin=a1; aMax=a2;
3783             }
3784           if(nbOfCompMin==1)
3785             {
3786               ret=DataArrayDouble::New();
3787               ret->alloc(nbOfTuple,nbOfCompMax);
3788               const double *aMinPtr=aMin->getConstPointer();
3789               const double *aMaxPtr=aMax->getConstPointer();
3790               double *res=ret->getPointer();
3791               for(int i=0;i<nbOfTuple;i++)
3792                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<double>(),aMinPtr[i]));
3793               ret->copyStringInfoFrom(*aMax);
3794             }
3795           else
3796             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
3797         }
3798     }
3799   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
3800     {
3801       if(nbOfComp==nbOfComp2)
3802         {
3803           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
3804           const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
3805           const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
3806           const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
3807           ret=DataArrayDouble::New();
3808           ret->alloc(nbOfTupleMax,nbOfComp);
3809           double *res=ret->getPointer();
3810           for(int i=0;i<nbOfTupleMax;i++)
3811             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<double>());
3812           ret->copyStringInfoFrom(*aMax);
3813         }
3814       else
3815         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
3816     }
3817   else
3818     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
3819   return ret.retn();
3820 }
3821
3822 /*!
3823  * Adds values of another DataArrayDouble to values of \a this one. There are 3
3824  * valid cases.
3825  * 1.  The arrays have same number of tuples and components. Then each value of
3826  *   \a other array is added to the corresponding value of \a this array, i.e.:
3827  *   _a_ [ i, j ] += _other_ [ i, j ].
3828  * 2.  The arrays have same number of tuples and \a other array has one component. Then
3829  *   _a_ [ i, j ] += _other_ [ i, 0 ].
3830  * 3.  The arrays have same number of components and \a other array has one tuple. Then
3831  *   _a_ [ i, j ] += _a2_ [ 0, j ].
3832  *
3833  *  \param [in] other - an array to add to \a this one.
3834  *  \throw If \a other is NULL.
3835  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
3836  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
3837  *         \a other has number of both tuples and components not equal to 1.
3838  */
3839 void DataArrayDouble::addEqual(const DataArrayDouble *other)
3840 {
3841   if(!other)
3842     throw INTERP_KERNEL::Exception("DataArrayDouble::addEqual : input DataArrayDouble instance is NULL !");
3843   const char *msg="Nb of tuples mismatch for DataArrayDouble::addEqual  !";
3844   checkAllocated();
3845   other->checkAllocated();
3846   int nbOfTuple=getNumberOfTuples();
3847   int nbOfTuple2=other->getNumberOfTuples();
3848   int nbOfComp=getNumberOfComponents();
3849   int nbOfComp2=other->getNumberOfComponents();
3850   if(nbOfTuple==nbOfTuple2)
3851     {
3852       if(nbOfComp==nbOfComp2)
3853         {
3854           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<double>());
3855         }
3856       else if(nbOfComp2==1)
3857         {
3858           double *ptr=getPointer();
3859           const double *ptrc=other->getConstPointer();
3860           for(int i=0;i<nbOfTuple;i++)
3861             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<double>(),*ptrc++));
3862         }
3863       else
3864         throw INTERP_KERNEL::Exception(msg);
3865     }
3866   else if(nbOfTuple2==1)
3867     {
3868       if(nbOfComp2==nbOfComp)
3869         {
3870           double *ptr=getPointer();
3871           const double *ptrc=other->getConstPointer();
3872           for(int i=0;i<nbOfTuple;i++)
3873             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<double>());
3874         }
3875       else
3876         throw INTERP_KERNEL::Exception(msg);
3877     }
3878   else
3879     throw INTERP_KERNEL::Exception(msg);
3880   declareAsNew();
3881 }
3882
3883 /*!
3884  * Returns a new DataArrayDouble that is a subtraction of two given arrays. There are 3
3885  * valid cases.
3886  * 1.  The arrays have same number of tuples and components. Then each value of
3887  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
3888  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
3889  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
3890  *   component. Then
3891  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
3892  * 3.  The arrays have same number of components and one array, say _a2_, has one
3893  *   tuple. Then
3894  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
3895  *
3896  * Info on components is copied either from the first array (in the first case) or from
3897  * the array with maximal number of elements (getNbOfElems()).
3898  *  \param [in] a1 - an array to subtract from.
3899  *  \param [in] a2 - an array to subtract.
3900  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3901  *          The caller is to delete this result array using decrRef() as it is no more
3902  *          needed.
3903  *  \throw If either \a a1 or \a a2 is NULL.
3904  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
3905  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
3906  *         none of them has number of tuples or components equal to 1.
3907  */
3908 DataArrayDouble *DataArrayDouble::Substract(const DataArrayDouble *a1, const DataArrayDouble *a2)
3909 {
3910   if(!a1 || !a2)
3911     throw INTERP_KERNEL::Exception("DataArrayDouble::Substract : input DataArrayDouble instance is NULL !");
3912   int nbOfTuple1=a1->getNumberOfTuples();
3913   int nbOfTuple2=a2->getNumberOfTuples();
3914   int nbOfComp1=a1->getNumberOfComponents();
3915   int nbOfComp2=a2->getNumberOfComponents();
3916   if(nbOfTuple2==nbOfTuple1)
3917     {
3918       if(nbOfComp1==nbOfComp2)
3919         {
3920           MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
3921           ret->alloc(nbOfTuple2,nbOfComp1);
3922           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<double>());
3923           ret->copyStringInfoFrom(*a1);
3924           return ret.retn();
3925         }
3926       else if(nbOfComp2==1)
3927         {
3928           MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
3929           ret->alloc(nbOfTuple1,nbOfComp1);
3930           const double *a2Ptr=a2->getConstPointer();
3931           const double *a1Ptr=a1->getConstPointer();
3932           double *res=ret->getPointer();
3933           for(int i=0;i<nbOfTuple1;i++)
3934             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<double>(),a2Ptr[i]));
3935           ret->copyStringInfoFrom(*a1);
3936           return ret.retn();
3937         }
3938       else
3939         {
3940           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
3941           return 0;
3942         }
3943     }
3944   else if(nbOfTuple2==1)
3945     {
3946       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
3947       MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
3948       ret->alloc(nbOfTuple1,nbOfComp1);
3949       const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
3950       double *pt=ret->getPointer();
3951       for(int i=0;i<nbOfTuple1;i++)
3952         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<double>());
3953       ret->copyStringInfoFrom(*a1);
3954       return ret.retn();
3955     }
3956   else
3957     {
3958       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
3959       return 0;
3960     }
3961 }
3962
3963 /*!
3964  * Subtract values of another DataArrayDouble from values of \a this one. There are 3
3965  * valid cases.
3966  * 1.  The arrays have same number of tuples and components. Then each value of
3967  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
3968  *   _a_ [ i, j ] -= _other_ [ i, j ].
3969  * 2.  The arrays have same number of tuples and \a other array has one component. Then
3970  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
3971  * 3.  The arrays have same number of components and \a other array has one tuple. Then
3972  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
3973  *
3974  *  \param [in] other - an array to subtract from \a this one.
3975  *  \throw If \a other is NULL.
3976  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
3977  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
3978  *         \a other has number of both tuples and components not equal to 1.
3979  */
3980 void DataArrayDouble::substractEqual(const DataArrayDouble *other)
3981 {
3982   if(!other)
3983     throw INTERP_KERNEL::Exception("DataArrayDouble::substractEqual : input DataArrayDouble instance is NULL !");
3984   const char *msg="Nb of tuples mismatch for DataArrayDouble::substractEqual  !";
3985   checkAllocated();
3986   other->checkAllocated();
3987   int nbOfTuple=getNumberOfTuples();
3988   int nbOfTuple2=other->getNumberOfTuples();
3989   int nbOfComp=getNumberOfComponents();
3990   int nbOfComp2=other->getNumberOfComponents();
3991   if(nbOfTuple==nbOfTuple2)
3992     {
3993       if(nbOfComp==nbOfComp2)
3994         {
3995           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<double>());
3996         }
3997       else if(nbOfComp2==1)
3998         {
3999           double *ptr=getPointer();
4000           const double *ptrc=other->getConstPointer();
4001           for(int i=0;i<nbOfTuple;i++)
4002             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<double>(),*ptrc++)); 
4003         }
4004       else
4005         throw INTERP_KERNEL::Exception(msg);
4006     }
4007   else if(nbOfTuple2==1)
4008     {
4009       if(nbOfComp2==nbOfComp)
4010         {
4011           double *ptr=getPointer();
4012           const double *ptrc=other->getConstPointer();
4013           for(int i=0;i<nbOfTuple;i++)
4014             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<double>());
4015         }
4016       else
4017         throw INTERP_KERNEL::Exception(msg);
4018     }
4019   else
4020     throw INTERP_KERNEL::Exception(msg);
4021   declareAsNew();
4022 }
4023
4024 /*!
4025  * Returns a new DataArrayDouble that is a product of two given arrays. There are 3
4026  * valid cases.
4027  * 1.  The arrays have same number of tuples and components. Then each value of
4028  *   the result array (_a_) is a product of the corresponding values of \a a1 and
4029  *   \a a2, i.e. _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
4030  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
4031  *   component. Then
4032  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
4033  * 3.  The arrays have same number of components and one array, say _a2_, has one
4034  *   tuple. Then
4035  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
4036  *
4037  * Info on components is copied either from the first array (in the first case) or from
4038  * the array with maximal number of elements (getNbOfElems()).
4039  *  \param [in] a1 - a factor array.
4040  *  \param [in] a2 - another factor array.
4041  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4042  *          The caller is to delete this result array using decrRef() as it is no more
4043  *          needed.
4044  *  \throw If either \a a1 or \a a2 is NULL.
4045  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
4046  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
4047  *         none of them has number of tuples or components equal to 1.
4048  */
4049 DataArrayDouble *DataArrayDouble::Multiply(const DataArrayDouble *a1, const DataArrayDouble *a2)
4050 {
4051   if(!a1 || !a2)
4052     throw INTERP_KERNEL::Exception("DataArrayDouble::Multiply : input DataArrayDouble instance is NULL !");
4053   int nbOfTuple=a1->getNumberOfTuples();
4054   int nbOfTuple2=a2->getNumberOfTuples();
4055   int nbOfComp=a1->getNumberOfComponents();
4056   int nbOfComp2=a2->getNumberOfComponents();
4057   MCAuto<DataArrayDouble> ret=0;
4058   if(nbOfTuple==nbOfTuple2)
4059     {
4060       if(nbOfComp==nbOfComp2)
4061         {
4062           ret=DataArrayDouble::New();
4063           ret->alloc(nbOfTuple,nbOfComp);
4064           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<double>());
4065           ret->copyStringInfoFrom(*a1);
4066         }
4067       else
4068         {
4069           int nbOfCompMin,nbOfCompMax;
4070           const DataArrayDouble *aMin, *aMax;
4071           if(nbOfComp>nbOfComp2)
4072             {
4073               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
4074               aMin=a2; aMax=a1;
4075             }
4076           else
4077             {
4078               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
4079               aMin=a1; aMax=a2;
4080             }
4081           if(nbOfCompMin==1)
4082             {
4083               ret=DataArrayDouble::New();
4084               ret->alloc(nbOfTuple,nbOfCompMax);
4085               const double *aMinPtr=aMin->getConstPointer();
4086               const double *aMaxPtr=aMax->getConstPointer();
4087               double *res=ret->getPointer();
4088               for(int i=0;i<nbOfTuple;i++)
4089                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<double>(),aMinPtr[i]));
4090               ret->copyStringInfoFrom(*aMax);
4091             }
4092           else
4093             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
4094         }
4095     }
4096   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
4097     {
4098       if(nbOfComp==nbOfComp2)
4099         {
4100           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
4101           const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
4102           const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
4103           const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
4104           ret=DataArrayDouble::New();
4105           ret->alloc(nbOfTupleMax,nbOfComp);
4106           double *res=ret->getPointer();
4107           for(int i=0;i<nbOfTupleMax;i++)
4108             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<double>());
4109           ret->copyStringInfoFrom(*aMax);
4110         }
4111       else
4112         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
4113     }
4114   else
4115     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
4116   return ret.retn();
4117 }
4118
4119 /*!
4120  * Multiply values of another DataArrayDouble to values of \a this one. There are 3
4121  * valid cases.
4122  * 1.  The arrays have same number of tuples and components. Then each value of
4123  *   \a other array is multiplied to the corresponding value of \a this array, i.e.
4124  *   _this_ [ i, j ] *= _other_ [ i, j ].
4125  * 2.  The arrays have same number of tuples and \a other array has one component. Then
4126  *   _this_ [ i, j ] *= _other_ [ i, 0 ].
4127  * 3.  The arrays have same number of components and \a other array has one tuple. Then
4128  *   _this_ [ i, j ] *= _a2_ [ 0, j ].
4129  *
4130  *  \param [in] other - an array to multiply to \a this one.
4131  *  \throw If \a other is NULL.
4132  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
4133  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
4134  *         \a other has number of both tuples and components not equal to 1.
4135  */
4136 void DataArrayDouble::multiplyEqual(const DataArrayDouble *other)
4137 {
4138   if(!other)
4139     throw INTERP_KERNEL::Exception("DataArrayDouble::multiplyEqual : input DataArrayDouble instance is NULL !");
4140   const char *msg="Nb of tuples mismatch for DataArrayDouble::multiplyEqual !";
4141   checkAllocated();
4142   other->checkAllocated();
4143   int nbOfTuple=getNumberOfTuples();
4144   int nbOfTuple2=other->getNumberOfTuples();
4145   int nbOfComp=getNumberOfComponents();
4146   int nbOfComp2=other->getNumberOfComponents();
4147   if(nbOfTuple==nbOfTuple2)
4148     {
4149       if(nbOfComp==nbOfComp2)
4150         {
4151           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<double>());
4152         }
4153       else if(nbOfComp2==1)
4154         {
4155           double *ptr=getPointer();
4156           const double *ptrc=other->getConstPointer();
4157           for(int i=0;i<nbOfTuple;i++)
4158             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<double>(),*ptrc++));
4159         }
4160       else
4161         throw INTERP_KERNEL::Exception(msg);
4162     }
4163   else if(nbOfTuple2==1)
4164     {
4165       if(nbOfComp2==nbOfComp)
4166         {
4167           double *ptr=getPointer();
4168           const double *ptrc=other->getConstPointer();
4169           for(int i=0;i<nbOfTuple;i++)
4170             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<double>());
4171         }
4172       else
4173         throw INTERP_KERNEL::Exception(msg);
4174     }
4175   else
4176     throw INTERP_KERNEL::Exception(msg);
4177   declareAsNew();
4178 }
4179
4180 /*!
4181  * Returns a new DataArrayDouble that is a division of two given arrays. There are 3
4182  * valid cases.
4183  * 1.  The arrays have same number of tuples and components. Then each value of
4184  *   the result array (_a_) is a division of the corresponding values of \a a1 and
4185  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
4186  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
4187  *   component. Then
4188  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
4189  * 3.  The arrays have same number of components and one array, say _a2_, has one
4190  *   tuple. Then
4191  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
4192  *
4193  * Info on components is copied either from the first array (in the first case) or from
4194  * the array with maximal number of elements (getNbOfElems()).
4195  *  \warning No check of division by zero is performed!
4196  *  \param [in] a1 - a numerator array.
4197  *  \param [in] a2 - a denominator array.
4198  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4199  *          The caller is to delete this result array using decrRef() as it is no more
4200  *          needed.
4201  *  \throw If either \a a1 or \a a2 is NULL.
4202  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
4203  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
4204  *         none of them has number of tuples or components equal to 1.
4205  */
4206 DataArrayDouble *DataArrayDouble::Divide(const DataArrayDouble *a1, const DataArrayDouble *a2)
4207 {
4208   if(!a1 || !a2)
4209     throw INTERP_KERNEL::Exception("DataArrayDouble::Divide : input DataArrayDouble instance is NULL !");
4210   int nbOfTuple1=a1->getNumberOfTuples();
4211   int nbOfTuple2=a2->getNumberOfTuples();
4212   int nbOfComp1=a1->getNumberOfComponents();
4213   int nbOfComp2=a2->getNumberOfComponents();
4214   if(nbOfTuple2==nbOfTuple1)
4215     {
4216       if(nbOfComp1==nbOfComp2)
4217         {
4218           MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
4219           ret->alloc(nbOfTuple2,nbOfComp1);
4220           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<double>());
4221           ret->copyStringInfoFrom(*a1);
4222           return ret.retn();
4223         }
4224       else if(nbOfComp2==1)
4225         {
4226           MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
4227           ret->alloc(nbOfTuple1,nbOfComp1);
4228           const double *a2Ptr=a2->getConstPointer();
4229           const double *a1Ptr=a1->getConstPointer();
4230           double *res=ret->getPointer();
4231           for(int i=0;i<nbOfTuple1;i++)
4232             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<double>(),a2Ptr[i]));
4233           ret->copyStringInfoFrom(*a1);
4234           return ret.retn();
4235         }
4236       else
4237         {
4238           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
4239           return 0;
4240         }
4241     }
4242   else if(nbOfTuple2==1)
4243     {
4244       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
4245       MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
4246       ret->alloc(nbOfTuple1,nbOfComp1);
4247       const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
4248       double *pt=ret->getPointer();
4249       for(int i=0;i<nbOfTuple1;i++)
4250         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<double>());
4251       ret->copyStringInfoFrom(*a1);
4252       return ret.retn();
4253     }
4254   else
4255     {
4256       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
4257       return 0;
4258     }
4259 }
4260
4261 /*!
4262  * Divide values of \a this array by values of another DataArrayDouble. There are 3
4263  * valid cases.
4264  * 1.  The arrays have same number of tuples and components. Then each value of
4265  *    \a this array is divided by the corresponding value of \a other one, i.e.:
4266  *   _a_ [ i, j ] /= _other_ [ i, j ].
4267  * 2.  The arrays have same number of tuples and \a other array has one component. Then
4268  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
4269  * 3.  The arrays have same number of components and \a other array has one tuple. Then
4270  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
4271  *
4272  *  \warning No check of division by zero is performed!
4273  *  \param [in] other - an array to divide \a this one by.
4274  *  \throw If \a other is NULL.
4275  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
4276  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
4277  *         \a other has number of both tuples and components not equal to 1.
4278  */
4279 void DataArrayDouble::divideEqual(const DataArrayDouble *other)
4280 {
4281   if(!other)
4282     throw INTERP_KERNEL::Exception("DataArrayDouble::divideEqual : input DataArrayDouble instance is NULL !");
4283   const char *msg="Nb of tuples mismatch for DataArrayDouble::divideEqual !";
4284   checkAllocated();
4285   other->checkAllocated();
4286   int nbOfTuple=getNumberOfTuples();
4287   int nbOfTuple2=other->getNumberOfTuples();
4288   int nbOfComp=getNumberOfComponents();
4289   int nbOfComp2=other->getNumberOfComponents();
4290   if(nbOfTuple==nbOfTuple2)
4291     {
4292       if(nbOfComp==nbOfComp2)
4293         {
4294           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<double>());
4295         }
4296       else if(nbOfComp2==1)
4297         {
4298           double *ptr=getPointer();
4299           const double *ptrc=other->getConstPointer();
4300           for(int i=0;i<nbOfTuple;i++)
4301             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<double>(),*ptrc++));
4302         }
4303       else
4304         throw INTERP_KERNEL::Exception(msg);
4305     }
4306   else if(nbOfTuple2==1)
4307     {
4308       if(nbOfComp2==nbOfComp)
4309         {
4310           double *ptr=getPointer();
4311           const double *ptrc=other->getConstPointer();
4312           for(int i=0;i<nbOfTuple;i++)
4313             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<double>());
4314         }
4315       else
4316         throw INTERP_KERNEL::Exception(msg);
4317     }
4318   else
4319     throw INTERP_KERNEL::Exception(msg);
4320   declareAsNew();
4321 }
4322
4323 /*!
4324  * Returns a new DataArrayDouble that is the result of pow of two given arrays. There are 3
4325  * valid cases.
4326  *
4327  *  \param [in] a1 - an array to pow up.
4328  *  \param [in] a2 - another array to sum up.
4329  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4330  *          The caller is to delete this result array using decrRef() as it is no more
4331  *          needed.
4332  *  \throw If either \a a1 or \a a2 is NULL.
4333  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4334  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
4335  *  \throw If there is a negative value in \a a1.
4336  */
4337 DataArrayDouble *DataArrayDouble::Pow(const DataArrayDouble *a1, const DataArrayDouble *a2)
4338 {
4339   if(!a1 || !a2)
4340     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : at least one of input instances is null !");
4341   int nbOfTuple=a1->getNumberOfTuples();
4342   int nbOfTuple2=a2->getNumberOfTuples();
4343   int nbOfComp=a1->getNumberOfComponents();
4344   int nbOfComp2=a2->getNumberOfComponents();
4345   if(nbOfTuple!=nbOfTuple2)
4346     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of tuples mismatches !");
4347   if(nbOfComp!=1 || nbOfComp2!=1)
4348     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of components of both arrays must be equal to 1 !");
4349   MCAuto<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbOfTuple,1);
4350   const double *ptr1(a1->begin()),*ptr2(a2->begin());
4351   double *ptr=ret->getPointer();
4352   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
4353     {
4354       if(*ptr1>=0)
4355         {
4356           *ptr=pow(*ptr1,*ptr2);
4357         }
4358       else
4359         {
4360           std::ostringstream oss; oss << "DataArrayDouble::Pow : on tuple #" << i << " of a1 value is < 0 (" << *ptr1 << ") !";
4361           throw INTERP_KERNEL::Exception(oss.str().c_str());
4362         }
4363     }
4364   return ret.retn();
4365 }
4366
4367 /*!
4368  * Apply pow on values of another DataArrayDouble to values of \a this one.
4369  *
4370  *  \param [in] other - an array to pow to \a this one.
4371  *  \throw If \a other is NULL.
4372  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
4373  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
4374  *  \throw If there is a negative value in \a this.
4375  */
4376 void DataArrayDouble::powEqual(const DataArrayDouble *other)
4377 {
4378   if(!other)
4379     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : input instance is null !");
4380   int nbOfTuple=getNumberOfTuples();
4381   int nbOfTuple2=other->getNumberOfTuples();
4382   int nbOfComp=getNumberOfComponents();
4383   int nbOfComp2=other->getNumberOfComponents();
4384   if(nbOfTuple!=nbOfTuple2)
4385     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of tuples mismatches !");
4386   if(nbOfComp!=1 || nbOfComp2!=1)
4387     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of components of both arrays must be equal to 1 !");
4388   double *ptr=getPointer();
4389   const double *ptrc=other->begin();
4390   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
4391     {
4392       if(*ptr>=0)
4393         *ptr=pow(*ptr,*ptrc);
4394       else
4395         {
4396           std::ostringstream oss; oss << "DataArrayDouble::powEqual : on tuple #" << i << " of this value is < 0 (" << *ptr << ") !";
4397           throw INTERP_KERNEL::Exception(oss.str().c_str());
4398         }
4399     }
4400   declareAsNew();
4401 }
4402
4403 /*!
4404  * This method is \b NOT wrapped into python because it can be useful only for performance reasons in C++ context.
4405  * All values in \a this must be 0. or 1. within eps error. 0 means false, 1 means true.
4406  * If an another value than 0 or 1 appear (within eps precision) an INTERP_KERNEL::Exception will be thrown.
4407  *
4408  * \throw if \a this is not allocated.
4409  * \throw if \a this has not exactly one component.
4410  */
4411 std::vector<bool> DataArrayDouble::toVectorOfBool(double eps) const
4412 {
4413   checkAllocated();
4414   if(getNumberOfComponents()!=1)
4415     throw INTERP_KERNEL::Exception("DataArrayDouble::toVectorOfBool : must be applied on single component array !");
4416   int nbt(getNumberOfTuples());
4417   std::vector<bool> ret(nbt);
4418   const double *pt(begin());
4419   for(int i=0;i<nbt;i++)
4420     {
4421       if(fabs(pt[i])<eps)
4422         ret[i]=false;
4423       else if(fabs(pt[i]-1.)<eps)
4424         ret[i]=true;
4425       else
4426         {
4427           std::ostringstream oss; oss << "DataArrayDouble::toVectorOfBool : the tuple #" << i << " has value " << pt[i] << " is invalid ! must be 0. or 1. !";
4428           throw INTERP_KERNEL::Exception(oss.str().c_str());
4429         }
4430     }
4431   return ret;
4432 }
4433
4434 /*!
4435  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
4436  * Server side.
4437  */
4438 void DataArrayDouble::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
4439 {
4440   tinyInfo.resize(2);
4441   if(isAllocated())
4442     {
4443       tinyInfo[0]=getNumberOfTuples();
4444       tinyInfo[1]=getNumberOfComponents();
4445     }
4446   else
4447     {
4448       tinyInfo[0]=-1;
4449       tinyInfo[1]=-1;
4450     }
4451 }
4452
4453 /*!
4454  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
4455  * Server side.
4456  */
4457 void DataArrayDouble::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
4458 {
4459   if(isAllocated())
4460     {
4461       int nbOfCompo=getNumberOfComponents();
4462       tinyInfo.resize(nbOfCompo+1);
4463       tinyInfo[0]=getName();
4464       for(int i=0;i<nbOfCompo;i++)
4465         tinyInfo[i+1]=getInfoOnComponent(i);
4466     }
4467   else
4468     {
4469       tinyInfo.resize(1);
4470       tinyInfo[0]=getName();
4471     }
4472 }
4473
4474 /*!
4475  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
4476  * This method returns if a feeding is needed.
4477  */
4478 bool DataArrayDouble::resizeForUnserialization(const std::vector<int>& tinyInfoI)
4479 {
4480   int nbOfTuple=tinyInfoI[0];
4481   int nbOfComp=tinyInfoI[1];
4482   if(nbOfTuple!=-1 || nbOfComp!=-1)
4483     {
4484       alloc(nbOfTuple,nbOfComp);
4485       return true;
4486     }
4487   return false;
4488 }
4489
4490 /*!
4491  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
4492  */
4493 void DataArrayDouble::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
4494 {
4495   setName(tinyInfoS[0]);
4496   if(isAllocated())
4497     {
4498       int nbOfCompo=getNumberOfComponents();
4499       for(int i=0;i<nbOfCompo;i++)
4500         setInfoOnComponent(i,tinyInfoS[i+1]);
4501     }
4502 }
4503
4504 /*!
4505  * Low static method that operates 3D rotation of 'nbNodes' 3D nodes whose coordinates are arranged in \a coordsIn
4506  * around an axe ( \a center, \a vect) and with angle \a angle.
4507  */
4508 void DataArrayDouble::Rotate3DAlg(const double *center, const double *vect, double angle, int nbNodes, const double *coordsIn, double *coordsOut)
4509 {
4510   if(!center || !vect)
4511     throw INTERP_KERNEL::Exception("DataArrayDouble::Rotate3DAlg : null vector in input !");
4512   double sina(sin(angle));
4513   double cosa(cos(angle));
4514   double vectorNorm[3];
4515   double matrix[9];
4516   double matrixTmp[9];
4517   double norm(sqrt(vect[0]*vect[0]+vect[1]*vect[1]+vect[2]*vect[2]));
4518   if(norm<std::numeric_limits<double>::min())
4519     throw INTERP_KERNEL::Exception("DataArrayDouble::Rotate3DAlg : magnitude of input vector is too close of 0. !");
4520   std::transform(vect,vect+3,vectorNorm,std::bind2nd(std::multiplies<double>(),1/norm));
4521   //rotation matrix computation
4522   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;
4523   matrixTmp[0]=vectorNorm[0]*vectorNorm[0]; matrixTmp[1]=vectorNorm[0]*vectorNorm[1]; matrixTmp[2]=vectorNorm[0]*vectorNorm[2];
4524   matrixTmp[3]=vectorNorm[1]*vectorNorm[0]; matrixTmp[4]=vectorNorm[1]*vectorNorm[1]; matrixTmp[5]=vectorNorm[1]*vectorNorm[2];
4525   matrixTmp[6]=vectorNorm[2]*vectorNorm[0]; matrixTmp[7]=vectorNorm[2]*vectorNorm[1]; matrixTmp[8]=vectorNorm[2]*vectorNorm[2];
4526   std::transform(matrixTmp,matrixTmp+9,matrixTmp,std::bind2nd(std::multiplies<double>(),1-cosa));
4527   std::transform(matrix,matrix+9,matrixTmp,matrix,std::plus<double>());
4528   matrixTmp[0]=0.; matrixTmp[1]=-vectorNorm[2]; matrixTmp[2]=vectorNorm[1];
4529   matrixTmp[3]=vectorNorm[2]; matrixTmp[4]=0.; matrixTmp[5]=-vectorNorm[0];
4530   matrixTmp[6]=-vectorNorm[1]; matrixTmp[7]=vectorNorm[0]; matrixTmp[8]=0.;
4531   std::transform(matrixTmp,matrixTmp+9,matrixTmp,std::bind2nd(std::multiplies<double>(),sina));
4532   std::transform(matrix,matrix+9,matrixTmp,matrix,std::plus<double>());
4533   //rotation matrix computed.
4534   double tmp[3];
4535   for(int i=0; i<nbNodes; i++)
4536     {
4537       std::transform(coordsIn+i*3,coordsIn+(i+1)*3,center,tmp,std::minus<double>());
4538       coordsOut[i*3]=matrix[0]*tmp[0]+matrix[1]*tmp[1]+matrix[2]*tmp[2]+center[0];
4539       coordsOut[i*3+1]=matrix[3]*tmp[0]+matrix[4]*tmp[1]+matrix[5]*tmp[2]+center[1];
4540       coordsOut[i*3+2]=matrix[6]*tmp[0]+matrix[7]*tmp[1]+matrix[8]*tmp[2]+center[2];
4541     }
4542 }
4543
4544 void DataArrayDouble::Symmetry3DPlane(const double point[3], const double normalVector[3], int nbNodes, const double *coordsIn, double *coordsOut)
4545 {
4546   double matrix[9],matrix2[9],matrix3[9];
4547   double vect[3],crossVect[3];
4548   INTERP_KERNEL::orthogonalVect3(normalVector,vect);
4549   crossVect[0]=normalVector[1]*vect[2]-normalVector[2]*vect[1];
4550   crossVect[1]=normalVector[2]*vect[0]-normalVector[0]*vect[2];
4551   crossVect[2]=normalVector[0]*vect[1]-normalVector[1]*vect[0];
4552   double nv(INTERP_KERNEL::norm<3>(vect)),ni(INTERP_KERNEL::norm<3>(normalVector)),nc(INTERP_KERNEL::norm<3>(crossVect));
4553   matrix[0]=vect[0]/nv; matrix[1]=crossVect[0]/nc; matrix[2]=-normalVector[0]/ni;
4554   matrix[3]=vect[1]/nv; matrix[4]=crossVect[1]/nc; matrix[5]=-normalVector[1]/ni;
4555   matrix[6]=vect[2]/nv; matrix[7]=crossVect[2]/nc; matrix[8]=-normalVector[2]/ni;
4556   matrix2[0]=vect[0]/nv; matrix2[1]=vect[1]/nv; matrix2[2]=vect[2]/nv;
4557   matrix2[3]=crossVect[0]/nc; matrix2[4]=crossVect[1]/nc; matrix2[5]=crossVect[2]/nc;
4558   matrix2[6]=normalVector[0]/ni; matrix2[7]=normalVector[1]/ni; matrix2[8]=normalVector[2]/ni;
4559   for(int i=0;i<3;i++)
4560     for(int j=0;j<3;j++)
4561       {
4562         double val(0.);
4563         for(int k=0;k<3;k++)
4564           val+=matrix[3*i+k]*matrix2[3*k+j];
4565         matrix3[3*i+j]=val;
4566       }
4567   //rotation matrix computed.
4568   double tmp[3];
4569   for(int i=0; i<nbNodes; i++)
4570     {
4571       std::transform(coordsIn+i*3,coordsIn+(i+1)*3,point,tmp,std::minus<double>());
4572       coordsOut[i*3]=matrix3[0]*tmp[0]+matrix3[1]*tmp[1]+matrix3[2]*tmp[2]+point[0];
4573       coordsOut[i*3+1]=matrix3[3]*tmp[0]+matrix3[4]*tmp[1]+matrix3[5]*tmp[2]+point[1];
4574       coordsOut[i*3+2]=matrix3[6]*tmp[0]+matrix3[7]*tmp[1]+matrix3[8]*tmp[2]+point[2];
4575     }
4576 }
4577
4578 void DataArrayDouble::GiveBaseForPlane(const double normalVector[3], double baseOfPlane[9])
4579 {
4580   double vect[3],crossVect[3];
4581   INTERP_KERNEL::orthogonalVect3(normalVector,vect);
4582   crossVect[0]=normalVector[1]*vect[2]-normalVector[2]*vect[1];
4583   crossVect[1]=normalVector[2]*vect[0]-normalVector[0]*vect[2];
4584   crossVect[2]=normalVector[0]*vect[1]-normalVector[1]*vect[0];
4585   double nv(INTERP_KERNEL::norm<3>(vect)),ni(INTERP_KERNEL::norm<3>(normalVector)),nc(INTERP_KERNEL::norm<3>(crossVect));
4586   baseOfPlane[0]=vect[0]/nv; baseOfPlane[1]=vect[1]/nv; baseOfPlane[2]=vect[2]/nv;
4587   baseOfPlane[3]=crossVect[0]/nc; baseOfPlane[4]=crossVect[1]/nc; baseOfPlane[5]=crossVect[2]/nc;
4588   baseOfPlane[6]=normalVector[0]/ni; baseOfPlane[7]=normalVector[1]/ni; baseOfPlane[8]=normalVector[2]/ni;
4589 }
4590
4591 /*!
4592  * Low static method that operates 3D rotation of \a nbNodes 3D nodes whose coordinates are arranged in \a coords
4593  * around the center point \a center and with angle \a angle.
4594  */
4595 void DataArrayDouble::Rotate2DAlg(const double *center, double angle, int nbNodes, const double *coordsIn, double *coordsOut)
4596 {
4597   double cosa=cos(angle);
4598   double sina=sin(angle);
4599   double matrix[4];
4600   matrix[0]=cosa; matrix[1]=-sina; matrix[2]=sina; matrix[3]=cosa;
4601   double tmp[2];
4602   for(int i=0; i<nbNodes; i++)
4603     {
4604       std::transform(coordsIn+i*2,coordsIn+(i+1)*2,center,tmp,std::minus<double>());
4605       coordsOut[i*2]=matrix[0]*tmp[0]+matrix[1]*tmp[1]+center[0];
4606       coordsOut[i*2+1]=matrix[2]*tmp[0]+matrix[3]*tmp[1]+center[1];
4607     }
4608 }
4609
4610 DataArrayDoubleIterator::DataArrayDoubleIterator(DataArrayDouble *da):_da(da),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
4611 {
4612   if(_da)
4613     {
4614       _da->incrRef();
4615       if(_da->isAllocated())
4616         {
4617           _nb_comp=da->getNumberOfComponents();
4618           _nb_tuple=da->getNumberOfTuples();
4619           _pt=da->getPointer();
4620         }
4621     }
4622 }
4623
4624 DataArrayDoubleIterator::~DataArrayDoubleIterator()
4625 {
4626   if(_da)
4627     _da->decrRef();
4628 }
4629
4630 DataArrayDoubleTuple *DataArrayDoubleIterator::nextt()
4631 {
4632   if(_tuple_id<_nb_tuple)
4633     {
4634       _tuple_id++;
4635       DataArrayDoubleTuple *ret=new DataArrayDoubleTuple(_pt,_nb_comp);
4636       _pt+=_nb_comp;
4637       return ret;
4638     }
4639   else
4640     return 0;
4641 }
4642
4643 DataArrayDoubleTuple::DataArrayDoubleTuple(double *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
4644 {
4645 }
4646
4647
4648 std::string DataArrayDoubleTuple::repr() const
4649 {
4650   std::ostringstream oss; oss.precision(17); oss << "(";
4651   for(int i=0;i<_nb_of_compo-1;i++)
4652     oss << _pt[i] << ", ";
4653   oss << _pt[_nb_of_compo-1] << ")";
4654   return oss.str();
4655 }
4656
4657 double DataArrayDoubleTuple::doubleValue() const
4658 {
4659   if(_nb_of_compo==1)
4660     return *_pt;
4661   throw INTERP_KERNEL::Exception("DataArrayDoubleTuple::doubleValue : DataArrayDoubleTuple instance has not exactly 1 component -> Not possible to convert it into a double precision float !");
4662 }
4663
4664 /*!
4665  * This method returns a newly allocated instance the caller should dealed with by a MEDCoupling::DataArrayDouble::decrRef.
4666  * This method performs \b no copy of data. The content is only referenced using MEDCoupling::DataArrayDouble::useArray with ownership set to \b false.
4667  * 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
4668  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
4669  */
4670 DataArrayDouble *DataArrayDoubleTuple::buildDADouble(int nbOfTuples, int nbOfCompo) const
4671 {
4672   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
4673     {
4674       DataArrayDouble *ret=DataArrayDouble::New();
4675       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
4676       return ret;
4677     }
4678   else
4679     {
4680       std::ostringstream oss; oss << "DataArrayDoubleTuple::buildDADouble : unable to build a requested DataArrayDouble instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
4681       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
4682       throw INTERP_KERNEL::Exception(oss.str().c_str());
4683     }
4684 }
4685
4686 /*!
4687  * Returns a new instance of DataArrayInt. The caller is to delete this array
4688  * using decrRef() as it is no more needed. 
4689  */
4690 DataArrayInt *DataArrayInt::New()
4691 {
4692   return new DataArrayInt;
4693 }
4694
4695 /*!
4696  * Returns the only one value in \a this, if and only if number of elements
4697  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
4698  *  \return double - the sole value stored in \a this array.
4699  *  \throw If at least one of conditions stated above is not fulfilled.
4700  */
4701 int DataArrayInt::intValue() const
4702 {
4703   if(isAllocated())
4704     {
4705       if(getNbOfElems()==1)
4706         {
4707           return *getConstPointer();
4708         }
4709       else
4710         throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is allocated but number of elements is not equal to 1 !");
4711     }
4712   else
4713     throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is not allocated !");
4714 }
4715
4716 /*!
4717  * Returns an integer value characterizing \a this array, which is useful for a quick
4718  * comparison of many instances of DataArrayInt.
4719  *  \return int - the hash value.
4720  *  \throw If \a this is not allocated.
4721  */
4722 int DataArrayInt::getHashCode() const
4723 {
4724   checkAllocated();
4725   std::size_t nbOfElems=getNbOfElems();
4726   int ret=nbOfElems*65536;
4727   int delta=3;
4728   if(nbOfElems>48)
4729     delta=nbOfElems/8;
4730   int ret0=0;
4731   const int *pt=begin();
4732   for(std::size_t i=0;i<nbOfElems;i+=delta)
4733     ret0+=pt[i] & 0x1FFF;
4734   return ret+ret0;
4735 }
4736
4737 /*!
4738  * Returns a full copy of \a this. For more info on copying data arrays see
4739  * \ref MEDCouplingArrayBasicsCopyDeep.
4740  *  \return DataArrayInt * - a new instance of DataArrayInt.
4741  */
4742 DataArrayInt *DataArrayInt::deepCopy() const
4743 {
4744   return new DataArrayInt(*this);
4745 }
4746
4747 /*!
4748  * Returns either a \a deep or \a shallow copy of this array. For more info see
4749  * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
4750  *  \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
4751  *  \return DataArrayInt * - either a new instance of DataArrayInt (if \a dCpy
4752  *          == \a true) or \a this instance (if \a dCpy == \a false).
4753  */
4754 DataArrayInt *DataArrayInt::performCopyOrIncrRef(bool dCpy) const
4755 {
4756   if(dCpy)
4757     return deepCopy();
4758   else
4759     {
4760       incrRef();
4761       return const_cast<DataArrayInt *>(this);
4762     }
4763 }
4764
4765 /*!
4766  * Assign zero to all values in \a this array. To know more on filling arrays see
4767  * \ref MEDCouplingArrayFill.
4768  * \throw If \a this is not allocated.
4769  */
4770 void DataArrayInt::fillWithZero()
4771 {
4772   fillWithValue(0);
4773 }
4774
4775 /*!
4776  * Set all values in \a this array so that the i-th element equals to \a init + i
4777  * (i starts from zero). To know more on filling arrays see \ref MEDCouplingArrayFill.
4778  *  \param [in] init - value to assign to the first element of array.
4779  *  \throw If \a this->getNumberOfComponents() != 1
4780  *  \throw If \a this is not allocated.
4781  */
4782 void DataArrayInt::iota(int init)
4783 {
4784   checkAllocated();
4785   if(getNumberOfComponents()!=1)
4786     throw INTERP_KERNEL::Exception("DataArrayInt::iota : works only for arrays with only one component, you can call 'rearrange' method before !");
4787   int *ptr=getPointer();
4788   int ntuples=getNumberOfTuples();
4789   for(int i=0;i<ntuples;i++)
4790     ptr[i]=init+i;
4791   declareAsNew();
4792 }
4793
4794 /*!
4795  * Returns a textual and human readable representation of \a this instance of
4796  * DataArrayInt. This text is shown when a DataArrayInt is printed in Python.
4797  * \return std::string - text describing \a this DataArrayInt.
4798  * 
4799  * \sa reprNotTooLong, reprZip
4800  */
4801 std::string DataArrayInt::repr() const
4802 {
4803   std::ostringstream ret;
4804   reprStream(ret);
4805   return ret.str();
4806 }
4807
4808 std::string DataArrayInt::reprZip() const
4809 {
4810   std::ostringstream ret;
4811   reprZipStream(ret);
4812   return ret.str();
4813 }
4814
4815 /*!
4816  * This method is close to repr method except that when \a this has more than 1000 tuples, all tuples are not
4817  * printed out to avoid to consume too much space in interpretor.
4818  * \sa repr
4819  */
4820 std::string DataArrayInt::reprNotTooLong() const
4821 {
4822   std::ostringstream ret;
4823   reprNotTooLongStream(ret);
4824   return ret.str();
4825 }
4826
4827 void DataArrayInt::writeVTK(std::ostream& ofs, int indent, const std::string& type, const std::string& nameInFile, DataArrayByte *byteArr) const
4828 {
4829   static const char SPACE[4]={' ',' ',' ',' '};
4830   checkAllocated();
4831   std::string idt(indent,' ');
4832   ofs << idt << "<DataArray type=\"" << type << "\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
4833   if(byteArr)
4834     {
4835       ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
4836       if(std::string(type)=="Int32")
4837         {
4838           const char *data(reinterpret_cast<const char *>(begin()));
4839           std::size_t sz(getNbOfElems()*sizeof(int));
4840           byteArr->insertAtTheEnd(data,data+sz);
4841           byteArr->insertAtTheEnd(SPACE,SPACE+4);
4842         }
4843       else if(std::string(type)=="Int8")
4844         {
4845           INTERP_KERNEL::AutoPtr<char> tmp(new char[getNbOfElems()]);
4846           std::copy(begin(),end(),(char *)tmp);
4847           byteArr->insertAtTheEnd((char *)tmp,(char *)tmp+getNbOfElems());
4848           byteArr->insertAtTheEnd(SPACE,SPACE+4);
4849         }
4850       else if(std::string(type)=="UInt8")
4851         {
4852           INTERP_KERNEL::AutoPtr<unsigned char> tmp(new unsigned char[getNbOfElems()]);
4853           std::copy(begin(),end(),(unsigned char *)tmp);
4854           byteArr->insertAtTheEnd((unsigned char *)tmp,(unsigned char *)tmp+getNbOfElems());
4855           byteArr->insertAtTheEnd(SPACE,SPACE+4);
4856         }
4857       else
4858         throw INTERP_KERNEL::Exception("DataArrayInt::writeVTK : Only Int32, Int8 and UInt8 supported !");
4859     }
4860   else
4861     {
4862       ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
4863       std::copy(begin(),end(),std::ostream_iterator<int>(ofs," "));
4864     }
4865   ofs << std::endl << idt << "</DataArray>\n";
4866 }
4867
4868 void DataArrayInt::reprStream(std::ostream& stream) const
4869 {
4870   stream << "Name of int array : \"" << _name << "\"\n";
4871   reprWithoutNameStream(stream);
4872 }
4873
4874 void DataArrayInt::reprZipStream(std::ostream& stream) const
4875 {
4876   stream << "Name of int array : \"" << _name << "\"\n";
4877   reprZipWithoutNameStream(stream);
4878 }
4879
4880 void DataArrayInt::reprNotTooLongStream(std::ostream& stream) const
4881 {
4882   stream << "Name of int array : \"" << _name << "\"\n";
4883   reprNotTooLongWithoutNameStream(stream);
4884 }
4885
4886 void DataArrayInt::reprWithoutNameStream(std::ostream& stream) const
4887 {
4888   DataArray::reprWithoutNameStream(stream);
4889   _mem.repr(getNumberOfComponents(),stream);
4890 }
4891
4892 void DataArrayInt::reprZipWithoutNameStream(std::ostream& stream) const
4893 {
4894   DataArray::reprWithoutNameStream(stream);
4895   _mem.reprZip(getNumberOfComponents(),stream);
4896 }
4897
4898 void DataArrayInt::reprNotTooLongWithoutNameStream(std::ostream& stream) const
4899 {
4900   DataArray::reprWithoutNameStream(stream);
4901   stream.precision(17);
4902   _mem.reprNotTooLong(getNumberOfComponents(),stream);
4903 }
4904
4905 void DataArrayInt::reprCppStream(const std::string& varName, std::ostream& stream) const
4906 {
4907   int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
4908   const int *data=getConstPointer();
4909   stream << "DataArrayInt *" << varName << "=DataArrayInt::New();" << std::endl;
4910   if(nbTuples*nbComp>=1)
4911     {
4912       stream << "const int " << varName << "Data[" << nbTuples*nbComp << "]={";
4913       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<int>(stream,","));
4914       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
4915       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
4916     }
4917   else
4918     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
4919   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
4920 }
4921
4922 /*!
4923  * Method that gives a quick overvien of \a this for python.
4924  */
4925 void DataArrayInt::reprQuickOverview(std::ostream& stream) const
4926 {
4927   static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
4928   stream << "DataArrayInt C++ instance at " << this << ". ";
4929   if(isAllocated())
4930     {
4931       int nbOfCompo=(int)_info_on_compo.size();
4932       if(nbOfCompo>=1)
4933         {
4934           int nbOfTuples=getNumberOfTuples();
4935           stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
4936           reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
4937         }
4938       else
4939         stream << "Number of components : 0.";
4940     }
4941   else
4942     stream << "*** No data allocated ****";
4943 }
4944
4945 void DataArrayInt::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
4946 {
4947   const int *data=begin();
4948   int nbOfTuples=getNumberOfTuples();
4949   int nbOfCompo=(int)_info_on_compo.size();
4950   std::ostringstream oss2; oss2 << "[";
4951   std::string oss2Str(oss2.str());
4952   bool isFinished=true;
4953   for(int i=0;i<nbOfTuples && isFinished;i++)
4954     {
4955       if(nbOfCompo>1)
4956         {
4957           oss2 << "(";
4958           for(int j=0;j<nbOfCompo;j++,data++)
4959             {
4960               oss2 << *data;
4961               if(j!=nbOfCompo-1) oss2 << ", ";
4962             }
4963           oss2 << ")";
4964         }
4965       else
4966         oss2 << *data++;
4967       if(i!=nbOfTuples-1) oss2 << ", ";
4968       std::string oss3Str(oss2.str());
4969       if(oss3Str.length()<maxNbOfByteInRepr)
4970         oss2Str=oss3Str;
4971       else
4972         isFinished=false;
4973     }
4974   stream << oss2Str;
4975   if(!isFinished)
4976     stream << "... ";
4977   stream << "]";
4978 }
4979
4980 /*!
4981  * Modifies in place \a this one-dimensional array so that each value \a v = \a indArrBg[ \a v ],
4982  * i.e. a current value is used as in index to get a new value from \a indArrBg.
4983  *  \param [in] indArrBg - pointer to the first element of array of new values to assign
4984  *         to \a this array.
4985  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
4986  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
4987  *  \throw If \a this->getNumberOfComponents() != 1
4988  *  \throw If any value of \a this can't be used as a valid index for 
4989  *         [\a indArrBg, \a indArrEnd).
4990  *
4991  *  \sa changeValue
4992  */
4993 void DataArrayInt::transformWithIndArr(const int *indArrBg, const int *indArrEnd)
4994 {
4995   checkAllocated();
4996   if(getNumberOfComponents()!=1)
4997     throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
4998   int nbElemsIn((int)std::distance(indArrBg,indArrEnd)),nbOfTuples(getNumberOfTuples()),*pt(getPointer());
4999   for(int i=0;i<nbOfTuples;i++,pt++)
5000     {
5001       if(*pt>=0 && *pt<nbElemsIn)
5002         *pt=indArrBg[*pt];
5003       else
5004         {
5005           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " of this value is " << *pt << ", should be in [0," << nbElemsIn << ") !";
5006           throw INTERP_KERNEL::Exception(oss.str().c_str());
5007         }
5008     }
5009   declareAsNew();
5010 }
5011
5012 /*!
5013  * Computes distribution of values of \a this one-dimensional array between given value
5014  * ranges (casts). This method is typically useful for entity number spliting by types,
5015  * for example. 
5016  *  \warning The values contained in \a arrBg should be sorted ascendently. No
5017  *           check of this is be done. If not, the result is not warranted. 
5018  *  \param [in] arrBg - the array of ascending values defining the value ranges. The i-th
5019  *         value of \a arrBg (\a arrBg[ i ]) gives the lowest value of the i-th range,
5020  *         and the greatest value of the i-th range equals to \a arrBg[ i+1 ] - 1. \a
5021  *         arrBg containing \a n values defines \a n-1 ranges. The last value of \a arrBg
5022  *         should be more than every value in \a this array.
5023  *  \param [in] arrEnd - specifies the end of the array \a arrBg, so that
5024  *              the last value of \a arrBg is \a arrEnd[ -1 ].
5025  *  \param [out] castArr - a new instance of DataArrayInt, of same size as \a this array
5026  *         (same number of tuples and components), the caller is to delete 
5027  *         using decrRef() as it is no more needed.
5028  *         This array contains indices of ranges for every value of \a this array. I.e.
5029  *         the i-th value of \a castArr gives the index of range the i-th value of \a this
5030  *         belongs to. Or, in other words, this parameter contains for each tuple in \a
5031  *         this in which cast it holds.
5032  *  \param [out] rankInsideCast - a new instance of DataArrayInt, of same size as \a this
5033  *         array, the caller is to delete using decrRef() as it is no more needed.
5034  *         This array contains ranks of values of \a this array within ranges
5035  *         they belongs to. I.e. the i-th value of \a rankInsideCast gives the rank of
5036  *         the i-th value of \a this array within the \a castArr[ i ]-th range, to which
5037  *         the i-th value of \a this belongs to. Or, in other words, this param contains 
5038  *         for each tuple its rank inside its cast. The rank is computed as difference
5039  *         between the value and the lowest value of range.
5040  *  \param [out] castsPresent - a new instance of DataArrayInt, containing indices of
5041  *         ranges (casts) to which at least one value of \a this array belongs.
5042  *         Or, in other words, this param contains the casts that \a this contains.
5043  *         The caller is to delete this array using decrRef() as it is no more needed.
5044  *
5045  * \b Example: If \a this contains [6,5,0,3,2,7,8,1,4] and \a arrBg contains [0,4,9] then
5046  *            the output of this method will be : 
5047  * - \a castArr       : [1,1,0,0,0,1,1,0,1]
5048  * - \a rankInsideCast: [2,1,0,3,2,3,4,1,0]
5049  * - \a castsPresent  : [0,1]
5050  *
5051  * I.e. values of \a this array belong to 2 ranges: #0 and #1. Value 6 belongs to the
5052  * range #1 and its rank within this range is 2; etc.
5053  *
5054  *  \throw If \a this->getNumberOfComponents() != 1.
5055  *  \throw If \a arrEnd - arrBg < 2.
5056  *  \throw If any value of \a this is not less than \a arrEnd[-1].
5057  */
5058 void DataArrayInt::splitByValueRange(const int *arrBg, const int *arrEnd,
5059                                      DataArrayInt *& castArr, DataArrayInt *& rankInsideCast, DataArrayInt *& castsPresent) const
5060 {
5061   checkAllocated();
5062   if(getNumberOfComponents()!=1)
5063     throw INTERP_KERNEL::Exception("Call splitByValueRange  method on DataArrayInt with only one component, you can call 'rearrange' method before !");
5064   int nbOfTuples=getNumberOfTuples();
5065   std::size_t nbOfCast=std::distance(arrBg,arrEnd);
5066   if(nbOfCast<2)
5067     throw INTERP_KERNEL::Exception("DataArrayInt::splitByValueRange : The input array giving the cast range values should be of size >=2 !");
5068   nbOfCast--;
5069   const int *work=getConstPointer();
5070   typedef std::reverse_iterator<const int *> rintstart;
5071   rintstart bg(arrEnd);//OK no problem because size of 'arr' is greater or equal 2
5072   rintstart end2(arrBg);
5073   MCAuto<DataArrayInt> ret1=DataArrayInt::New();
5074   MCAuto<DataArrayInt> ret2=DataArrayInt::New();
5075   MCAuto<DataArrayInt> ret3=DataArrayInt::New();
5076   ret1->alloc(nbOfTuples,1);
5077   ret2->alloc(nbOfTuples,1);
5078   int *ret1Ptr=ret1->getPointer();
5079   int *ret2Ptr=ret2->getPointer();
5080   std::set<std::size_t> castsDetected;
5081   for(int i=0;i<nbOfTuples;i++)
5082     {
5083       rintstart res=std::find_if(bg,end2,std::bind2nd(std::less_equal<int>(), work[i]));
5084       std::size_t pos=std::distance(bg,res);
5085       std::size_t pos2=nbOfCast-pos;
5086       if(pos2<nbOfCast)
5087         {
5088           ret1Ptr[i]=(int)pos2;
5089           ret2Ptr[i]=work[i]-arrBg[pos2];
5090           castsDetected.insert(pos2);
5091         }
5092       else
5093         {
5094           std::ostringstream oss; oss << "DataArrayInt::splitByValueRange : At rank #" << i << " the value is " << work[i] << " should be in [0," << *bg << ") !";
5095           throw INTERP_KERNEL::Exception(oss.str().c_str());
5096         }
5097     }
5098   ret3->alloc((int)castsDetected.size(),1);
5099   std::copy(castsDetected.begin(),castsDetected.end(),ret3->getPointer());
5100   castArr=ret1.retn();
5101   rankInsideCast=ret2.retn();
5102   castsPresent=ret3.retn();
5103 }
5104
5105 /*!
5106  * 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 ).
5107  * 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 ).
5108  * This method works only if \a this is allocated and single component. If not an exception will be thrown.
5109  *
5110  * \param [out] strt - the start of the range (included) if true is returned.
5111  * \param [out] sttoopp - the end of the range (not included) if true is returned.
5112  * \param [out] stteepp - the step of the range if true is returned.
5113  * \return the verdict of the check.
5114  *
5115  * \sa DataArray::GetNumberOfItemGivenBES
5116  */
5117 bool DataArrayInt::isRange(int& strt, int& sttoopp, int& stteepp) const
5118 {
5119   checkAllocated();
5120   if(getNumberOfComponents()!=1)
5121     throw INTERP_KERNEL::Exception("DataArrayInt::isRange : this must be single component array !");
5122   int nbTuples(getNumberOfTuples());
5123   if(nbTuples==0)
5124     { strt=0; sttoopp=0; stteepp=1; return true; }
5125   const int *pt(begin());
5126   strt=*pt; 
5127   if(nbTuples==1)
5128     { sttoopp=strt+1; stteepp=1; return true; }
5129   strt=*pt; sttoopp=pt[nbTuples-1];
5130   if(strt==sttoopp)
5131     return false;
5132   if(sttoopp>strt)
5133     {
5134       sttoopp++;
5135       int a(sttoopp-1-strt),tmp(strt);
5136       if(a%(nbTuples-1)!=0)
5137         return false;
5138       stteepp=a/(nbTuples-1);
5139       for(int i=0;i<nbTuples;i++,tmp+=stteepp)
5140         if(pt[i]!=tmp)
5141           return false;
5142       return true;
5143     }
5144   else
5145     {
5146       sttoopp--;
5147       int a(strt-sttoopp-1),tmp(strt);
5148       if(a%(nbTuples-1)!=0)
5149         return false;
5150       stteepp=-(a/(nbTuples-1));
5151       for(int i=0;i<nbTuples;i++,tmp+=stteepp)
5152         if(pt[i]!=tmp)
5153           return false;
5154       return true;
5155     }
5156 }
5157
5158 /*!
5159  * Creates a one-dimensional DataArrayInt (\a res) whose contents are computed from 
5160  * values of \a this (\a a) and the given (\a indArr) arrays as follows:
5161  * \a res[ \a indArr[ \a a[ i ]]] = i. I.e. for each value in place i \a v = \a a[ i ],
5162  * new value in place \a indArr[ \a v ] is i.
5163  *  \param [in] indArrBg - the array holding indices within the result array to assign
5164  *         indices of values of \a this array pointing to values of \a indArrBg.
5165  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
5166  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
5167  *  \return DataArrayInt * - the new instance of DataArrayInt.
5168  *          The caller is to delete this result array using decrRef() as it is no more
5169  *          needed.
5170  *  \throw If \a this->getNumberOfComponents() != 1.
5171  *  \throw If any value of \a this array is not a valid index for \a indArrBg array.
5172  *  \throw If any value of \a indArrBg is not a valid index for \a this array.
5173  */
5174 DataArrayInt *DataArrayInt::transformWithIndArrR(const int *indArrBg, const int *indArrEnd) const
5175 {
5176   checkAllocated();
5177   if(getNumberOfComponents()!=1)
5178     throw INTERP_KERNEL::Exception("Call transformWithIndArrR method on DataArrayInt with only one component, you can call 'rearrange' method before !");
5179   int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
5180   int nbOfTuples=getNumberOfTuples();
5181   const int *pt=getConstPointer();
5182   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5183   ret->alloc(nbOfTuples,1);
5184   ret->fillWithValue(-1);
5185   int *tmp=ret->getPointer();
5186   for(int i=0;i<nbOfTuples;i++,pt++)
5187     {
5188       if(*pt>=0 && *pt<nbElemsIn)
5189         {
5190           int pos=indArrBg[*pt];
5191           if(pos>=0 && pos<nbOfTuples)
5192             tmp[pos]=i;
5193           else
5194             {
5195               std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value of new pos is " << pos << " ( indArrBg[" << *pt << "]) ! Should be in [0," << nbOfTuples << ") !";
5196               throw INTERP_KERNEL::Exception(oss.str().c_str());
5197             }
5198         }
5199       else
5200         {
5201           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn << " !";
5202           throw INTERP_KERNEL::Exception(oss.str().c_str());
5203         }
5204     }
5205   return ret.retn();
5206 }
5207
5208 /*!
5209  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
5210  * from values of \a this array, which is supposed to contain a renumbering map in 
5211  * "Old to New" mode. The result array contains a renumbering map in "New to Old" mode.
5212  * To know how to use the renumbering maps see \ref numbering.
5213  *  \param [in] newNbOfElem - the number of tuples in the result array.
5214  *  \return DataArrayInt * - the new instance of DataArrayInt.
5215  *          The caller is to delete this result array using decrRef() as it is no more
5216  *          needed.
5217  * 
5218  *  \if ENABLE_EXAMPLES
5219  *  \ref cpp_mcdataarrayint_invertarrayo2n2n2o "Here is a C++ example".<br>
5220  *  \ref py_mcdataarrayint_invertarrayo2n2n2o  "Here is a Python example".
5221  *  \endif
5222  */
5223 DataArrayInt *DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const
5224 {
5225   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5226   ret->alloc(newNbOfElem,1);
5227   int nbOfOldNodes=getNumberOfTuples();
5228   const int *old2New=getConstPointer();
5229   int *pt=ret->getPointer();
5230   for(int i=0;i!=nbOfOldNodes;i++)
5231     {
5232       int newp(old2New[i]);
5233       if(newp!=-1)
5234         {
5235           if(newp>=0 && newp<newNbOfElem)
5236             pt[newp]=i;
5237           else
5238             {
5239               std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2O : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
5240               throw INTERP_KERNEL::Exception(oss.str().c_str());
5241             }
5242         }
5243     }
5244   return ret.retn();
5245 }
5246
5247 /*!
5248  * This method is similar to DataArrayInt::invertArrayO2N2N2O except that 
5249  * 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]
5250  */
5251 DataArrayInt *DataArrayInt::invertArrayO2N2N2OBis(int newNbOfElem) const
5252 {
5253   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5254   ret->alloc(newNbOfElem,1);
5255   int nbOfOldNodes=getNumberOfTuples();
5256   const int *old2New=getConstPointer();
5257   int *pt=ret->getPointer();
5258   for(int i=nbOfOldNodes-1;i>=0;i--)
5259     {
5260       int newp(old2New[i]);
5261       if(newp!=-1)
5262         {
5263           if(newp>=0 && newp<newNbOfElem)
5264             pt[newp]=i;
5265           else
5266             {
5267               std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2OBis : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
5268               throw INTERP_KERNEL::Exception(oss.str().c_str());
5269             }
5270         }
5271     }
5272   return ret.retn();
5273 }
5274
5275 /*!
5276  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
5277  * from values of \a this array, which is supposed to contain a renumbering map in 
5278  * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
5279  * To know how to use the renumbering maps see \ref numbering.
5280  *  \param [in] newNbOfElem - the number of tuples in the result array.
5281  *  \return DataArrayInt * - the new instance of DataArrayInt.
5282  *          The caller is to delete this result array using decrRef() as it is no more
5283  *          needed.
5284  * 
5285  *  \if ENABLE_EXAMPLES
5286  *  \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
5287  *
5288  *  \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
5289  *  \endif
5290  */
5291 DataArrayInt *DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const
5292 {
5293   checkAllocated();
5294   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5295   ret->alloc(oldNbOfElem,1);
5296   const int *new2Old=getConstPointer();
5297   int *pt=ret->getPointer();
5298   std::fill(pt,pt+oldNbOfElem,-1);
5299   int nbOfNewElems=getNumberOfTuples();
5300   for(int i=0;i<nbOfNewElems;i++)
5301     {
5302       int v(new2Old[i]);
5303       if(v>=0 && v<oldNbOfElem)
5304         pt[v]=i;
5305       else
5306         {
5307           std::ostringstream oss; oss << "DataArrayInt::invertArrayN2O2O2N : in new id #" << i << " old value is " << v << " expected to be in [0," << oldNbOfElem << ") !";
5308           throw INTERP_KERNEL::Exception(oss.str().c_str());
5309         }
5310     }
5311   return ret.retn();
5312 }
5313
5314 /*!
5315  * Equivalent to DataArrayInt::isEqual except that if false the reason of
5316  * mismatch is given.
5317  * 
5318  * \param [in] other the instance to be compared with \a this
5319  * \param [out] reason In case of inequality returns the reason.
5320  * \sa DataArrayInt::isEqual
5321  */
5322 bool DataArrayInt::isEqualIfNotWhy(const DataArrayInt& other, std::string& reason) const
5323 {
5324   if(!areInfoEqualsIfNotWhy(other,reason))
5325     return false;
5326   return _mem.isEqual(other._mem,0,reason);
5327 }
5328
5329 /*!
5330  * Checks if \a this and another DataArrayInt are fully equal. For more info see
5331  * \ref MEDCouplingArrayBasicsCompare.
5332  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
5333  *  \return bool - \a true if the two arrays are equal, \a false else.
5334  */
5335 bool DataArrayInt::isEqual(const DataArrayInt& other) const
5336 {
5337   std::string tmp;
5338   return isEqualIfNotWhy(other,tmp);
5339 }
5340
5341 /*!
5342  * Checks if values of \a this and another DataArrayInt are equal. For more info see
5343  * \ref MEDCouplingArrayBasicsCompare.
5344  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
5345  *  \return bool - \a true if the values of two arrays are equal, \a false else.
5346  */
5347 bool DataArrayInt::isEqualWithoutConsideringStr(const DataArrayInt& other) const
5348 {
5349   std::string tmp;
5350   return _mem.isEqual(other._mem,0,tmp);
5351 }
5352
5353 /*!
5354  * Checks if values of \a this and another DataArrayInt are equal. Comparison is
5355  * performed on sorted value sequences.
5356  * For more info see\ref MEDCouplingArrayBasicsCompare.
5357  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
5358  *  \return bool - \a true if the sorted values of two arrays are equal, \a false else.
5359  */
5360 bool DataArrayInt::isEqualWithoutConsideringStrAndOrder(const DataArrayInt& other) const
5361 {
5362   MCAuto<DataArrayInt> a=deepCopy();
5363   MCAuto<DataArrayInt> b=other.deepCopy();
5364   a->sort();
5365   b->sort();
5366   return a->isEqualWithoutConsideringStr(*b);
5367 }
5368
5369 /*!
5370  * This method compares content of input vector \a v and \a this.
5371  * 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.
5372  * For performance reasons \a this is expected to be sorted ascendingly. If not an exception will be thrown.
5373  *
5374  * \param [in] v - the vector of 'flags' to be compared with \a this.
5375  *
5376  * \throw If \a this is not sorted ascendingly.
5377  * \throw If \a this has not exactly one component.
5378  * \throw If \a this is not allocated.
5379  */
5380 bool DataArrayInt::isFittingWith(const std::vector<bool>& v) const
5381 {
5382   checkAllocated();
5383   if(getNumberOfComponents()!=1)
5384     throw INTERP_KERNEL::Exception("DataArrayInt::isFittingWith : number of components of this should be equal to one !");
5385   const int *w(begin()),*end2(end());
5386   int refVal=-std::numeric_limits<int>::max();
5387   int i=0;
5388   std::vector<bool>::const_iterator it(v.begin());
5389   for(;it!=v.end();it++,i++)
5390     {
5391       if(*it)
5392         {
5393           if(w!=end2)
5394             {
5395               if(*w++==i)
5396                 {
5397                   if(i>refVal)
5398                     refVal=i;
5399                   else
5400                     {
5401                       std::ostringstream oss; oss << "DataArrayInt::isFittingWith : At pos #" << std::distance(begin(),w-1) << " this is not sorted ascendingly !";
5402                       throw INTERP_KERNEL::Exception(oss.str().c_str());
5403                     }
5404                 }
5405               else
5406                 return false;
5407             }
5408           else
5409             return false;
5410         }
5411     }
5412   return w==end2;
5413 }
5414
5415 /*!
5416  * 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
5417  * put True to the corresponding entry in \a vec.
5418  * \a vec is expected to be with the same size than the number of tuples of \a this.
5419  *
5420  *  \sa DataArrayInt::switchOnTupleNotEqualTo.
5421  */
5422 void DataArrayInt::switchOnTupleEqualTo(int val, std::vector<bool>& vec) const
5423 {
5424   checkAllocated();
5425   if(getNumberOfComponents()!=1)
5426     throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleEqualTo : number of components of this should be equal to one !");
5427   int nbOfTuples(getNumberOfTuples());
5428   if(nbOfTuples!=(int)vec.size())
5429     throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleEqualTo : number of tuples of this should be equal to size of input vector of bool !");
5430   const int *pt(begin());
5431   for(int i=0;i<nbOfTuples;i++)
5432     if(pt[i]==val)
5433       vec[i]=true;
5434 }
5435
5436 /*!
5437  * 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
5438  * put True to the corresponding entry in \a vec.
5439  * \a vec is expected to be with the same size than the number of tuples of \a this.
5440  * 
5441  *  \sa DataArrayInt::switchOnTupleEqualTo.
5442  */
5443 void DataArrayInt::switchOnTupleNotEqualTo(int val, std::vector<bool>& vec) const
5444 {
5445   checkAllocated();
5446   if(getNumberOfComponents()!=1)
5447     throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleNotEqualTo : number of components of this should be equal to one !");
5448   int nbOfTuples(getNumberOfTuples());
5449   if(nbOfTuples!=(int)vec.size())
5450     throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleNotEqualTo : number of tuples of this should be equal to size of input vector of bool !");
5451   const int *pt(begin());
5452   for(int i=0;i<nbOfTuples;i++)
5453     if(pt[i]!=val)
5454       vec[i]=true;
5455 }
5456
5457 /*!
5458  * Computes for each tuple the sum of number of components values in the tuple and return it.
5459  * 
5460  * \return DataArrayInt * - the new instance of DataArrayInt containing the
5461  *          same number of tuples as \a this array and one component.
5462  *          The caller is to delete this result array using decrRef() as it is no more
5463  *          needed.
5464  *  \throw If \a this is not allocated.
5465  */
5466 DataArrayInt *DataArrayInt::sumPerTuple() const
5467 {
5468   checkAllocated();
5469   int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
5470   MCAuto<DataArrayInt> ret(DataArrayInt::New());
5471   ret->alloc(nbOfTuple,1);
5472   const int *src(getConstPointer());
5473   int *dest(ret->getPointer());
5474   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
5475     *dest=std::accumulate(src,src+nbOfComp,0);
5476   return ret.retn();
5477 }
5478
5479 /*!
5480  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
5481  * If not an exception is thrown.
5482  *  \param [in] increasing - if \a true, the array values should be increasing.
5483  *  \throw If sequence of values is not strictly monotonic in agreement with \a
5484  *         increasing arg.
5485  *  \throw If \a this->getNumberOfComponents() != 1.
5486  *  \throw If \a this is not allocated.
5487  */
5488 void DataArrayInt::checkMonotonic(bool increasing) const
5489 {
5490   if(!isMonotonic(increasing))
5491     {
5492       if (increasing)
5493         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not INCREASING monotonic !");
5494       else
5495         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not DECREASING monotonic !");
5496     }
5497 }
5498
5499 /*!
5500  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
5501  *  \param [in] increasing - if \a true, array values should be increasing.
5502  *  \return bool - \a true if values change in accordance with \a increasing arg.
5503  *  \throw If \a this->getNumberOfComponents() != 1.
5504  *  \throw If \a this is not allocated.
5505  */
5506 bool DataArrayInt::isMonotonic(bool increasing) const
5507 {
5508   checkAllocated();
5509   if(getNumberOfComponents()!=1)
5510     throw INTERP_KERNEL::Exception("DataArrayInt::isMonotonic : only supported with 'this' array with ONE component !");
5511   int nbOfElements=getNumberOfTuples();
5512   const int *ptr=getConstPointer();
5513   if(nbOfElements==0)
5514     return true;
5515   int ref=ptr[0];
5516   if(increasing)
5517     {
5518       for(int i=1;i<nbOfElements;i++)
5519         {
5520           if(ptr[i]>=ref)
5521             ref=ptr[i];
5522           else
5523             return false;
5524         }
5525     }
5526   else
5527     {
5528       for(int i=1;i<nbOfElements;i++)
5529         {
5530           if(ptr[i]<=ref)
5531             ref=ptr[i];
5532           else
5533             return false;
5534         }
5535     }
5536   return true;
5537 }
5538
5539 /*!
5540  * This method check that array consistently INCREASING or DECREASING in value.
5541  */
5542 bool DataArrayInt::isStrictlyMonotonic(bool increasing) const
5543 {
5544   checkAllocated();
5545   if(getNumberOfComponents()!=1)
5546     throw INTERP_KERNEL::Exception("DataArrayInt::isStrictlyMonotonic : only supported with 'this' array with ONE component !");
5547   int nbOfElements=getNumberOfTuples();
5548   const int *ptr=getConstPointer();
5549   if(nbOfElements==0)
5550     return true;
5551   int ref=ptr[0];
5552   if(increasing)
5553     {
5554       for(int i=1;i<nbOfElements;i++)
5555         {
5556           if(ptr[i]>ref)
5557             ref=ptr[i];
5558           else
5559             return false;
5560         }
5561     }
5562   else
5563     {
5564       for(int i=1;i<nbOfElements;i++)
5565         {
5566           if(ptr[i]<ref)
5567             ref=ptr[i];
5568           else
5569             return false;
5570         }
5571     }
5572   return true;
5573 }
5574
5575 /*!
5576  * This method check that array consistently INCREASING or DECREASING in value.
5577  */
5578 void DataArrayInt::checkStrictlyMonotonic(bool increasing) const
5579 {
5580   if(!isStrictlyMonotonic(increasing))
5581     {
5582       if (increasing)
5583         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly INCREASING monotonic !");
5584       else
5585         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly DECREASING monotonic !");
5586     }
5587 }
5588
5589 /*!
5590  * Creates a new one-dimensional DataArrayInt of the same size as \a this and a given
5591  * one-dimensional arrays that must be of the same length. The result array describes
5592  * correspondence between \a this and \a other arrays, so that 
5593  * <em> other.getIJ(i,0) == this->getIJ(ret->getIJ(i),0)</em>. If such a permutation is
5594  * not possible because some element in \a other is not in \a this, an exception is thrown.
5595  *  \param [in] other - an array to compute permutation to.
5596  *  \return DataArrayInt * - a new instance of DataArrayInt, which is a permutation array
5597  * from \a this to \a other. The caller is to delete this array using decrRef() as it is
5598  * no more needed.
5599  *  \throw If \a this->getNumberOfComponents() != 1.
5600  *  \throw If \a other->getNumberOfComponents() != 1.
5601  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples().
5602  *  \throw If \a other includes a value which is not in \a this array.
5603  * 
5604  *  \if ENABLE_EXAMPLES
5605  *  \ref cpp_mcdataarrayint_buildpermutationarr "Here is a C++ example".
5606  *
5607  *  \ref py_mcdataarrayint_buildpermutationarr "Here is a Python example".
5608  *  \endif
5609  */
5610 DataArrayInt *DataArrayInt::buildPermutationArr(const DataArrayInt& other) const
5611 {
5612   checkAllocated();
5613   if(getNumberOfComponents()!=1 || other.getNumberOfComponents()!=1)
5614     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' have to have exactly ONE component !");
5615   int nbTuple=getNumberOfTuples();
5616   other.checkAllocated();
5617   if(nbTuple!=other.getNumberOfTuples())
5618     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' must have the same number of tuple !");
5619   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5620   ret->alloc(nbTuple,1);
5621   ret->fillWithValue(-1);
5622   const int *pt=getConstPointer();
5623   std::map<int,int> mm;
5624   for(int i=0;i<nbTuple;i++)
5625     mm[pt[i]]=i;
5626   pt=other.getConstPointer();
5627   int *retToFill=ret->getPointer();
5628   for(int i=0;i<nbTuple;i++)
5629     {
5630       std::map<int,int>::const_iterator it=mm.find(pt[i]);
5631       if(it==mm.end())
5632         {
5633           std::ostringstream oss; oss << "DataArrayInt::buildPermutationArr : Arrays mismatch : element (" << pt[i] << ") in 'other' not findable in 'this' !";
5634           throw INTERP_KERNEL::Exception(oss.str().c_str());
5635         }
5636       retToFill[i]=(*it).second;
5637     }
5638   return ret.retn();
5639 }
5640
5641 /*!
5642  * Elements of \a partOfThis are expected to be included in \a this.
5643  * The returned array \a ret is so that this[ret]==partOfThis
5644  *
5645  * 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]
5646  * the return array will contain [3,2,5,7].
5647  *
5648  * \a this is expected to be a 1 compo allocated array.
5649  * \param [in] partOfThis - A 1 compo allocated array
5650  * \return - A newly allocated array to be dealed by caller having the same number of tuples than \a partOfThis.
5651  * \throw if two same element is present twice in \a this
5652  * \throw if an element in \a partOfThis is \b NOT in \a this.
5653  */
5654 DataArrayInt *DataArrayInt::indicesOfSubPart(const DataArrayInt& partOfThis) const
5655 {
5656   if(getNumberOfComponents()!=1 || partOfThis.getNumberOfComponents()!=1)
5657     throw INTERP_KERNEL::Exception("DataArrayInt::indicesOfSubPart : this and input array must be one component array !");
5658   checkAllocated(); partOfThis.checkAllocated();
5659   int thisNbTuples(getNumberOfTuples()),nbTuples(partOfThis.getNumberOfTuples());
5660   const int *thisPt(begin()),*pt(partOfThis.begin());
5661   MCAuto<DataArrayInt> ret(DataArrayInt::New());
5662   ret->alloc(nbTuples,1);
5663   int *retPt(ret->getPointer());
5664   std::map<int,int> m;
5665   for(int i=0;i<thisNbTuples;i++,thisPt++)
5666     m[*thisPt]=i;
5667   if(m.size()!=thisNbTuples)
5668     throw INTERP_KERNEL::Exception("DataArrayInt::indicesOfSubPart : some elements appears more than once !");
5669   for(int i=0;i<nbTuples;i++,retPt++,pt++)
5670     {
5671       std::map<int,int>::const_iterator it(m.find(*pt));
5672       if(it!=m.end())
5673         *retPt=(*it).second;
5674       else
5675         {
5676           std::ostringstream oss; oss << "DataArrayInt::indicesOfSubPart : At pos #" << i << " of input array value is " << *pt << " not in this !";
5677           throw INTERP_KERNEL::Exception(oss.str());
5678         }
5679     }
5680   return ret.retn();
5681 }
5682
5683 void DataArrayInt::aggregate(const DataArrayInt *other)
5684 {
5685   if(!other)
5686     throw INTERP_KERNEL::Exception("DataArrayInt::aggregate : null pointer !");
5687   if(getNumberOfComponents()!=other->getNumberOfComponents())
5688     throw INTERP_KERNEL::Exception("DataArrayInt::aggregate : mismatch number of components !");
5689   _mem.insertAtTheEnd(other->begin(),other->end());
5690 }
5691
5692 /*!
5693  * Returns a new DataArrayInt holding the same values as \a this array but differently
5694  * arranged in memory. If \a this array holds 2 components of 3 values:
5695  * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
5696  * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
5697  *  \warning Do not confuse this method with transpose()!
5698  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
5699  *          is to delete using decrRef() as it is no more needed.
5700  *  \throw If \a this is not allocated.
5701  */
5702 DataArrayInt *DataArrayInt::fromNoInterlace() const
5703 {
5704   checkAllocated();
5705   if(_mem.isNull())
5706     throw INTERP_KERNEL::Exception("DataArrayInt::fromNoInterlace : Not defined array !");
5707   int *tab=_mem.fromNoInterlace(getNumberOfComponents());
5708   DataArrayInt *ret=DataArrayInt::New();
5709   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
5710   return ret;
5711 }
5712
5713 /*!
5714  * Returns a new DataArrayInt holding the same values as \a this array but differently
5715  * arranged in memory. If \a this array holds 2 components of 3 values:
5716  * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
5717  * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
5718  *  \warning Do not confuse this method with transpose()!
5719  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
5720  *          is to delete using decrRef() as it is no more needed.
5721  *  \throw If \a this is not allocated.
5722  */
5723 DataArrayInt *DataArrayInt::toNoInterlace() const
5724 {
5725   checkAllocated();
5726   if(_mem.isNull())
5727     throw INTERP_KERNEL::Exception("DataArrayInt::toNoInterlace : Not defined array !");
5728   int *tab=_mem.toNoInterlace(getNumberOfComponents());
5729   DataArrayInt *ret=DataArrayInt::New();
5730   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
5731   return ret;
5732 }
5733
5734 /*!
5735  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode.
5736  * This map, if applied to \a this array, would make it sorted. For example, if
5737  * \a this array contents are [9,10,0,6,4,11,3,7] then the contents of the result array
5738  * are [5,6,0,3,2,7,1,4]; if this result array (\a res) is used as an argument in call
5739  * \a this->renumber(\a res) then the returned array contains [0,3,4,6,7,9,10,11].
5740  * This method is useful for renumbering (in MED file for example). For more info
5741  * on renumbering see \ref numbering.
5742  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5743  *          array using decrRef() as it is no more needed.
5744  *  \throw If \a this is not allocated.
5745  *  \throw If \a this->getNumberOfComponents() != 1.
5746  *  \throw If there are equal values in \a this array.
5747  */
5748 DataArrayInt *DataArrayInt::checkAndPreparePermutation() const
5749 {
5750   checkAllocated();
5751   if(getNumberOfComponents()!=1)
5752     throw INTERP_KERNEL::Exception("DataArrayInt::checkAndPreparePermutation : number of components must == 1 !");
5753   int nbTuples=getNumberOfTuples();
5754   const int *pt=getConstPointer();
5755   int *pt2=CheckAndPreparePermutation(pt,pt+nbTuples);
5756   DataArrayInt *ret=DataArrayInt::New();
5757   ret->useArray(pt2,true,C_DEALLOC,nbTuples,1);
5758   return ret;
5759 }
5760
5761 /*!
5762  * 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
5763  * input array \a ids2.
5764  * \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.
5765  * 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
5766  * inversely.
5767  * In case of success (no throw) : \c ids1->renumber(ret)->isEqual(ids2) where \a ret is the return of this method.
5768  *
5769  * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5770  *          array using decrRef() as it is no more needed.
5771  * \throw If either ids1 or ids2 is null not allocated or not with one components.
5772  * 
5773  */
5774 DataArrayInt *DataArrayInt::FindPermutationFromFirstToSecond(const DataArrayInt *ids1, const DataArrayInt *ids2)
5775 {
5776   if(!ids1 || !ids2)
5777     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be not null !");
5778   if(!ids1->isAllocated() || !ids2->isAllocated())
5779     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be allocated !");
5780   if(ids1->getNumberOfComponents()!=1 || ids2->getNumberOfComponents()!=1)
5781     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays have exactly one component !");
5782   if(ids1->getNumberOfTuples()!=ids2->getNumberOfTuples())
5783     {
5784       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 !";
5785       throw INTERP_KERNEL::Exception(oss.str().c_str());
5786     }
5787   MCAuto<DataArrayInt> p1(ids1->deepCopy());
5788   MCAuto<DataArrayInt> p2(ids2->deepCopy());
5789   p1->sort(true); p2->sort(true);
5790   if(!p1->isEqualWithoutConsideringStr(*p2))
5791     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two arrays are not lying on same ids ! Impossible to find a permutation between the 2 arrays !");
5792   p1=ids1->checkAndPreparePermutation();
5793   p2=ids2->checkAndPreparePermutation();
5794   p2=p2->invertArrayO2N2N2O(p2->getNumberOfTuples());
5795   p2=p2->selectByTupleIdSafe(p1->begin(),p1->end());
5796   return p2.retn();
5797 }
5798
5799 /*!
5800  * Returns two arrays describing a surjective mapping from \a this set of values (\a A)
5801  * onto a set of values of size \a targetNb (\a B). The surjective function is 
5802  * \a B[ \a A[ i ]] = i. That is to say that for each \a id in [0,\a targetNb), where \a
5803  * targetNb < \a this->getNumberOfTuples(), there exists at least one tupleId (\a tid) so
5804  * that <em> this->getIJ( tid, 0 ) == id</em>. <br>
5805  * The first of out arrays returns indices of elements of \a this array, grouped by their
5806  * place in the set \a B. The second out array is the index of the first one; it shows how
5807  * many elements of \a A are mapped into each element of \a B. <br>
5808  * For more info on
5809  * mapping and its usage in renumbering see \ref numbering. <br>
5810  * \b Example:
5811  * - \a this: [0,3,2,3,2,2,1,2]
5812  * - \a targetNb: 4
5813  * - \a arr:  [0,  6,  2,4,5,7,  1,3]
5814  * - \a arrI: [0,1,2,6,8]
5815  *
5816  * This result means: <br>
5817  * the element of \a B 0 encounters within \a A once (\a arrI[ 0+1 ] - \a arrI[ 0 ]) and
5818  * its index within \a A is 0 ( \a arr[ 0:1 ] == \a arr[ \a arrI[ 0 ] : \a arrI[ 0+1 ]]);<br>
5819  * the element of \a B 2 encounters within \a A 4 times (\a arrI[ 2+1 ] - \a arrI[ 2 ]) and
5820  * its indices within \a A are [2,4,5,7] ( \a arr[ 2:6 ] == \a arr[ \a arrI[ 2 ] : 
5821  * \a arrI[ 2+1 ]]); <br> etc.
5822  *  \param [in] targetNb - the size of the set \a B. \a targetNb must be equal or more
5823  *         than the maximal value of \a A.
5824  *  \param [out] arr - a new instance of DataArrayInt returning indices of
5825  *         elements of \a this, grouped by their place in the set \a B. The caller is to delete
5826  *         this array using decrRef() as it is no more needed.
5827  *  \param [out] arrI - a new instance of DataArrayInt returning size of groups of equal
5828  *         elements of \a this. The caller is to delete this array using decrRef() as it
5829  *         is no more needed.
5830  *  \throw If \a this is not allocated.
5831  *  \throw If \a this->getNumberOfComponents() != 1.
5832  *  \throw If any value in \a this is more or equal to \a targetNb.
5833  */
5834 void DataArrayInt::changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, DataArrayInt *&arrI) const
5835 {
5836   checkAllocated();
5837   if(getNumberOfComponents()!=1)
5838     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : number of components must == 1 !");
5839   int nbOfTuples=getNumberOfTuples();
5840   MCAuto<DataArrayInt> ret(DataArrayInt::New());
5841   MCAuto<DataArrayInt> retI(DataArrayInt::New());
5842   retI->alloc(targetNb+1,1);
5843   const int *input=getConstPointer();
5844   std::vector< std::vector<int> > tmp(targetNb);
5845   for(int i=0;i<nbOfTuples;i++)
5846     {
5847       int tmp2=input[i];
5848       if(tmp2>=0 && tmp2<targetNb)
5849         tmp[tmp2].push_back(i);
5850       else
5851         {
5852           std::ostringstream oss; oss << "DataArrayInt::changeSurjectiveFormat : At pos " << i << " presence of element " << tmp2 << " ! should be in [0," << targetNb << ") !";
5853           throw INTERP_KERNEL::Exception(oss.str().c_str());
5854         }
5855     }
5856   int *retIPtr=retI->getPointer();
5857   *retIPtr=0;
5858   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++,retIPtr++)
5859     retIPtr[1]=retIPtr[0]+(int)((*it1).size());
5860   if(nbOfTuples!=retI->getIJ(targetNb,0))
5861     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : big problem should never happen !");
5862   ret->alloc(nbOfTuples,1);
5863   int *retPtr=ret->getPointer();
5864   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++)
5865     retPtr=std::copy((*it1).begin(),(*it1).end(),retPtr);
5866   arr=ret.retn();
5867   arrI=retI.retn();
5868 }
5869
5870
5871 /*!
5872  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode computed
5873  * from a zip representation of a surjective format (returned e.g. by
5874  * \ref MEDCoupling::DataArrayDouble::findCommonTuples() "DataArrayDouble::findCommonTuples()"
5875  * for example). The result array minimizes the permutation. <br>
5876  * For more info on renumbering see \ref numbering. <br>
5877  * \b Example: <br>
5878  * - \a nbOfOldTuples: 10 
5879  * - \a arr          : [0,3, 5,7,9]
5880  * - \a arrIBg       : [0,2,5]
5881  * - \a newNbOfTuples: 7
5882  * - result array    : [0,1,2,0,3,4,5,4,6,4]
5883  *
5884  *  \param [in] nbOfOldTuples - number of tuples in the initial array \a arr.
5885  *  \param [in] arr - the array of tuple indices grouped by \a arrIBg array.
5886  *  \param [in] arrIBg - the array dividing all indices stored in \a arr into groups of
5887  *         (indices of) equal values. Its every element (except the last one) points to
5888  *         the first element of a group of equal values.
5889  *  \param [in] arrIEnd - specifies the end of \a arrIBg, so that the last element of \a
5890  *          arrIBg is \a arrIEnd[ -1 ].
5891  *  \param [out] newNbOfTuples - number of tuples after surjection application.
5892  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5893  *          array using decrRef() as it is no more needed.
5894  *  \throw If any value of \a arr breaks condition ( 0 <= \a arr[ i ] < \a nbOfOldTuples ).
5895  */
5896 DataArrayInt *DataArrayInt::ConvertIndexArrayToO2N(int nbOfOldTuples, const int *arr, const int *arrIBg, const int *arrIEnd, int &newNbOfTuples)
5897 {
5898   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5899   ret->alloc(nbOfOldTuples,1);
5900   int *pt=ret->getPointer();
5901   std::fill(pt,pt+nbOfOldTuples,-1);
5902   int nbOfGrps=((int)std::distance(arrIBg,arrIEnd))-1;
5903   const int *cIPtr=arrIBg;
5904   for(int i=0;i<nbOfGrps;i++)
5905     pt[arr[cIPtr[i]]]=-(i+2);
5906   int newNb=0;
5907   for(int iNode=0;iNode<nbOfOldTuples;iNode++)
5908     {
5909       if(pt[iNode]<0)
5910         {
5911           if(pt[iNode]==-1)
5912             pt[iNode]=newNb++;
5913           else
5914             {
5915               int grpId=-(pt[iNode]+2);
5916               for(int j=cIPtr[grpId];j<cIPtr[grpId+1];j++)
5917                 {
5918                   if(arr[j]>=0 && arr[j]<nbOfOldTuples)
5919                     pt[arr[j]]=newNb;
5920                   else
5921                     {
5922                       std::ostringstream oss; oss << "DataArrayInt::ConvertIndexArrayToO2N : With element #" << j << " value is " << arr[j] << " should be in [0," << nbOfOldTuples << ") !";
5923                       throw INTERP_KERNEL::Exception(oss.str().c_str());
5924                     }
5925                 }
5926               newNb++;
5927             }
5928         }
5929     }
5930   newNbOfTuples=newNb;
5931   return ret.retn();
5932 }
5933
5934 /*!
5935  * Returns a new DataArrayInt containing a renumbering map in "New to Old" mode,
5936  * which if applied to \a this array would make it sorted ascendingly.
5937  * For more info on renumbering see \ref numbering. <br>
5938  * \b Example: <br>
5939  * - \a this: [2,0,1,1,0,1,2,0,1,1,0,0]
5940  * - result: [10,0,5,6,1,7,11,2,8,9,3,4]
5941  * - after applying result to \a this: [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2] 
5942  *
5943  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5944  *          array using decrRef() as it is no more needed.
5945  *  \throw If \a this is not allocated.
5946  *  \throw If \a this->getNumberOfComponents() != 1.
5947  */
5948 DataArrayInt *DataArrayInt::buildPermArrPerLevel() const
5949 {
5950   checkAllocated();
5951   if(getNumberOfComponents()!=1)
5952     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermArrPerLevel : number of components must == 1 !");
5953   int nbOfTuples=getNumberOfTuples();
5954   const int *pt=getConstPointer();
5955   std::map<int,int> m;
5956   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5957   ret->alloc(nbOfTuples,1);
5958   int *opt=ret->getPointer();
5959   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
5960     {
5961       int val=*pt;
5962       std::map<int,int>::iterator it=m.find(val);
5963       if(it!=m.end())
5964         {
5965           *opt=(*it).second;
5966           (*it).second++;
5967         }
5968       else
5969         {
5970           *opt=0;
5971           m.insert(std::pair<int,int>(val,1));
5972         }
5973     }
5974   int sum=0;
5975   for(std::map<int,int>::iterator it=m.begin();it!=m.end();it++)
5976     {
5977       int vt=(*it).second;
5978       (*it).second=sum;
5979       sum+=vt;
5980     }
5981   pt=getConstPointer();
5982   opt=ret->getPointer();
5983   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
5984     *opt+=m[*pt];
5985   //
5986   return ret.retn();
5987 }
5988
5989 /*!
5990  * Checks if \a this array has the given size, and if its contents is equal to an array filled with
5991  * iota(). This method is particularly useful for DataArrayInt instances that represent
5992  * a renumbering array, to check if there is a real need in renumbering.
5993  * This method checks than \a this can be considered as an identity mapping
5994  * of a set having \a sizeExpected elements into itself.
5995  *
5996  *  \param [in] sizeExpected - The number of elements expected.
5997  *  \return bool - \a true if \a this array contents == \a range( \a this->getNumberOfTuples())
5998  *  \throw If \a this is not allocated.
5999  *  \throw If \a this->getNumberOfComponents() != 1.
6000  */
6001 bool DataArrayInt::isIota(int sizeExpected) const
6002 {
6003   checkAllocated();
6004   if(getNumberOfComponents()!=1)
6005     return false;
6006   int nbOfTuples(getNumberOfTuples());
6007   if(nbOfTuples!=sizeExpected)
6008     return false;
6009   const int *pt=getConstPointer();
6010   for(int i=0;i<nbOfTuples;i++,pt++)
6011     if(*pt!=i)
6012       return false;
6013   return true;
6014 }
6015
6016 /*!
6017  * Checks if all values in \a this array are equal to \a val.
6018  *  \param [in] val - value to check equality of array values to.
6019  *  \return bool - \a true if all values are \a val.
6020  *  \throw If \a this is not allocated.
6021  *  \throw If \a this->getNumberOfComponents() != 1
6022  */
6023 bool DataArrayInt::isUniform(int val) const
6024 {
6025   checkAllocated();
6026   if(getNumberOfComponents()!=1)
6027     throw INTERP_KERNEL::Exception("DataArrayInt::isUniform : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
6028   int nbOfTuples=getNumberOfTuples();
6029   const int *w=getConstPointer();
6030   const int *end2=w+nbOfTuples;
6031   for(;w!=end2;w++)
6032     if(*w!=val)
6033       return false;
6034   return true;
6035 }
6036
6037 /*!
6038  * Checks if all values in \a this array are unique.
6039  *  \return bool - \a true if condition above is true
6040  *  \throw If \a this is not allocated.
6041  *  \throw If \a this->getNumberOfComponents() != 1
6042  */
6043 bool DataArrayInt::hasUniqueValues() const
6044 {
6045   checkAllocated();
6046   if(getNumberOfComponents()!=1)
6047     throw INTERP_KERNEL::Exception("DataArrayInt::hasOnlyUniqueValues: must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
6048   int nbOfTuples(getNumberOfTuples());
6049   std::set<int> s(begin(),end());  // in C++11, should use unordered_set (O(1) complexity)
6050   if (s.size() != nbOfTuples)
6051     return false;
6052   return true;
6053 }
6054
6055 /*!
6056  * Creates a new DataArrayDouble and assigns all (textual and numerical) data of \a this
6057  * array to the new one.
6058  *  \return DataArrayDouble * - the new instance of DataArrayInt.
6059  */
6060 DataArrayDouble *DataArrayInt::convertToDblArr() const
6061 {
6062   checkAllocated();
6063   DataArrayDouble *ret=DataArrayDouble::New();
6064   ret->alloc(getNumberOfTuples(),getNumberOfComponents());
6065   std::size_t nbOfVals=getNbOfElems();
6066   const int *src=getConstPointer();
6067   double *dest=ret->getPointer();
6068   std::copy(src,src+nbOfVals,dest);
6069   ret->copyStringInfoFrom(*this);
6070   return ret;
6071 }
6072
6073 /*!
6074  * Appends components of another array to components of \a this one, tuple by tuple.
6075  * So that the number of tuples of \a this array remains the same and the number of 
6076  * components increases.
6077  *  \param [in] other - the DataArrayInt to append to \a this one.
6078  *  \throw If \a this is not allocated.
6079  *  \throw If \a this and \a other arrays have different number of tuples.
6080  *
6081  *  \if ENABLE_EXAMPLES
6082  *  \ref cpp_mcdataarrayint_meldwith "Here is a C++ example".
6083  *
6084  *  \ref py_mcdataarrayint_meldwith "Here is a Python example".
6085  *  \endif
6086  */
6087 void DataArrayInt::meldWith(const DataArrayInt *other)
6088 {
6089   if(!other)
6090     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : DataArrayInt pointer in input is NULL !");
6091   checkAllocated();
6092   other->checkAllocated();
6093   int nbOfTuples=getNumberOfTuples();
6094   if(nbOfTuples!=other->getNumberOfTuples())
6095     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : mismatch of number of tuples !");
6096   int nbOfComp1=getNumberOfComponents();
6097   int nbOfComp2=other->getNumberOfComponents();
6098   int *newArr=(int *)malloc(nbOfTuples*(nbOfComp1+nbOfComp2)*sizeof(int));
6099   int *w=newArr;
6100   const int *inp1=getConstPointer();
6101   const int *inp2=other->getConstPointer();
6102   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
6103     {
6104       w=std::copy(inp1,inp1+nbOfComp1,w);
6105       w=std::copy(inp2,inp2+nbOfComp2,w);
6106     }
6107   useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
6108   std::vector<int> compIds(nbOfComp2);
6109   for(int i=0;i<nbOfComp2;i++)
6110     compIds[i]=nbOfComp1+i;
6111   copyPartOfStringInfoFrom2(compIds,*other);
6112 }
6113
6114 /*!
6115  * Copy all components in a specified order from another DataArrayInt.
6116  * The specified components become the first ones in \a this array.
6117  * Both numerical and textual data is copied. The number of tuples in \a this and
6118  * the other array can be different.
6119  *  \param [in] a - the array to copy data from.
6120  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
6121  *              to be copied.
6122  *  \throw If \a a is NULL.
6123  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
6124  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
6125  *
6126  *  \if ENABLE_EXAMPLES
6127  *  \ref py_mcdataarrayint_setselectedcomponents "Here is a Python example".
6128  *  \endif
6129  */
6130 void DataArrayInt::setSelectedComponents(const DataArrayInt *a, const std::vector<int>& compoIds)
6131 {
6132   if(!a)
6133     throw INTERP_KERNEL::Exception("DataArrayInt::setSelectedComponents : input DataArrayInt is NULL !");
6134   checkAllocated();
6135   a->checkAllocated();
6136   copyPartOfStringInfoFrom2(compoIds,*a);
6137   std::size_t partOfCompoSz=compoIds.size();
6138   int nbOfCompo=getNumberOfComponents();
6139   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
6140   const int *ac=a->getConstPointer();
6141   int *nc=getPointer();
6142   for(int i=0;i<nbOfTuples;i++)
6143     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
6144       nc[nbOfCompo*i+compoIds[j]]=*ac;
6145 }
6146
6147 /*!
6148  * Assign pointer to one array to a pointer to another appay. Reference counter of
6149  * \a arrayToSet is incremented / decremented.
6150  *  \param [in] newArray - the pointer to array to assign to \a arrayToSet.
6151  *  \param [in,out] arrayToSet - the pointer to array to assign to.
6152  */
6153 void DataArrayInt::SetArrayIn(DataArrayInt *newArray, DataArrayInt* &arrayToSet)
6154 {
6155   if(newArray!=arrayToSet)
6156     {
6157       if(arrayToSet)
6158         arrayToSet->decrRef();
6159       arrayToSet=newArray;
6160       if(arrayToSet)
6161         arrayToSet->incrRef();
6162     }
6163 }
6164
6165 DataArrayIntIterator *DataArrayInt::iterator()
6166 {
6167   return new DataArrayIntIterator(this);
6168 }
6169
6170 /*!
6171  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to a
6172  * given one. The ids are sorted in the ascending order.
6173  *  \param [in] val - the value to find within \a this.
6174  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6175  *          array using decrRef() as it is no more needed.
6176  *  \throw If \a this is not allocated.
6177  *  \throw If \a this->getNumberOfComponents() != 1.
6178  *  \sa DataArrayInt::findIdsEqualTuple
6179  */
6180 DataArrayInt *DataArrayInt::findIdsEqual(int val) const
6181 {
6182   checkAllocated();
6183   if(getNumberOfComponents()!=1)
6184     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqual : the array must have only one component, you can call 'rearrange' method before !");
6185   const int *cptr(getConstPointer());
6186   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6187   int nbOfTuples=getNumberOfTuples();
6188   for(int i=0;i<nbOfTuples;i++,cptr++)
6189     if(*cptr==val)
6190       ret->pushBackSilent(i);
6191   return ret.retn();
6192 }
6193
6194 /*!
6195  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value \b not
6196  * equal to a given one. 
6197  *  \param [in] val - the value to ignore within \a this.
6198  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6199  *          array using decrRef() as it is no more needed.
6200  *  \throw If \a this is not allocated.
6201  *  \throw If \a this->getNumberOfComponents() != 1.
6202  */
6203 DataArrayInt *DataArrayInt::findIdsNotEqual(int val) const
6204 {
6205   checkAllocated();
6206   if(getNumberOfComponents()!=1)
6207     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotEqual : the array must have only one component, you can call 'rearrange' method before !");
6208   const int *cptr(getConstPointer());
6209   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6210   int nbOfTuples=getNumberOfTuples();
6211   for(int i=0;i<nbOfTuples;i++,cptr++)
6212     if(*cptr!=val)
6213       ret->pushBackSilent(i);
6214   return ret.retn();
6215 }
6216
6217 /*!
6218  * Creates a new DataArrayInt containing IDs (indices) of tuples holding tuple equal to those defined by [ \a tupleBg , \a tupleEnd )
6219  * This method is an extension of  DataArrayInt::findIdsEqual method.
6220  *
6221  *  \param [in] tupleBg - the begin (included) of the input tuple to find within \a this.
6222  *  \param [in] tupleEnd - the end (excluded) of the input tuple to find within \a this.
6223  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6224  *          array using decrRef() as it is no more needed.
6225  *  \throw If \a this is not allocated.
6226  *  \throw If \a this->getNumberOfComponents() != std::distance(tupleBg,tupleEnd).
6227  * \throw If \a this->getNumberOfComponents() is equal to 0.
6228  * \sa DataArrayInt::findIdsEqual
6229  */
6230 DataArrayInt *DataArrayInt::findIdsEqualTuple(const int *tupleBg, const int *tupleEnd) const
6231 {
6232   std::size_t nbOfCompoExp(std::distance(tupleBg,tupleEnd));
6233   checkAllocated();
6234   if(getNumberOfComponents()!=(int)nbOfCompoExp)
6235     {
6236       std::ostringstream oss; oss << "DataArrayInt::findIdsEqualTuple : mismatch of number of components. Input tuple has " << nbOfCompoExp << " whereas this array has " << getNumberOfComponents() << " components !";
6237       throw INTERP_KERNEL::Exception(oss.str().c_str());
6238     }
6239   if(nbOfCompoExp==0)
6240     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqualTuple : number of components should be > 0 !");
6241   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6242   const int *bg(begin()),*end2(end()),*work(begin());
6243   while(work!=end2)
6244     {
6245       work=std::search(work,end2,tupleBg,tupleEnd);
6246       if(work!=end2)
6247         {
6248           std::size_t pos(std::distance(bg,work));
6249           if(pos%nbOfCompoExp==0)
6250             ret->pushBackSilent(pos/nbOfCompoExp);
6251           work++;
6252         }
6253     }
6254   return ret.retn();
6255 }
6256
6257 /*!
6258  * Assigns \a newValue to all elements holding \a oldValue within \a this
6259  * one-dimensional array.
6260  *  \param [in] oldValue - the value to replace.
6261  *  \param [in] newValue - the value to assign.
6262  *  \return int - number of replacements performed.
6263  *  \throw If \a this is not allocated.
6264  *  \throw If \a this->getNumberOfComponents() != 1.
6265  */
6266 int DataArrayInt::changeValue(int oldValue, int newValue)
6267 {
6268   checkAllocated();
6269   if(getNumberOfComponents()!=1)
6270     throw INTERP_KERNEL::Exception("DataArrayInt::changeValue : the array must have only one component, you can call 'rearrange' method before !");
6271   if(oldValue==newValue)
6272     return 0;
6273   int *start(getPointer()),*end2(start+getNbOfElems());
6274   int ret(0);
6275   for(int *val=start;val!=end2;val++)
6276     {
6277       if(*val==oldValue)
6278         {
6279           *val=newValue;
6280           ret++;
6281         }
6282     }
6283   if(ret>0)
6284     declareAsNew();
6285   return ret;
6286 }
6287
6288 /*!
6289  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to
6290  * one of given values.
6291  *  \param [in] valsBg - an array of values to find within \a this array.
6292  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
6293  *              the last value of \a valsBg is \a valsEnd[ -1 ].
6294  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6295  *          array using decrRef() as it is no more needed.
6296  *  \throw If \a this->getNumberOfComponents() != 1.
6297  */
6298 DataArrayInt *DataArrayInt::findIdsEqualList(const int *valsBg, const int *valsEnd) const
6299 {
6300   if(getNumberOfComponents()!=1)
6301     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqualList : the array must have only one component, you can call 'rearrange' method before !");
6302   std::set<int> vals2(valsBg,valsEnd);
6303   const int *cptr(getConstPointer());
6304   std::vector<int> res;
6305   int nbOfTuples(getNumberOfTuples());
6306   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6307   for(int i=0;i<nbOfTuples;i++,cptr++)
6308     if(vals2.find(*cptr)!=vals2.end())
6309       ret->pushBackSilent(i);
6310   return ret.retn();
6311 }
6312
6313 /*!
6314  * Creates a new DataArrayInt containing IDs (indices) of tuples holding values \b not
6315  * equal to any of given values.
6316  *  \param [in] valsBg - an array of values to ignore within \a this array.
6317  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
6318  *              the last value of \a valsBg is \a valsEnd[ -1 ].
6319  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6320  *          array using decrRef() as it is no more needed.
6321  *  \throw If \a this->getNumberOfComponents() != 1.
6322  */
6323 DataArrayInt *DataArrayInt::findIdsNotEqualList(const int *valsBg, const int *valsEnd) const
6324 {
6325   if(getNumberOfComponents()!=1)
6326     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotEqualList : the array must have only one component, you can call 'rearrange' method before !");
6327   std::set<int> vals2(valsBg,valsEnd);
6328   const int *cptr=getConstPointer();
6329   std::vector<int> res;
6330   int nbOfTuples=getNumberOfTuples();
6331   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6332   for(int i=0;i<nbOfTuples;i++,cptr++)
6333     if(vals2.find(*cptr)==vals2.end())
6334       ret->pushBackSilent(i);
6335   return ret.retn();
6336 }
6337
6338 /*!
6339  * This method is an extension of DataArrayInt::findIdFirstEqual method because this method works for DataArrayInt with
6340  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
6341  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
6342  * If any the tuple id is returned. If not -1 is returned.
6343  * 
6344  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
6345  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
6346  *
6347  * \return tuple id where \b tupl is. -1 if no such tuple exists in \b this.
6348  * \sa DataArrayInt::findIdSequence, DataArrayInt::presenceOfTuple.
6349  */
6350 int DataArrayInt::findIdFirstEqualTuple(const std::vector<int>& tupl) const
6351 {
6352   checkAllocated();
6353   int nbOfCompo=getNumberOfComponents();
6354   if(nbOfCompo==0)
6355     throw INTERP_KERNEL::Exception("DataArrayInt::findIdFirstEqualTuple : 0 components in 'this' !");
6356   if(nbOfCompo!=(int)tupl.size())
6357     {
6358       std::ostringstream oss; oss << "DataArrayInt::findIdFirstEqualTuple : 'this' contains " << nbOfCompo << " components and searching for a tuple of length " << tupl.size() << " !";
6359       throw INTERP_KERNEL::Exception(oss.str().c_str());
6360     }
6361   const int *cptr=getConstPointer();
6362   std::size_t nbOfVals=getNbOfElems();
6363   for(const int *work=cptr;work!=cptr+nbOfVals;)
6364     {
6365       work=std::search(work,cptr+nbOfVals,tupl.begin(),tupl.end());
6366       if(work!=cptr+nbOfVals)
6367         {
6368           if(std::distance(cptr,work)%nbOfCompo!=0)
6369             work++;
6370           else
6371             return std::distance(cptr,work)/nbOfCompo;
6372         }
6373     }
6374   return -1;
6375 }
6376
6377 /*!
6378  * This method searches the sequence specified in input parameter \b vals in \b this.
6379  * This works only for DataArrayInt having number of components equal to one (if not an INTERP_KERNEL::Exception will be thrown).
6380  * This method differs from DataArrayInt::findIdFirstEqualTuple in that the position is internal raw data is not considered here contrary to DataArrayInt::findIdFirstEqualTuple.
6381  * \sa DataArrayInt::findIdFirstEqualTuple
6382  */
6383 int DataArrayInt::findIdSequence(const std::vector<int>& vals) const
6384 {
6385   checkAllocated();
6386   int nbOfCompo=getNumberOfComponents();
6387   if(nbOfCompo!=1)
6388     throw INTERP_KERNEL::Exception("DataArrayInt::findIdSequence : works only for DataArrayInt instance with one component !");
6389   const int *cptr=getConstPointer();
6390   std::size_t nbOfVals=getNbOfElems();
6391   const int *loc=std::search(cptr,cptr+nbOfVals,vals.begin(),vals.end());
6392   if(loc!=cptr+nbOfVals)
6393     return std::distance(cptr,loc);
6394   return -1;
6395 }
6396
6397 /*!
6398  * This method expects to be called when number of components of this is equal to one.
6399  * This method returns the tuple id, if it exists, of the first tuple equal to \b value.
6400  * If not any tuple contains \b value -1 is returned.
6401  * \sa DataArrayInt::presenceOfValue
6402  */
6403 int DataArrayInt::findIdFirstEqual(int value) const
6404 {
6405   checkAllocated();
6406   if(getNumberOfComponents()!=1)
6407     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
6408   const int *cptr=getConstPointer();
6409   int nbOfTuples=getNumberOfTuples();
6410   const int *ret=std::find(cptr,cptr+nbOfTuples,value);
6411   if(ret!=cptr+nbOfTuples)
6412     return std::distance(cptr,ret);
6413   return -1;
6414 }
6415
6416 /*!
6417  * This method expects to be called when number of components of this is equal to one.
6418  * This method returns the tuple id, if it exists, of the first tuple so that the value is contained in \b vals.
6419  * If not any tuple contains one of the values contained in 'vals' -1 is returned.
6420  * \sa DataArrayInt::presenceOfValue
6421  */
6422 int DataArrayInt::findIdFirstEqual(const std::vector<int>& vals) const
6423 {
6424   checkAllocated();
6425   if(getNumberOfComponents()!=1)
6426     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
6427   std::set<int> vals2(vals.begin(),vals.end());
6428   const int *cptr=getConstPointer();
6429   int nbOfTuples=getNumberOfTuples();
6430   for(const int *w=cptr;w!=cptr+nbOfTuples;w++)
6431     if(vals2.find(*w)!=vals2.end())
6432       return std::distance(cptr,w);
6433   return -1;
6434 }
6435
6436 /*!
6437  * This method returns the number of values in \a this that are equals to input parameter \a value.
6438  * This method only works for single component array.
6439  *
6440  * \return a value in [ 0, \c this->getNumberOfTuples() )
6441  *
6442  * \throw If \a this is not allocated
6443  *
6444  */
6445 int DataArrayInt::count(int value) const
6446 {
6447   int ret=0;
6448   checkAllocated();
6449   if(getNumberOfComponents()!=1)
6450     throw INTERP_KERNEL::Exception("DataArrayInt::count : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
6451   const int *vals=begin();
6452   int nbOfTuples=getNumberOfTuples();
6453   for(int i=0;i<nbOfTuples;i++,vals++)
6454     if(*vals==value)
6455       ret++;
6456   return ret;
6457 }
6458
6459 /*!
6460  * This method is an extension of DataArrayInt::presenceOfValue method because this method works for DataArrayInt with
6461  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
6462  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
6463  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
6464  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
6465  * \sa DataArrayInt::findIdFirstEqualTuple
6466  */
6467 bool DataArrayInt::presenceOfTuple(const std::vector<int>& tupl) const
6468 {
6469   return findIdFirstEqualTuple(tupl)!=-1;
6470 }
6471
6472
6473 /*!
6474  * Returns \a true if a given value is present within \a this one-dimensional array.
6475  *  \param [in] value - the value to find within \a this array.
6476  *  \return bool - \a true in case if \a value is present within \a this array.
6477  *  \throw If \a this is not allocated.
6478  *  \throw If \a this->getNumberOfComponents() != 1.
6479  *  \sa findIdFirstEqual()
6480  */
6481 bool DataArrayInt::presenceOfValue(int value) const
6482 {
6483   return findIdFirstEqual(value)!=-1;
6484 }
6485
6486 /*!
6487  * This method expects to be called when number of components of this is equal to one.
6488  * This method returns true if it exists a tuple so that the value is contained in \b vals.
6489  * If not any tuple contains one of the values contained in 'vals' false is returned.
6490  * \sa DataArrayInt::findIdFirstEqual
6491  */
6492 bool DataArrayInt::presenceOfValue(const std::vector<int>& vals) const
6493 {
6494   return findIdFirstEqual(vals)!=-1;
6495 }
6496
6497 /*!
6498  * Accumulates values of each component of \a this array.
6499  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
6500  *         by the caller, that is filled by this method with sum value for each
6501  *         component.
6502  *  \throw If \a this is not allocated.
6503  */
6504 void DataArrayInt::accumulate(int *res) const
6505 {
6506   checkAllocated();
6507   const int *ptr=getConstPointer();
6508   int nbTuple=getNumberOfTuples();
6509   int nbComps=getNumberOfComponents();
6510   std::fill(res,res+nbComps,0);
6511   for(int i=0;i<nbTuple;i++)
6512     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<int>());
6513 }
6514
6515 int DataArrayInt::accumulate(int compId) const
6516 {
6517   checkAllocated();
6518   const int *ptr=getConstPointer();
6519   int nbTuple=getNumberOfTuples();
6520   int nbComps=getNumberOfComponents();
6521   if(compId<0 || compId>=nbComps)
6522     throw INTERP_KERNEL::Exception("DataArrayInt::accumulate : Invalid compId specified : No such nb of components !");
6523   int ret=0;
6524   for(int i=0;i<nbTuple;i++)
6525     ret+=ptr[i*nbComps+compId];
6526   return ret;
6527 }
6528
6529 /*!
6530  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
6531  * The returned array will have same number of components than \a this and number of tuples equal to
6532  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
6533  *
6534  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
6535  *
6536  * \param [in] bgOfIndex - begin (included) of the input index array.
6537  * \param [in] endOfIndex - end (excluded) of the input index array.
6538  * \return DataArrayInt * - the new instance having the same number of components than \a this.
6539  * 
6540  * \throw If bgOfIndex or end is NULL.
6541  * \throw If input index array is not ascendingly sorted.
6542  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
6543  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
6544  */
6545 DataArrayInt *DataArrayInt::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
6546 {
6547   if(!bgOfIndex || !endOfIndex)
6548     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : input pointer NULL !");
6549   checkAllocated();
6550   int nbCompo=getNumberOfComponents();
6551   int nbOfTuples=getNumberOfTuples();
6552   int sz=(int)std::distance(bgOfIndex,endOfIndex);
6553   if(sz<1)
6554     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : invalid size of input index array !");
6555   sz--;
6556   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(sz,nbCompo);
6557   const int *w=bgOfIndex;
6558   if(*w<0 || *w>=nbOfTuples)
6559     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
6560   const int *srcPt=begin()+(*w)*nbCompo;
6561   int *tmp=ret->getPointer();
6562   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
6563     {
6564       std::fill(tmp,tmp+nbCompo,0);
6565       if(w[1]>=w[0])
6566         {
6567           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
6568             {
6569               if(j>=0 && j<nbOfTuples)
6570                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<int>());
6571               else
6572                 {
6573                   std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
6574                   throw INTERP_KERNEL::Exception(oss.str().c_str());
6575                 }
6576             }
6577         }
6578       else
6579         {
6580           std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
6581           throw INTERP_KERNEL::Exception(oss.str().c_str());
6582         }
6583     }
6584   ret->copyStringInfoFrom(*this);
6585   return ret.retn();
6586 }
6587
6588 /*!
6589  * Returns a new DataArrayInt by concatenating two given arrays, so that (1) the number
6590  * of tuples in the result array is <em> a1->getNumberOfTuples() + a2->getNumberOfTuples() -
6591  * offsetA2</em> and (2)
6592  * the number of component in the result array is same as that of each of given arrays.
6593  * First \a offsetA2 tuples of \a a2 are skipped and thus are missing from the result array.
6594  * Info on components is copied from the first of the given arrays. Number of components
6595  * in the given arrays must be the same.
6596  *  \param [in] a1 - an array to include in the result array.
6597  *  \param [in] a2 - another array to include in the result array.
6598  *  \param [in] offsetA2 - number of tuples of \a a2 to skip.
6599  *  \return DataArrayInt * - the new instance of DataArrayInt.
6600  *          The caller is to delete this result array using decrRef() as it is no more
6601  *          needed.
6602  *  \throw If either \a a1 or \a a2 is NULL.
6603  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
6604  */
6605 DataArrayInt *DataArrayInt::Aggregate(const DataArrayInt *a1, const DataArrayInt *a2, int offsetA2)
6606 {
6607   if(!a1 || !a2)
6608     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input DataArrayInt instance is NULL !");
6609   int nbOfComp=a1->getNumberOfComponents();
6610   if(nbOfComp!=a2->getNumberOfComponents())
6611     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Aggregation !");
6612   int nbOfTuple1=a1->getNumberOfTuples();
6613   int nbOfTuple2=a2->getNumberOfTuples();
6614   DataArrayInt *ret=DataArrayInt::New();
6615   ret->alloc(nbOfTuple1+nbOfTuple2-offsetA2,nbOfComp);
6616   int *pt=std::copy(a1->getConstPointer(),a1->getConstPointer()+nbOfTuple1*nbOfComp,ret->getPointer());
6617   std::copy(a2->getConstPointer()+offsetA2*nbOfComp,a2->getConstPointer()+nbOfTuple2*nbOfComp,pt);
6618   ret->copyStringInfoFrom(*a1);
6619   return ret;
6620 }
6621
6622 /*!
6623  * Returns a new DataArrayInt by concatenating all given arrays, so that (1) the number
6624  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
6625  * the number of component in the result array is same as that of each of given arrays.
6626  * Info on components is copied from the first of the given arrays. Number of components
6627  * in the given arrays must be  the same.
6628  * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it
6629  * not the object itself.
6630  *  \param [in] arr - a sequence of arrays to include in the result array.
6631  *  \return DataArrayInt * - the new instance of DataArrayInt.
6632  *          The caller is to delete this result array using decrRef() as it is no more
6633  *          needed.
6634  *  \throw If all arrays within \a arr are NULL.
6635  *  \throw If getNumberOfComponents() of arrays within \a arr.
6636  */
6637 DataArrayInt *DataArrayInt::Aggregate(const std::vector<const DataArrayInt *>& arr)
6638 {
6639   std::vector<const DataArrayInt *> a;
6640   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
6641     if(*it4)
6642       a.push_back(*it4);
6643   if(a.empty())
6644     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input list must be NON EMPTY !");
6645   std::vector<const DataArrayInt *>::const_iterator it=a.begin();
6646   int nbOfComp=(*it)->getNumberOfComponents();
6647   int nbt=(*it++)->getNumberOfTuples();
6648   for(int i=1;it!=a.end();it++,i++)
6649     {
6650       if((*it)->getNumberOfComponents()!=nbOfComp)
6651         throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : Nb of components mismatch for array aggregation !");
6652       nbt+=(*it)->getNumberOfTuples();
6653     }
6654   MCAuto<DataArrayInt> ret=DataArrayInt::New();
6655   ret->alloc(nbt,nbOfComp);
6656   int *pt=ret->getPointer();
6657   for(it=a.begin();it!=a.end();it++)
6658     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
6659   ret->copyStringInfoFrom(*(a[0]));
6660   return ret.retn();
6661 }
6662
6663 /*!
6664  * This method takes as input a list of DataArrayInt instances \a arrs that represent each a packed index arrays.
6665  * A packed index array is an allocated array with one component, and at least one tuple. The first element
6666  * of each array in \a arrs must be 0. Each array in \a arrs is expected to be increasingly monotonic.
6667  * 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.
6668  * 
6669  * \return DataArrayInt * - a new object to be managed by the caller.
6670  */
6671 DataArrayInt *DataArrayInt::AggregateIndexes(const std::vector<const DataArrayInt *>& arrs)
6672 {
6673   int retSz=1;
6674   for(std::vector<const DataArrayInt *>::const_iterator it4=arrs.begin();it4!=arrs.end();it4++)
6675     {
6676       if(*it4)
6677         {
6678           (*it4)->checkAllocated();
6679           if((*it4)->getNumberOfComponents()!=1)
6680             {
6681               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of compo != 1 at pos " << std::distance(arrs.begin(),it4) << " !";
6682               throw INTERP_KERNEL::Exception(oss.str().c_str());
6683             }
6684           int nbTupl=(*it4)->getNumberOfTuples();
6685           if(nbTupl<1)
6686             {
6687               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of tuples < 1 at pos " << std::distance(arrs.begin(),it4) << " !";
6688               throw INTERP_KERNEL::Exception(oss.str().c_str());
6689             }
6690           if((*it4)->front()!=0)
6691             {
6692               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with front value != 0 at pos " << std::distance(arrs.begin(),it4) << " !";
6693               throw INTERP_KERNEL::Exception(oss.str().c_str());
6694             }
6695           retSz+=nbTupl-1;
6696         }
6697       else
6698         {
6699           std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a null instance at pos " << std::distance(arrs.begin(),it4) << " !";
6700           throw INTERP_KERNEL::Exception(oss.str().c_str());
6701         }
6702     }
6703   if(arrs.empty())
6704     throw INTERP_KERNEL::Exception("DataArrayInt::AggregateIndexes : input list must be NON EMPTY !");
6705   MCAuto<DataArrayInt> ret=DataArrayInt::New();
6706   ret->alloc(retSz,1);
6707   int *pt=ret->getPointer(); *pt++=0;
6708   for(std::vector<const DataArrayInt *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
6709     pt=std::transform((*it)->begin()+1,(*it)->end(),pt,std::bind2nd(std::plus<int>(),pt[-1]));
6710   ret->copyStringInfoFrom(*(arrs[0]));
6711   return ret.retn();
6712 }
6713
6714 /*!
6715  * Returns in a single walk in \a this the min value and the max value in \a this.
6716  * \a this is expected to be single component array.
6717  *
6718  * \param [out] minValue - the min value in \a this.
6719  * \param [out] maxValue - the max value in \a this.
6720  *
6721  * \sa getMinValueInArray, getMinValue, getMaxValueInArray, getMaxValue
6722  */
6723 void DataArrayInt::getMinMaxValues(int& minValue, int& maxValue) const
6724 {
6725   checkAllocated();
6726   if(getNumberOfComponents()!=1)
6727     throw INTERP_KERNEL::Exception("DataArrayInt::getMinMaxValues : must be applied on DataArrayInt with only one component !");
6728   int nbTuples(getNumberOfTuples());
6729   const int *pt(begin());
6730   minValue=std::numeric_limits<int>::max(); maxValue=-std::numeric_limits<int>::max();
6731   for(int i=0;i<nbTuples;i++,pt++)
6732     {
6733       if(*pt<minValue)
6734         minValue=*pt;
6735       if(*pt>maxValue)
6736         maxValue=*pt;
6737     }
6738 }
6739
6740 /*!
6741  * Converts every value of \a this array to its absolute value.
6742  * \b WARNING this method is non const. If a new DataArrayInt instance should be built containing the result of abs DataArrayInt::computeAbs
6743  * should be called instead.
6744  *
6745  * \throw If \a this is not allocated.
6746  * \sa DataArrayInt::computeAbs
6747  */
6748 void DataArrayInt::abs()
6749 {
6750   checkAllocated();
6751   int *ptr(getPointer());
6752   std::size_t nbOfElems(getNbOfElems());
6753   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<int,int>(std::abs));
6754   declareAsNew();
6755 }
6756
6757 /*!
6758  * This method builds a new instance of \a this object containing the result of std::abs applied of all elements in \a this.
6759  * This method is a const method (that do not change any values in \a this) contrary to  DataArrayInt::abs method.
6760  *
6761  * \return DataArrayInt * - the new instance of DataArrayInt containing the
6762  *         same number of tuples and component as \a this array.
6763  *         The caller is to delete this result array using decrRef() as it is no more
6764  *         needed.
6765  * \throw If \a this is not allocated.
6766  * \sa DataArrayInt::abs
6767  */
6768 DataArrayInt *DataArrayInt::computeAbs() const
6769 {
6770   checkAllocated();
6771   DataArrayInt *newArr(DataArrayInt::New());
6772   int nbOfTuples(getNumberOfTuples());
6773   int nbOfComp(getNumberOfComponents());
6774   newArr->alloc(nbOfTuples,nbOfComp);
6775   std::transform(begin(),end(),newArr->getPointer(),std::ptr_fun<int,int>(std::abs));
6776   newArr->copyStringInfoFrom(*this);
6777   return newArr;
6778 }
6779
6780 /*!
6781  * Apply a liner function to a given component of \a this array, so that
6782  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
6783  *  \param [in] a - the first coefficient of the function.
6784  *  \param [in] b - the second coefficient of the function.
6785  *  \param [in] compoId - the index of component to modify.
6786  *  \throw If \a this is not allocated.
6787  */
6788 void DataArrayInt::applyLin(int a, int b, int compoId)
6789 {
6790   checkAllocated();
6791   int *ptr=getPointer()+compoId;
6792   int nbOfComp=getNumberOfComponents();
6793   int nbOfTuple=getNumberOfTuples();
6794   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
6795     *ptr=a*(*ptr)+b;
6796   declareAsNew();
6797 }
6798
6799 /*!
6800  * Apply a liner function to all elements of \a this array, so that
6801  * an element _x_ becomes \f$ a * x + b \f$.
6802  *  \param [in] a - the first coefficient of the function.
6803  *  \param [in] b - the second coefficient of the function.
6804  *  \throw If \a this is not allocated.
6805  */
6806 void DataArrayInt::applyLin(int a, int b)
6807 {
6808   checkAllocated();
6809   int *ptr=getPointer();
6810   std::size_t nbOfElems=getNbOfElems();
6811   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
6812     *ptr=a*(*ptr)+b;
6813   declareAsNew();
6814 }
6815
6816 /*!
6817  * Returns a full copy of \a this array except that sign of all elements is reversed.
6818  *  \return DataArrayInt * - the new instance of DataArrayInt containing the
6819  *          same number of tuples and component as \a this array.
6820  *          The caller is to delete this result array using decrRef() as it is no more
6821  *          needed.
6822  *  \throw If \a this is not allocated.
6823  */
6824 DataArrayInt *DataArrayInt::negate() const
6825 {
6826   checkAllocated();
6827   DataArrayInt *newArr=DataArrayInt::New();
6828   int nbOfTuples=getNumberOfTuples();
6829   int nbOfComp=getNumberOfComponents();
6830   newArr->alloc(nbOfTuples,nbOfComp);
6831   const int *cptr=getConstPointer();
6832   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<int>());
6833   newArr->copyStringInfoFrom(*this);
6834   return newArr;
6835 }
6836
6837 /*!
6838  * Modify all elements of \a this array, so that
6839  * an element _x_ becomes \f$ numerator / x \f$.
6840  *  \warning If an exception is thrown because of presence of 0 element in \a this 
6841  *           array, all elements processed before detection of the zero element remain
6842  *           modified.
6843  *  \param [in] numerator - the numerator used to modify array elements.
6844  *  \throw If \a this is not allocated.
6845  *  \throw If there is an element equal to 0 in \a this array.
6846  */
6847 void DataArrayInt::applyInv(int numerator)
6848 {
6849   checkAllocated();
6850   int *ptr=getPointer();
6851   std::size_t nbOfElems=getNbOfElems();
6852   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
6853     {
6854       if(*ptr!=0)
6855         {
6856           *ptr=numerator/(*ptr);
6857         }
6858       else
6859         {
6860           std::ostringstream oss; oss << "DataArrayInt::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
6861           oss << " !";
6862           throw INTERP_KERNEL::Exception(oss.str().c_str());
6863         }
6864     }
6865   declareAsNew();
6866 }
6867
6868 /*!
6869  * Modify all elements of \a this array, so that
6870  * an element _x_ becomes \f$ x / val \f$.
6871  *  \param [in] val - the denominator used to modify array elements.
6872  *  \throw If \a this is not allocated.
6873  *  \throw If \a val == 0.
6874  */
6875 void DataArrayInt::applyDivideBy(int val)
6876 {
6877   if(val==0)
6878     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to divide by 0 !");
6879   checkAllocated();
6880   int *ptr=getPointer();
6881   std::size_t nbOfElems=getNbOfElems();
6882   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::divides<int>(),val));
6883   declareAsNew();
6884 }
6885
6886 /*!
6887  * Modify all elements of \a this array, so that
6888  * an element _x_ becomes  <em> x % val </em>.
6889  *  \param [in] val - the divisor used to modify array elements.
6890  *  \throw If \a this is not allocated.
6891  *  \throw If \a val <= 0.
6892  */
6893 void DataArrayInt::applyModulus(int val)
6894 {
6895   if(val<=0)
6896     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to operate modulus on value <= 0 !");
6897   checkAllocated();
6898   int *ptr=getPointer();
6899   std::size_t nbOfElems=getNbOfElems();
6900   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::modulus<int>(),val));
6901   declareAsNew();
6902 }
6903
6904 /*!
6905  * This method works only on data array with one component.
6906  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
6907  * this[*id] in [\b vmin,\b vmax)
6908  * 
6909  * \param [in] vmin begin of range. This value is included in range (included).
6910  * \param [in] vmax end of range. This value is \b not included in range (excluded).
6911  * \return a newly allocated data array that the caller should deal with.
6912  *
6913  * \sa DataArrayInt::findIdsNotInRange , DataArrayInt::findIdsStricltyNegative
6914  */
6915 DataArrayInt *DataArrayInt::findIdsInRange(int vmin, int vmax) const
6916 {
6917   checkAllocated();
6918   if(getNumberOfComponents()!=1)
6919     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsInRange : this must have exactly one component !");
6920   const int *cptr(begin());
6921   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6922   int nbOfTuples(getNumberOfTuples());
6923   for(int i=0;i<nbOfTuples;i++,cptr++)
6924     if(*cptr>=vmin && *cptr<vmax)
6925       ret->pushBackSilent(i);
6926   return ret.retn();
6927 }
6928
6929 /*!
6930  * This method works only on data array with one component.
6931  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
6932  * this[*id] \b not in [\b vmin,\b vmax)
6933  * 
6934  * \param [in] vmin begin of range. This value is \b not included in range (excluded).
6935  * \param [in] vmax end of range. This value is included in range (included).
6936  * \return a newly allocated data array that the caller should deal with.
6937  * 
6938  * \sa DataArrayInt::findIdsInRange , DataArrayInt::findIdsStricltyNegative
6939  */
6940 DataArrayInt *DataArrayInt::findIdsNotInRange(int vmin, int vmax) const
6941 {
6942   checkAllocated();
6943   if(getNumberOfComponents()!=1)
6944     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotInRange : this must have exactly one component !");
6945   const int *cptr(getConstPointer());
6946   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6947   int nbOfTuples(getNumberOfTuples());
6948   for(int i=0;i<nbOfTuples;i++,cptr++)
6949     if(*cptr<vmin || *cptr>=vmax)
6950       ret->pushBackSilent(i);
6951   return ret.retn();
6952 }
6953
6954 /*!
6955  * 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.
6956  *
6957  * \return a newly allocated data array that the caller should deal with.
6958  * \sa DataArrayInt::findIdsInRange
6959  */
6960 DataArrayInt *DataArrayInt::findIdsStricltyNegative() const
6961 {
6962   checkAllocated();
6963   if(getNumberOfComponents()!=1)
6964     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsStricltyNegative : this must have exactly one component !");
6965   const int *cptr(getConstPointer());
6966   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6967   int nbOfTuples(getNumberOfTuples());
6968   for(int i=0;i<nbOfTuples;i++,cptr++)
6969     if(*cptr<0)
6970       ret->pushBackSilent(i);
6971   return ret.retn();
6972 }
6973
6974 /*!
6975  * This method works only on data array with one component.
6976  * 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.
6977  * 
6978  * \param [in] vmin begin of range. This value is included in range (included).
6979  * \param [in] vmax end of range. This value is \b not included in range (excluded).
6980  * \return if all ids in \a this are so that (*this)[i]==i for all i in [ 0, \c this->getNumberOfTuples() ). */
6981 bool DataArrayInt::checkAllIdsInRange(int vmin, int vmax) const
6982 {
6983   checkAllocated();
6984   if(getNumberOfComponents()!=1)
6985     throw INTERP_KERNEL::Exception("DataArrayInt::checkAllIdsInRange : this must have exactly one component !");
6986   int nbOfTuples=getNumberOfTuples();
6987   bool ret=true;
6988   const int *cptr=getConstPointer();
6989   for(int i=0;i<nbOfTuples;i++,cptr++)
6990     {
6991       if(*cptr>=vmin && *cptr<vmax)
6992         { ret=ret && *cptr==i; }
6993       else
6994         {
6995           std::ostringstream oss; oss << "DataArrayInt::checkAllIdsInRange : tuple #" << i << " has value " << *cptr << " should be in [" << vmin << "," << vmax << ") !";
6996           throw INTERP_KERNEL::Exception(oss.str().c_str());
6997         }
6998     }
6999   return ret;
7000 }
7001
7002 /*!
7003  * Modify all elements of \a this array, so that
7004  * an element _x_ becomes <em> val % x </em>.
7005  *  \warning If an exception is thrown because of presence of an element <= 0 in \a this 
7006  *           array, all elements processed before detection of the zero element remain
7007  *           modified.
7008  *  \param [in] val - the divident used to modify array elements.
7009  *  \throw If \a this is not allocated.
7010  *  \throw If there is an element equal to or less than 0 in \a this array.
7011  */
7012 void DataArrayInt::applyRModulus(int val)
7013 {
7014   checkAllocated();
7015   int *ptr=getPointer();
7016   std::size_t nbOfElems=getNbOfElems();
7017   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
7018     {
7019       if(*ptr>0)
7020         {
7021           *ptr=val%(*ptr);
7022         }
7023       else
7024         {
7025           std::ostringstream oss; oss << "DataArrayInt::applyRModulus : presence of value <=0 in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
7026           oss << " !";
7027           throw INTERP_KERNEL::Exception(oss.str().c_str());
7028         }
7029     }
7030   declareAsNew();
7031 }
7032
7033 /*!
7034  * Modify all elements of \a this array, so that
7035  * an element _x_ becomes <em> val ^ x </em>.
7036  *  \param [in] val - the value used to apply pow on all array elements.
7037  *  \throw If \a this is not allocated.
7038  *  \throw If \a val < 0.
7039  */
7040 void DataArrayInt::applyPow(int val)
7041 {
7042   checkAllocated();
7043   if(val<0)
7044     throw INTERP_KERNEL::Exception("DataArrayInt::applyPow : input pow in < 0 !");
7045   int *ptr=getPointer();
7046   std::size_t nbOfElems=getNbOfElems();
7047   if(val==0)
7048     {
7049       std::fill(ptr,ptr+nbOfElems,1);
7050       return ;
7051     }
7052   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
7053     {
7054       int tmp=1;
7055       for(int j=0;j<val;j++)
7056         tmp*=*ptr;
7057       *ptr=tmp;
7058     }
7059   declareAsNew();
7060 }
7061
7062 /*!
7063  * Modify all elements of \a this array, so that
7064  * an element _x_ becomes \f$ val ^ x \f$.
7065  *  \param [in] val - the value used to apply pow on all array elements.
7066  *  \throw If \a this is not allocated.
7067  *  \throw If there is an element < 0 in \a this array.
7068  *  \warning If an exception is thrown because of presence of 0 element in \a this 
7069  *           array, all elements processed before detection of the zero element remain
7070  *           modified.
7071  */
7072 void DataArrayInt::applyRPow(int val)
7073 {
7074   checkAllocated();
7075   int *ptr=getPointer();
7076   std::size_t nbOfElems=getNbOfElems();
7077   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
7078     {
7079       if(*ptr>=0)
7080         {
7081           int tmp=1;
7082           for(int j=0;j<*ptr;j++)
7083             tmp*=val;
7084           *ptr=tmp;
7085         }
7086       else
7087         {
7088           std::ostringstream oss; oss << "DataArrayInt::applyRPow : presence of negative value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
7089           oss << " !";
7090           throw INTERP_KERNEL::Exception(oss.str().c_str());
7091         }
7092     }
7093   declareAsNew();
7094 }
7095
7096 /*!
7097  * Returns a new DataArrayInt by aggregating two given arrays, so that (1) the number
7098  * of components in the result array is a sum of the number of components of given arrays
7099  * and (2) the number of tuples in the result array is same as that of each of given
7100  * arrays. In other words the i-th tuple of result array includes all components of
7101  * i-th tuples of all given arrays.
7102  * Number of tuples in the given arrays must be the same.
7103  *  \param [in] a1 - an array to include in the result array.
7104  *  \param [in] a2 - another array to include in the result array.
7105  *  \return DataArrayInt * - the new instance of DataArrayInt.
7106  *          The caller is to delete this result array using decrRef() as it is no more
7107  *          needed.
7108  *  \throw If both \a a1 and \a a2 are NULL.
7109  *  \throw If any given array is not allocated.
7110  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
7111  */
7112 DataArrayInt *DataArrayInt::Meld(const DataArrayInt *a1, const DataArrayInt *a2)
7113 {
7114   std::vector<const DataArrayInt *> arr(2);
7115   arr[0]=a1; arr[1]=a2;
7116   return Meld(arr);
7117 }
7118
7119 /*!
7120  * Returns a new DataArrayInt by aggregating all 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] arr - a sequence of arrays to include in the result array.
7127  *  \return DataArrayInt * - the new instance of DataArrayInt.
7128  *          The caller is to delete this result array using decrRef() as it is no more
7129  *          needed.
7130  *  \throw If all arrays within \a arr are NULL.
7131  *  \throw If any given array is not allocated.
7132  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
7133  */
7134 DataArrayInt *DataArrayInt::Meld(const std::vector<const DataArrayInt *>& arr)
7135 {
7136   std::vector<const DataArrayInt *> a;
7137   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
7138     if(*it4)
7139       a.push_back(*it4);
7140   if(a.empty())
7141     throw INTERP_KERNEL::Exception("DataArrayInt::Meld : array must be NON empty !");
7142   std::vector<const DataArrayInt *>::const_iterator it;
7143   for(it=a.begin();it!=a.end();it++)
7144     (*it)->checkAllocated();
7145   it=a.begin();
7146   int nbOfTuples=(*it)->getNumberOfTuples();
7147   std::vector<int> nbc(a.size());
7148   std::vector<const int *> pts(a.size());
7149   nbc[0]=(*it)->getNumberOfComponents();
7150   pts[0]=(*it++)->getConstPointer();
7151   for(int i=1;it!=a.end();it++,i++)
7152     {
7153       if(nbOfTuples!=(*it)->getNumberOfTuples())
7154         throw INTERP_KERNEL::Exception("DataArrayInt::meld : mismatch of number of tuples !");
7155       nbc[i]=(*it)->getNumberOfComponents();
7156       pts[i]=(*it)->getConstPointer();
7157     }
7158   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
7159   DataArrayInt *ret=DataArrayInt::New();
7160   ret->alloc(nbOfTuples,totalNbOfComp);
7161   int *retPtr=ret->getPointer();
7162   for(int i=0;i<nbOfTuples;i++)
7163     for(int j=0;j<(int)a.size();j++)
7164       {
7165         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
7166         pts[j]+=nbc[j];
7167       }
7168   int k=0;
7169   for(int i=0;i<(int)a.size();i++)
7170     for(int j=0;j<nbc[i];j++,k++)
7171       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j));
7172   return ret;
7173 }
7174
7175 /*!
7176  * Returns a new DataArrayInt which is a minimal partition of elements of \a groups.
7177  * The i-th item of the result array is an ID of a set of elements belonging to a
7178  * unique set of groups, which the i-th element is a part of. This set of elements
7179  * belonging to a unique set of groups is called \a family, so the result array contains
7180  * IDs of families each element belongs to.
7181  *
7182  * \b Example: if we have two groups of elements: \a group1 [0,4] and \a group2 [ 0,1,2 ],
7183  * then there are 3 families:
7184  * - \a family1 (with ID 1) contains element [0] belonging to ( \a group1 + \a group2 ),
7185  * - \a family2 (with ID 2) contains elements [4] belonging to ( \a group1 ),
7186  * - \a family3 (with ID 3) contains element [1,2] belonging to ( \a group2 ), <br>
7187  * and the result array contains IDs of families [ 1,3,3,0,2 ]. <br> Note a family ID 0 which
7188  * stands for the element #3 which is in none of groups.
7189  *
7190  *  \param [in] groups - sequence of groups of element IDs.
7191  *  \param [in] newNb - total number of elements; it must be more than max ID of element
7192  *         in \a groups.
7193  *  \param [out] fidsOfGroups - IDs of families the elements of each group belong to.
7194  *  \return DataArrayInt * - a new instance of DataArrayInt containing IDs of families
7195  *         each element with ID from range [0, \a newNb ) belongs to. The caller is to
7196  *         delete this array using decrRef() as it is no more needed.
7197  *  \throw If any element ID in \a groups violates condition ( 0 <= ID < \a newNb ).
7198  */
7199 DataArrayInt *DataArrayInt::MakePartition(const std::vector<const DataArrayInt *>& groups, int newNb, std::vector< std::vector<int> >& fidsOfGroups)
7200 {
7201   std::vector<const DataArrayInt *> groups2;
7202   for(std::vector<const DataArrayInt *>::const_iterator it4=groups.begin();it4!=groups.end();it4++)
7203     if(*it4)
7204       groups2.push_back(*it4);
7205   MCAuto<DataArrayInt> ret=DataArrayInt::New();
7206   ret->alloc(newNb,1);
7207   int *retPtr=ret->getPointer();
7208   std::fill(retPtr,retPtr+newNb,0);
7209   int fid=1;
7210   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++)
7211     {
7212       const int *ptr=(*iter)->getConstPointer();
7213       std::size_t nbOfElem=(*iter)->getNbOfElems();
7214       int sfid=fid;
7215       for(int j=0;j<sfid;j++)
7216         {
7217           bool found=false;
7218           for(std::size_t i=0;i<nbOfElem;i++)
7219             {
7220               if(ptr[i]>=0 && ptr[i]<newNb)
7221                 {
7222                   if(retPtr[ptr[i]]==j)
7223                     {
7224                       retPtr[ptr[i]]=fid;
7225                       found=true;
7226                     }
7227                 }
7228               else
7229                 {
7230                   std::ostringstream oss; oss << "DataArrayInt::MakePartition : In group \"" << (*iter)->getName() << "\" in tuple #" << i << " value = " << ptr[i] << " ! Should be in [0," << newNb;
7231                   oss << ") !";
7232                   throw INTERP_KERNEL::Exception(oss.str().c_str());
7233                 }
7234             }
7235           if(found)
7236             fid++;
7237         }
7238     }
7239   fidsOfGroups.clear();
7240   fidsOfGroups.resize(groups2.size());
7241   int grId=0;
7242   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++,grId++)
7243     {
7244       std::set<int> tmp;
7245       const int *ptr=(*iter)->getConstPointer();
7246       std::size_t nbOfElem=(*iter)->getNbOfElems();
7247       for(const int *p=ptr;p!=ptr+nbOfElem;p++)
7248         tmp.insert(retPtr[*p]);
7249       fidsOfGroups[grId].insert(fidsOfGroups[grId].end(),tmp.begin(),tmp.end());
7250     }
7251   return ret.retn();
7252 }
7253
7254 /*!
7255  * Returns a new DataArrayInt which contains all elements of given one-dimensional
7256  * arrays. The result array does not contain any duplicates and its values
7257  * are sorted in ascending order.
7258  *  \param [in] arr - sequence of DataArrayInt's to unite.
7259  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7260  *         array using decrRef() as it is no more needed.
7261  *  \throw If any \a arr[i] is not allocated.
7262  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
7263  */
7264 DataArrayInt *DataArrayInt::BuildUnion(const std::vector<const DataArrayInt *>& arr)
7265 {
7266   std::vector<const DataArrayInt *> a;
7267   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
7268     if(*it4)
7269       a.push_back(*it4);
7270   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
7271     {
7272       (*it)->checkAllocated();
7273       if((*it)->getNumberOfComponents()!=1)
7274         throw INTERP_KERNEL::Exception("DataArrayInt::BuildUnion : only single component allowed !");
7275     }
7276   //
7277   std::set<int> r;
7278   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
7279     {
7280       const int *pt=(*it)->getConstPointer();
7281       int nbOfTuples=(*it)->getNumberOfTuples();
7282       r.insert(pt,pt+nbOfTuples);
7283     }
7284   DataArrayInt *ret=DataArrayInt::New();
7285   ret->alloc((int)r.size(),1);
7286   std::copy(r.begin(),r.end(),ret->getPointer());
7287   return ret;
7288 }
7289
7290 /*!
7291  * Returns a new DataArrayInt which contains elements present in each of given one-dimensional
7292  * arrays. The result array does not contain any duplicates and its values
7293  * are sorted in ascending order.
7294  *  \param [in] arr - sequence of DataArrayInt's to intersect.
7295  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7296  *         array using decrRef() as it is no more needed.
7297  *  \throw If any \a arr[i] is not allocated.
7298  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
7299  */
7300 DataArrayInt *DataArrayInt::BuildIntersection(const std::vector<const DataArrayInt *>& arr)
7301 {
7302   std::vector<const DataArrayInt *> a;
7303   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
7304     if(*it4)
7305       a.push_back(*it4);
7306   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
7307     {
7308       (*it)->checkAllocated();
7309       if((*it)->getNumberOfComponents()!=1)
7310         throw INTERP_KERNEL::Exception("DataArrayInt::BuildIntersection : only single component allowed !");
7311     }
7312   //
7313   std::set<int> r;
7314   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
7315     {
7316       const int *pt=(*it)->getConstPointer();
7317       int nbOfTuples=(*it)->getNumberOfTuples();
7318       std::set<int> s1(pt,pt+nbOfTuples);
7319       if(it!=a.begin())
7320         {
7321           std::set<int> r2;
7322           std::set_intersection(r.begin(),r.end(),s1.begin(),s1.end(),inserter(r2,r2.end()));
7323           r=r2;
7324         }
7325       else
7326         r=s1;
7327     }
7328   DataArrayInt *ret(DataArrayInt::New());
7329   ret->alloc((int)r.size(),1);
7330   std::copy(r.begin(),r.end(),ret->getPointer());
7331   return ret;
7332 }
7333
7334 /// @cond INTERNAL
7335 namespace MEDCouplingImpl
7336 {
7337   class OpSwitchedOn
7338   {
7339   public:
7340     OpSwitchedOn(int *pt):_pt(pt),_cnt(0) { }
7341     void operator()(const bool& b) { if(b) *_pt++=_cnt; _cnt++; }
7342   private:
7343     int *_pt;
7344     int _cnt;
7345   };
7346
7347   class OpSwitchedOff
7348   {
7349   public:
7350     OpSwitchedOff(int *pt):_pt(pt),_cnt(0) { }
7351     void operator()(const bool& b) { if(!b) *_pt++=_cnt; _cnt++; }
7352   private:
7353     int *_pt;
7354     int _cnt;
7355   };
7356 }
7357 /// @endcond
7358
7359 /*!
7360  * This method returns the list of ids in ascending mode so that v[id]==true.
7361  */
7362 DataArrayInt *DataArrayInt::BuildListOfSwitchedOn(const std::vector<bool>& v)
7363 {
7364   int sz((int)std::count(v.begin(),v.end(),true));
7365   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
7366   std::for_each(v.begin(),v.end(),MEDCouplingImpl::OpSwitchedOn(ret->getPointer()));
7367   return ret.retn();
7368 }
7369
7370 /*!
7371  * This method returns the list of ids in ascending mode so that v[id]==false.
7372  */
7373 DataArrayInt *DataArrayInt::BuildListOfSwitchedOff(const std::vector<bool>& v)
7374 {
7375   int sz((int)std::count(v.begin(),v.end(),false));
7376   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
7377   std::for_each(v.begin(),v.end(),MEDCouplingImpl::OpSwitchedOff(ret->getPointer()));
7378   return ret.retn();
7379 }
7380
7381 /*!
7382  * This method allows to put a vector of vector of integer into a more compact data stucture (skyline). 
7383  * This method is not available into python because no available optimized data structure available to map std::vector< std::vector<int> >.
7384  *
7385  * \param [in] v the input data structure to be translate into skyline format.
7386  * \param [out] data the first element of the skyline format. The user is expected to deal with newly allocated array.
7387  * \param [out] dataIndex the second element of the skyline format.
7388  */
7389 void DataArrayInt::PutIntoToSkylineFrmt(const std::vector< std::vector<int> >& v, DataArrayInt *& data, DataArrayInt *& dataIndex)
7390 {
7391   int sz((int)v.size());
7392   MCAuto<DataArrayInt> ret0(DataArrayInt::New()),ret1(DataArrayInt::New());
7393   ret1->alloc(sz+1,1);
7394   int *pt(ret1->getPointer()); *pt=0;
7395   for(int i=0;i<sz;i++,pt++)
7396     pt[1]=pt[0]+(int)v[i].size();
7397   ret0->alloc(ret1->back(),1);
7398   pt=ret0->getPointer();
7399   for(int i=0;i<sz;i++)
7400     pt=std::copy(v[i].begin(),v[i].end(),pt);
7401   data=ret0.retn(); dataIndex=ret1.retn();
7402 }
7403
7404 /*!
7405  * Returns a new DataArrayInt which contains a complement of elements of \a this
7406  * one-dimensional array. I.e. the result array contains all elements from the range [0,
7407  * \a nbOfElement) not present in \a this array.
7408  *  \param [in] nbOfElement - maximal size of the result array.
7409  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7410  *         array using decrRef() as it is no more needed.
7411  *  \throw If \a this is not allocated.
7412  *  \throw If \a this->getNumberOfComponents() != 1.
7413  *  \throw If any element \a x of \a this array violates condition ( 0 <= \a x < \a
7414  *         nbOfElement ).
7415  */
7416 DataArrayInt *DataArrayInt::buildComplement(int nbOfElement) const
7417 {
7418   checkAllocated();
7419   if(getNumberOfComponents()!=1)
7420     throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : only single component allowed !");
7421   std::vector<bool> tmp(nbOfElement);
7422   const int *pt=getConstPointer();
7423   int nbOfTuples=getNumberOfTuples();
7424   for(const int *w=pt;w!=pt+nbOfTuples;w++)
7425     if(*w>=0 && *w<nbOfElement)
7426       tmp[*w]=true;
7427     else
7428       throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : an element is not in valid range : [0,nbOfElement) !");
7429   int nbOfRetVal=(int)std::count(tmp.begin(),tmp.end(),false);
7430   DataArrayInt *ret=DataArrayInt::New();
7431   ret->alloc(nbOfRetVal,1);
7432   int j=0;
7433   int *retPtr=ret->getPointer();
7434   for(int i=0;i<nbOfElement;i++)
7435     if(!tmp[i])
7436       retPtr[j++]=i;
7437   return ret;
7438 }
7439
7440 /*!
7441  * Returns a new DataArrayInt containing elements of \a this one-dimensional missing
7442  * from an \a other one-dimensional array.
7443  *  \param [in] other - a DataArrayInt containing elements not to include in the result array.
7444  *  \return DataArrayInt * - a new instance of DataArrayInt with one component. The
7445  *         caller is to delete this array using decrRef() as it is no more needed.
7446  *  \throw If \a other is NULL.
7447  *  \throw If \a other is not allocated.
7448  *  \throw If \a other->getNumberOfComponents() != 1.
7449  *  \throw If \a this is not allocated.
7450  *  \throw If \a this->getNumberOfComponents() != 1.
7451  *  \sa DataArrayInt::buildSubstractionOptimized()
7452  */
7453 DataArrayInt *DataArrayInt::buildSubstraction(const DataArrayInt *other) const
7454 {
7455   if(!other)
7456     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : DataArrayInt pointer in input is NULL !");
7457   checkAllocated();
7458   other->checkAllocated();
7459   if(getNumberOfComponents()!=1)
7460     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed !");
7461   if(other->getNumberOfComponents()!=1)
7462     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed for other type !");
7463   const int *pt=getConstPointer();
7464   int nbOfTuples=getNumberOfTuples();
7465   std::set<int> s1(pt,pt+nbOfTuples);
7466   pt=other->getConstPointer();
7467   nbOfTuples=other->getNumberOfTuples();
7468   std::set<int> s2(pt,pt+nbOfTuples);
7469   std::vector<int> r;
7470   std::set_difference(s1.begin(),s1.end(),s2.begin(),s2.end(),std::back_insert_iterator< std::vector<int> >(r));
7471   DataArrayInt *ret=DataArrayInt::New();
7472   ret->alloc((int)r.size(),1);
7473   std::copy(r.begin(),r.end(),ret->getPointer());
7474   return ret;
7475 }
7476
7477 /*!
7478  * \a this is expected to have one component and to be sorted ascendingly (as for \a other).
7479  * \a other is expected to be a part of \a this. If not DataArrayInt::buildSubstraction should be called instead.
7480  * 
7481  * \param [in] other an array with one component and expected to be sorted ascendingly.
7482  * \ret list of ids in \a this but not in \a other.
7483  * \sa DataArrayInt::buildSubstraction
7484  */
7485 DataArrayInt *DataArrayInt::buildSubstractionOptimized(const DataArrayInt *other) const
7486 {
7487   static const char *MSG="DataArrayInt::buildSubstractionOptimized : only single component allowed !";
7488   if(!other) throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstractionOptimized : NULL input array !");
7489   checkAllocated(); other->checkAllocated();
7490   if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
7491   if(other->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
7492   const int *pt1Bg(begin()),*pt1End(end()),*pt2Bg(other->begin()),*pt2End(other->end());
7493   const int *work1(pt1Bg),*work2(pt2Bg);
7494   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
7495   for(;work1!=pt1End;work1++)
7496     {
7497       if(work2!=pt2End && *work1==*work2)
7498         work2++;
7499       else
7500         ret->pushBackSilent(*work1);
7501     }
7502   return ret.retn();
7503 }
7504
7505
7506 /*!
7507  * Returns a new DataArrayInt which contains all elements of \a this and a given
7508  * one-dimensional arrays. The result array does not contain any duplicates
7509  * and its values are sorted in ascending order.
7510  *  \param [in] other - an array to unite with \a this one.
7511  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7512  *         array using decrRef() as it is no more needed.
7513  *  \throw If \a this or \a other is not allocated.
7514  *  \throw If \a this->getNumberOfComponents() != 1.
7515  *  \throw If \a other->getNumberOfComponents() != 1.
7516  */
7517 DataArrayInt *DataArrayInt::buildUnion(const DataArrayInt *other) const
7518 {
7519   std::vector<const DataArrayInt *>arrs(2);
7520   arrs[0]=this; arrs[1]=other;
7521   return BuildUnion(arrs);
7522 }
7523
7524
7525 /*!
7526  * Returns a new DataArrayInt which contains elements present in both \a this and a given
7527  * one-dimensional arrays. The result array does not contain any duplicates
7528  * and its values are sorted in ascending order.
7529  *  \param [in] other - an array to intersect with \a this one.
7530  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7531  *         array using decrRef() as it is no more needed.
7532  *  \throw If \a this or \a other is not allocated.
7533  *  \throw If \a this->getNumberOfComponents() != 1.
7534  *  \throw If \a other->getNumberOfComponents() != 1.
7535  */
7536 DataArrayInt *DataArrayInt::buildIntersection(const DataArrayInt *other) const
7537 {
7538   std::vector<const DataArrayInt *>arrs(2);
7539   arrs[0]=this; arrs[1]=other;
7540   return BuildIntersection(arrs);
7541 }
7542
7543 /*!
7544  * This method can be applied on allocated with one component DataArrayInt instance.
7545  * This method is typically relevant for sorted arrays. All consecutive duplicated items in \a this will appear only once in returned DataArrayInt instance.
7546  * 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]
7547  * 
7548  * \return a newly allocated array that contain the result of the unique operation applied on \a this.
7549  * \throw if \a this is not allocated or if \a this has not exactly one component.
7550  * \sa DataArrayInt::buildUniqueNotSorted
7551  */
7552 DataArrayInt *DataArrayInt::buildUnique() const
7553 {
7554   checkAllocated();
7555   if(getNumberOfComponents()!=1)
7556     throw INTERP_KERNEL::Exception("DataArrayInt::buildUnique : only single component allowed !");
7557   int nbOfTuples=getNumberOfTuples();
7558   MCAuto<DataArrayInt> tmp=deepCopy();
7559   int *data=tmp->getPointer();
7560   int *last=std::unique(data,data+nbOfTuples);
7561   MCAuto<DataArrayInt> ret=DataArrayInt::New();
7562   ret->alloc(std::distance(data,last),1);
7563   std::copy(data,last,ret->getPointer());
7564   return ret.retn();
7565 }
7566
7567 /*!
7568  * This method can be applied on allocated with one component DataArrayInt instance.
7569  * This method keep elements only once by keeping the same order in \a this that is not expected to be sorted.
7570  *
7571  * \return a newly allocated array that contain the result of the unique operation applied on \a this.
7572  *
7573  * \throw if \a this is not allocated or if \a this has not exactly one component.
7574  *
7575  * \sa DataArrayInt::buildUnique
7576  */
7577 DataArrayInt *DataArrayInt::buildUniqueNotSorted() const
7578 {
7579   checkAllocated();
7580     if(getNumberOfComponents()!=1)
7581       throw INTERP_KERNEL::Exception("DataArrayInt::buildUniqueNotSorted : only single component allowed !");
7582   int minVal,maxVal;
7583   getMinMaxValues(minVal,maxVal);
7584   std::vector<bool> b(maxVal-minVal+1,false);
7585   const int *ptBg(begin()),*endBg(end());
7586   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
7587   for(const int *pt=ptBg;pt!=endBg;pt++)
7588     {
7589       if(!b[*pt-minVal])
7590         {
7591           ret->pushBackSilent(*pt);
7592           b[*pt-minVal]=true;
7593         }
7594     }
7595   ret->copyStringInfoFrom(*this);
7596   return ret.retn();
7597 }
7598
7599 /*!
7600  * Returns a new DataArrayInt which contains size of every of groups described by \a this
7601  * "index" array. Such "index" array is returned for example by 
7602  * \ref MEDCoupling::MEDCouplingUMesh::buildDescendingConnectivity
7603  * "MEDCouplingUMesh::buildDescendingConnectivity" and
7604  * \ref MEDCoupling::MEDCouplingUMesh::getNodalConnectivityIndex
7605  * "MEDCouplingUMesh::getNodalConnectivityIndex" etc.
7606  * This method preforms the reverse operation of DataArrayInt::computeOffsetsFull.
7607  *  \return DataArrayInt * - a new instance of DataArrayInt, whose number of tuples
7608  *          equals to \a this->getNumberOfComponents() - 1, and number of components is 1.
7609  *          The caller is to delete this array using decrRef() as it is no more needed. 
7610  *  \throw If \a this is not allocated.
7611  *  \throw If \a this->getNumberOfComponents() != 1.
7612  *  \throw If \a this->getNumberOfTuples() < 2.
7613  *
7614  *  \b Example: <br> 
7615  *         - this contains [1,3,6,7,7,9,15]
7616  *         - result array contains [2,3,1,0,2,6],
7617  *          where 2 = 3 - 1, 3 = 6 - 3, 1 = 7 - 6 etc.
7618  *
7619  * \sa DataArrayInt::computeOffsetsFull
7620  */
7621 DataArrayInt *DataArrayInt::deltaShiftIndex() const
7622 {
7623   checkAllocated();
7624   if(getNumberOfComponents()!=1)
7625     throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : only single component allowed !");
7626   int nbOfTuples=getNumberOfTuples();
7627   if(nbOfTuples<2)
7628     throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : 1 tuple at least must be present in 'this' !");
7629   const int *ptr=getConstPointer();
7630   DataArrayInt *ret=DataArrayInt::New();
7631   ret->alloc(nbOfTuples-1,1);
7632   int *out=ret->getPointer();
7633   std::transform(ptr+1,ptr+nbOfTuples,ptr,out,std::minus<int>());
7634   return ret;
7635 }
7636
7637 /*!
7638  * Modifies \a this one-dimensional array so that value of each element \a x
7639  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
7640  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number of tuples
7641  * and components remains the same.<br>
7642  * This method is useful for allToAllV in MPI with contiguous policy. This method
7643  * differs from computeOffsetsFull() in that the number of tuples is \b not changed by
7644  * this one.
7645  *  \throw If \a this is not allocated.
7646  *  \throw If \a this->getNumberOfComponents() != 1.
7647  *
7648  *  \b Example: <br>
7649  *          - Before \a this contains [3,5,1,2,0,8]
7650  *          - After \a this contains  [0,3,8,9,11,11]<br>
7651  *          Note that the last element 19 = 11 + 8 is missing because size of \a this
7652  *          array is retained and thus there is no space to store the last element.
7653  */
7654 void DataArrayInt::computeOffsets()
7655 {
7656   checkAllocated();
7657   if(getNumberOfComponents()!=1)
7658     throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets : only single component allowed !");
7659   int nbOfTuples=getNumberOfTuples();
7660   if(nbOfTuples==0)
7661     return ;
7662   int *work=getPointer();
7663   int tmp=work[0];
7664   work[0]=0;
7665   for(int i=1;i<nbOfTuples;i++)
7666     {
7667       int tmp2=work[i];
7668       work[i]=work[i-1]+tmp;
7669       tmp=tmp2;
7670     }
7671   declareAsNew();
7672 }
7673
7674
7675 /*!
7676  * Modifies \a this one-dimensional array so that value of each element \a x
7677  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
7678  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number
7679  * components remains the same and number of tuples is inceamented by one.<br>
7680  * This method is useful for allToAllV in MPI with contiguous policy. This method
7681  * differs from computeOffsets() in that the number of tuples is changed by this one.
7682  * This method preforms the reverse operation of DataArrayInt::deltaShiftIndex.
7683  *  \throw If \a this is not allocated.
7684  *  \throw If \a this->getNumberOfComponents() != 1.
7685  *
7686  *  \b Example: <br>
7687  *          - Before \a this contains [3,5,1,2,0,8]
7688  *          - After \a this contains  [0,3,8,9,11,11,19]<br>
7689  * \sa DataArrayInt::deltaShiftIndex
7690  */
7691 void DataArrayInt::computeOffsetsFull()
7692 {
7693   checkAllocated();
7694   if(getNumberOfComponents()!=1)
7695     throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsetsFull : only single component allowed !");
7696   int nbOfTuples=getNumberOfTuples();
7697   int *ret=(int *)malloc((nbOfTuples+1)*sizeof(int));
7698   const int *work=getConstPointer();
7699   ret[0]=0;
7700   for(int i=0;i<nbOfTuples;i++)
7701     ret[i+1]=work[i]+ret[i];
7702   useArray(ret,true,C_DEALLOC,nbOfTuples+1,1);
7703   declareAsNew();
7704 }
7705
7706 /*!
7707  * Returns two new DataArrayInt instances whose contents is computed from that of \a this and \a listOfIds arrays as follows.
7708  * \a this is expected to be an offset format ( as returned by DataArrayInt::computeOffsetsFull ) that is to say with one component
7709  * and ** sorted strictly increasingly **. \a listOfIds is expected to be sorted ascendingly (not strictly needed for \a listOfIds).
7710  * This methods searches in \a this, considered as a set of contiguous \c this->getNumberOfComponents() ranges, all ids in \a listOfIds
7711  * filling completely one of the ranges in \a this.
7712  *
7713  * \param [in] listOfIds a list of ids that has to be sorted ascendingly.
7714  * \param [out] rangeIdsFetched the range ids fetched
7715  * \param [out] idsInInputListThatFetch contains the list of ids in \a listOfIds that are \b fully included in a range in \a this. So
7716  *              \a idsInInputListThatFetch is a part of input \a listOfIds.
7717  *
7718  * \sa DataArrayInt::computeOffsetsFull
7719  *
7720  *  \b Example: <br>
7721  *          - \a this : [0,3,7,9,15,18]
7722  *          - \a listOfIds contains  [0,1,2,3,7,8,15,16,17]
7723  *          - \a rangeIdsFetched result array: [0,2,4]
7724  *          - \a idsInInputListThatFetch result array: [0,1,2,7,8,15,16,17]
7725  * In this example id 3 in input \a listOfIds is alone so it do not appear in output \a idsInInputListThatFetch.
7726  * <br>
7727  */
7728 void DataArrayInt::findIdsRangesInListOfIds(const DataArrayInt *listOfIds, DataArrayInt *& rangeIdsFetched, DataArrayInt *& idsInInputListThatFetch) const
7729 {
7730   if(!listOfIds)
7731     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : input list of ids is null !");
7732   listOfIds->checkAllocated(); checkAllocated();
7733   if(listOfIds->getNumberOfComponents()!=1)
7734     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : input list of ids must have exactly one component !");
7735   if(getNumberOfComponents()!=1)
7736     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : this must have exactly one component !");
7737   MCAuto<DataArrayInt> ret0=DataArrayInt::New(); ret0->alloc(0,1);
7738   MCAuto<DataArrayInt> ret1=DataArrayInt::New(); ret1->alloc(0,1);
7739   const int *tupEnd(listOfIds->end()),*offBg(begin()),*offEnd(end()-1);
7740   const int *tupPtr(listOfIds->begin()),*offPtr(offBg);
7741   while(tupPtr!=tupEnd && offPtr!=offEnd)
7742     {
7743       if(*tupPtr==*offPtr)
7744         {
7745           int i=offPtr[0];
7746           while(i<offPtr[1] && *tupPtr==i && tupPtr!=tupEnd) { i++; tupPtr++; }
7747           if(i==offPtr[1])
7748             {
7749               ret0->pushBackSilent((int)std::distance(offBg,offPtr));
7750               ret1->pushBackValsSilent(tupPtr-(offPtr[1]-offPtr[0]),tupPtr);
7751               offPtr++;
7752             }
7753         }
7754       else
7755         { if(*tupPtr<*offPtr) tupPtr++; else offPtr++; }
7756     }
7757   rangeIdsFetched=ret0.retn();
7758   idsInInputListThatFetch=ret1.retn();
7759 }
7760
7761 /*!
7762  * Returns a new DataArrayInt whose contents is computed from that of \a this and \a
7763  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
7764  * "index" array of a "iota" array, thus, whose each element gives an index of a group
7765  * beginning within the "iota" array. And \a this is a one-dimensional array
7766  * considered as a selector of groups described by \a offsets to include into the result array.
7767  *  \throw If \a offsets is NULL.
7768  *  \throw If \a offsets is not allocated.
7769  *  \throw If \a offsets->getNumberOfComponents() != 1.
7770  *  \throw If \a offsets is not monotonically increasing.
7771  *  \throw If \a this is not allocated.
7772  *  \throw If \a this->getNumberOfComponents() != 1.
7773  *  \throw If any element of \a this is not a valid index for \a offsets array.
7774  *
7775  *  \b Example: <br>
7776  *          - \a this: [0,2,3]
7777  *          - \a offsets: [0,3,6,10,14,20]
7778  *          - result array: [0,1,2,6,7,8,9,10,11,12,13] == <br>
7779  *            \c range(0,3) + \c range(6,10) + \c range(10,14) ==<br>
7780  *            \c range( \a offsets[ \a this[0] ], offsets[ \a this[0]+1 ]) + 
7781  *            \c range( \a offsets[ \a this[1] ], offsets[ \a this[1]+1 ]) + 
7782  *            \c range( \a offsets[ \a this[2] ], offsets[ \a this[2]+1 ])
7783  */
7784 DataArrayInt *DataArrayInt::buildExplicitArrByRanges(const DataArrayInt *offsets) const
7785 {
7786   if(!offsets)
7787     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : DataArrayInt pointer in input is NULL !");
7788   checkAllocated();
7789   if(getNumberOfComponents()!=1)
7790     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : only single component allowed !");
7791   offsets->checkAllocated();
7792   if(offsets->getNumberOfComponents()!=1)
7793     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : input array should have only single component !");
7794   int othNbTuples=offsets->getNumberOfTuples()-1;
7795   int nbOfTuples=getNumberOfTuples();
7796   int retNbOftuples=0;
7797   const int *work=getConstPointer();
7798   const int *offPtr=offsets->getConstPointer();
7799   for(int i=0;i<nbOfTuples;i++)
7800     {
7801       int val=work[i];
7802       if(val>=0 && val<othNbTuples)
7803         {
7804           int delta=offPtr[val+1]-offPtr[val];
7805           if(delta>=0)
7806             retNbOftuples+=delta;
7807           else
7808             {
7809               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << val << " of offset array has a delta < 0 !";
7810               throw INTERP_KERNEL::Exception(oss.str().c_str());
7811             }
7812         }
7813       else
7814         {
7815           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << i << " in this contains " << val;
7816           oss << " whereas offsets array is of size " << othNbTuples+1 << " !";
7817           throw INTERP_KERNEL::Exception(oss.str().c_str());
7818         }
7819     }
7820   MCAuto<DataArrayInt> ret=DataArrayInt::New();
7821   ret->alloc(retNbOftuples,1);
7822   int *retPtr=ret->getPointer();
7823   for(int i=0;i<nbOfTuples;i++)
7824     {
7825       int val=work[i];
7826       int start=offPtr[val];
7827       int off=offPtr[val+1]-start;
7828       for(int j=0;j<off;j++,retPtr++)
7829         *retPtr=start+j;
7830     }
7831   return ret.retn();
7832 }
7833
7834 /*!
7835  * Returns a new DataArrayInt whose contents is computed using \a this that must be a 
7836  * scaled array (monotonically increasing).
7837 from that of \a this and \a
7838  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
7839  * "index" array of a "iota" array, thus, whose each element gives an index of a group
7840  * beginning within the "iota" array. And \a this is a one-dimensional array
7841  * considered as a selector of groups described by \a offsets to include into the result array.
7842  *  \throw If \a  is NULL.
7843  *  \throw If \a this is not allocated.
7844  *  \throw If \a this->getNumberOfComponents() != 1.
7845  *  \throw If \a this->getNumberOfTuples() == 0.
7846  *  \throw If \a this is not monotonically increasing.
7847  *  \throw If any element of ids in ( \a bg \a stop \a step ) points outside the scale in \a this.
7848  *
7849  *  \b Example: <br>
7850  *          - \a bg , \a stop and \a step : (0,5,2)
7851  *          - \a this: [0,3,6,10,14,20]
7852  *          - result array: [0,0,0, 2,2,2,2, 4,4,4,4,4,4] == <br>
7853  */
7854 DataArrayInt *DataArrayInt::buildExplicitArrOfSliceOnScaledArr(int bg, int stop, int step) const
7855 {
7856   if(!isAllocated())
7857     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : not allocated array !");
7858   if(getNumberOfComponents()!=1)
7859     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of components is expected to be equal to one !");
7860   int nbOfTuples(getNumberOfTuples());
7861   if(nbOfTuples==0)
7862     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of tuples must be != 0 !");
7863   const int *ids(begin());
7864   int nbOfEltsInSlc(GetNumberOfItemGivenBESRelative(bg,stop,step,"DataArrayInt::buildExplicitArrOfSliceOnScaledArr")),sz(0),pos(bg);
7865   for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
7866     {
7867       if(pos>=0 && pos<nbOfTuples-1)
7868         {
7869           int delta(ids[pos+1]-ids[pos]);
7870           sz+=delta;
7871           if(delta<0)
7872             {
7873               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " and at this pos this is not monotonically increasing !";
7874               throw INTERP_KERNEL::Exception(oss.str().c_str());
7875             }          
7876         }
7877       else
7878         {
7879           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " should be in [0," << nbOfTuples-1 << ") !";  
7880           throw INTERP_KERNEL::Exception(oss.str().c_str());
7881         }
7882     }
7883   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
7884   int *retPtr(ret->getPointer());
7885   pos=bg;
7886   for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
7887     {
7888       int delta(ids[pos+1]-ids[pos]);
7889       for(int j=0;j<delta;j++,retPtr++)
7890         *retPtr=pos;
7891     }
7892   return ret.retn();
7893 }
7894
7895 /*!
7896  * 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.
7897  * 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
7898  * in tuple **i** of returned DataArrayInt.
7899  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the first range.
7900  *
7901  * 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)]
7902  * The return DataArrayInt will contain : **[0,4,1,2,2,3]**
7903  * 
7904  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
7905  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
7906  * \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
7907  *        is thrown if no ranges in \a ranges contains value in \a this.
7908  * 
7909  * \sa DataArrayInt::findIdInRangeForEachTuple
7910  */
7911 DataArrayInt *DataArrayInt::findRangeIdForEachTuple(const DataArrayInt *ranges) const
7912 {
7913   if(!ranges)
7914     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : null input pointer !");
7915   if(ranges->getNumberOfComponents()!=2)
7916     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : input DataArrayInt instance should have 2 components !");
7917   checkAllocated();
7918   if(getNumberOfComponents()!=1)
7919     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : this should have only one component !");
7920   int nbTuples=getNumberOfTuples();
7921   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
7922   int nbOfRanges=ranges->getNumberOfTuples();
7923   const int *rangesPtr=ranges->getConstPointer();
7924   int *retPtr=ret->getPointer();
7925   const int *inPtr=getConstPointer();
7926   for(int i=0;i<nbTuples;i++,retPtr++)
7927     {
7928       int val=inPtr[i];
7929       bool found=false;
7930       for(int j=0;j<nbOfRanges && !found;j++)
7931         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
7932           { *retPtr=j; found=true; }
7933       if(found)
7934         continue;
7935       else
7936         {
7937           std::ostringstream oss; oss << "DataArrayInt::findRangeIdForEachTuple : tuple #" << i << " not found by any ranges !";
7938           throw INTERP_KERNEL::Exception(oss.str().c_str());
7939         }
7940     }
7941   return ret.retn();
7942 }
7943
7944 /*!
7945  * 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.
7946  * 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
7947  * in tuple **i** of returned DataArrayInt.
7948  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the sub position of the first range.
7949  *
7950  * 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)]
7951  * The return DataArrayInt will contain : **[1,2,4,0,2,2]**
7952  * This method is often called in pair with DataArrayInt::findRangeIdForEachTuple method.
7953  * 
7954  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
7955  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
7956  * \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
7957  *        is thrown if no ranges in \a ranges contains value in \a this.
7958  * \sa DataArrayInt::findRangeIdForEachTuple
7959  */
7960 DataArrayInt *DataArrayInt::findIdInRangeForEachTuple(const DataArrayInt *ranges) const
7961 {
7962   if(!ranges)
7963     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : null input pointer !");
7964   if(ranges->getNumberOfComponents()!=2)
7965     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : input DataArrayInt instance should have 2 components !");
7966   checkAllocated();
7967   if(getNumberOfComponents()!=1)
7968     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : this should have only one component !");
7969   int nbTuples=getNumberOfTuples();
7970   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
7971   int nbOfRanges=ranges->getNumberOfTuples();
7972   const int *rangesPtr=ranges->getConstPointer();
7973   int *retPtr=ret->getPointer();
7974   const int *inPtr=getConstPointer();
7975   for(int i=0;i<nbTuples;i++,retPtr++)
7976     {
7977       int val=inPtr[i];
7978       bool found=false;
7979       for(int j=0;j<nbOfRanges && !found;j++)
7980         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
7981           { *retPtr=val-rangesPtr[2*j]; found=true; }
7982       if(found)
7983         continue;
7984       else
7985         {
7986           std::ostringstream oss; oss << "DataArrayInt::findIdInRangeForEachTuple : tuple #" << i << " not found by any ranges !";
7987           throw INTERP_KERNEL::Exception(oss.str().c_str());
7988         }
7989     }
7990   return ret.retn();
7991 }
7992
7993 /*!
7994  * \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).
7995  * 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).
7996  * 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 !
7997  * If this method has correctly worked, \a this will be able to be considered as a linked list.
7998  * This method does nothing if number of tuples is lower of equal to 1.
7999  *
8000  * This method is useful for users having an unstructured mesh having only SEG2 to rearrange internaly the connectibity without any coordinates consideration.
8001  *
8002  * \sa MEDCouplingUMesh::orderConsecutiveCells1D
8003  */
8004 void DataArrayInt::sortEachPairToMakeALinkedList()
8005 {
8006   checkAllocated();
8007   if(getNumberOfComponents()!=2)
8008     throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : Only works on DataArrayInt instance with nb of components equal to 2 !");
8009   int nbOfTuples(getNumberOfTuples());
8010   if(nbOfTuples<=1)
8011     return ;
8012   int *conn(getPointer());
8013   for(int i=1;i<nbOfTuples;i++,conn+=2)
8014     {
8015       if(i>1)
8016         {
8017           if(conn[2]==conn[3])
8018             {
8019               std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " presence of a pair filled with same ids !";
8020               throw INTERP_KERNEL::Exception(oss.str().c_str());
8021             }
8022           if(conn[2]!=conn[1] && conn[3]==conn[1] && conn[2]!=conn[0])
8023             std::swap(conn[2],conn[3]);
8024           //not(conn[2]==conn[1] && conn[3]!=conn[1] && conn[3]!=conn[0])
8025           if(conn[2]!=conn[1] || conn[3]==conn[1] || conn[3]==conn[0])
8026             {
8027               std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " something is invalid !";
8028               throw INTERP_KERNEL::Exception(oss.str().c_str());
8029             }
8030         }
8031       else
8032         {
8033           if(conn[0]==conn[1] || conn[2]==conn[3])
8034             throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : In the 2 first tuples presence of a pair filled with same ids !");
8035           int tmp[4];
8036           std::set<int> s;
8037           s.insert(conn,conn+4);
8038           if(s.size()!=3)
8039             throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : This can't be considered as a linked list regarding 2 first tuples !");
8040           if(std::count(conn,conn+4,conn[0])==2)
8041             {
8042               tmp[0]=conn[1];
8043               tmp[1]=conn[0];
8044               tmp[2]=conn[0];
8045               if(conn[2]==conn[0])
8046                 { tmp[3]=conn[3]; }
8047               else
8048                 { tmp[3]=conn[2];}
8049               std::copy(tmp,tmp+4,conn);
8050             }
8051           else
8052             {//here we are sure to have (std::count(conn,conn+4,conn[1])==2)
8053               if(conn[1]==conn[3])
8054                 std::swap(conn[2],conn[3]);
8055             }
8056         }
8057     }
8058 }
8059
8060 /*!
8061  * 
8062  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayInt instance.
8063  *             \a nbTimes  should be at least equal to 1.
8064  * \return a newly allocated DataArrayInt having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
8065  * \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.
8066  */
8067 DataArrayInt *DataArrayInt::duplicateEachTupleNTimes(int nbTimes) const
8068 {
8069   checkAllocated();
8070   if(getNumberOfComponents()!=1)
8071     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : this should have only one component !");
8072   if(nbTimes<1)
8073     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : nb times should be >= 1 !");
8074   int nbTuples=getNumberOfTuples();
8075   const int *inPtr=getConstPointer();
8076   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTimes*nbTuples,1);
8077   int *retPtr=ret->getPointer();
8078   for(int i=0;i<nbTuples;i++,inPtr++)
8079     {
8080       int val=*inPtr;
8081       for(int j=0;j<nbTimes;j++,retPtr++)
8082         *retPtr=val;
8083     }
8084   ret->copyStringInfoFrom(*this);
8085   return ret.retn();
8086 }
8087
8088 /*!
8089  * This method returns all different values found in \a this. This method throws if \a this has not been allocated.
8090  * But the number of components can be different from one.
8091  * \return a newly allocated array (that should be dealt by the caller) containing different values in \a this.
8092  */
8093 DataArrayInt *DataArrayInt::getDifferentValues() const
8094 {
8095   checkAllocated();
8096   std::set<int> ret;
8097   ret.insert(begin(),end());
8098   MCAuto<DataArrayInt> ret2=DataArrayInt::New(); ret2->alloc((int)ret.size(),1);
8099   std::copy(ret.begin(),ret.end(),ret2->getPointer());
8100   return ret2.retn();
8101 }
8102
8103 /*!
8104  * This method is a refinement of DataArrayInt::getDifferentValues because it returns not only different values in \a this but also, for each of
8105  * them it tells which tuple id have this id.
8106  * This method works only on arrays with one component (if it is not the case call DataArrayInt::rearrange(1) ).
8107  * This method returns two arrays having same size.
8108  * 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.
8109  * 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]]
8110  */
8111 std::vector<DataArrayInt *> DataArrayInt::partitionByDifferentValues(std::vector<int>& differentIds) const
8112 {
8113   checkAllocated();
8114   if(getNumberOfComponents()!=1)
8115     throw INTERP_KERNEL::Exception("DataArrayInt::partitionByDifferentValues : this should have only one component !");
8116   int id=0;
8117   std::map<int,int> m,m2,m3;
8118   for(const int *w=begin();w!=end();w++)
8119     m[*w]++;
8120   differentIds.resize(m.size());
8121   std::vector<DataArrayInt *> ret(m.size());
8122   std::vector<int *> retPtr(m.size());
8123   for(std::map<int,int>::const_iterator it=m.begin();it!=m.end();it++,id++)
8124     {
8125       m2[(*it).first]=id;
8126       ret[id]=DataArrayInt::New();
8127       ret[id]->alloc((*it).second,1);
8128       retPtr[id]=ret[id]->getPointer();
8129       differentIds[id]=(*it).first;
8130     }
8131   id=0;
8132   for(const int *w=begin();w!=end();w++,id++)
8133     {
8134       retPtr[m2[*w]][m3[*w]++]=id;
8135     }
8136   return ret;
8137 }
8138
8139 /*!
8140  * This method split ids in [0, \c this->getNumberOfTuples() ) using \a this array as a field of weight (>=0 each).
8141  * The aim of this method is to return a set of \a nbOfSlices chunk of contiguous ids as balanced as possible.
8142  *
8143  * \param [in] nbOfSlices - number of slices expected.
8144  * \return - a vector having a size equal to \a nbOfSlices giving the start (included) and the stop (excluded) of each chunks.
8145  * 
8146  * \sa DataArray::GetSlice
8147  * \throw If \a this is not allocated or not with exactly one component.
8148  * \throw If an element in \a this if < 0.
8149  */
8150 std::vector< std::pair<int,int> > DataArrayInt::splitInBalancedSlices(int nbOfSlices) const
8151 {
8152   if(!isAllocated() || getNumberOfComponents()!=1)
8153     throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : this array should have number of components equal to one and must be allocated !");
8154   if(nbOfSlices<=0)
8155     throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : number of slices must be >= 1 !");
8156   int sum(accumulate(0)),nbOfTuples(getNumberOfTuples());
8157   int sumPerSlc(sum/nbOfSlices),pos(0);
8158   const int *w(begin());
8159   std::vector< std::pair<int,int> > ret(nbOfSlices);
8160   for(int i=0;i<nbOfSlices;i++)
8161     {
8162       std::pair<int,int> p(pos,-1);
8163       int locSum(0);
8164       while(locSum<sumPerSlc && pos<nbOfTuples) { pos++; locSum+=*w++; }
8165       if(i!=nbOfSlices-1)
8166         p.second=pos;
8167       else
8168         p.second=nbOfTuples;
8169       ret[i]=p;
8170     }
8171   return ret;
8172 }
8173
8174 /*!
8175  * Returns a new DataArrayInt that is a sum of two given arrays. There are 3
8176  * valid cases.
8177  * 1.  The arrays have same number of tuples and components. Then each value of
8178  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
8179  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
8180  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
8181  *   component. Then
8182  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
8183  * 3.  The arrays have same number of components and one array, say _a2_, has one
8184  *   tuple. Then
8185  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
8186  *
8187  * Info on components is copied either from the first array (in the first case) or from
8188  * the array with maximal number of elements (getNbOfElems()).
8189  *  \param [in] a1 - an array to sum up.
8190  *  \param [in] a2 - another array to sum up.
8191  *  \return DataArrayInt * - the new instance of DataArrayInt.
8192  *          The caller is to delete this result array using decrRef() as it is no more
8193  *          needed.
8194  *  \throw If either \a a1 or \a a2 is NULL.
8195  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
8196  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
8197  *         none of them has number of tuples or components equal to 1.
8198  */
8199 DataArrayInt *DataArrayInt::Add(const DataArrayInt *a1, const DataArrayInt *a2)
8200 {
8201   if(!a1 || !a2)
8202     throw INTERP_KERNEL::Exception("DataArrayInt::Add : input DataArrayInt instance is NULL !");
8203   int nbOfTuple=a1->getNumberOfTuples();
8204   int nbOfTuple2=a2->getNumberOfTuples();
8205   int nbOfComp=a1->getNumberOfComponents();
8206   int nbOfComp2=a2->getNumberOfComponents();
8207   MCAuto<DataArrayInt> ret=0;
8208   if(nbOfTuple==nbOfTuple2)
8209     {
8210       if(nbOfComp==nbOfComp2)
8211         {
8212           ret=DataArrayInt::New();
8213           ret->alloc(nbOfTuple,nbOfComp);
8214           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<int>());
8215           ret->copyStringInfoFrom(*a1);
8216         }
8217       else
8218         {
8219           int nbOfCompMin,nbOfCompMax;
8220           const DataArrayInt *aMin, *aMax;
8221           if(nbOfComp>nbOfComp2)
8222             {
8223               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
8224               aMin=a2; aMax=a1;
8225             }
8226           else
8227             {
8228               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
8229               aMin=a1; aMax=a2;
8230             }
8231           if(nbOfCompMin==1)
8232             {
8233               ret=DataArrayInt::New();
8234               ret->alloc(nbOfTuple,nbOfCompMax);
8235               const int *aMinPtr=aMin->getConstPointer();
8236               const int *aMaxPtr=aMax->getConstPointer();
8237               int *res=ret->getPointer();
8238               for(int i=0;i<nbOfTuple;i++)
8239                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<int>(),aMinPtr[i]));
8240               ret->copyStringInfoFrom(*aMax);
8241             }
8242           else
8243             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
8244         }
8245     }
8246   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
8247     {
8248       if(nbOfComp==nbOfComp2)
8249         {
8250           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
8251           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
8252           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
8253           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
8254           ret=DataArrayInt::New();
8255           ret->alloc(nbOfTupleMax,nbOfComp);
8256           int *res=ret->getPointer();
8257           for(int i=0;i<nbOfTupleMax;i++)
8258             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<int>());
8259           ret->copyStringInfoFrom(*aMax);
8260         }
8261       else
8262         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
8263     }
8264   else
8265     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
8266   return ret.retn();
8267 }
8268
8269 /*!
8270  * Adds values of another DataArrayInt to values of \a this one. There are 3
8271  * valid cases.
8272  * 1.  The arrays have same number of tuples and components. Then each value of
8273  *   \a other array is added to the corresponding value of \a this array, i.e.:
8274  *   _a_ [ i, j ] += _other_ [ i, j ].
8275  * 2.  The arrays have same number of tuples and \a other array has one component. Then
8276  *   _a_ [ i, j ] += _other_ [ i, 0 ].
8277  * 3.  The arrays have same number of components and \a other array has one tuple. Then
8278  *   _a_ [ i, j ] += _a2_ [ 0, j ].
8279  *
8280  *  \param [in] other - an array to add to \a this one.
8281  *  \throw If \a other is NULL.
8282  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
8283  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
8284  *         \a other has number of both tuples and components not equal to 1.
8285  */
8286 void DataArrayInt::addEqual(const DataArrayInt *other)
8287 {
8288   if(!other)
8289     throw INTERP_KERNEL::Exception("DataArrayInt::addEqual : input DataArrayInt instance is NULL !");
8290   const char *msg="Nb of tuples mismatch for DataArrayInt::addEqual  !";
8291   checkAllocated(); other->checkAllocated();
8292   int nbOfTuple=getNumberOfTuples();
8293   int nbOfTuple2=other->getNumberOfTuples();
8294   int nbOfComp=getNumberOfComponents();
8295   int nbOfComp2=other->getNumberOfComponents();
8296   if(nbOfTuple==nbOfTuple2)
8297     {
8298       if(nbOfComp==nbOfComp2)
8299         {
8300           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<int>());
8301         }
8302       else if(nbOfComp2==1)
8303         {
8304           int *ptr=getPointer();
8305           const int *ptrc=other->getConstPointer();
8306           for(int i=0;i<nbOfTuple;i++)
8307             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<int>(),*ptrc++));
8308         }
8309       else
8310         throw INTERP_KERNEL::Exception(msg);
8311     }
8312   else if(nbOfTuple2==1)
8313     {
8314       if(nbOfComp2==nbOfComp)
8315         {
8316           int *ptr=getPointer();
8317           const int *ptrc=other->getConstPointer();
8318           for(int i=0;i<nbOfTuple;i++)
8319             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<int>());
8320         }
8321       else
8322         throw INTERP_KERNEL::Exception(msg);
8323     }
8324   else
8325     throw INTERP_KERNEL::Exception(msg);
8326   declareAsNew();
8327 }
8328
8329 /*!
8330  * Returns a new DataArrayInt that is a subtraction of two given arrays. There are 3
8331  * valid cases.
8332  * 1.  The arrays have same number of tuples and components. Then each value of
8333  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
8334  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
8335  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
8336  *   component. Then
8337  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
8338  * 3.  The arrays have same number of components and one array, say _a2_, has one
8339  *   tuple. Then
8340  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
8341  *
8342  * Info on components is copied either from the first array (in the first case) or from
8343  * the array with maximal number of elements (getNbOfElems()).
8344  *  \param [in] a1 - an array to subtract from.
8345  *  \param [in] a2 - an array to subtract.
8346  *  \return DataArrayInt * - the new instance of DataArrayInt.
8347  *          The caller is to delete this result array using decrRef() as it is no more
8348  *          needed.
8349  *  \throw If either \a a1 or \a a2 is NULL.
8350  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
8351  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
8352  *         none of them has number of tuples or components equal to 1.
8353  */
8354 DataArrayInt *DataArrayInt::Substract(const DataArrayInt *a1, const DataArrayInt *a2)
8355 {
8356   if(!a1 || !a2)
8357     throw INTERP_KERNEL::Exception("DataArrayInt::Substract : input DataArrayInt instance is NULL !");
8358   int nbOfTuple1=a1->getNumberOfTuples();
8359   int nbOfTuple2=a2->getNumberOfTuples();
8360   int nbOfComp1=a1->getNumberOfComponents();
8361   int nbOfComp2=a2->getNumberOfComponents();
8362   if(nbOfTuple2==nbOfTuple1)
8363     {
8364       if(nbOfComp1==nbOfComp2)
8365         {
8366           MCAuto<DataArrayInt> ret=DataArrayInt::New();
8367           ret->alloc(nbOfTuple2,nbOfComp1);
8368           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<int>());
8369           ret->copyStringInfoFrom(*a1);
8370           return ret.retn();
8371         }
8372       else if(nbOfComp2==1)
8373         {
8374           MCAuto<DataArrayInt> ret=DataArrayInt::New();
8375           ret->alloc(nbOfTuple1,nbOfComp1);
8376           const int *a2Ptr=a2->getConstPointer();
8377           const int *a1Ptr=a1->getConstPointer();
8378           int *res=ret->getPointer();
8379           for(int i=0;i<nbOfTuple1;i++)
8380             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<int>(),a2Ptr[i]));
8381           ret->copyStringInfoFrom(*a1);
8382           return ret.retn();
8383         }
8384       else
8385         {
8386           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
8387           return 0;
8388         }
8389     }
8390   else if(nbOfTuple2==1)
8391     {
8392       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
8393       MCAuto<DataArrayInt> ret=DataArrayInt::New();
8394       ret->alloc(nbOfTuple1,nbOfComp1);
8395       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
8396       int *pt=ret->getPointer();
8397       for(int i=0;i<nbOfTuple1;i++)
8398         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<int>());
8399       ret->copyStringInfoFrom(*a1);
8400       return ret.retn();
8401     }
8402   else
8403     {
8404       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
8405       return 0;
8406     }
8407 }
8408
8409 /*!
8410  * Subtract values of another DataArrayInt from values of \a this one. There are 3
8411  * valid cases.
8412  * 1.  The arrays have same number of tuples and components. Then each value of
8413  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
8414  *   _a_ [ i, j ] -= _other_ [ i, j ].
8415  * 2.  The arrays have same number of tuples and \a other array has one component. Then
8416  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
8417  * 3.  The arrays have same number of components and \a other array has one tuple. Then
8418  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
8419  *
8420  *  \param [in] other - an array to subtract from \a this one.
8421  *  \throw If \a other is NULL.
8422  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
8423  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
8424  *         \a other has number of both tuples and components not equal to 1.
8425  */
8426 void DataArrayInt::substractEqual(const DataArrayInt *other)
8427 {
8428   if(!other)
8429     throw INTERP_KERNEL::Exception("DataArrayInt::substractEqual : input DataArrayInt instance is NULL !");
8430   const char *msg="Nb of tuples mismatch for DataArrayInt::substractEqual  !";
8431   checkAllocated(); other->checkAllocated();
8432   int nbOfTuple=getNumberOfTuples();
8433   int nbOfTuple2=other->getNumberOfTuples();
8434   int nbOfComp=getNumberOfComponents();
8435   int nbOfComp2=other->getNumberOfComponents();
8436   if(nbOfTuple==nbOfTuple2)
8437     {
8438       if(nbOfComp==nbOfComp2)
8439         {
8440           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<int>());
8441         }
8442       else if(nbOfComp2==1)
8443         {
8444           int *ptr=getPointer();
8445           const int *ptrc=other->getConstPointer();
8446           for(int i=0;i<nbOfTuple;i++)
8447             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<int>(),*ptrc++));
8448         }
8449       else
8450         throw INTERP_KERNEL::Exception(msg);
8451     }
8452   else if(nbOfTuple2==1)
8453     {
8454       int *ptr=getPointer();
8455       const int *ptrc=other->getConstPointer();
8456       for(int i=0;i<nbOfTuple;i++)
8457         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<int>());
8458     }
8459   else
8460     throw INTERP_KERNEL::Exception(msg);
8461   declareAsNew();
8462 }
8463
8464 /*!
8465  * Returns a new DataArrayInt that is a product of two given arrays. There are 3
8466  * valid cases.
8467  * 1.  The arrays have same number of tuples and components. Then each value of
8468  *   the result array (_a_) is a product of the corresponding values of \a a1 and
8469  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
8470  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
8471  *   component. Then
8472  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
8473  * 3.  The arrays have same number of components and one array, say _a2_, has one
8474  *   tuple. Then
8475  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
8476  *
8477  * Info on components is copied either from the first array (in the first case) or from
8478  * the array with maximal number of elements (getNbOfElems()).
8479  *  \param [in] a1 - a factor array.
8480  *  \param [in] a2 - another factor array.
8481  *  \return DataArrayInt * - the new instance of DataArrayInt.
8482  *          The caller is to delete this result array using decrRef() as it is no more
8483  *          needed.
8484  *  \throw If either \a a1 or \a a2 is NULL.
8485  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
8486  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
8487  *         none of them has number of tuples or components equal to 1.
8488  */
8489 DataArrayInt *DataArrayInt::Multiply(const DataArrayInt *a1, const DataArrayInt *a2)
8490 {
8491   if(!a1 || !a2)
8492     throw INTERP_KERNEL::Exception("DataArrayInt::Multiply : input DataArrayInt instance is NULL !");
8493   int nbOfTuple=a1->getNumberOfTuples();
8494   int nbOfTuple2=a2->getNumberOfTuples();
8495   int nbOfComp=a1->getNumberOfComponents();
8496   int nbOfComp2=a2->getNumberOfComponents();
8497   MCAuto<DataArrayInt> ret=0;
8498   if(nbOfTuple==nbOfTuple2)
8499     {
8500       if(nbOfComp==nbOfComp2)
8501         {
8502           ret=DataArrayInt::New();
8503           ret->alloc(nbOfTuple,nbOfComp);
8504           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<int>());
8505           ret->copyStringInfoFrom(*a1);
8506         }
8507       else
8508         {
8509           int nbOfCompMin,nbOfCompMax;
8510           const DataArrayInt *aMin, *aMax;
8511           if(nbOfComp>nbOfComp2)
8512             {
8513               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
8514               aMin=a2; aMax=a1;
8515             }
8516           else
8517             {
8518               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
8519               aMin=a1; aMax=a2;
8520             }
8521           if(nbOfCompMin==1)
8522             {
8523               ret=DataArrayInt::New();
8524               ret->alloc(nbOfTuple,nbOfCompMax);
8525               const int *aMinPtr=aMin->getConstPointer();
8526               const int *aMaxPtr=aMax->getConstPointer();
8527               int *res=ret->getPointer();
8528               for(int i=0;i<nbOfTuple;i++)
8529                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<int>(),aMinPtr[i]));
8530               ret->copyStringInfoFrom(*aMax);
8531             }
8532           else
8533             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
8534         }
8535     }
8536   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
8537     {
8538       if(nbOfComp==nbOfComp2)
8539         {
8540           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
8541           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
8542           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
8543           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
8544           ret=DataArrayInt::New();
8545           ret->alloc(nbOfTupleMax,nbOfComp);
8546           int *res=ret->getPointer();
8547           for(int i=0;i<nbOfTupleMax;i++)
8548             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<int>());
8549           ret->copyStringInfoFrom(*aMax);
8550         }
8551       else
8552         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
8553     }
8554   else
8555     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
8556   return ret.retn();
8557 }
8558
8559
8560 /*!
8561  * Multiply values of another DataArrayInt to values of \a this one. There are 3
8562  * valid cases.
8563  * 1.  The arrays have same number of tuples and components. Then each value of
8564  *   \a other array is multiplied to the corresponding value of \a this array, i.e.:
8565  *   _a_ [ i, j ] *= _other_ [ i, j ].
8566  * 2.  The arrays have same number of tuples and \a other array has one component. Then
8567  *   _a_ [ i, j ] *= _other_ [ i, 0 ].
8568  * 3.  The arrays have same number of components and \a other array has one tuple. Then
8569  *   _a_ [ i, j ] *= _a2_ [ 0, j ].
8570  *
8571  *  \param [in] other - an array to multiply to \a this one.
8572  *  \throw If \a other is NULL.
8573  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
8574  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
8575  *         \a other has number of both tuples and components not equal to 1.
8576  */
8577 void DataArrayInt::multiplyEqual(const DataArrayInt *other)
8578 {
8579   if(!other)
8580     throw INTERP_KERNEL::Exception("DataArrayInt::multiplyEqual : input DataArrayInt instance is NULL !");
8581   const char *msg="Nb of tuples mismatch for DataArrayInt::multiplyEqual !";
8582   checkAllocated(); other->checkAllocated();
8583   int nbOfTuple=getNumberOfTuples();
8584   int nbOfTuple2=other->getNumberOfTuples();
8585   int nbOfComp=getNumberOfComponents();
8586   int nbOfComp2=other->getNumberOfComponents();
8587   if(nbOfTuple==nbOfTuple2)
8588     {
8589       if(nbOfComp==nbOfComp2)
8590         {
8591           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<int>());
8592         }
8593       else if(nbOfComp2==1)
8594         {
8595           int *ptr=getPointer();
8596           const int *ptrc=other->getConstPointer();
8597           for(int i=0;i<nbOfTuple;i++)
8598             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<int>(),*ptrc++));    
8599         }
8600       else
8601         throw INTERP_KERNEL::Exception(msg);
8602     }
8603   else if(nbOfTuple2==1)
8604     {
8605       if(nbOfComp2==nbOfComp)
8606         {
8607           int *ptr=getPointer();
8608           const int *ptrc=other->getConstPointer();
8609           for(int i=0;i<nbOfTuple;i++)
8610             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<int>());
8611         }
8612       else
8613         throw INTERP_KERNEL::Exception(msg);
8614     }
8615   else
8616     throw INTERP_KERNEL::Exception(msg);
8617   declareAsNew();
8618 }
8619
8620
8621 /*!
8622  * Returns a new DataArrayInt that is a division of two given arrays. There are 3
8623  * valid cases.
8624  * 1.  The arrays have same number of tuples and components. Then each value of
8625  *   the result array (_a_) is a division of the corresponding values of \a a1 and
8626  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
8627  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
8628  *   component. Then
8629  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
8630  * 3.  The arrays have same number of components and one array, say _a2_, has one
8631  *   tuple. Then
8632  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
8633  *
8634  * Info on components is copied either from the first array (in the first case) or from
8635  * the array with maximal number of elements (getNbOfElems()).
8636  *  \warning No check of division by zero is performed!
8637  *  \param [in] a1 - a numerator array.
8638  *  \param [in] a2 - a denominator array.
8639  *  \return DataArrayInt * - the new instance of DataArrayInt.
8640  *          The caller is to delete this result array using decrRef() as it is no more
8641  *          needed.
8642  *  \throw If either \a a1 or \a a2 is NULL.
8643  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
8644  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
8645  *         none of them has number of tuples or components equal to 1.
8646  */
8647 DataArrayInt *DataArrayInt::Divide(const DataArrayInt *a1, const DataArrayInt *a2)
8648 {
8649   if(!a1 || !a2)
8650     throw INTERP_KERNEL::Exception("DataArrayInt::Divide : input DataArrayInt instance is NULL !");
8651   int nbOfTuple1=a1->getNumberOfTuples();
8652   int nbOfTuple2=a2->getNumberOfTuples();
8653   int nbOfComp1=a1->getNumberOfComponents();
8654   int nbOfComp2=a2->getNumberOfComponents();
8655   if(nbOfTuple2==nbOfTuple1)
8656     {
8657       if(nbOfComp1==nbOfComp2)
8658         {
8659           MCAuto<DataArrayInt> ret=DataArrayInt::New();
8660           ret->alloc(nbOfTuple2,nbOfComp1);
8661           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<int>());
8662           ret->copyStringInfoFrom(*a1);
8663           return ret.retn();
8664         }
8665       else if(nbOfComp2==1)
8666         {
8667           MCAuto<DataArrayInt> ret=DataArrayInt::New();
8668           ret->alloc(nbOfTuple1,nbOfComp1);
8669           const int *a2Ptr=a2->getConstPointer();
8670           const int *a1Ptr=a1->getConstPointer();
8671           int *res=ret->getPointer();
8672           for(int i=0;i<nbOfTuple1;i++)
8673             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<int>(),a2Ptr[i]));
8674           ret->copyStringInfoFrom(*a1);
8675           return ret.retn();
8676         }
8677       else
8678         {
8679           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
8680           return 0;
8681         }
8682     }
8683   else if(nbOfTuple2==1)
8684     {
8685       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
8686       MCAuto<DataArrayInt> ret=DataArrayInt::New();
8687       ret->alloc(nbOfTuple1,nbOfComp1);
8688       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
8689       int *pt=ret->getPointer();
8690       for(int i=0;i<nbOfTuple1;i++)
8691         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<int>());
8692       ret->copyStringInfoFrom(*a1);
8693       return ret.retn();
8694     }
8695   else
8696     {
8697       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
8698       return 0;
8699     }
8700 }
8701
8702 /*!
8703  * Divide values of \a this array by values of another DataArrayInt. There are 3
8704  * valid cases.
8705  * 1.  The arrays have same number of tuples and components. Then each value of
8706  *    \a this array is divided by the corresponding value of \a other one, i.e.:
8707  *   _a_ [ i, j ] /= _other_ [ i, j ].
8708  * 2.  The arrays have same number of tuples and \a other array has one component. Then
8709  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
8710  * 3.  The arrays have same number of components and \a other array has one tuple. Then
8711  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
8712  *
8713  *  \warning No check of division by zero is performed!
8714  *  \param [in] other - an array to divide \a this one by.
8715  *  \throw If \a other is NULL.
8716  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
8717  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
8718  *         \a other has number of both tuples and components not equal to 1.
8719  */
8720 void DataArrayInt::divideEqual(const DataArrayInt *other)
8721 {
8722   if(!other)
8723     throw INTERP_KERNEL::Exception("DataArrayInt::divideEqual : input DataArrayInt instance is NULL !");
8724   const char *msg="Nb of tuples mismatch for DataArrayInt::divideEqual !";
8725   checkAllocated(); other->checkAllocated();
8726   int nbOfTuple=getNumberOfTuples();
8727   int nbOfTuple2=other->getNumberOfTuples();
8728   int nbOfComp=getNumberOfComponents();
8729   int nbOfComp2=other->getNumberOfComponents();
8730   if(nbOfTuple==nbOfTuple2)
8731     {
8732       if(nbOfComp==nbOfComp2)
8733         {
8734           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<int>());
8735         }
8736       else if(nbOfComp2==1)
8737         {
8738           int *ptr=getPointer();
8739           const int *ptrc=other->getConstPointer();
8740           for(int i=0;i<nbOfTuple;i++)
8741             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<int>(),*ptrc++));
8742         }
8743       else
8744         throw INTERP_KERNEL::Exception(msg);
8745     }
8746   else if(nbOfTuple2==1)
8747     {
8748       if(nbOfComp2==nbOfComp)
8749         {
8750           int *ptr=getPointer();
8751           const int *ptrc=other->getConstPointer();
8752           for(int i=0;i<nbOfTuple;i++)
8753             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<int>());
8754         }
8755       else
8756         throw INTERP_KERNEL::Exception(msg);
8757     }
8758   else
8759     throw INTERP_KERNEL::Exception(msg);
8760   declareAsNew();
8761 }
8762
8763
8764 /*!
8765  * Returns a new DataArrayInt that is a modulus of two given arrays. There are 3
8766  * valid cases.
8767  * 1.  The arrays have same number of tuples and components. Then each value of
8768  *   the result array (_a_) is a division of the corresponding values of \a a1 and
8769  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, j ].
8770  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
8771  *   component. Then
8772  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, 0 ].
8773  * 3.  The arrays have same number of components and one array, say _a2_, has one
8774  *   tuple. Then
8775  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ 0, j ].
8776  *
8777  * Info on components is copied either from the first array (in the first case) or from
8778  * the array with maximal number of elements (getNbOfElems()).
8779  *  \warning No check of division by zero is performed!
8780  *  \param [in] a1 - a dividend array.
8781  *  \param [in] a2 - a divisor array.
8782  *  \return DataArrayInt * - the new instance of DataArrayInt.
8783  *          The caller is to delete this result array using decrRef() as it is no more
8784  *          needed.
8785  *  \throw If either \a a1 or \a a2 is NULL.
8786  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
8787  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
8788  *         none of them has number of tuples or components equal to 1.
8789  */
8790 DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt *a2)
8791 {
8792   if(!a1 || !a2)
8793     throw INTERP_KERNEL::Exception("DataArrayInt::Modulus : input DataArrayInt instance is NULL !");
8794   int nbOfTuple1=a1->getNumberOfTuples();
8795   int nbOfTuple2=a2->getNumberOfTuples();
8796   int nbOfComp1=a1->getNumberOfComponents();
8797   int nbOfComp2=a2->getNumberOfComponents();
8798   if(nbOfTuple2==nbOfTuple1)
8799     {
8800       if(nbOfComp1==nbOfComp2)
8801         {
8802           MCAuto<DataArrayInt> ret=DataArrayInt::New();
8803           ret->alloc(nbOfTuple2,nbOfComp1);
8804           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::modulus<int>());
8805           ret->copyStringInfoFrom(*a1);
8806           return ret.retn();
8807         }
8808       else if(nbOfComp2==1)
8809         {
8810           MCAuto<DataArrayInt> ret=DataArrayInt::New();
8811           ret->alloc(nbOfTuple1,nbOfComp1);
8812           const int *a2Ptr=a2->getConstPointer();
8813           const int *a1Ptr=a1->getConstPointer();
8814           int *res=ret->getPointer();
8815           for(int i=0;i<nbOfTuple1;i++)
8816             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::modulus<int>(),a2Ptr[i]));
8817           ret->copyStringInfoFrom(*a1);
8818           return ret.retn();
8819         }
8820       else
8821         {
8822           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
8823           return 0;
8824         }
8825     }
8826   else if(nbOfTuple2==1)
8827     {
8828       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
8829       MCAuto<DataArrayInt> ret=DataArrayInt::New();
8830       ret->alloc(nbOfTuple1,nbOfComp1);
8831       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
8832       int *pt=ret->getPointer();
8833       for(int i=0;i<nbOfTuple1;i++)
8834         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::modulus<int>());
8835       ret->copyStringInfoFrom(*a1);
8836       return ret.retn();
8837     }
8838   else
8839     {
8840       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Modulus !");//will always throw an exception
8841       return 0;
8842     }
8843 }
8844
8845 /*!
8846  * Modify \a this array so that each value becomes a modulus of division of this value by
8847  * a value of another DataArrayInt. There are 3 valid cases.
8848  * 1.  The arrays have same number of tuples and components. Then each value of
8849  *    \a this array is divided by the corresponding value of \a other one, i.e.:
8850  *   _a_ [ i, j ] %= _other_ [ i, j ].
8851  * 2.  The arrays have same number of tuples and \a other array has one component. Then
8852  *   _a_ [ i, j ] %= _other_ [ i, 0 ].
8853  * 3.  The arrays have same number of components and \a other array has one tuple. Then
8854  *   _a_ [ i, j ] %= _a2_ [ 0, j ].
8855  *
8856  *  \warning No check of division by zero is performed!
8857  *  \param [in] other - a divisor array.
8858  *  \throw If \a other is NULL.
8859  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
8860  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
8861  *         \a other has number of both tuples and components not equal to 1.
8862  */
8863 void DataArrayInt::modulusEqual(const DataArrayInt *other)
8864 {
8865   if(!other)
8866     throw INTERP_KERNEL::Exception("DataArrayInt::modulusEqual : input DataArrayInt instance is NULL !");
8867   const char *msg="Nb of tuples mismatch for DataArrayInt::modulusEqual !";
8868   checkAllocated(); other->checkAllocated();
8869   int nbOfTuple=getNumberOfTuples();
8870   int nbOfTuple2=other->getNumberOfTuples();
8871   int nbOfComp=getNumberOfComponents();
8872   int nbOfComp2=other->getNumberOfComponents();
8873   if(nbOfTuple==nbOfTuple2)
8874     {
8875       if(nbOfComp==nbOfComp2)
8876         {
8877           std::transform(begin(),end(),other->begin(),getPointer(),std::modulus<int>());
8878         }
8879       else if(nbOfComp2==1)
8880         {
8881           if(nbOfComp2==nbOfComp)
8882             {
8883               int *ptr=getPointer();
8884               const int *ptrc=other->getConstPointer();
8885               for(int i=0;i<nbOfTuple;i++)
8886                 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::modulus<int>(),*ptrc++));
8887             }
8888           else
8889             throw INTERP_KERNEL::Exception(msg);
8890         }
8891       else
8892         throw INTERP_KERNEL::Exception(msg);
8893     }
8894   else if(nbOfTuple2==1)
8895     {
8896       int *ptr=getPointer();
8897       const int *ptrc=other->getConstPointer();
8898       for(int i=0;i<nbOfTuple;i++)
8899         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::modulus<int>());
8900     }
8901   else
8902     throw INTERP_KERNEL::Exception(msg);
8903   declareAsNew();
8904 }
8905
8906 /*!
8907  * Returns a new DataArrayInt that is the result of pow of two given arrays. There are 3
8908  * valid cases.
8909  *
8910  *  \param [in] a1 - an array to pow up.
8911  *  \param [in] a2 - another array to sum up.
8912  *  \return DataArrayInt * - the new instance of DataArrayInt.
8913  *          The caller is to delete this result array using decrRef() as it is no more
8914  *          needed.
8915  *  \throw If either \a a1 or \a a2 is NULL.
8916  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
8917  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
8918  *  \throw If there is a negative value in \a a2.
8919  */
8920 DataArrayInt *DataArrayInt::Pow(const DataArrayInt *a1, const DataArrayInt *a2)
8921 {
8922   if(!a1 || !a2)
8923     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : at least one of input instances is null !");
8924   int nbOfTuple=a1->getNumberOfTuples();
8925   int nbOfTuple2=a2->getNumberOfTuples();
8926   int nbOfComp=a1->getNumberOfComponents();
8927   int nbOfComp2=a2->getNumberOfComponents();
8928   if(nbOfTuple!=nbOfTuple2)
8929     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of tuples mismatches !");
8930   if(nbOfComp!=1 || nbOfComp2!=1)
8931     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of components of both arrays must be equal to 1 !");
8932   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuple,1);
8933   const int *ptr1(a1->begin()),*ptr2(a2->begin());
8934   int *ptr=ret->getPointer();
8935   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
8936     {
8937       if(*ptr2>=0)
8938         {
8939           int tmp=1;
8940           for(int j=0;j<*ptr2;j++)
8941             tmp*=*ptr1;
8942           *ptr=tmp;
8943         }
8944       else
8945         {
8946           std::ostringstream oss; oss << "DataArrayInt::Pow : on tuple #" << i << " of a2 value is < 0 (" << *ptr2 << ") !";
8947           throw INTERP_KERNEL::Exception(oss.str().c_str());
8948         }
8949     }
8950   return ret.retn();
8951 }
8952
8953 /*!
8954  * Apply pow on values of another DataArrayInt to values of \a this one.
8955  *
8956  *  \param [in] other - an array to pow to \a this one.
8957  *  \throw If \a other is NULL.
8958  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
8959  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
8960  *  \throw If there is a negative value in \a other.
8961  */
8962 void DataArrayInt::powEqual(const DataArrayInt *other)
8963 {
8964   if(!other)
8965     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : input instance is null !");
8966   int nbOfTuple=getNumberOfTuples();
8967   int nbOfTuple2=other->getNumberOfTuples();
8968   int nbOfComp=getNumberOfComponents();
8969   int nbOfComp2=other->getNumberOfComponents();
8970   if(nbOfTuple!=nbOfTuple2)
8971     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of tuples mismatches !");
8972   if(nbOfComp!=1 || nbOfComp2!=1)
8973     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of components of both arrays must be equal to 1 !");
8974   int *ptr=getPointer();
8975   const int *ptrc=other->begin();
8976   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
8977     {
8978       if(*ptrc>=0)
8979         {
8980           int tmp=1;
8981           for(int j=0;j<*ptrc;j++)
8982             tmp*=*ptr;
8983           *ptr=tmp;
8984         }
8985       else
8986         {
8987           std::ostringstream oss; oss << "DataArrayInt::powEqual : on tuple #" << i << " of other value is < 0 (" << *ptrc << ") !";
8988           throw INTERP_KERNEL::Exception(oss.str().c_str());
8989         }
8990     }
8991   declareAsNew();
8992 }
8993
8994 /*!
8995  * Returns a C array which is a renumbering map in "Old to New" mode for the input array.
8996  * This map, if applied to \a start array, would make it sorted. For example, if
8997  * \a start array contents are [9,10,0,6,4,11,3,7] then the contents of the result array is
8998  * [5,6,0,3,2,7,1,4].
8999  *  \param [in] start - pointer to the first element of the array for which the
9000  *         permutation map is computed.
9001  *  \param [in] end - pointer specifying the end of the array \a start, so that
9002  *         the last value of \a start is \a end[ -1 ].
9003  *  \return int * - the result permutation array that the caller is to delete as it is no
9004  *         more needed.
9005  *  \throw If there are equal values in the input array.
9006  */
9007 int *DataArrayInt::CheckAndPreparePermutation(const int *start, const int *end)
9008 {
9009   std::size_t sz=std::distance(start,end);
9010   int *ret=(int *)malloc(sz*sizeof(int));
9011   int *work=new int[sz];
9012   std::copy(start,end,work);
9013   std::sort(work,work+sz);
9014   if(std::unique(work,work+sz)!=work+sz)
9015     {
9016       delete [] work;
9017       free(ret);
9018       throw INTERP_KERNEL::Exception("Some elements are equals in the specified array !");
9019     }
9020   std::map<int,int> m;
9021   for(int *workPt=work;workPt!=work+sz;workPt++)
9022     m[*workPt]=(int)std::distance(work,workPt);
9023   int *iter2=ret;
9024   for(const int *iter=start;iter!=end;iter++,iter2++)
9025     *iter2=m[*iter];
9026   delete [] work;
9027   return ret;
9028 }
9029
9030 /*!
9031  * Returns a new DataArrayInt containing an arithmetic progression
9032  * that is equal to the sequence returned by Python \c range(\a begin,\a  end,\a  step )
9033  * function.
9034  *  \param [in] begin - the start value of the result sequence.
9035  *  \param [in] end - limiting value, so that every value of the result array is less than
9036  *              \a end.
9037  *  \param [in] step - specifies the increment or decrement.
9038  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9039  *          array using decrRef() as it is no more needed.
9040  *  \throw If \a step == 0.
9041  *  \throw If \a end < \a begin && \a step > 0.
9042  *  \throw If \a end > \a begin && \a step < 0.
9043  */
9044 DataArrayInt *DataArrayInt::Range(int begin, int end, int step)
9045 {
9046   int nbOfTuples=GetNumberOfItemGivenBESRelative(begin,end,step,"DataArrayInt::Range");
9047   MCAuto<DataArrayInt> ret=DataArrayInt::New();
9048   ret->alloc(nbOfTuples,1);
9049   int *ptr=ret->getPointer();
9050   if(step>0)
9051     {
9052       for(int i=begin;i<end;i+=step,ptr++)
9053         *ptr=i;
9054     }
9055   else
9056     {
9057       for(int i=begin;i>end;i+=step,ptr++)
9058         *ptr=i;
9059     }
9060   return ret.retn();
9061 }
9062
9063 /*!
9064  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
9065  * Server side.
9066  */
9067 void DataArrayInt::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
9068 {
9069   tinyInfo.resize(2);
9070   if(isAllocated())
9071     {
9072       tinyInfo[0]=getNumberOfTuples();
9073       tinyInfo[1]=getNumberOfComponents();
9074     }
9075   else
9076     {
9077       tinyInfo[0]=-1;
9078       tinyInfo[1]=-1;
9079     }
9080 }
9081
9082 /*!
9083  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
9084  * Server side.
9085  */
9086 void DataArrayInt::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
9087 {
9088   if(isAllocated())
9089     {
9090       int nbOfCompo=getNumberOfComponents();
9091       tinyInfo.resize(nbOfCompo+1);
9092       tinyInfo[0]=getName();
9093       for(int i=0;i<nbOfCompo;i++)
9094         tinyInfo[i+1]=getInfoOnComponent(i);
9095     }
9096   else
9097     {
9098       tinyInfo.resize(1);
9099       tinyInfo[0]=getName();
9100     }
9101 }
9102
9103 /*!
9104  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
9105  * This method returns if a feeding is needed.
9106  */
9107 bool DataArrayInt::resizeForUnserialization(const std::vector<int>& tinyInfoI)
9108 {
9109   int nbOfTuple=tinyInfoI[0];
9110   int nbOfComp=tinyInfoI[1];
9111   if(nbOfTuple!=-1 || nbOfComp!=-1)
9112     {
9113       alloc(nbOfTuple,nbOfComp);
9114       return true;
9115     }
9116   return false;
9117 }
9118
9119 /*!
9120  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
9121  * This method returns if a feeding is needed.
9122  */
9123 void DataArrayInt::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
9124 {
9125   setName(tinyInfoS[0]);
9126   if(isAllocated())
9127     {
9128       int nbOfCompo=tinyInfoI[1];
9129       for(int i=0;i<nbOfCompo;i++)
9130         setInfoOnComponent(i,tinyInfoS[i+1]);
9131     }
9132 }
9133
9134 DataArrayIntIterator::DataArrayIntIterator(DataArrayInt *da):_da(da),_pt(0),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
9135 {
9136   if(_da)
9137     {
9138       _da->incrRef();
9139       if(_da->isAllocated())
9140         {
9141           _nb_comp=da->getNumberOfComponents();
9142           _nb_tuple=da->getNumberOfTuples();
9143           _pt=da->getPointer();
9144         }
9145     }
9146 }
9147
9148 DataArrayIntIterator::~DataArrayIntIterator()
9149 {
9150   if(_da)
9151     _da->decrRef();
9152 }
9153
9154 DataArrayIntTuple *DataArrayIntIterator::nextt()
9155 {
9156   if(_tuple_id<_nb_tuple)
9157     {
9158       _tuple_id++;
9159       DataArrayIntTuple *ret=new DataArrayIntTuple(_pt,_nb_comp);
9160       _pt+=_nb_comp;
9161       return ret;
9162     }
9163   else
9164     return 0;
9165 }
9166
9167 DataArrayIntTuple::DataArrayIntTuple(int *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
9168 {
9169 }
9170
9171 std::string DataArrayIntTuple::repr() const
9172 {
9173   std::ostringstream oss; oss << "(";
9174   for(int i=0;i<_nb_of_compo-1;i++)
9175     oss << _pt[i] << ", ";
9176   oss << _pt[_nb_of_compo-1] << ")";
9177   return oss.str();
9178 }
9179
9180 int DataArrayIntTuple::intValue() const
9181 {
9182   if(_nb_of_compo==1)
9183     return *_pt;
9184   throw INTERP_KERNEL::Exception("DataArrayIntTuple::intValue : DataArrayIntTuple instance has not exactly 1 component -> Not possible to convert it into an integer !");
9185 }
9186
9187 /*!
9188  * This method returns a newly allocated instance the caller should dealed with by a MEDCoupling::DataArrayInt::decrRef.
9189  * This method performs \b no copy of data. The content is only referenced using MEDCoupling::DataArrayInt::useArray with ownership set to \b false.
9190  * 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
9191  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
9192  */
9193 DataArrayInt *DataArrayIntTuple::buildDAInt(int nbOfTuples, int nbOfCompo) const
9194 {
9195   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
9196     {
9197       DataArrayInt *ret=DataArrayInt::New();
9198       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
9199       return ret;
9200     }
9201   else
9202     {
9203       std::ostringstream oss; oss << "DataArrayIntTuple::buildDAInt : unable to build a requested DataArrayInt instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
9204       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
9205       throw INTERP_KERNEL::Exception(oss.str().c_str());
9206     }
9207 }