Salome HOME
First impl of MEDCouplingFieldFloat
[tools/medcoupling.git] / src / MEDCoupling / MEDCouplingMemArray.cxx
1 // Copyright (C) 2007-2016  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 // Author : Anthony Geay (CEA/DEN)
20
21 #include "MEDCouplingMemArray.txx"
22
23 #include "BBTree.txx"
24 #include "GenMathFormulae.hxx"
25 #include "InterpKernelAutoPtr.hxx"
26 #include "InterpKernelExprParser.hxx"
27
28 #include <set>
29 #include <cmath>
30 #include <limits>
31 #include <numeric>
32 #include <algorithm>
33 #include <functional>
34
35 typedef double (*MYFUNCPTR)(double);
36
37 using namespace MEDCoupling;
38
39 template class MEDCoupling::MemArray<int>;
40 template class MEDCoupling::MemArray<double>;
41 template class MEDCoupling::DataArrayTemplate<int>;
42 template class MEDCoupling::DataArrayTemplate<double>;
43 template class MEDCoupling::DataArrayTemplateClassic<int>;
44 template class MEDCoupling::DataArrayTemplateClassic<double>;
45 template class MEDCoupling::DataArrayTemplateFP<double>;
46
47 template<int SPACEDIM>
48 void DataArrayDouble::findCommonTuplesAlg(const double *bbox, int nbNodes, int limitNodeId, double prec, DataArrayInt *c, DataArrayInt *cI) const
49 {
50   const double *coordsPtr=getConstPointer();
51   BBTreePts<SPACEDIM,int> myTree(bbox,0,0,nbNodes,prec);
52   std::vector<bool> isDone(nbNodes);
53   for(int i=0;i<nbNodes;i++)
54     {
55       if(!isDone[i])
56         {
57           std::vector<int> intersectingElems;
58           myTree.getElementsAroundPoint(coordsPtr+i*SPACEDIM,intersectingElems);
59           if(intersectingElems.size()>1)
60             {
61               std::vector<int> commonNodes;
62               for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
63                 if(*it!=i)
64                   if(*it>=limitNodeId)
65                     {
66                       commonNodes.push_back(*it);
67                       isDone[*it]=true;
68                     }
69               if(!commonNodes.empty())
70                 {
71                   cI->pushBackSilent(cI->back()+(int)commonNodes.size()+1);
72                   c->pushBackSilent(i);
73                   c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
74                 }
75             }
76         }
77     }
78 }
79
80 template<int SPACEDIM>
81 void DataArrayDouble::FindTupleIdsNearTuplesAlg(const BBTreePts<SPACEDIM,int>& myTree, const double *pos, int nbOfTuples, double eps,
82                                                 DataArrayInt *c, DataArrayInt *cI)
83 {
84   for(int i=0;i<nbOfTuples;i++)
85     {
86       std::vector<int> intersectingElems;
87       myTree.getElementsAroundPoint(pos+i*SPACEDIM,intersectingElems);
88       std::vector<int> commonNodes;
89       for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
90         commonNodes.push_back(*it);
91       cI->pushBackSilent(cI->back()+(int)commonNodes.size());
92       c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
93     }
94 }
95
96 template<int SPACEDIM>
97 void DataArrayDouble::FindClosestTupleIdAlg(const BBTreePts<SPACEDIM,int>& myTree, double dist, const double *pos, int nbOfTuples, const double *thisPt, int thisNbOfTuples, int *res)
98 {
99   double distOpt(dist);
100   const double *p(pos);
101   int *r(res);
102   for(int i=0;i<nbOfTuples;i++,p+=SPACEDIM,r++)
103     {
104       while(true)
105         {
106           int elem=-1;
107           double ret=myTree.getElementsAroundPoint2(p,distOpt,elem);
108           if(ret!=std::numeric_limits<double>::max())
109             {
110               distOpt=std::max(ret,1e-4);
111               *r=elem;
112               break;
113             }
114           else
115             { distOpt=2*distOpt; continue; }
116         }
117     }
118 }
119
120 int DataArray::EffectiveCircPerm(int nbOfShift, int nbOfTuples)
121 {
122   if(nbOfTuples<=0)
123     throw INTERP_KERNEL::Exception("DataArray::EffectiveCircPerm : number of tuples is expected to be > 0 !");
124   if(nbOfShift>=0)
125     {
126       return nbOfShift%nbOfTuples;
127     }
128   else
129     {
130       int tmp(-nbOfShift);
131       tmp=tmp%nbOfTuples;
132       return nbOfTuples-tmp;
133     }
134 }
135
136 std::size_t DataArray::getHeapMemorySizeWithoutChildren() const
137 {
138   std::size_t sz1=_name.capacity();
139   std::size_t sz2=_info_on_compo.capacity();
140   std::size_t sz3=0;
141   for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
142     sz3+=(*it).capacity();
143   return sz1+sz2+sz3;
144 }
145
146 std::vector<const BigMemoryObject *> DataArray::getDirectChildrenWithNull() const
147 {
148   return std::vector<const BigMemoryObject *>();
149 }
150
151 /*!
152  * Sets the attribute \a _name of \a this array.
153  * See \ref MEDCouplingArrayBasicsName "DataArrays infos" for more information.
154  *  \param [in] name - new array name
155  */
156 void DataArray::setName(const std::string& name)
157 {
158   _name=name;
159 }
160
161 /*!
162  * Copies textual data from an \a other DataArray. The copied data are
163  * - the name attribute,
164  * - the information of components.
165  *
166  * For more information on these data see \ref MEDCouplingArrayBasicsName "DataArrays infos".
167  *
168  *  \param [in] other - another instance of DataArray to copy the textual data from.
169  *  \throw If number of components of \a this array differs from that of the \a other.
170  */
171 void DataArray::copyStringInfoFrom(const DataArray& other)
172 {
173   if(_info_on_compo.size()!=other._info_on_compo.size())
174     throw INTERP_KERNEL::Exception("Size of arrays mismatches on copyStringInfoFrom !");
175   _name=other._name;
176   _info_on_compo=other._info_on_compo;
177 }
178
179 void DataArray::copyPartOfStringInfoFrom(const DataArray& other, const std::vector<int>& compoIds)
180 {
181   int nbOfCompoOth=other.getNumberOfComponents();
182   std::size_t newNbOfCompo=compoIds.size();
183   for(std::size_t i=0;i<newNbOfCompo;i++)
184     if(compoIds[i]>=nbOfCompoOth || compoIds[i]<0)
185       {
186         std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompoOth << ")";
187         throw INTERP_KERNEL::Exception(oss.str().c_str());
188       }
189   for(std::size_t i=0;i<newNbOfCompo;i++)
190     setInfoOnComponent((int)i,other.getInfoOnComponent(compoIds[i]));
191 }
192
193 void DataArray::copyPartOfStringInfoFrom2(const std::vector<int>& compoIds, const DataArray& other)
194 {
195   int nbOfCompo=getNumberOfComponents();
196   std::size_t partOfCompoToSet=compoIds.size();
197   if((int)partOfCompoToSet!=other.getNumberOfComponents())
198     throw INTERP_KERNEL::Exception("Given compoIds has not the same size as number of components of given array !");
199   for(std::size_t i=0;i<partOfCompoToSet;i++)
200     if(compoIds[i]>=nbOfCompo || compoIds[i]<0)
201       {
202         std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompo << ")";
203         throw INTERP_KERNEL::Exception(oss.str().c_str());
204       }
205   for(std::size_t i=0;i<partOfCompoToSet;i++)
206     setInfoOnComponent(compoIds[i],other.getInfoOnComponent((int)i));
207 }
208
209 bool DataArray::areInfoEqualsIfNotWhy(const DataArray& other, std::string& reason) const
210 {
211   std::ostringstream oss;
212   if(_name!=other._name)
213     {
214       oss << "Names DataArray mismatch : this name=\"" << _name << " other name=\"" << other._name << "\" !";
215       reason=oss.str();
216       return false;
217     }
218   if(_info_on_compo!=other._info_on_compo)
219     {
220       oss << "Components DataArray mismatch : \nThis components=";
221       for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
222         oss << "\"" << *it << "\",";
223       oss << "\nOther components=";
224       for(std::vector<std::string>::const_iterator it=other._info_on_compo.begin();it!=other._info_on_compo.end();it++)
225         oss << "\"" << *it << "\",";
226       reason=oss.str();
227       return false;
228     }
229   return true;
230 }
231
232 /*!
233  * Compares textual information of \a this DataArray with that of an \a other one.
234  * The compared data are
235  * - the name attribute,
236  * - the information of components.
237  *
238  * For more information on these data see \ref MEDCouplingArrayBasicsName "DataArrays infos".
239  *  \param [in] other - another instance of DataArray to compare the textual data of.
240  *  \return bool - \a true if the textual information is same, \a false else.
241  */
242 bool DataArray::areInfoEquals(const DataArray& other) const
243 {
244   std::string tmp;
245   return areInfoEqualsIfNotWhy(other,tmp);
246 }
247
248 void DataArray::reprWithoutNameStream(std::ostream& stream) const
249 {
250   stream << "Number of components : "<< getNumberOfComponents() << "\n";
251   stream << "Info of these components : ";
252   for(std::vector<std::string>::const_iterator iter=_info_on_compo.begin();iter!=_info_on_compo.end();iter++)
253     stream << "\"" << *iter << "\"   ";
254   stream << "\n";
255 }
256
257 std::string DataArray::cppRepr(const std::string& varName) const
258 {
259   std::ostringstream ret;
260   reprCppStream(varName,ret);
261   return ret.str();
262 }
263
264 /*!
265  * Sets information on all components. To know more on format of this information
266  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
267  *  \param [in] info - a vector of strings.
268  *  \throw If size of \a info differs from the number of components of \a this.
269  */
270 void DataArray::setInfoOnComponents(const std::vector<std::string>& info)
271 {
272   if(getNumberOfComponents()!=(int)info.size())
273     {
274       std::ostringstream oss; oss << "DataArray::setInfoOnComponents : input is of size " << info.size() << " whereas number of components is equal to " << getNumberOfComponents() << " !";
275       throw INTERP_KERNEL::Exception(oss.str().c_str());
276     }
277   _info_on_compo=info;
278 }
279
280 /*!
281  * This method is only a dispatcher towards DataArrayDouble::setPartOfValues3, DataArrayInt::setPartOfValues3, DataArrayChar::setPartOfValues3 depending on the true
282  * type of \a this and \a aBase.
283  *
284  * \throw If \a aBase and \a this do not have the same type.
285  *
286  * \sa DataArrayDouble::setPartOfValues3, DataArrayInt::setPartOfValues3, DataArrayChar::setPartOfValues3.
287  */
288 void DataArray::setPartOfValuesBase3(const DataArray *aBase, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
289 {
290   if(!aBase)
291     throw INTERP_KERNEL::Exception("DataArray::setPartOfValuesBase3 : input aBase object is NULL !");
292   DataArrayDouble *this1(dynamic_cast<DataArrayDouble *>(this));
293   DataArrayInt *this2(dynamic_cast<DataArrayInt *>(this));
294   DataArrayChar *this3(dynamic_cast<DataArrayChar *>(this));
295   const DataArrayDouble *a1(dynamic_cast<const DataArrayDouble *>(aBase));
296   const DataArrayInt *a2(dynamic_cast<const DataArrayInt *>(aBase));
297   const DataArrayChar *a3(dynamic_cast<const DataArrayChar *>(aBase));
298   if(this1 && a1)
299     {
300       this1->setPartOfValues3(a1,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
301       return ;
302     }
303   if(this2 && a2)
304     {
305       this2->setPartOfValues3(a2,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
306       return ;
307     }
308   if(this3 && a3)
309     {
310       this3->setPartOfValues3(a3,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
311       return ;
312     }
313   throw INTERP_KERNEL::Exception("DataArray::setPartOfValuesBase3 : input aBase object and this do not have the same type !");
314 }
315
316 std::vector<std::string> DataArray::getVarsOnComponent() const
317 {
318   int nbOfCompo=(int)_info_on_compo.size();
319   std::vector<std::string> ret(nbOfCompo);
320   for(int i=0;i<nbOfCompo;i++)
321     ret[i]=getVarOnComponent(i);
322   return ret;
323 }
324
325 std::vector<std::string> DataArray::getUnitsOnComponent() const
326 {
327   int nbOfCompo=(int)_info_on_compo.size();
328   std::vector<std::string> ret(nbOfCompo);
329   for(int i=0;i<nbOfCompo;i++)
330     ret[i]=getUnitOnComponent(i);
331   return ret;
332 }
333
334 /*!
335  * Returns information on a component specified by an index.
336  * To know more on format of this information
337  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
338  *  \param [in] i - the index (zero based) of the component of interest.
339  *  \return std::string - a string containing the information on \a i-th component.
340  *  \throw If \a i is not a valid component index.
341  */
342 std::string DataArray::getInfoOnComponent(int i) const
343 {
344   if(i<(int)_info_on_compo.size() && i>=0)
345     return _info_on_compo[i];
346   else
347     {
348       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();
349       throw INTERP_KERNEL::Exception(oss.str().c_str());
350     }
351 }
352
353 /*!
354  * Returns the var part of the full information of the \a i-th component.
355  * For example, if \c getInfoOnComponent(0) returns "SIGXY [N/m^2]", then
356  * \c getVarOnComponent(0) returns "SIGXY".
357  * If a unit part of information is not detected by presence of
358  * two square brackets, then the full information is returned.
359  * To read more about the component information format, see
360  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
361  *  \param [in] i - the index (zero based) of the component of interest.
362  *  \return std::string - a string containing the var information, or the full info.
363  *  \throw If \a i is not a valid component index.
364  */
365 std::string DataArray::getVarOnComponent(int i) const
366 {
367   if(i<(int)_info_on_compo.size() && i>=0)
368     {
369       return GetVarNameFromInfo(_info_on_compo[i]);
370     }
371   else
372     {
373       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();
374       throw INTERP_KERNEL::Exception(oss.str().c_str());
375     }
376 }
377
378 /*!
379  * Returns the unit part of the full information of the \a i-th component.
380  * For example, if \c getInfoOnComponent(0) returns "SIGXY [ N/m^2]", then
381  * \c getUnitOnComponent(0) returns " N/m^2".
382  * If a unit part of information is not detected by presence of
383  * two square brackets, then an empty string is returned.
384  * To read more about the component information format, see
385  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
386  *  \param [in] i - the index (zero based) of the component of interest.
387  *  \return std::string - a string containing the unit information, if any, or "".
388  *  \throw If \a i is not a valid component index.
389  */
390 std::string DataArray::getUnitOnComponent(int i) const
391 {
392   if(i<(int)_info_on_compo.size() && i>=0)
393     {
394       return GetUnitFromInfo(_info_on_compo[i]);
395     }
396   else
397     {
398       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();
399       throw INTERP_KERNEL::Exception(oss.str().c_str());
400     }
401 }
402
403 /*!
404  * Returns the var part of the full component information.
405  * For example, if \a info == "SIGXY [N/m^2]", then this method returns "SIGXY".
406  * If a unit part of information is not detected by presence of
407  * two square brackets, then the whole \a info is returned.
408  * To read more about the component information format, see
409  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
410  *  \param [in] info - the full component information.
411  *  \return std::string - a string containing only var information, or the \a info.
412  */
413 std::string DataArray::GetVarNameFromInfo(const std::string& info)
414 {
415   std::size_t p1=info.find_last_of('[');
416   std::size_t p2=info.find_last_of(']');
417   if(p1==std::string::npos || p2==std::string::npos)
418     return info;
419   if(p1>p2)
420     return info;
421   if(p1==0)
422     return std::string();
423   std::size_t p3=info.find_last_not_of(' ',p1-1);
424   return info.substr(0,p3+1);
425 }
426
427 /*!
428  * Returns the unit part of the full component information.
429  * For example, if \a info == "SIGXY [ N/m^2]", then this method returns " N/m^2".
430  * If a unit part of information is not detected by presence of
431  * two square brackets, then an empty string is returned.
432  * To read more about the component information format, see
433  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
434  *  \param [in] info - the full component information.
435  *  \return std::string - a string containing only unit information, if any, or "".
436  */
437 std::string DataArray::GetUnitFromInfo(const std::string& info)
438 {
439   std::size_t p1=info.find_last_of('[');
440   std::size_t p2=info.find_last_of(']');
441   if(p1==std::string::npos || p2==std::string::npos)
442     return std::string();
443   if(p1>p2)
444     return std::string();
445   return info.substr(p1+1,p2-p1-1);
446 }
447
448 /*!
449  * This method put in info format the result of the merge of \a var and \a unit.
450  * The standard format for that is "var [unit]".
451  * Inversely you can retrieve the var part or the unit part of info string using resp. GetVarNameFromInfo and GetUnitFromInfo.
452  */
453 std::string DataArray::BuildInfoFromVarAndUnit(const std::string& var, const std::string& unit)
454 {
455   std::ostringstream oss;
456   oss << var << " [" << unit << "]";
457   return oss.str();
458 }
459
460 std::string DataArray::GetAxisTypeRepr(MEDCouplingAxisType at)
461 {
462   switch(at)
463     {
464     case AX_CART:
465       return std::string("AX_CART");
466     case AX_CYL:
467       return std::string("AX_CYL");
468     case AX_SPHER:
469       return std::string("AX_SPHER");
470     default:
471       throw INTERP_KERNEL::Exception("DataArray::GetAxisTypeRepr : unrecognized axis type enum !");
472     }
473 }
474
475 /*!
476  * Returns a new DataArray by concatenating all given arrays, so that (1) the number
477  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
478  * the number of component in the result array is same as that of each of given arrays.
479  * Info on components is copied from the first of the given arrays. Number of components
480  * in the given arrays must be  the same.
481  *  \param [in] arrs - a sequence of arrays to include in the result array. All arrays must have the same type.
482  *  \return DataArray * - the new instance of DataArray (that can be either DataArrayInt, DataArrayDouble, DataArrayChar).
483  *          The caller is to delete this result array using decrRef() as it is no more
484  *          needed.
485  *  \throw If all arrays within \a arrs are NULL.
486  *  \throw If all not null arrays in \a arrs have not the same type.
487  *  \throw If getNumberOfComponents() of arrays within \a arrs.
488  */
489 DataArray *DataArray::Aggregate(const std::vector<const DataArray *>& arrs)
490 {
491   std::vector<const DataArray *> arr2;
492   for(std::vector<const DataArray *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
493     if(*it)
494       arr2.push_back(*it);
495   if(arr2.empty())
496     throw INTERP_KERNEL::Exception("DataArray::Aggregate : only null instance in input vector !");
497   std::vector<const DataArrayDouble *> arrd;
498   std::vector<const DataArrayInt *> arri;
499   std::vector<const DataArrayChar *> arrc;
500   for(std::vector<const DataArray *>::const_iterator it=arr2.begin();it!=arr2.end();it++)
501     {
502       const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(*it);
503       if(a)
504         { arrd.push_back(a); continue; }
505       const DataArrayInt *b=dynamic_cast<const DataArrayInt *>(*it);
506       if(b)
507         { arri.push_back(b); continue; }
508       const DataArrayChar *c=dynamic_cast<const DataArrayChar *>(*it);
509       if(c)
510         { arrc.push_back(c); continue; }
511       throw INTERP_KERNEL::Exception("DataArray::Aggregate : presence of not null instance in inuput that is not in [DataArrayDouble, DataArrayInt, DataArrayChar] !");
512     }
513   if(arr2.size()==arrd.size())
514     return DataArrayDouble::Aggregate(arrd);
515   if(arr2.size()==arri.size())
516     return DataArrayInt::Aggregate(arri);
517   if(arr2.size()==arrc.size())
518     return DataArrayChar::Aggregate(arrc);
519   throw INTERP_KERNEL::Exception("DataArray::Aggregate : all input arrays must have the same type !");
520 }
521
522 /*!
523  * Sets information on a component specified by an index.
524  * To know more on format of this information
525  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
526  *  \warning Don't pass NULL as \a info!
527  *  \param [in] i - the index (zero based) of the component of interest.
528  *  \param [in] info - the string containing the information.
529  *  \throw If \a i is not a valid component index.
530  */
531 void DataArray::setInfoOnComponent(int i, const std::string& info)
532 {
533   if(i<(int)_info_on_compo.size() && i>=0)
534     _info_on_compo[i]=info;
535   else
536     {
537       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();
538       throw INTERP_KERNEL::Exception(oss.str().c_str());
539     }
540 }
541
542 /*!
543  * Sets information on all components. This method can change number of components
544  * at certain conditions; if the conditions are not respected, an exception is thrown.
545  * The number of components can be changed in \a this only if \a this is not allocated.
546  * The condition of number of components must not be changed.
547  *
548  * To know more on format of the component information see
549  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
550  *  \param [in] info - a vector of component infos.
551  *  \throw If \a this->getNumberOfComponents() != \a info.size() && \a this->isAllocated()
552  */
553 void DataArray::setInfoAndChangeNbOfCompo(const std::vector<std::string>& info)
554 {
555   if(getNumberOfComponents()!=(int)info.size())
556     {
557       if(!isAllocated())
558         _info_on_compo=info;
559       else
560         {
561           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 !";
562           throw INTERP_KERNEL::Exception(oss.str().c_str());
563         }
564     }
565   else
566     _info_on_compo=info;
567 }
568
569 void DataArray::checkNbOfTuples(int nbOfTuples, const std::string& msg) const
570 {
571   if(getNumberOfTuples()!=nbOfTuples)
572     {
573       std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " <<  nbOfTuples << " having " << getNumberOfTuples() << " !";
574       throw INTERP_KERNEL::Exception(oss.str().c_str());
575     }
576 }
577
578 void DataArray::checkNbOfComps(int nbOfCompo, const std::string& msg) const
579 {
580   if(getNumberOfComponents()!=nbOfCompo)
581     {
582       std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << nbOfCompo << " having " << getNumberOfComponents() << " !";
583       throw INTERP_KERNEL::Exception(oss.str().c_str());
584     }
585 }
586
587 void DataArray::checkNbOfElems(std::size_t nbOfElems, const std::string& msg) const
588 {
589   if(getNbOfElems()!=nbOfElems)
590     {
591       std::ostringstream oss; oss << msg << " : mismatch number of elems : Expected " << nbOfElems << " having " << getNbOfElems() << " !";
592       throw INTERP_KERNEL::Exception(oss.str().c_str());
593     }
594 }
595
596 void DataArray::checkNbOfTuplesAndComp(const DataArray& other, const std::string& msg) const
597 {
598   if(getNumberOfTuples()!=other.getNumberOfTuples())
599     {
600       std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " <<  other.getNumberOfTuples() << " having " << getNumberOfTuples() << " !";
601       throw INTERP_KERNEL::Exception(oss.str().c_str());
602     }
603   if(getNumberOfComponents()!=other.getNumberOfComponents())
604     {
605       std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << other.getNumberOfComponents() << " having " << getNumberOfComponents() << " !";
606       throw INTERP_KERNEL::Exception(oss.str().c_str());
607     }
608 }
609
610 void DataArray::checkNbOfTuplesAndComp(int nbOfTuples, int nbOfCompo, const std::string& msg) const
611 {
612   checkNbOfTuples(nbOfTuples,msg);
613   checkNbOfComps(nbOfCompo,msg);
614 }
615
616 /*!
617  * Simply this method checks that \b value is in [0,\b ref).
618  */
619 void DataArray::CheckValueInRange(int ref, int value, const std::string& msg)
620 {
621   if(value<0 || value>=ref)
622     {
623       std::ostringstream oss; oss << "DataArray::CheckValueInRange : " << msg  << " ! Expected in range [0," << ref << "[ having " << value << " !";
624       throw INTERP_KERNEL::Exception(oss.str().c_str());
625     }
626 }
627
628 /*!
629  * This method checks that [\b start, \b end) is compliant with ref length \b value.
630  * typicaly start in [0,\b value) and end in [0,\b value). If value==start and start==end, it is supported.
631  */
632 void DataArray::CheckValueInRangeEx(int value, int start, int end, const std::string& msg)
633 {
634   if(start<0 || start>=value)
635     {
636       if(value!=start || end!=start)
637         {
638           std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg  << " ! Expected start " << start << " of input range, in [0," << value << "[ !";
639           throw INTERP_KERNEL::Exception(oss.str().c_str());
640         }
641     }
642   if(end<0 || end>value)
643     {
644       std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg  << " ! Expected end " << end << " of input range, in [0," << value << "] !";
645       throw INTERP_KERNEL::Exception(oss.str().c_str());
646     }
647 }
648
649 void DataArray::CheckClosingParInRange(int ref, int value, const std::string& msg)
650 {
651   if(value<0 || value>ref)
652     {
653       std::ostringstream oss; oss << "DataArray::CheckClosingParInRange : " << msg  << " ! Expected input range in [0," << ref << "] having closing open parenthesis " << value << " !";
654       throw INTERP_KERNEL::Exception(oss.str().c_str());
655     }
656 }
657
658 /*!
659  * 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, 
660  * typically it is a whole slice of tuples of DataArray or cells, nodes of a mesh...
661  *
662  * The input \a sliceId should be an id in [0, \a nbOfSlices) that specifies the slice of work.
663  *
664  * \param [in] start - the start of the input slice of the whole work to perform splitted into slices.
665  * \param [in] stop - the stop of the input slice of the whole work to perform splitted into slices.
666  * \param [in] step - the step (that can be <0) of the input slice of the whole work to perform splitted into slices.
667  * \param [in] sliceId - the slice id considered
668  * \param [in] nbOfSlices - the number of slices (typically the number of cores on which the work is expected to be sliced)
669  * \param [out] startSlice - the start of the slice considered
670  * \param [out] stopSlice - the stop of the slice consided
671  * 
672  * \throw If \a step == 0
673  * \throw If \a nbOfSlices not > 0
674  * \throw If \a sliceId not in [0,nbOfSlices)
675  */
676 void DataArray::GetSlice(int start, int stop, int step, int sliceId, int nbOfSlices, int& startSlice, int& stopSlice)
677 {
678   if(nbOfSlices<=0)
679     {
680       std::ostringstream oss; oss << "DataArray::GetSlice : nbOfSlices (" << nbOfSlices << ") must be > 0 !";
681       throw INTERP_KERNEL::Exception(oss.str().c_str());
682     }
683   if(sliceId<0 || sliceId>=nbOfSlices)
684     {
685       std::ostringstream oss; oss << "DataArray::GetSlice : sliceId (" << nbOfSlices << ") must be in [0 , nbOfSlices (" << nbOfSlices << ") ) !";
686       throw INTERP_KERNEL::Exception(oss.str().c_str());
687     }
688   int nbElems=GetNumberOfItemGivenBESRelative(start,stop,step,"DataArray::GetSlice");
689   int minNbOfElemsPerSlice=nbElems/nbOfSlices;
690   startSlice=start+minNbOfElemsPerSlice*step*sliceId;
691   if(sliceId<nbOfSlices-1)
692     stopSlice=start+minNbOfElemsPerSlice*step*(sliceId+1);
693   else
694     stopSlice=stop;
695 }
696
697 int DataArray::GetNumberOfItemGivenBES(int begin, int end, int step, const std::string& msg)
698 {
699   if(end<begin)
700     {
701       std::ostringstream oss; oss << msg << " : end before begin !";
702       throw INTERP_KERNEL::Exception(oss.str().c_str());
703     }
704   if(end==begin)
705     return 0;
706   if(step<=0)
707     {
708       std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
709       throw INTERP_KERNEL::Exception(oss.str().c_str());
710     }
711   return (end-1-begin)/step+1;
712 }
713
714 int DataArray::GetNumberOfItemGivenBESRelative(int begin, int end, int step, const std::string& msg)
715 {
716   if(step==0)
717     throw INTERP_KERNEL::Exception("DataArray::GetNumberOfItemGivenBES : step=0 is not allowed !");
718   if(end<begin && step>0)
719     {
720       std::ostringstream oss; oss << msg << " : end before begin whereas step is positive !";
721       throw INTERP_KERNEL::Exception(oss.str().c_str());
722     }
723   if(begin<end && step<0)
724     {
725       std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
726       throw INTERP_KERNEL::Exception(oss.str().c_str());
727     }
728   if(begin!=end)
729     return (std::max(begin,end)-1-std::min(begin,end))/std::abs(step)+1;
730   else
731     return 0;
732 }
733
734 int DataArray::GetPosOfItemGivenBESRelativeNoThrow(int value, int begin, int end, int step)
735 {
736   if(step!=0)
737     {
738       if(step>0)
739         {
740           if(begin<=value && value<end)
741             {
742               if((value-begin)%step==0)
743                 return (value-begin)/step;
744               else
745                 return -1;
746             }
747           else
748             return -1;
749         }
750       else
751         {
752           if(begin>=value && value>end)
753             {
754               if((begin-value)%(-step)==0)
755                 return (begin-value)/(-step);
756               else
757                 return -1;
758             }
759           else
760             return -1;
761         }
762     }
763   else
764     return -1;
765 }
766
767 /*!
768  * Returns a new instance of DataArrayDouble. The caller is to delete this array
769  * using decrRef() as it is no more needed. 
770  */
771 DataArrayDouble *DataArrayDouble::New()
772 {
773   return new DataArrayDouble;
774 }
775
776 /*!
777  * Returns the only one value in \a this, if and only if number of elements
778  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
779  *  \return double - the sole value stored in \a this array.
780  *  \throw If at least one of conditions stated above is not fulfilled.
781  */
782 double DataArrayDouble::doubleValue() const
783 {
784   if(isAllocated())
785     {
786       if(getNbOfElems()==1)
787         {
788           return *getConstPointer();
789         }
790       else
791         throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is allocated but number of elements is not equal to 1 !");
792     }
793   else
794     throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is not allocated !");
795 }
796
797 /*!
798  * Returns a full copy of \a this. For more info on copying data arrays see
799  * \ref MEDCouplingArrayBasicsCopyDeep.
800  *  \return DataArrayDouble * - a new instance of DataArrayDouble. The caller is to
801  *          delete this array using decrRef() as it is no more needed. 
802  */
803 DataArrayDouble *DataArrayDouble::deepCopy() const
804 {
805   return new DataArrayDouble(*this);
806 }
807
808 /*!
809  * Returns either a \a deep or \a shallow copy of this array. For more info see
810  * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
811  *  \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
812  *  \return DataArrayDouble * - either a new instance of DataArrayDouble (if \a dCpy
813  *          == \a true) or \a this instance (if \a dCpy == \a false).
814  */
815 DataArrayDouble *DataArrayDouble::performCopyOrIncrRef(bool dCpy) const
816 {
817   return DataArrayTemplateClassic<double>::PerformCopyOrIncrRef(dCpy,*this);
818 }
819
820 /*!
821  * Assign zero to all values in \a this array. To know more on filling arrays see
822  * \ref MEDCouplingArrayFill.
823  * \throw If \a this is not allocated.
824  */
825 void DataArrayDouble::fillWithZero()
826 {
827   fillWithValue(0.);
828 }
829
830 /*!
831  * Checks that \a this array is consistently **increasing** or **decreasing** in value,
832  * with at least absolute difference value of |\a eps| at each step.
833  * If not an exception is thrown.
834  *  \param [in] increasing - if \a true, the array values should be increasing.
835  *  \param [in] eps - minimal absolute difference between the neighbor values at which 
836  *                    the values are considered different.
837  *  \throw If sequence of values is not strictly monotonic in agreement with \a
838  *         increasing arg.
839  *  \throw If \a this->getNumberOfComponents() != 1.
840  *  \throw If \a this is not allocated.
841  */
842 void DataArrayDouble::checkMonotonic(bool increasing, double eps) const
843 {
844   if(!isMonotonic(increasing,eps))
845     {
846       if (increasing)
847         throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not INCREASING monotonic !");
848       else
849         throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not DECREASING monotonic !");
850     }
851 }
852
853 /*!
854  * Checks that \a this array is consistently **increasing** or **decreasing** in value,
855  * with at least absolute difference value of |\a eps| at each step.
856  *  \param [in] increasing - if \a true, array values should be increasing.
857  *  \param [in] eps - minimal absolute difference between the neighbor values at which 
858  *                    the values are considered different.
859  *  \return bool - \a true if values change in accordance with \a increasing arg.
860  *  \throw If \a this->getNumberOfComponents() != 1.
861  *  \throw If \a this is not allocated.
862  */
863 bool DataArrayDouble::isMonotonic(bool increasing, double eps) const
864 {
865   checkAllocated();
866   if(getNumberOfComponents()!=1)
867     throw INTERP_KERNEL::Exception("DataArrayDouble::isMonotonic : only supported with 'this' array with ONE component !");
868   int nbOfElements=getNumberOfTuples();
869   const double *ptr=getConstPointer();
870   if(nbOfElements==0)
871     return true;
872   double ref=ptr[0];
873   double absEps=fabs(eps);
874   if(increasing)
875     {
876       for(int i=1;i<nbOfElements;i++)
877         {
878           if(ptr[i]<(ref+absEps))
879             return false;
880           ref=ptr[i];
881         }
882       return true;
883     }
884   else
885     {
886       for(int i=1;i<nbOfElements;i++)
887         {
888           if(ptr[i]>(ref-absEps))
889             return false;
890           ref=ptr[i];
891         }
892       return true;
893     }
894 }
895
896 /*!
897  * Returns a textual and human readable representation of \a this instance of
898  * DataArrayDouble. This text is shown when a DataArrayDouble is printed in Python.
899  * \return std::string - text describing \a this DataArrayDouble.
900  *
901  * \sa reprNotTooLong, reprZip
902  */
903 std::string DataArrayDouble::repr() const
904 {
905   std::ostringstream ret;
906   reprStream(ret);
907   return ret.str();
908 }
909
910 std::string DataArrayDouble::reprZip() const
911 {
912   std::ostringstream ret;
913   reprZipStream(ret);
914   return ret.str();
915 }
916
917 /*!
918  * This method is close to repr method except that when \a this has more than 1000 tuples, all tuples are not
919  * printed out to avoid to consume too much space in interpretor.
920  * \sa repr
921  */
922 std::string DataArrayDouble::reprNotTooLong() const
923 {
924   std::ostringstream ret;
925   reprNotTooLongStream(ret);
926   return ret.str();
927 }
928
929 void DataArrayDouble::writeVTK(std::ostream& ofs, int indent, const std::string& nameInFile, DataArrayByte *byteArr) const
930 {
931   static const char SPACE[4]={' ',' ',' ',' '};
932   checkAllocated();
933   std::string idt(indent,' ');
934   ofs.precision(17);
935   ofs << idt << "<DataArray type=\"Float32\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
936   //
937   bool areAllEmpty(true);
938   for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
939     if(!(*it).empty())
940       areAllEmpty=false;
941   if(!areAllEmpty)
942     for(std::size_t i=0;i<_info_on_compo.size();i++)
943       ofs << " ComponentName" << i << "=\"" << _info_on_compo[i] << "\"";
944   //
945   if(byteArr)
946     {
947       ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
948       INTERP_KERNEL::AutoPtr<float> tmp(new float[getNbOfElems()]);
949       float *pt(tmp);
950       // to make Visual C++ happy : instead of std::copy(begin(),end(),(float *)tmp);
951       for(const double *src=begin();src!=end();src++,pt++)
952         *pt=float(*src);
953       const char *data(reinterpret_cast<const char *>((float *)tmp));
954       std::size_t sz(getNbOfElems()*sizeof(float));
955       byteArr->insertAtTheEnd(data,data+sz);
956       byteArr->insertAtTheEnd(SPACE,SPACE+4);
957     }
958   else
959     {
960       ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
961       std::copy(begin(),end(),std::ostream_iterator<double>(ofs," "));
962     }
963   ofs << std::endl << idt << "</DataArray>\n";
964 }
965
966 void DataArrayDouble::reprStream(std::ostream& stream) const
967 {
968   stream << "Name of double array : \"" << _name << "\"\n";
969   reprWithoutNameStream(stream);
970 }
971
972 void DataArrayDouble::reprZipStream(std::ostream& stream) const
973 {
974   stream << "Name of double array : \"" << _name << "\"\n";
975   reprZipWithoutNameStream(stream);
976 }
977
978 void DataArrayDouble::reprNotTooLongStream(std::ostream& stream) const
979 {
980   stream << "Name of double array : \"" << _name << "\"\n";
981   reprNotTooLongWithoutNameStream(stream);
982 }
983
984 void DataArrayDouble::reprWithoutNameStream(std::ostream& stream) const
985 {
986   DataArray::reprWithoutNameStream(stream);
987   stream.precision(17);
988   _mem.repr(getNumberOfComponents(),stream);
989 }
990
991 void DataArrayDouble::reprZipWithoutNameStream(std::ostream& stream) const
992 {
993   DataArray::reprWithoutNameStream(stream);
994   stream.precision(17);
995   _mem.reprZip(getNumberOfComponents(),stream);
996 }
997
998 void DataArrayDouble::reprNotTooLongWithoutNameStream(std::ostream& stream) const
999 {
1000   DataArray::reprWithoutNameStream(stream);
1001   stream.precision(17);
1002   _mem.reprNotTooLong(getNumberOfComponents(),stream);
1003 }
1004
1005 void DataArrayDouble::reprCppStream(const std::string& varName, std::ostream& stream) const
1006 {
1007   int nbTuples(getNumberOfTuples()),nbComp(getNumberOfComponents());
1008   const double *data(getConstPointer());
1009   stream.precision(17);
1010   stream << "DataArrayDouble *" << varName << "=DataArrayDouble::New();" << std::endl;
1011   if(nbTuples*nbComp>=1)
1012     {
1013       stream << "const double " << varName << "Data[" << nbTuples*nbComp << "]={";
1014       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<double>(stream,","));
1015       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
1016       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
1017     }
1018   else
1019     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
1020   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
1021 }
1022
1023 /*!
1024  * Method that gives a quick overvien of \a this for python.
1025  */
1026 void DataArrayDouble::reprQuickOverview(std::ostream& stream) const
1027 {
1028   static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
1029   stream << "DataArrayDouble C++ instance at " << this << ". ";
1030   if(isAllocated())
1031     {
1032       int nbOfCompo=(int)_info_on_compo.size();
1033       if(nbOfCompo>=1)
1034         {
1035           int nbOfTuples=getNumberOfTuples();
1036           stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
1037           reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
1038         }
1039       else
1040         stream << "Number of components : 0.";
1041     }
1042   else
1043     stream << "*** No data allocated ****";
1044 }
1045
1046 void DataArrayDouble::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
1047 {
1048   const double *data=begin();
1049   int nbOfTuples=getNumberOfTuples();
1050   int nbOfCompo=(int)_info_on_compo.size();
1051   std::ostringstream oss2; oss2 << "[";
1052   oss2.precision(17);
1053   std::string oss2Str(oss2.str());
1054   bool isFinished=true;
1055   for(int i=0;i<nbOfTuples && isFinished;i++)
1056     {
1057       if(nbOfCompo>1)
1058         {
1059           oss2 << "(";
1060           for(int j=0;j<nbOfCompo;j++,data++)
1061             {
1062               oss2 << *data;
1063               if(j!=nbOfCompo-1) oss2 << ", ";
1064             }
1065           oss2 << ")";
1066         }
1067       else
1068         oss2 << *data++;
1069       if(i!=nbOfTuples-1) oss2 << ", ";
1070       std::string oss3Str(oss2.str());
1071       if(oss3Str.length()<maxNbOfByteInRepr)
1072         oss2Str=oss3Str;
1073       else
1074         isFinished=false;
1075     }
1076   stream << oss2Str;
1077   if(!isFinished)
1078     stream << "... ";
1079   stream << "]";
1080 }
1081
1082 /*!
1083  * Equivalent to DataArrayDouble::isEqual except that if false the reason of
1084  * mismatch is given.
1085  * 
1086  * \param [in] other the instance to be compared with \a this
1087  * \param [in] prec the precision to compare numeric data of the arrays.
1088  * \param [out] reason In case of inequality returns the reason.
1089  * \sa DataArrayDouble::isEqual
1090  */
1091 bool DataArrayDouble::isEqualIfNotWhy(const DataArrayDouble& other, double prec, std::string& reason) const
1092 {
1093   if(!areInfoEqualsIfNotWhy(other,reason))
1094     return false;
1095   return _mem.isEqual(other._mem,prec,reason);
1096 }
1097
1098 /*!
1099  * Checks if \a this and another DataArrayDouble are fully equal. For more info see
1100  * \ref MEDCouplingArrayBasicsCompare.
1101  *  \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1102  *  \param [in] prec - precision value to compare numeric data of the arrays.
1103  *  \return bool - \a true if the two arrays are equal, \a false else.
1104  */
1105 bool DataArrayDouble::isEqual(const DataArrayDouble& other, double prec) const
1106 {
1107   std::string tmp;
1108   return isEqualIfNotWhy(other,prec,tmp);
1109 }
1110
1111 /*!
1112  * Checks if values of \a this and another DataArrayDouble are equal. For more info see
1113  * \ref MEDCouplingArrayBasicsCompare.
1114  *  \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1115  *  \param [in] prec - precision value to compare numeric data of the arrays.
1116  *  \return bool - \a true if the values of two arrays are equal, \a false else.
1117  */
1118 bool DataArrayDouble::isEqualWithoutConsideringStr(const DataArrayDouble& other, double prec) const
1119 {
1120   std::string tmp;
1121   return _mem.isEqual(other._mem,prec,tmp);
1122 }
1123
1124 /*!
1125  * Returns a new DataArrayDouble holding the same values as \a this array but differently
1126  * arranged in memory. If \a this array holds 2 components of 3 values:
1127  * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
1128  * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
1129  *  \warning Do not confuse this method with transpose()!
1130  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1131  *          is to delete using decrRef() as it is no more needed.
1132  *  \throw If \a this is not allocated.
1133  */
1134 DataArrayDouble *DataArrayDouble::fromNoInterlace() const
1135 {
1136   if(_mem.isNull())
1137     throw INTERP_KERNEL::Exception("DataArrayDouble::fromNoInterlace : Not defined array !");
1138   double *tab=_mem.fromNoInterlace(getNumberOfComponents());
1139   DataArrayDouble *ret=DataArrayDouble::New();
1140   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
1141   return ret;
1142 }
1143
1144 /*!
1145  * Returns a new DataArrayDouble holding the same values as \a this array but differently
1146  * arranged in memory. If \a this array holds 2 components of 3 values:
1147  * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
1148  * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
1149  *  \warning Do not confuse this method with transpose()!
1150  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1151  *          is to delete using decrRef() as it is no more needed.
1152  *  \throw If \a this is not allocated.
1153  */
1154 DataArrayDouble *DataArrayDouble::toNoInterlace() const
1155 {
1156   if(_mem.isNull())
1157     throw INTERP_KERNEL::Exception("DataArrayDouble::toNoInterlace : Not defined array !");
1158   double *tab=_mem.toNoInterlace(getNumberOfComponents());
1159   DataArrayDouble *ret=DataArrayDouble::New();
1160   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
1161   return ret;
1162 }
1163
1164 /*!
1165  * Appends components of another array to components of \a this one, tuple by tuple.
1166  * So that the number of tuples of \a this array remains the same and the number of 
1167  * components increases.
1168  *  \param [in] other - the DataArrayDouble to append to \a this one.
1169  *  \throw If \a this is not allocated.
1170  *  \throw If \a this and \a other arrays have different number of tuples.
1171  *
1172  *  \if ENABLE_EXAMPLES
1173  *  \ref cpp_mcdataarraydouble_meldwith "Here is a C++ example".
1174  *
1175  *  \ref py_mcdataarraydouble_meldwith "Here is a Python example".
1176  *  \endif
1177  */
1178 void DataArrayDouble::meldWith(const DataArrayDouble *other)
1179 {
1180   checkAllocated();
1181   other->checkAllocated();
1182   int nbOfTuples=getNumberOfTuples();
1183   if(nbOfTuples!=other->getNumberOfTuples())
1184     throw INTERP_KERNEL::Exception("DataArrayDouble::meldWith : mismatch of number of tuples !");
1185   int nbOfComp1=getNumberOfComponents();
1186   int nbOfComp2=other->getNumberOfComponents();
1187   double *newArr=(double *)malloc((nbOfTuples*(nbOfComp1+nbOfComp2))*sizeof(double));
1188   double *w=newArr;
1189   const double *inp1=getConstPointer();
1190   const double *inp2=other->getConstPointer();
1191   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
1192     {
1193       w=std::copy(inp1,inp1+nbOfComp1,w);
1194       w=std::copy(inp2,inp2+nbOfComp2,w);
1195     }
1196   useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
1197   std::vector<int> compIds(nbOfComp2);
1198   for(int i=0;i<nbOfComp2;i++)
1199     compIds[i]=nbOfComp1+i;
1200   copyPartOfStringInfoFrom2(compIds,*other);
1201 }
1202
1203 /*!
1204  * This method checks that all tuples in \a other are in \a this.
1205  * If true, the output param \a tupleIds contains the tuples ids of \a this that correspond to tupes in \a this.
1206  * 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.
1207  *
1208  * \param [in] other - the array having the same number of components than \a this.
1209  * \param [out] tupleIds - the tuple ids containing the same number of tuples than \a other has.
1210  * \sa DataArrayDouble::findCommonTuples
1211  */
1212 bool DataArrayDouble::areIncludedInMe(const DataArrayDouble *other, double prec, DataArrayInt *&tupleIds) const
1213 {
1214   if(!other)
1215     throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : input array is NULL !");
1216   checkAllocated(); other->checkAllocated();
1217   if(getNumberOfComponents()!=other->getNumberOfComponents())
1218     throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : the number of components does not match !");
1219   MCAuto<DataArrayDouble> a=DataArrayDouble::Aggregate(this,other);
1220   DataArrayInt *c=0,*ci=0;
1221   a->findCommonTuples(prec,getNumberOfTuples(),c,ci);
1222   MCAuto<DataArrayInt> cSafe(c),ciSafe(ci);
1223   int newNbOfTuples=-1;
1224   MCAuto<DataArrayInt> ids=DataArrayInt::ConvertIndexArrayToO2N(a->getNumberOfTuples(),c->begin(),ci->begin(),ci->end(),newNbOfTuples);
1225   MCAuto<DataArrayInt> ret1=ids->selectByTupleIdSafeSlice(getNumberOfTuples(),a->getNumberOfTuples(),1);
1226   tupleIds=ret1.retn();
1227   return newNbOfTuples==getNumberOfTuples();
1228 }
1229
1230 /*!
1231  * Searches for tuples coincident within \a prec tolerance. Each tuple is considered
1232  * as coordinates of a point in getNumberOfComponents()-dimensional space. The
1233  * distance separating two points is computed with the infinite norm.
1234  *
1235  * Indices of coincident tuples are stored in output arrays.
1236  * A pair of arrays (\a comm, \a commIndex) is called "Surjective Format 2".
1237  *
1238  * This method is typically used by MEDCouplingPointSet::findCommonNodes() and
1239  * MEDCouplingUMesh::mergeNodes().
1240  *  \param [in] prec - minimal absolute distance between two tuples (infinite norm) at which they are
1241  *              considered not coincident.
1242  *  \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
1243  *              tuples have id strictly lower than \a limitTupleId then they are not returned.
1244  *  \param [out] comm - the array holding ids (== indices) of coincident tuples. 
1245  *               \a comm->getNumberOfComponents() == 1. 
1246  *               \a comm->getNumberOfTuples() == \a commIndex->back().
1247  *  \param [out] commIndex - the array dividing all indices stored in \a comm into
1248  *               groups of (indices of) coincident tuples. Its every value is a tuple
1249  *               index where a next group of tuples begins. For example the second
1250  *               group of tuples in \a comm is described by following range of indices:
1251  *               [ \a commIndex[1], \a commIndex[2] ). \a commIndex->getNumberOfTuples()-1
1252  *               gives the number of groups of coincident tuples.
1253  *  \throw If \a this is not allocated.
1254  *  \throw If the number of components is not in [1,2,3,4].
1255  *
1256  *  \if ENABLE_EXAMPLES
1257  *  \ref cpp_mcdataarraydouble_findcommontuples "Here is a C++ example".
1258  *
1259  *  \ref py_mcdataarraydouble_findcommontuples  "Here is a Python example".
1260  *  \endif
1261  *  \sa DataArrayInt::ConvertIndexArrayToO2N(), DataArrayDouble::areIncludedInMe
1262  */
1263 void DataArrayDouble::findCommonTuples(double prec, int limitTupleId, DataArrayInt *&comm, DataArrayInt *&commIndex) const
1264 {
1265   checkAllocated();
1266   int nbOfCompo=getNumberOfComponents();
1267   if ((nbOfCompo<1) || (nbOfCompo>4)) //test before work
1268     throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : Unexpected spacedim of coords. Must be 1, 2, 3 or 4.");
1269
1270   int nbOfTuples=getNumberOfTuples();
1271   //
1272   MCAuto<DataArrayInt> c(DataArrayInt::New()),cI(DataArrayInt::New()); c->alloc(0,1); cI->pushBackSilent(0);
1273   switch(nbOfCompo)
1274   {
1275     case 4:
1276       findCommonTuplesAlg<4>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1277       break;
1278     case 3:
1279       findCommonTuplesAlg<3>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1280       break;
1281     case 2:
1282       findCommonTuplesAlg<2>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1283       break;
1284     case 1:
1285       findCommonTuplesAlg<1>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1286       break;
1287     default:
1288       throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : nb of components managed are 1,2,3 and 4 ! not implemented for other number of components !");
1289   }
1290   comm=c.retn();
1291   commIndex=cI.retn();
1292 }
1293
1294 /*!
1295  * 
1296  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayDouble instance.
1297  *             \a nbTimes  should be at least equal to 1.
1298  * \return a newly allocated DataArrayDouble having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
1299  * \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.
1300  */
1301 DataArrayDouble *DataArrayDouble::duplicateEachTupleNTimes(int nbTimes) const
1302 {
1303   checkAllocated();
1304   if(getNumberOfComponents()!=1)
1305     throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : this should have only one component !");
1306   if(nbTimes<1)
1307     throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : nb times should be >= 1 !");
1308   int nbTuples=getNumberOfTuples();
1309   const double *inPtr=getConstPointer();
1310   MCAuto<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbTimes*nbTuples,1);
1311   double *retPtr=ret->getPointer();
1312   for(int i=0;i<nbTuples;i++,inPtr++)
1313     {
1314       double val=*inPtr;
1315       for(int j=0;j<nbTimes;j++,retPtr++)
1316         *retPtr=val;
1317     }
1318   ret->copyStringInfoFrom(*this);
1319   return ret.retn();
1320 }
1321
1322 /*!
1323  * This methods returns the minimal distance between the two set of points \a this and \a other.
1324  * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
1325  * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
1326  *
1327  * \param [out] thisTupleId the tuple id in \a this corresponding to the returned minimal distance
1328  * \param [out] otherTupleId the tuple id in \a other corresponding to the returned minimal distance
1329  * \return the minimal distance between the two set of points \a this and \a other.
1330  * \sa DataArrayDouble::findClosestTupleId
1331  */
1332 double DataArrayDouble::minimalDistanceTo(const DataArrayDouble *other, int& thisTupleId, int& otherTupleId) const
1333 {
1334   MCAuto<DataArrayInt> part1=findClosestTupleId(other);
1335   int nbOfCompo(getNumberOfComponents());
1336   int otherNbTuples(other->getNumberOfTuples());
1337   const double *thisPt(begin()),*otherPt(other->begin());
1338   const int *part1Pt(part1->begin());
1339   double ret=std::numeric_limits<double>::max();
1340   for(int i=0;i<otherNbTuples;i++,part1Pt++,otherPt+=nbOfCompo)
1341     {
1342       double tmp(0.);
1343       for(int j=0;j<nbOfCompo;j++)
1344         tmp+=(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j])*(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j]);
1345       if(tmp<ret)
1346         { ret=tmp; thisTupleId=*part1Pt; otherTupleId=i; }
1347     }
1348   return sqrt(ret);
1349 }
1350
1351 /*!
1352  * This methods returns for each tuple in \a other which tuple in \a this is the closest.
1353  * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
1354  * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
1355  *
1356  * \return a newly allocated (new object to be dealt by the caller) DataArrayInt having \c other->getNumberOfTuples() tuples and one components.
1357  * \sa DataArrayDouble::minimalDistanceTo
1358  */
1359 DataArrayInt *DataArrayDouble::findClosestTupleId(const DataArrayDouble *other) const
1360 {
1361   if(!other)
1362     throw INTERP_KERNEL::Exception("DataArrayDouble::findClosestTupleId : other instance is NULL !");
1363   checkAllocated(); other->checkAllocated();
1364   int nbOfCompo=getNumberOfComponents();
1365   if(nbOfCompo!=other->getNumberOfComponents())
1366     {
1367       std::ostringstream oss; oss << "DataArrayDouble::findClosestTupleId : number of components in this is " << nbOfCompo;
1368       oss << ", whereas number of components in other is " << other->getNumberOfComponents() << "! Should be equal !";
1369       throw INTERP_KERNEL::Exception(oss.str().c_str());
1370     }
1371   int nbOfTuples=other->getNumberOfTuples();
1372   int thisNbOfTuples=getNumberOfTuples();
1373   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuples,1);
1374   double bounds[6];
1375   getMinMaxPerComponent(bounds);
1376   switch(nbOfCompo)
1377   {
1378     case 3:
1379       {
1380         double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2])),zDelta(fabs(bounds[5]-bounds[4]));
1381         double delta=std::max(xDelta,yDelta); delta=std::max(delta,zDelta);
1382         double characSize=pow((delta*delta*delta)/((double)thisNbOfTuples),1./3.);
1383         BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1384         FindClosestTupleIdAlg<3>(myTree,3.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1385         break;
1386       }
1387     case 2:
1388       {
1389         double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2]));
1390         double delta=std::max(xDelta,yDelta);
1391         double characSize=sqrt(delta/(double)thisNbOfTuples);
1392         BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1393         FindClosestTupleIdAlg<2>(myTree,2.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1394         break;
1395       }
1396     case 1:
1397       {
1398         double characSize=fabs(bounds[1]-bounds[0])/thisNbOfTuples;
1399         BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1400         FindClosestTupleIdAlg<1>(myTree,1.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1401         break;
1402       }
1403     default:
1404       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for findClosestTupleId. Must be 1, 2 or 3.");
1405   }
1406   return ret.retn();
1407 }
1408
1409 /*!
1410  * This method expects that \a this and \a otherBBoxFrmt arrays are bounding box arrays ( as the output of MEDCouplingPointSet::getBoundingBoxForBBTree method ).
1411  * 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
1412  * how many bounding boxes in \a otherBBoxFrmt.
1413  * So, this method expects that \a this and \a otherBBoxFrmt have the same number of components.
1414  *
1415  * \param [in] otherBBoxFrmt - It is an array .
1416  * \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.
1417  * \sa MEDCouplingPointSet::getBoundingBoxForBBTree
1418  * \throw If \a this and \a otherBBoxFrmt have not the same number of components.
1419  * \throw If \a this and \a otherBBoxFrmt number of components is not even (BBox format).
1420  */
1421 DataArrayInt *DataArrayDouble::computeNbOfInteractionsWith(const DataArrayDouble *otherBBoxFrmt, double eps) const
1422 {
1423   if(!otherBBoxFrmt)
1424     throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : input array is NULL !");
1425   if(!isAllocated() || !otherBBoxFrmt->isAllocated())
1426     throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : this and input array must be allocated !");
1427   int nbOfComp(getNumberOfComponents()),nbOfTuples(getNumberOfTuples());
1428   if(nbOfComp!=otherBBoxFrmt->getNumberOfComponents())
1429     {
1430       std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : this number of components (" << nbOfComp << ") must be equal to the number of components of input array (" << otherBBoxFrmt->getNumberOfComponents() << ") !";
1431       throw INTERP_KERNEL::Exception(oss.str().c_str());
1432     }
1433   if(nbOfComp%2!=0)
1434     {
1435       std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : Number of components (" << nbOfComp << ") is not even ! It should be to be compatible with bbox format !";
1436       throw INTERP_KERNEL::Exception(oss.str().c_str());
1437     }
1438   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbOfTuples,1);
1439   const double *thisBBPtr(begin());
1440   int *retPtr(ret->getPointer());
1441   switch(nbOfComp/2)
1442   {
1443     case 3:
1444       {
1445         BBTree<3,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
1446         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
1447           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
1448         break;
1449       }
1450     case 2:
1451       {
1452         BBTree<2,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
1453         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
1454           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
1455         break;
1456       }
1457     case 1:
1458       {
1459         BBTree<1,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
1460         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
1461           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
1462         break;
1463       }
1464     default:
1465       throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : space dimension supported are [1,2,3] !");
1466   }
1467
1468   return ret.retn();
1469 }
1470
1471 /*!
1472  * Returns a copy of \a this array by excluding coincident tuples. Each tuple is
1473  * considered as coordinates of a point in getNumberOfComponents()-dimensional
1474  * space. The distance between tuples is computed using norm2. If several tuples are
1475  * not far each from other than \a prec, only one of them remains in the result
1476  * array. The order of tuples in the result array is same as in \a this one except
1477  * that coincident tuples are excluded.
1478  *  \param [in] prec - minimal absolute distance between two tuples at which they are
1479  *              considered not coincident.
1480  *  \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
1481  *              tuples have id strictly lower than \a limitTupleId then they are not excluded.
1482  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1483  *          is to delete using decrRef() as it is no more needed.
1484  *  \throw If \a this is not allocated.
1485  *  \throw If the number of components is not in [1,2,3,4].
1486  *
1487  *  \if ENABLE_EXAMPLES
1488  *  \ref py_mcdataarraydouble_getdifferentvalues "Here is a Python example".
1489  *  \endif
1490  */
1491 DataArrayDouble *DataArrayDouble::getDifferentValues(double prec, int limitTupleId) const
1492 {
1493   checkAllocated();
1494   DataArrayInt *c0=0,*cI0=0;
1495   findCommonTuples(prec,limitTupleId,c0,cI0);
1496   MCAuto<DataArrayInt> c(c0),cI(cI0);
1497   int newNbOfTuples=-1;
1498   MCAuto<DataArrayInt> o2n=DataArrayInt::ConvertIndexArrayToO2N(getNumberOfTuples(),c0->begin(),cI0->begin(),cI0->end(),newNbOfTuples);
1499   return renumberAndReduce(o2n->getConstPointer(),newNbOfTuples);
1500 }
1501
1502 /*!
1503  * Copy all components in a specified order from another DataArrayDouble.
1504  * Both numerical and textual data is copied. The number of tuples in \a this and
1505  * the other array can be different.
1506  *  \param [in] a - the array to copy data from.
1507  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
1508  *              to be copied.
1509  *  \throw If \a a is NULL.
1510  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
1511  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
1512  *
1513  *  \if ENABLE_EXAMPLES
1514  *  \ref py_mcdataarraydouble_setselectedcomponents "Here is a Python example".
1515  *  \endif
1516  */
1517 void DataArrayDouble::setSelectedComponents(const DataArrayDouble *a, const std::vector<int>& compoIds)
1518 {
1519   if(!a)
1520     throw INTERP_KERNEL::Exception("DataArrayDouble::setSelectedComponents : input DataArrayDouble is NULL !");
1521   checkAllocated();
1522   copyPartOfStringInfoFrom2(compoIds,*a);
1523   std::size_t partOfCompoSz=compoIds.size();
1524   int nbOfCompo=getNumberOfComponents();
1525   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
1526   const double *ac=a->getConstPointer();
1527   double *nc=getPointer();
1528   for(int i=0;i<nbOfTuples;i++)
1529     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
1530       nc[nbOfCompo*i+compoIds[j]]=*ac;
1531 }
1532
1533 void DataArrayDouble::SetArrayIn(DataArrayDouble *newArray, DataArrayDouble* &arrayToSet)
1534 {
1535   if(newArray!=arrayToSet)
1536     {
1537       if(arrayToSet)
1538         arrayToSet->decrRef();
1539       arrayToSet=newArray;
1540       if(arrayToSet)
1541         arrayToSet->incrRef();
1542     }
1543 }
1544
1545 void DataArrayDouble::aggregate(const DataArrayDouble *other)
1546 {
1547   if(!other)
1548     throw INTERP_KERNEL::Exception("DataArrayDouble::aggregate : null pointer !");
1549   if(getNumberOfComponents()!=other->getNumberOfComponents())
1550     throw INTERP_KERNEL::Exception("DataArrayDouble::aggregate : mismatch number of components !");
1551   _mem.insertAtTheEnd(other->begin(),other->end());
1552 }
1553
1554 /*!
1555  * Checks if 0.0 value is present in \a this array. If it is the case, an exception
1556  * is thrown.
1557  * \throw If zero is found in \a this array.
1558  */
1559 void DataArrayDouble::checkNoNullValues() const
1560 {
1561   const double *tmp=getConstPointer();
1562   std::size_t nbOfElems=getNbOfElems();
1563   const double *where=std::find(tmp,tmp+nbOfElems,0.);
1564   if(where!=tmp+nbOfElems)
1565     throw INTERP_KERNEL::Exception("A value 0.0 have been detected !");
1566 }
1567
1568 /*!
1569  * Computes minimal and maximal value in each component. An output array is filled
1570  * with \c 2 * \a this->getNumberOfComponents() values, so the caller is to allocate
1571  * enough memory before calling this method.
1572  *  \param [out] bounds - array of size at least 2 *\a this->getNumberOfComponents().
1573  *               It is filled as follows:<br>
1574  *               \a bounds[0] = \c min_of_component_0 <br>
1575  *               \a bounds[1] = \c max_of_component_0 <br>
1576  *               \a bounds[2] = \c min_of_component_1 <br>
1577  *               \a bounds[3] = \c max_of_component_1 <br>
1578  *               ...
1579  */
1580 void DataArrayDouble::getMinMaxPerComponent(double *bounds) const
1581 {
1582   checkAllocated();
1583   int dim=getNumberOfComponents();
1584   for (int idim=0; idim<dim; idim++)
1585     {
1586       bounds[idim*2]=std::numeric_limits<double>::max();
1587       bounds[idim*2+1]=-std::numeric_limits<double>::max();
1588     } 
1589   const double *ptr=getConstPointer();
1590   int nbOfTuples=getNumberOfTuples();
1591   for(int i=0;i<nbOfTuples;i++)
1592     {
1593       for(int idim=0;idim<dim;idim++)
1594         {
1595           if(bounds[idim*2]>ptr[i*dim+idim])
1596             {
1597               bounds[idim*2]=ptr[i*dim+idim];
1598             }
1599           if(bounds[idim*2+1]<ptr[i*dim+idim])
1600             {
1601               bounds[idim*2+1]=ptr[i*dim+idim];
1602             }
1603         }
1604     }
1605 }
1606
1607 /*!
1608  * This method retrieves a newly allocated DataArrayDouble instance having same number of tuples than \a this and twice number of components than \a this
1609  * to store both the min and max per component of each tuples. 
1610  * \param [in] epsilon the width of the bbox (identical in each direction) - 0.0 by default
1611  *
1612  * \return a newly created DataArrayDouble instance having \c this->getNumberOfTuples() tuples and 2 * \c this->getNumberOfComponent() components
1613  *
1614  * \throw If \a this is not allocated yet.
1615  */
1616 DataArrayDouble *DataArrayDouble::computeBBoxPerTuple(double epsilon) const
1617 {
1618   checkAllocated();
1619   const double *dataPtr=getConstPointer();
1620   int nbOfCompo=getNumberOfComponents();
1621   int nbTuples=getNumberOfTuples();
1622   MCAuto<DataArrayDouble> bbox=DataArrayDouble::New();
1623   bbox->alloc(nbTuples,2*nbOfCompo);
1624   double *bboxPtr=bbox->getPointer();
1625   for(int i=0;i<nbTuples;i++)
1626     {
1627       for(int j=0;j<nbOfCompo;j++)
1628         {
1629           bboxPtr[2*nbOfCompo*i+2*j]=dataPtr[nbOfCompo*i+j]-epsilon;
1630           bboxPtr[2*nbOfCompo*i+2*j+1]=dataPtr[nbOfCompo*i+j]+epsilon;
1631         }
1632     }
1633   return bbox.retn();
1634 }
1635
1636 /*!
1637  * For each tuples **t** in \a other, this method retrieves tuples in \a this that are equal to **t**.
1638  * Two tuples are considered equal if the euclidian distance between the two tuples is lower than \a eps.
1639  * 
1640  * \param [in] other a DataArrayDouble having same number of components than \a this.
1641  * \param [in] eps absolute precision representing distance (using infinite norm) between 2 tuples behind which 2 tuples are considered equal.
1642  * \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.
1643  *             \a cI allows to extract information in \a c.
1644  * \param [out] cI is an indirection array that allows to extract the data contained in \a c.
1645  *
1646  * \throw In case of:
1647  *  - \a this is not allocated
1648  *  - \a other is not allocated or null
1649  *  - \a this and \a other do not have the same number of components
1650  *  - if number of components of \a this is not in [1,2,3]
1651  *
1652  * \sa MEDCouplingPointSet::getNodeIdsNearPoints, DataArrayDouble::getDifferentValues
1653  */
1654 void DataArrayDouble::computeTupleIdsNearTuples(const DataArrayDouble *other, double eps, DataArrayInt *& c, DataArrayInt *& cI) const
1655 {
1656   if(!other)
1657     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : input pointer other is null !");
1658   checkAllocated();
1659   other->checkAllocated();
1660   int nbOfCompo=getNumberOfComponents();
1661   int otherNbOfCompo=other->getNumberOfComponents();
1662   if(nbOfCompo!=otherNbOfCompo)
1663     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : number of components should be equal between this and other !");
1664   int nbOfTuplesOther=other->getNumberOfTuples();
1665   MCAuto<DataArrayInt> cArr(DataArrayInt::New()),cIArr(DataArrayInt::New()); cArr->alloc(0,1); cIArr->pushBackSilent(0);
1666   switch(nbOfCompo)
1667   {
1668     case 3:
1669       {
1670         BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
1671         FindTupleIdsNearTuplesAlg<3>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
1672         break;
1673       }
1674     case 2:
1675       {
1676         BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
1677         FindTupleIdsNearTuplesAlg<2>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
1678         break;
1679       }
1680     case 1:
1681       {
1682         BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
1683         FindTupleIdsNearTuplesAlg<1>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
1684         break;
1685       }
1686     default:
1687       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for computeTupleIdsNearTuples. Must be 1, 2 or 3.");
1688   }
1689   c=cArr.retn(); cI=cIArr.retn();
1690 }
1691
1692 /*!
1693  * 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
1694  * around origin of 'radius' 1.
1695  * 
1696  * \param [in] eps absolute epsilon. under that value of delta between max and min no scale is performed.
1697  */
1698 void DataArrayDouble::recenterForMaxPrecision(double eps)
1699 {
1700   checkAllocated();
1701   int dim=getNumberOfComponents();
1702   std::vector<double> bounds(2*dim);
1703   getMinMaxPerComponent(&bounds[0]);
1704   for(int i=0;i<dim;i++)
1705     {
1706       double delta=bounds[2*i+1]-bounds[2*i];
1707       double offset=(bounds[2*i]+bounds[2*i+1])/2.;
1708       if(delta>eps)
1709         applyLin(1./delta,-offset/delta,i);
1710       else
1711         applyLin(1.,-offset,i);
1712     }
1713 }
1714
1715 /*!
1716  * Returns the maximal value and all its locations within \a this one-dimensional array.
1717  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
1718  *               tuples holding the maximal value. The caller is to delete it using
1719  *               decrRef() as it is no more needed.
1720  *  \return double - the maximal value among all values of \a this array.
1721  *  \throw If \a this->getNumberOfComponents() != 1
1722  *  \throw If \a this->getNumberOfTuples() < 1
1723  */
1724 double DataArrayDouble::getMaxValue2(DataArrayInt*& tupleIds) const
1725 {
1726   int tmp;
1727   tupleIds=0;
1728   double ret=getMaxValue(tmp);
1729   tupleIds=findIdsInRange(ret,ret);
1730   return ret;
1731 }
1732
1733 /*!
1734  * Returns the minimal value and all its locations within \a this one-dimensional array.
1735  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
1736  *               tuples holding the minimal value. The caller is to delete it using
1737  *               decrRef() as it is no more needed.
1738  *  \return double - the minimal value among all values of \a this array.
1739  *  \throw If \a this->getNumberOfComponents() != 1
1740  *  \throw If \a this->getNumberOfTuples() < 1
1741  */
1742 double DataArrayDouble::getMinValue2(DataArrayInt*& tupleIds) const
1743 {
1744   int tmp;
1745   tupleIds=0;
1746   double ret=getMinValue(tmp);
1747   tupleIds=findIdsInRange(ret,ret);
1748   return ret;
1749 }
1750
1751 /*!
1752  * 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.
1753  * This method only works for single component array.
1754  *
1755  * \return a value in [ 0, \c this->getNumberOfTuples() )
1756  *
1757  * \throw If \a this is not allocated
1758  *
1759  */
1760 int DataArrayDouble::count(double value, double eps) const
1761 {
1762   int ret=0;
1763   checkAllocated();
1764   if(getNumberOfComponents()!=1)
1765     throw INTERP_KERNEL::Exception("DataArrayDouble::count : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
1766   const double *vals=begin();
1767   int nbOfTuples=getNumberOfTuples();
1768   for(int i=0;i<nbOfTuples;i++,vals++)
1769     if(fabs(*vals-value)<=eps)
1770       ret++;
1771   return ret;
1772 }
1773
1774 /*!
1775  * Returns the average value of \a this one-dimensional array.
1776  *  \return double - the average value over all values of \a this array.
1777  *  \throw If \a this->getNumberOfComponents() != 1
1778  *  \throw If \a this->getNumberOfTuples() < 1
1779  */
1780 double DataArrayDouble::getAverageValue() const
1781 {
1782   if(getNumberOfComponents()!=1)
1783     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
1784   int nbOfTuples=getNumberOfTuples();
1785   if(nbOfTuples<=0)
1786     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : array exists but number of tuples must be > 0 !");
1787   const double *vals=getConstPointer();
1788   double ret=std::accumulate(vals,vals+nbOfTuples,0.);
1789   return ret/nbOfTuples;
1790 }
1791
1792 /*!
1793  * Returns the Euclidean norm of the vector defined by \a this array.
1794  *  \return double - the value of the Euclidean norm, i.e.
1795  *          the square root of the inner product of vector.
1796  *  \throw If \a this is not allocated.
1797  */
1798 double DataArrayDouble::norm2() const
1799 {
1800   checkAllocated();
1801   double ret=0.;
1802   std::size_t nbOfElems=getNbOfElems();
1803   const double *pt=getConstPointer();
1804   for(std::size_t i=0;i<nbOfElems;i++,pt++)
1805     ret+=(*pt)*(*pt);
1806   return sqrt(ret);
1807 }
1808
1809 /*!
1810  * Returns the maximum norm of the vector defined by \a this array.
1811  * This method works even if the number of components is diferent from one.
1812  * If the number of elements in \a this is 0, -1. is returned.
1813  *  \return double - the value of the maximum norm, i.e.
1814  *          the maximal absolute value among values of \a this array (whatever its number of components).
1815  *  \throw If \a this is not allocated.
1816  */
1817 double DataArrayDouble::normMax() const
1818 {
1819   checkAllocated();
1820   double ret(-1.);
1821   std::size_t nbOfElems(getNbOfElems());
1822   const double *pt(getConstPointer());
1823   for(std::size_t i=0;i<nbOfElems;i++,pt++)
1824     {
1825       double val(std::abs(*pt));
1826       if(val>ret)
1827         ret=val;
1828     }
1829   return ret;
1830 }
1831
1832 /*!
1833  * Returns the minimum norm (absolute value) of the vector defined by \a this array.
1834  * This method works even if the number of components is diferent from one.
1835  * If the number of elements in \a this is 0, std::numeric_limits<double>::max() is returned.
1836  *  \return double - the value of the minimum norm, i.e.
1837  *          the minimal absolute value among values of \a this array (whatever its number of components).
1838  *  \throw If \a this is not allocated.
1839  */
1840 double DataArrayDouble::normMin() const
1841 {
1842   checkAllocated();
1843   double ret(std::numeric_limits<double>::max());
1844   std::size_t nbOfElems(getNbOfElems());
1845   const double *pt(getConstPointer());
1846   for(std::size_t i=0;i<nbOfElems;i++,pt++)
1847     {
1848       double val(std::abs(*pt));
1849       if(val<ret)
1850         ret=val;
1851     }
1852   return ret;
1853 }
1854
1855 /*!
1856  * Accumulates values of each component of \a this array.
1857  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
1858  *         by the caller, that is filled by this method with sum value for each
1859  *         component.
1860  *  \throw If \a this is not allocated.
1861  */
1862 void DataArrayDouble::accumulate(double *res) const
1863 {
1864   checkAllocated();
1865   const double *ptr=getConstPointer();
1866   int nbTuple=getNumberOfTuples();
1867   int nbComps=getNumberOfComponents();
1868   std::fill(res,res+nbComps,0.);
1869   for(int i=0;i<nbTuple;i++)
1870     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<double>());
1871 }
1872
1873 /*!
1874  * This method returns the min distance from an external tuple defined by [ \a tupleBg , \a tupleEnd ) to \a this and
1875  * the first tuple in \a this that matches the returned distance. If there is no tuples in \a this an exception will be thrown.
1876  *
1877  *
1878  * \a this is expected to be allocated and expected to have a number of components equal to the distance from \a tupleBg to
1879  * \a tupleEnd. If not an exception will be thrown.
1880  *
1881  * \param [in] tupleBg start pointer (included) of input external tuple
1882  * \param [in] tupleEnd end pointer (not included) of input external tuple
1883  * \param [out] tupleId the tuple id in \a this that matches the min of distance between \a this and input external tuple
1884  * \return the min distance.
1885  * \sa MEDCouplingUMesh::distanceToPoint
1886  */
1887 double DataArrayDouble::distanceToTuple(const double *tupleBg, const double *tupleEnd, int& tupleId) const
1888 {
1889   checkAllocated();
1890   int nbTuple=getNumberOfTuples();
1891   int nbComps=getNumberOfComponents();
1892   if(nbComps!=(int)std::distance(tupleBg,tupleEnd))
1893     { 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()); }
1894   if(nbTuple==0)
1895     throw INTERP_KERNEL::Exception("DataArrayDouble::distanceToTuple : no tuple in this ! No distance to compute !");
1896   double ret0=std::numeric_limits<double>::max();
1897   tupleId=-1;
1898   const double *work=getConstPointer();
1899   for(int i=0;i<nbTuple;i++)
1900     {
1901       double val=0.;
1902       for(int j=0;j<nbComps;j++,work++) 
1903         val+=(*work-tupleBg[j])*((*work-tupleBg[j]));
1904       if(val>=ret0)
1905         continue;
1906       else
1907         { ret0=val; tupleId=i; }
1908     }
1909   return sqrt(ret0);
1910 }
1911
1912 /*!
1913  * Accumulate values of the given component of \a this array.
1914  *  \param [in] compId - the index of the component of interest.
1915  *  \return double - a sum value of \a compId-th component.
1916  *  \throw If \a this is not allocated.
1917  *  \throw If \a the condition ( 0 <= \a compId < \a this->getNumberOfComponents() ) is
1918  *         not respected.
1919  */
1920 double DataArrayDouble::accumulate(int compId) const
1921 {
1922   checkAllocated();
1923   const double *ptr=getConstPointer();
1924   int nbTuple=getNumberOfTuples();
1925   int nbComps=getNumberOfComponents();
1926   if(compId<0 || compId>=nbComps)
1927     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulate : Invalid compId specified : No such nb of components !");
1928   double ret=0.;
1929   for(int i=0;i<nbTuple;i++)
1930     ret+=ptr[i*nbComps+compId];
1931   return ret;
1932 }
1933
1934 /*!
1935  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
1936  * The returned array will have same number of components than \a this and number of tuples equal to
1937  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
1938  *
1939  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
1940  * 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.
1941  *
1942  * \param [in] bgOfIndex - begin (included) of the input index array.
1943  * \param [in] endOfIndex - end (excluded) of the input index array.
1944  * \return DataArrayDouble * - the new instance having the same number of components than \a this.
1945  * 
1946  * \throw If bgOfIndex or end is NULL.
1947  * \throw If input index array is not ascendingly sorted.
1948  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
1949  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
1950  */
1951 DataArrayDouble *DataArrayDouble::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
1952 {
1953   if(!bgOfIndex || !endOfIndex)
1954     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : input pointer NULL !");
1955   checkAllocated();
1956   int nbCompo=getNumberOfComponents();
1957   int nbOfTuples=getNumberOfTuples();
1958   int sz=(int)std::distance(bgOfIndex,endOfIndex);
1959   if(sz<1)
1960     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : invalid size of input index array !");
1961   sz--;
1962   MCAuto<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(sz,nbCompo);
1963   const int *w=bgOfIndex;
1964   if(*w<0 || *w>=nbOfTuples)
1965     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
1966   const double *srcPt=begin()+(*w)*nbCompo;
1967   double *tmp=ret->getPointer();
1968   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
1969     {
1970       std::fill(tmp,tmp+nbCompo,0.);
1971       if(w[1]>=w[0])
1972         {
1973           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
1974             {
1975               if(j>=0 && j<nbOfTuples)
1976                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<double>());
1977               else
1978                 {
1979                   std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
1980                   throw INTERP_KERNEL::Exception(oss.str().c_str());
1981                 }
1982             }
1983         }
1984       else
1985         {
1986           std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
1987           throw INTERP_KERNEL::Exception(oss.str().c_str());
1988         }
1989     }
1990   ret->copyStringInfoFrom(*this);
1991   return ret.retn();
1992 }
1993
1994 /*!
1995  * This method is close to numpy cumSum except that number of element is equal to \a this->getNumberOfTuples()+1. First element of DataArray returned is equal to 0.
1996  * This method expects that \a this as only one component. The returned array will have \a this->getNumberOfTuples()+1 tuple with also one component.
1997  * The ith element of returned array is equal to the sum of elements in \a this with rank strictly lower than i.
1998  *
1999  * \return DataArrayDouble - A newly built array containing cum sum of \a this.
2000  */
2001 MCAuto<DataArrayDouble> DataArrayDouble::cumSum() const
2002 {
2003   checkAllocated();
2004   checkNbOfComps(1,"DataArrayDouble::cumSum : this is expected to be single component");
2005   int nbOfTuple(getNumberOfTuples());
2006   MCAuto<DataArrayDouble> ret(DataArrayDouble::New()); ret->alloc(nbOfTuple+1,1);
2007   double *ptr(ret->getPointer());
2008   ptr[0]=0.;
2009   const double *thisPtr(begin());
2010   for(int i=0;i<nbOfTuple;i++)
2011     ptr[i+1]=ptr[i]+thisPtr[i];
2012   return ret;
2013 }
2014
2015 /*!
2016  * Converts each 2D point defined by the tuple of \a this array from the Polar to the
2017  * Cartesian coordinate system. The two components of the tuple of \a this array are 
2018  * considered to contain (1) radius and (2) angle of the point in the Polar CS.
2019  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
2020  *          contains X and Y coordinates of the point in the Cartesian CS. The caller
2021  *          is to delete this array using decrRef() as it is no more needed. The array
2022  *          does not contain any textual info on components.
2023  *  \throw If \a this->getNumberOfComponents() != 2.
2024  * \sa fromCartToPolar
2025  */
2026 DataArrayDouble *DataArrayDouble::fromPolarToCart() const
2027 {
2028   checkAllocated();
2029   int nbOfComp(getNumberOfComponents());
2030   if(nbOfComp!=2)
2031     throw INTERP_KERNEL::Exception("DataArrayDouble::fromPolarToCart : must be an array with exactly 2 components !");
2032   int nbOfTuple(getNumberOfTuples());
2033   DataArrayDouble *ret(DataArrayDouble::New());
2034   ret->alloc(nbOfTuple,2);
2035   double *w(ret->getPointer());
2036   const double *wIn(getConstPointer());
2037   for(int i=0;i<nbOfTuple;i++,w+=2,wIn+=2)
2038     {
2039       w[0]=wIn[0]*cos(wIn[1]);
2040       w[1]=wIn[0]*sin(wIn[1]);
2041     }
2042   return ret;
2043 }
2044
2045 /*!
2046  * Converts each 3D point defined by the tuple of \a this array from the Cylindrical to
2047  * the Cartesian coordinate system. The three components of the tuple of \a this array 
2048  * are considered to contain (1) radius, (2) azimuth and (3) altitude of the point in
2049  * the Cylindrical CS.
2050  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
2051  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
2052  *          on the third component is copied from \a this array. The caller
2053  *          is to delete this array using decrRef() as it is no more needed. 
2054  *  \throw If \a this->getNumberOfComponents() != 3.
2055  * \sa fromCartToCyl
2056  */
2057 DataArrayDouble *DataArrayDouble::fromCylToCart() const
2058 {
2059   checkAllocated();
2060   int nbOfComp(getNumberOfComponents());
2061   if(nbOfComp!=3)
2062     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCylToCart : must be an array with exactly 3 components !");
2063   int nbOfTuple(getNumberOfTuples());
2064   DataArrayDouble *ret(DataArrayDouble::New());
2065   ret->alloc(getNumberOfTuples(),3);
2066   double *w(ret->getPointer());
2067   const double *wIn(getConstPointer());
2068   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
2069     {
2070       w[0]=wIn[0]*cos(wIn[1]);
2071       w[1]=wIn[0]*sin(wIn[1]);
2072       w[2]=wIn[2];
2073     }
2074   ret->setInfoOnComponent(2,getInfoOnComponent(2));
2075   return ret;
2076 }
2077
2078 /*!
2079  * Converts each 3D point defined by the tuple of \a this array from the Spherical to
2080  * the Cartesian coordinate system. The three components of the tuple of \a this array 
2081  * are considered to contain (1) radius, (2) polar angle and (3) azimuthal angle of the
2082  * point in the Cylindrical CS.
2083  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
2084  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
2085  *          on the third component is copied from \a this array. The caller
2086  *          is to delete this array using decrRef() as it is no more needed.
2087  *  \throw If \a this->getNumberOfComponents() != 3.
2088  * \sa fromCartToSpher
2089  */
2090 DataArrayDouble *DataArrayDouble::fromSpherToCart() const
2091 {
2092   checkAllocated();
2093   int nbOfComp(getNumberOfComponents());
2094   if(nbOfComp!=3)
2095     throw INTERP_KERNEL::Exception("DataArrayDouble::fromSpherToCart : must be an array with exactly 3 components !");
2096   int nbOfTuple(getNumberOfTuples());
2097   DataArrayDouble *ret(DataArrayDouble::New());
2098   ret->alloc(getNumberOfTuples(),3);
2099   double *w(ret->getPointer());
2100   const double *wIn(getConstPointer());
2101   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
2102     {
2103       w[0]=wIn[0]*cos(wIn[2])*sin(wIn[1]);
2104       w[1]=wIn[0]*sin(wIn[2])*sin(wIn[1]);
2105       w[2]=wIn[0]*cos(wIn[1]);
2106     }
2107   return ret;
2108 }
2109
2110 /*!
2111  * 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.
2112  * 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.
2113  * If \a at equals to AX_CYL the returned array will be the result of operation cylindric to cartesian of \a this...
2114  *
2115  * \param [in] atOfThis - The axis type of \a this.
2116  * \return DataArrayDouble * - the new instance of DataArrayDouble (that must be dealed by caller) containing the result of the cartesianizification of \a this.
2117  */
2118 DataArrayDouble *DataArrayDouble::cartesianize(MEDCouplingAxisType atOfThis) const
2119 {
2120   checkAllocated();
2121   int nbOfComp(getNumberOfComponents());
2122   MCAuto<DataArrayDouble> ret;
2123   switch(atOfThis)
2124     {
2125     case AX_CART:
2126       ret=deepCopy();
2127     case AX_CYL:
2128       if(nbOfComp==3)
2129         {
2130           ret=fromCylToCart();
2131           break;
2132         }
2133       if(nbOfComp==2)
2134         {
2135           ret=fromPolarToCart();
2136           break;
2137         }
2138       else
2139         throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : For AX_CYL, number of components must be in [2,3] !");
2140     case AX_SPHER:
2141       if(nbOfComp==3)
2142         {
2143           ret=fromSpherToCart();
2144           break;
2145         }
2146       if(nbOfComp==2)
2147         {
2148           ret=fromPolarToCart();
2149           break;
2150         }
2151       else
2152         throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : For AX_CYL, number of components must be in [2,3] !");
2153     default:
2154       throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : not recognized axis type ! Only AX_CART, AX_CYL and AX_SPHER supported !");
2155     }
2156   ret->copyStringInfoFrom(*this);
2157   return ret.retn();
2158 }
2159
2160 /*!
2161  * This method returns a newly created array to be deallocated that contains the result of conversion from cartesian to polar.
2162  * This method expects that \a this has exactly 2 components.
2163  * \sa fromPolarToCart
2164  */
2165 DataArrayDouble *DataArrayDouble::fromCartToPolar() const
2166 {
2167   MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2168   checkAllocated();
2169   int nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2170   if(nbOfComp!=2)
2171     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToPolar : must be an array with exactly 2 components !");
2172   ret->alloc(nbTuples,2);
2173   double *retPtr(ret->getPointer());
2174   const double *ptr(begin());
2175   for(int i=0;i<nbTuples;i++,ptr+=2,retPtr+=2)
2176     {
2177       retPtr[0]=sqrt(ptr[0]*ptr[0]+ptr[1]*ptr[1]);
2178       retPtr[1]=atan2(ptr[1],ptr[0]);
2179     }
2180   return ret.retn();
2181 }
2182
2183 /*!
2184  * This method returns a newly created array to be deallocated that contains the result of conversion from cartesian to cylindrical.
2185  * This method expects that \a this has exactly 3 components.
2186  * \sa fromCylToCart
2187  */
2188 DataArrayDouble *DataArrayDouble::fromCartToCyl() const
2189 {
2190   MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2191   checkAllocated();
2192   int nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2193   if(nbOfComp!=3)
2194     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCyl : must be an array with exactly 3 components !");
2195   ret->alloc(nbTuples,3);
2196   double *retPtr(ret->getPointer());
2197   const double *ptr(begin());
2198   for(int i=0;i<nbTuples;i++,ptr+=3,retPtr+=3)
2199     {
2200       retPtr[0]=sqrt(ptr[0]*ptr[0]+ptr[1]*ptr[1]);
2201       retPtr[1]=atan2(ptr[1],ptr[0]);
2202       retPtr[2]=ptr[2];
2203     }
2204   return ret.retn();
2205 }
2206
2207 /*!
2208  * This method returns a newly created array to be deallocated that contains the result of conversion from cartesian to spherical coordinates.
2209  * \sa fromSpherToCart
2210  */
2211 DataArrayDouble *DataArrayDouble::fromCartToSpher() const
2212 {
2213   MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2214   checkAllocated();
2215   int nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2216   if(nbOfComp!=3)
2217     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToSpher : must be an array with exactly 3 components !");
2218   ret->alloc(nbTuples,3);
2219   double *retPtr(ret->getPointer());
2220   const double *ptr(begin());
2221   for(int i=0;i<nbTuples;i++,ptr+=3,retPtr+=3)
2222     {
2223       retPtr[0]=sqrt(ptr[0]*ptr[0]+ptr[1]*ptr[1]+ptr[2]*ptr[2]);
2224       retPtr[1]=acos(ptr[2]/retPtr[0]);
2225       retPtr[2]=atan2(ptr[1],ptr[0]);
2226     }
2227   return ret.retn();
2228 }
2229
2230 /*!
2231  * 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.
2232  * This method expects that \a this has exactly 3 components.
2233  * \sa MEDCouplingFieldDouble::computeVectorFieldCyl
2234  */
2235 DataArrayDouble *DataArrayDouble::fromCartToCylGiven(const DataArrayDouble *coords, const double center[3], const double vect[3]) const
2236 {
2237   if(!coords)
2238     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : input coords are NULL !");
2239   MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2240   checkAllocated(); coords->checkAllocated();
2241   int nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2242   if(nbOfComp!=3)
2243     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : must be an array with exactly 3 components !");
2244   if(coords->getNumberOfComponents()!=3)
2245     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : coords array must have exactly 3 components !");
2246   if(coords->getNumberOfTuples()!=nbTuples)
2247     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : coords array must have the same number of tuples !");
2248   ret->alloc(nbTuples,nbOfComp);
2249   double magOfVect(sqrt(vect[0]*vect[0]+vect[1]*vect[1]+vect[2]*vect[2]));
2250   if(magOfVect<1e-12)
2251     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : magnitude of vect is too low !");
2252   double Ur[3],Uteta[3],Uz[3],*retPtr(ret->getPointer());
2253   const double *coo(coords->begin()),*vectField(begin());
2254   std::transform(vect,vect+3,Uz,std::bind2nd(std::multiplies<double>(),1./magOfVect));
2255   for(int i=0;i<nbTuples;i++,vectField+=3,retPtr+=3,coo+=3)
2256     {
2257       std::transform(coo,coo+3,center,Ur,std::minus<double>());
2258       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];
2259       double magOfTeta(sqrt(Uteta[0]*Uteta[0]+Uteta[1]*Uteta[1]+Uteta[2]*Uteta[2]));
2260       std::transform(Uteta,Uteta+3,Uteta,std::bind2nd(std::multiplies<double>(),1./magOfTeta));
2261       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];
2262       retPtr[0]=Ur[0]*vectField[0]+Ur[1]*vectField[1]+Ur[2]*vectField[2];
2263       retPtr[1]=Uteta[0]*vectField[0]+Uteta[1]*vectField[1]+Uteta[2]*vectField[2];
2264       retPtr[2]=Uz[0]*vectField[0]+Uz[1]*vectField[1]+Uz[2]*vectField[2];
2265     }
2266   ret->copyStringInfoFrom(*this);
2267   return ret.retn();
2268 }
2269
2270 /*!
2271  * Computes the doubly contracted product of every tensor defined by the tuple of \a this
2272  * array contating 6 components.
2273  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
2274  *          is calculated from the tuple <em>(t)</em> of \a this array as follows:
2275  *          \f$ t[0]^2+t[1]^2+t[2]^2+2*t[3]^2+2*t[4]^2+2*t[5]^2\f$.
2276  *         The caller is to delete this result array using decrRef() as it is no more needed. 
2277  *  \throw If \a this->getNumberOfComponents() != 6.
2278  */
2279 DataArrayDouble *DataArrayDouble::doublyContractedProduct() const
2280 {
2281   checkAllocated();
2282   int nbOfComp(getNumberOfComponents());
2283   if(nbOfComp!=6)
2284     throw INTERP_KERNEL::Exception("DataArrayDouble::doublyContractedProduct : must be an array with exactly 6 components !");
2285   DataArrayDouble *ret=DataArrayDouble::New();
2286   int nbOfTuple=getNumberOfTuples();
2287   ret->alloc(nbOfTuple,1);
2288   const double *src=getConstPointer();
2289   double *dest=ret->getPointer();
2290   for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
2291     *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];
2292   return ret;
2293 }
2294
2295 /*!
2296  * Computes the determinant of every square matrix defined by the tuple of \a this
2297  * array, which contains either 4, 6 or 9 components. The case of 6 components
2298  * corresponds to that of the upper triangular matrix.
2299  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
2300  *          is the determinant of matrix of the corresponding tuple of \a this array.
2301  *          The caller is to delete this result array using decrRef() as it is no more
2302  *          needed. 
2303  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2304  */
2305 DataArrayDouble *DataArrayDouble::determinant() const
2306 {
2307   checkAllocated();
2308   DataArrayDouble *ret=DataArrayDouble::New();
2309   int nbOfTuple=getNumberOfTuples();
2310   ret->alloc(nbOfTuple,1);
2311   const double *src=getConstPointer();
2312   double *dest=ret->getPointer();
2313   switch(getNumberOfComponents())
2314   {
2315     case 6:
2316       for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
2317         *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];
2318       return ret;
2319     case 4:
2320       for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
2321         *dest=src[0]*src[3]-src[1]*src[2];
2322       return ret;
2323     case 9:
2324       for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
2325         *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];
2326       return ret;
2327     default:
2328       ret->decrRef();
2329       throw INTERP_KERNEL::Exception("DataArrayDouble::determinant : Invalid number of components ! must be in 4,6,9 !");
2330   }
2331 }
2332
2333 /*!
2334  * Computes 3 eigenvalues of every upper triangular matrix defined by the tuple of
2335  * \a this array, which contains 6 components.
2336  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 3
2337  *          components, whose each tuple contains the eigenvalues of the matrix of
2338  *          corresponding tuple of \a this array. 
2339  *          The caller is to delete this result array using decrRef() as it is no more
2340  *          needed. 
2341  *  \throw If \a this->getNumberOfComponents() != 6.
2342  */
2343 DataArrayDouble *DataArrayDouble::eigenValues() const
2344 {
2345   checkAllocated();
2346   int nbOfComp=getNumberOfComponents();
2347   if(nbOfComp!=6)
2348     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenValues : must be an array with exactly 6 components !");
2349   DataArrayDouble *ret=DataArrayDouble::New();
2350   int nbOfTuple=getNumberOfTuples();
2351   ret->alloc(nbOfTuple,3);
2352   const double *src=getConstPointer();
2353   double *dest=ret->getPointer();
2354   for(int i=0;i<nbOfTuple;i++,dest+=3,src+=6)
2355     INTERP_KERNEL::computeEigenValues6(src,dest);
2356   return ret;
2357 }
2358
2359 /*!
2360  * Computes 3 eigenvectors of every upper triangular matrix defined by the tuple of
2361  * \a this array, which contains 6 components.
2362  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 9
2363  *          components, whose each tuple contains 3 eigenvectors of the matrix of
2364  *          corresponding tuple of \a this array.
2365  *          The caller is to delete this result array using decrRef() as it is no more
2366  *          needed.
2367  *  \throw If \a this->getNumberOfComponents() != 6.
2368  */
2369 DataArrayDouble *DataArrayDouble::eigenVectors() const
2370 {
2371   checkAllocated();
2372   int nbOfComp=getNumberOfComponents();
2373   if(nbOfComp!=6)
2374     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenVectors : must be an array with exactly 6 components !");
2375   DataArrayDouble *ret=DataArrayDouble::New();
2376   int nbOfTuple=getNumberOfTuples();
2377   ret->alloc(nbOfTuple,9);
2378   const double *src=getConstPointer();
2379   double *dest=ret->getPointer();
2380   for(int i=0;i<nbOfTuple;i++,src+=6)
2381     {
2382       double tmp[3];
2383       INTERP_KERNEL::computeEigenValues6(src,tmp);
2384       for(int j=0;j<3;j++,dest+=3)
2385         INTERP_KERNEL::computeEigenVectorForEigenValue6(src,tmp[j],1e-12,dest);
2386     }
2387   return ret;
2388 }
2389
2390 /*!
2391  * Computes the inverse matrix of every matrix defined by the tuple of \a this
2392  * array, which contains either 4, 6 or 9 components. The case of 6 components
2393  * corresponds to that of the upper triangular matrix.
2394  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2395  *          same number of components as \a this one, whose each tuple is the inverse
2396  *          matrix of the matrix of corresponding tuple of \a this array. 
2397  *          The caller is to delete this result array using decrRef() as it is no more
2398  *          needed. 
2399  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2400  */
2401 DataArrayDouble *DataArrayDouble::inverse() const
2402 {
2403   checkAllocated();
2404   int nbOfComp=getNumberOfComponents();
2405   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
2406     throw INTERP_KERNEL::Exception("DataArrayDouble::inversion : must be an array with 4,6 or 9 components !");
2407   DataArrayDouble *ret=DataArrayDouble::New();
2408   int nbOfTuple=getNumberOfTuples();
2409   ret->alloc(nbOfTuple,nbOfComp);
2410   const double *src=getConstPointer();
2411   double *dest=ret->getPointer();
2412   if(nbOfComp==6)
2413     for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
2414       {
2415         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];
2416         dest[0]=(src[1]*src[2]-src[4]*src[4])/det;
2417         dest[1]=(src[0]*src[2]-src[5]*src[5])/det;
2418         dest[2]=(src[0]*src[1]-src[3]*src[3])/det;
2419         dest[3]=(src[5]*src[4]-src[3]*src[2])/det;
2420         dest[4]=(src[5]*src[3]-src[0]*src[4])/det;
2421         dest[5]=(src[3]*src[4]-src[1]*src[5])/det;
2422       }
2423   else if(nbOfComp==4)
2424     for(int i=0;i<nbOfTuple;i++,dest+=4,src+=4)
2425       {
2426         double det=src[0]*src[3]-src[1]*src[2];
2427         dest[0]=src[3]/det;
2428         dest[1]=-src[1]/det;
2429         dest[2]=-src[2]/det;
2430         dest[3]=src[0]/det;
2431       }
2432   else
2433     for(int i=0;i<nbOfTuple;i++,dest+=9,src+=9)
2434       {
2435         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];
2436         dest[0]=(src[4]*src[8]-src[7]*src[5])/det;
2437         dest[1]=(src[7]*src[2]-src[1]*src[8])/det;
2438         dest[2]=(src[1]*src[5]-src[4]*src[2])/det;
2439         dest[3]=(src[6]*src[5]-src[3]*src[8])/det;
2440         dest[4]=(src[0]*src[8]-src[6]*src[2])/det;
2441         dest[5]=(src[2]*src[3]-src[0]*src[5])/det;
2442         dest[6]=(src[3]*src[7]-src[6]*src[4])/det;
2443         dest[7]=(src[6]*src[1]-src[0]*src[7])/det;
2444         dest[8]=(src[0]*src[4]-src[1]*src[3])/det;
2445       }
2446   return ret;
2447 }
2448
2449 /*!
2450  * Computes the trace of every matrix defined by the tuple of \a this
2451  * array, which contains either 4, 6 or 9 components. The case of 6 components
2452  * corresponds to that of the upper triangular matrix.
2453  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 
2454  *          1 component, whose each tuple is the trace of
2455  *          the matrix of corresponding tuple of \a this array. 
2456  *          The caller is to delete this result array using decrRef() as it is no more
2457  *          needed. 
2458  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2459  */
2460 DataArrayDouble *DataArrayDouble::trace() const
2461 {
2462   checkAllocated();
2463   int nbOfComp=getNumberOfComponents();
2464   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
2465     throw INTERP_KERNEL::Exception("DataArrayDouble::trace : must be an array with 4,6 or 9 components !");
2466   DataArrayDouble *ret=DataArrayDouble::New();
2467   int nbOfTuple=getNumberOfTuples();
2468   ret->alloc(nbOfTuple,1);
2469   const double *src=getConstPointer();
2470   double *dest=ret->getPointer();
2471   if(nbOfComp==6)
2472     for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
2473       *dest=src[0]+src[1]+src[2];
2474   else if(nbOfComp==4)
2475     for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
2476       *dest=src[0]+src[3];
2477   else
2478     for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
2479       *dest=src[0]+src[4]+src[8];
2480   return ret;
2481 }
2482
2483 /*!
2484  * Computes the stress deviator tensor of every stress tensor defined by the tuple of
2485  * \a this array, which contains 6 components.
2486  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2487  *          same number of components and tuples as \a this array.
2488  *          The caller is to delete this result array using decrRef() as it is no more
2489  *          needed.
2490  *  \throw If \a this->getNumberOfComponents() != 6.
2491  */
2492 DataArrayDouble *DataArrayDouble::deviator() const
2493 {
2494   checkAllocated();
2495   int nbOfComp=getNumberOfComponents();
2496   if(nbOfComp!=6)
2497     throw INTERP_KERNEL::Exception("DataArrayDouble::deviator : must be an array with exactly 6 components !");
2498   DataArrayDouble *ret=DataArrayDouble::New();
2499   int nbOfTuple=getNumberOfTuples();
2500   ret->alloc(nbOfTuple,6);
2501   const double *src=getConstPointer();
2502   double *dest=ret->getPointer();
2503   for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
2504     {
2505       double tr=(src[0]+src[1]+src[2])/3.;
2506       dest[0]=src[0]-tr;
2507       dest[1]=src[1]-tr;
2508       dest[2]=src[2]-tr;
2509       dest[3]=src[3];
2510       dest[4]=src[4];
2511       dest[5]=src[5];
2512     }
2513   return ret;
2514 }
2515
2516 /*!
2517  * Computes the magnitude of every vector defined by the tuple of
2518  * \a this array.
2519  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2520  *          same number of tuples as \a this array and one component.
2521  *          The caller is to delete this result array using decrRef() as it is no more
2522  *          needed.
2523  *  \throw If \a this is not allocated.
2524  */
2525 DataArrayDouble *DataArrayDouble::magnitude() const
2526 {
2527   checkAllocated();
2528   int nbOfComp=getNumberOfComponents();
2529   DataArrayDouble *ret=DataArrayDouble::New();
2530   int nbOfTuple=getNumberOfTuples();
2531   ret->alloc(nbOfTuple,1);
2532   const double *src=getConstPointer();
2533   double *dest=ret->getPointer();
2534   for(int i=0;i<nbOfTuple;i++,dest++)
2535     {
2536       double sum=0.;
2537       for(int j=0;j<nbOfComp;j++,src++)
2538         sum+=(*src)*(*src);
2539       *dest=sqrt(sum);
2540     }
2541   return ret;
2542 }
2543
2544 /*!
2545  * Computes for each tuple the sum of number of components values in the tuple and return it.
2546  * 
2547  * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2548  *          same number of tuples as \a this array and one component.
2549  *          The caller is to delete this result array using decrRef() as it is no more
2550  *          needed.
2551  *  \throw If \a this is not allocated.
2552  */
2553 DataArrayDouble *DataArrayDouble::sumPerTuple() const
2554 {
2555   checkAllocated();
2556   int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
2557   MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2558   ret->alloc(nbOfTuple,1);
2559   const double *src(getConstPointer());
2560   double *dest(ret->getPointer());
2561   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
2562     *dest=std::accumulate(src,src+nbOfComp,0.);
2563   return ret.retn();
2564 }
2565
2566 /*!
2567  * Computes the maximal value within every tuple of \a this array.
2568  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2569  *          same number of tuples as \a this array and one component.
2570  *          The caller is to delete this result array using decrRef() as it is no more
2571  *          needed.
2572  *  \throw If \a this is not allocated.
2573  *  \sa DataArrayDouble::maxPerTupleWithCompoId
2574  */
2575 DataArrayDouble *DataArrayDouble::maxPerTuple() const
2576 {
2577   checkAllocated();
2578   int nbOfComp=getNumberOfComponents();
2579   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
2580   int nbOfTuple=getNumberOfTuples();
2581   ret->alloc(nbOfTuple,1);
2582   const double *src=getConstPointer();
2583   double *dest=ret->getPointer();
2584   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
2585     *dest=*std::max_element(src,src+nbOfComp);
2586   return ret.retn();
2587 }
2588
2589 /*!
2590  * Computes the maximal value within every tuple of \a this array and it returns the first component
2591  * id for each tuple that corresponds to the maximal value within the tuple.
2592  * 
2593  *  \param [out] compoIdOfMaxPerTuple - the new new instance of DataArrayInt containing the
2594  *          same number of tuples and only one component.
2595  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2596  *          same number of tuples as \a this array and one component.
2597  *          The caller is to delete this result array using decrRef() as it is no more
2598  *          needed.
2599  *  \throw If \a this is not allocated.
2600  *  \sa DataArrayDouble::maxPerTuple
2601  */
2602 DataArrayDouble *DataArrayDouble::maxPerTupleWithCompoId(DataArrayInt* &compoIdOfMaxPerTuple) const
2603 {
2604   checkAllocated();
2605   int nbOfComp=getNumberOfComponents();
2606   MCAuto<DataArrayDouble> ret0=DataArrayDouble::New();
2607   MCAuto<DataArrayInt> ret1=DataArrayInt::New();
2608   int nbOfTuple=getNumberOfTuples();
2609   ret0->alloc(nbOfTuple,1); ret1->alloc(nbOfTuple,1);
2610   const double *src=getConstPointer();
2611   double *dest=ret0->getPointer(); int *dest1=ret1->getPointer();
2612   for(int i=0;i<nbOfTuple;i++,dest++,dest1++,src+=nbOfComp)
2613     {
2614       const double *loc=std::max_element(src,src+nbOfComp);
2615       *dest=*loc;
2616       *dest1=(int)std::distance(src,loc);
2617     }
2618   compoIdOfMaxPerTuple=ret1.retn();
2619   return ret0.retn();
2620 }
2621
2622 /*!
2623  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c this->getNumberOfTuples() tuples.
2624  * \n This returned array contains the euclidian distance for each tuple in \a this. 
2625  * \n So the returned array can be seen as a dense symmetrical matrix whose diagonal elements are equal to 0.
2626  * \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)
2627  *
2628  * \warning use this method with care because it can leads to big amount of consumed memory !
2629  * 
2630  * \return A newly allocated (huge) MEDCoupling::DataArrayDouble instance that the caller should deal with.
2631  *
2632  * \throw If \a this is not allocated.
2633  *
2634  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrixWith
2635  */
2636 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrix() const
2637 {
2638   checkAllocated();
2639   int nbOfComp=getNumberOfComponents();
2640   int nbOfTuples=getNumberOfTuples();
2641   const double *inData=getConstPointer();
2642   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
2643   ret->alloc(nbOfTuples*nbOfTuples,1);
2644   double *outData=ret->getPointer();
2645   for(int i=0;i<nbOfTuples;i++)
2646     {
2647       outData[i*nbOfTuples+i]=0.;
2648       for(int j=i+1;j<nbOfTuples;j++)
2649         {
2650           double dist=0.;
2651           for(int k=0;k<nbOfComp;k++)
2652             { double delta=inData[i*nbOfComp+k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
2653           dist=sqrt(dist);
2654           outData[i*nbOfTuples+j]=dist;
2655           outData[j*nbOfTuples+i]=dist;
2656         }
2657     }
2658   return ret.retn();
2659 }
2660
2661 /*!
2662  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c other->getNumberOfTuples() tuples.
2663  * \n This returned array contains the euclidian distance for each tuple in \a other with each tuple in \a this. 
2664  * \n So the returned array can be seen as a dense rectangular matrix with \c other->getNumberOfTuples() rows and \c this->getNumberOfTuples() columns.
2665  * \n Output rectangular matrix is sorted along rows.
2666  * \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)
2667  *
2668  * \warning use this method with care because it can leads to big amount of consumed memory !
2669  * 
2670  * \param [in] other DataArrayDouble instance having same number of components than \a this.
2671  * \return A newly allocated (huge) MEDCoupling::DataArrayDouble instance that the caller should deal with.
2672  *
2673  * \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.
2674  *
2675  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrix
2676  */
2677 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrixWith(const DataArrayDouble *other) const
2678 {
2679   if(!other)
2680     throw INTERP_KERNEL::Exception("DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : input parameter is null !");
2681   checkAllocated();
2682   other->checkAllocated();
2683   int nbOfComp=getNumberOfComponents();
2684   int otherNbOfComp=other->getNumberOfComponents();
2685   if(nbOfComp!=otherNbOfComp)
2686     {
2687       std::ostringstream oss; oss << "DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : this nb of compo=" << nbOfComp << " and other nb of compo=" << otherNbOfComp << ". It should match !";
2688       throw INTERP_KERNEL::Exception(oss.str().c_str());
2689     }
2690   int nbOfTuples=getNumberOfTuples();
2691   int otherNbOfTuples=other->getNumberOfTuples();
2692   const double *inData=getConstPointer();
2693   const double *inDataOther=other->getConstPointer();
2694   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
2695   ret->alloc(otherNbOfTuples*nbOfTuples,1);
2696   double *outData=ret->getPointer();
2697   for(int i=0;i<otherNbOfTuples;i++,inDataOther+=nbOfComp)
2698     {
2699       for(int j=0;j<nbOfTuples;j++)
2700         {
2701           double dist=0.;
2702           for(int k=0;k<nbOfComp;k++)
2703             { double delta=inDataOther[k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
2704           dist=sqrt(dist);
2705           outData[i*nbOfTuples+j]=dist;
2706         }
2707     }
2708   return ret.retn();
2709 }
2710
2711 /*!
2712  * Sorts value within every tuple of \a this array.
2713  *  \param [in] asc - if \a true, the values are sorted in ascending order, else,
2714  *              in descending order.
2715  *  \throw If \a this is not allocated.
2716  */
2717 void DataArrayDouble::sortPerTuple(bool asc)
2718 {
2719   checkAllocated();
2720   double *pt=getPointer();
2721   int nbOfTuple=getNumberOfTuples();
2722   int nbOfComp=getNumberOfComponents();
2723   if(asc)
2724     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
2725       std::sort(pt,pt+nbOfComp);
2726   else
2727     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
2728       std::sort(pt,pt+nbOfComp,std::greater<double>());
2729   declareAsNew();
2730 }
2731
2732 /*!
2733  * Converts every value of \a this array to its absolute value.
2734  * \b WARNING this method is non const. If a new DataArrayDouble instance should be built containing the result of abs DataArrayDouble::computeAbs
2735  * should be called instead.
2736  *
2737  * \throw If \a this is not allocated.
2738  * \sa DataArrayDouble::computeAbs
2739  */
2740 void DataArrayDouble::abs()
2741 {
2742   checkAllocated();
2743   double *ptr(getPointer());
2744   std::size_t nbOfElems(getNbOfElems());
2745   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<double,double>(fabs));
2746   declareAsNew();
2747 }
2748
2749 /*!
2750  * This method builds a new instance of \a this object containing the result of std::abs applied of all elements in \a this.
2751  * This method is a const method (that do not change any values in \a this) contrary to  DataArrayDouble::abs method.
2752  *
2753  * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2754  *         same number of tuples and component as \a this array.
2755  *         The caller is to delete this result array using decrRef() as it is no more
2756  *         needed.
2757  * \throw If \a this is not allocated.
2758  * \sa DataArrayDouble::abs
2759  */
2760 DataArrayDouble *DataArrayDouble::computeAbs() const
2761 {
2762   checkAllocated();
2763   DataArrayDouble *newArr(DataArrayDouble::New());
2764   int nbOfTuples(getNumberOfTuples());
2765   int nbOfComp(getNumberOfComponents());
2766   newArr->alloc(nbOfTuples,nbOfComp);
2767   std::transform(begin(),end(),newArr->getPointer(),std::ptr_fun<double,double>(fabs));
2768   newArr->copyStringInfoFrom(*this);
2769   return newArr;
2770 }
2771
2772 /*!
2773  * Apply a linear function to a given component of \a this array, so that
2774  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
2775  *  \param [in] a - the first coefficient of the function.
2776  *  \param [in] b - the second coefficient of the function.
2777  *  \param [in] compoId - the index of component to modify.
2778  *  \throw If \a this is not allocated, or \a compoId is not in [0,\c this->getNumberOfComponents() ).
2779  */
2780 void DataArrayDouble::applyLin(double a, double b, int compoId)
2781 {
2782   checkAllocated();
2783   double *ptr(getPointer()+compoId);
2784   int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
2785   if(compoId<0 || compoId>=nbOfComp)
2786     {
2787       std::ostringstream oss; oss << "DataArrayDouble::applyLin : The compoId requested (" << compoId << ") is not valid ! Must be in [0," << nbOfComp << ") !";
2788       throw INTERP_KERNEL::Exception(oss.str().c_str());
2789     }
2790   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
2791     *ptr=a*(*ptr)+b;
2792   declareAsNew();
2793 }
2794
2795 /*!
2796  * Apply a linear function to all elements of \a this array, so that
2797  * an element _x_ becomes \f$ a * x + b \f$.
2798  *  \param [in] a - the first coefficient of the function.
2799  *  \param [in] b - the second coefficient of the function.
2800  *  \throw If \a this is not allocated.
2801  */
2802 void DataArrayDouble::applyLin(double a, double b)
2803 {
2804   checkAllocated();
2805   double *ptr=getPointer();
2806   std::size_t nbOfElems=getNbOfElems();
2807   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2808     *ptr=a*(*ptr)+b;
2809   declareAsNew();
2810 }
2811
2812 /*!
2813  * Modify all elements of \a this array, so that
2814  * an element _x_ becomes \f$ numerator / x \f$.
2815  *  \warning If an exception is thrown because of presence of 0.0 element in \a this 
2816  *           array, all elements processed before detection of the zero element remain
2817  *           modified.
2818  *  \param [in] numerator - the numerator used to modify array elements.
2819  *  \throw If \a this is not allocated.
2820  *  \throw If there is an element equal to 0.0 in \a this array.
2821  */
2822 void DataArrayDouble::applyInv(double numerator)
2823 {
2824   checkAllocated();
2825   double *ptr=getPointer();
2826   std::size_t nbOfElems=getNbOfElems();
2827   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2828     {
2829       if(std::abs(*ptr)>std::numeric_limits<double>::min())
2830         {
2831           *ptr=numerator/(*ptr);
2832         }
2833       else
2834         {
2835           std::ostringstream oss; oss << "DataArrayDouble::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
2836           oss << " !";
2837           throw INTERP_KERNEL::Exception(oss.str().c_str());
2838         }
2839     }
2840   declareAsNew();
2841 }
2842
2843 /*!
2844  * Returns a full copy of \a this array except that sign of all elements is reversed.
2845  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2846  *          same number of tuples and component as \a this array.
2847  *          The caller is to delete this result array using decrRef() as it is no more
2848  *          needed.
2849  *  \throw If \a this is not allocated.
2850  */
2851 DataArrayDouble *DataArrayDouble::negate() const
2852 {
2853   checkAllocated();
2854   DataArrayDouble *newArr=DataArrayDouble::New();
2855   int nbOfTuples=getNumberOfTuples();
2856   int nbOfComp=getNumberOfComponents();
2857   newArr->alloc(nbOfTuples,nbOfComp);
2858   const double *cptr=getConstPointer();
2859   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<double>());
2860   newArr->copyStringInfoFrom(*this);
2861   return newArr;
2862 }
2863
2864 /*!
2865  * Modify all elements of \a this array, so that
2866  * an element _x_ becomes <em> val ^ x </em>. Contrary to DataArrayInt::applyPow
2867  * all values in \a this have to be >= 0 if val is \b not integer.
2868  *  \param [in] val - the value used to apply pow on all array elements.
2869  *  \throw If \a this is not allocated.
2870  *  \warning If an exception is thrown because of presence of 0 element in \a this 
2871  *           array and \a val is \b not integer, all elements processed before detection of the zero element remain
2872  *           modified.
2873  */
2874 void DataArrayDouble::applyPow(double val)
2875 {
2876   checkAllocated();
2877   double *ptr=getPointer();
2878   std::size_t nbOfElems=getNbOfElems();
2879   int val2=(int)val;
2880   bool isInt=((double)val2)==val;
2881   if(!isInt)
2882     {
2883       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2884         {
2885           if(*ptr>=0)
2886             *ptr=pow(*ptr,val);
2887           else
2888             {
2889               std::ostringstream oss; oss << "DataArrayDouble::applyPow (double) : At elem # " << i << " value is " << *ptr << " ! must be >=0. !";
2890               throw INTERP_KERNEL::Exception(oss.str().c_str());
2891             }
2892         }
2893     }
2894   else
2895     {
2896       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2897         *ptr=pow(*ptr,val2);
2898     }
2899   declareAsNew();
2900 }
2901
2902 /*!
2903  * Modify all elements of \a this array, so that
2904  * an element _x_ becomes \f$ val ^ x \f$.
2905  *  \param [in] val - the value used to apply pow on all array elements.
2906  *  \throw If \a this is not allocated.
2907  *  \throw If \a val < 0.
2908  *  \warning If an exception is thrown because of presence of 0 element in \a this 
2909  *           array, all elements processed before detection of the zero element remain
2910  *           modified.
2911  */
2912 void DataArrayDouble::applyRPow(double val)
2913 {
2914   checkAllocated();
2915   if(val<0.)
2916     throw INTERP_KERNEL::Exception("DataArrayDouble::applyRPow : the input value has to be >= 0 !");
2917   double *ptr=getPointer();
2918   std::size_t nbOfElems=getNbOfElems();
2919   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2920     *ptr=pow(val,*ptr);
2921   declareAsNew();
2922 }
2923
2924 /*!
2925  * Returns a new DataArrayDouble created from \a this one by applying \a
2926  * FunctionToEvaluate to every tuple of \a this array. Textual data is not copied.
2927  * For more info see \ref MEDCouplingArrayApplyFunc
2928  *  \param [in] nbOfComp - number of components in the result array.
2929  *  \param [in] func - the \a FunctionToEvaluate declared as 
2930  *              \c bool (*\a func)(\c const \c double *\a pos, \c double *\a res), 
2931  *              where \a pos points to the first component of a tuple of \a this array
2932  *              and \a res points to the first component of a tuple of the result array.
2933  *              Note that length (number of components) of \a pos can differ from
2934  *              that of \a res.
2935  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2936  *          same number of tuples as \a this array.
2937  *          The caller is to delete this result array using decrRef() as it is no more
2938  *          needed.
2939  *  \throw If \a this is not allocated.
2940  *  \throw If \a func returns \a false.
2941  */
2942 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, FunctionToEvaluate func) const
2943 {
2944   checkAllocated();
2945   DataArrayDouble *newArr=DataArrayDouble::New();
2946   int nbOfTuples=getNumberOfTuples();
2947   int oldNbOfComp=getNumberOfComponents();
2948   newArr->alloc(nbOfTuples,nbOfComp);
2949   const double *ptr=getConstPointer();
2950   double *ptrToFill=newArr->getPointer();
2951   for(int i=0;i<nbOfTuples;i++)
2952     {
2953       if(!func(ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp))
2954         {
2955           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
2956           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
2957           oss << ") : Evaluation of function failed !";
2958           newArr->decrRef();
2959           throw INTERP_KERNEL::Exception(oss.str().c_str());
2960         }
2961     }
2962   return newArr;
2963 }
2964
2965 /*!
2966  * Returns a new DataArrayDouble created from \a this one by applying a function to every
2967  * tuple of \a this array. Textual data is not copied.
2968  * For more info see \ref MEDCouplingArrayApplyFunc1.
2969  *  \param [in] nbOfComp - number of components in the result array.
2970  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
2971  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
2972  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
2973  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
2974  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2975  *          same number of tuples as \a this array and \a nbOfComp components.
2976  *          The caller is to delete this result array using decrRef() as it is no more
2977  *          needed.
2978  *  \throw If \a this is not allocated.
2979  *  \throw If computing \a func fails.
2980  */
2981 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, const std::string& func, bool isSafe) const
2982 {
2983   INTERP_KERNEL::ExprParser expr(func);
2984   expr.parse();
2985   std::set<std::string> vars;
2986   expr.getTrueSetOfVars(vars);
2987   std::vector<std::string> varsV(vars.begin(),vars.end());
2988   return applyFuncNamedCompo(nbOfComp,varsV,func,isSafe);
2989 }
2990
2991 /*!
2992  * Returns a new DataArrayDouble created from \a this one by applying a function to every
2993  * tuple of \a this array. Textual data is not copied. This method works by tuples (whatever its size).
2994  * If \a this is a one component array, call applyFuncOnThis instead that performs the same work faster.
2995  *
2996  * For more info see \ref MEDCouplingArrayApplyFunc0.
2997  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
2998  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
2999  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
3000  *                       If false the computation is carried on without any notification. When false the evaluation is a little faster.
3001  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3002  *          same number of tuples and components as \a this array.
3003  *          The caller is to delete this result array using decrRef() as it is no more
3004  *          needed.
3005  *  \sa applyFuncOnThis
3006  *  \throw If \a this is not allocated.
3007  *  \throw If computing \a func fails.
3008  */
3009 DataArrayDouble *DataArrayDouble::applyFunc(const std::string& func, bool isSafe) const
3010 {
3011   int nbOfComp(getNumberOfComponents());
3012   if(nbOfComp<=0)
3013     throw INTERP_KERNEL::Exception("DataArrayDouble::applyFunc : output number of component must be > 0 !");
3014   checkAllocated();
3015   int nbOfTuples(getNumberOfTuples());
3016   MCAuto<DataArrayDouble> newArr(DataArrayDouble::New());
3017   newArr->alloc(nbOfTuples,nbOfComp);
3018   INTERP_KERNEL::ExprParser expr(func);
3019   expr.parse();
3020   std::set<std::string> vars;
3021   expr.getTrueSetOfVars(vars);
3022   if((int)vars.size()>1)
3023     {
3024       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 : ";
3025       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
3026       throw INTERP_KERNEL::Exception(oss.str().c_str());
3027     }
3028   if(vars.empty())
3029     {
3030       expr.prepareFastEvaluator();
3031       newArr->rearrange(1);
3032       newArr->fillWithValue(expr.evaluateDouble());
3033       newArr->rearrange(nbOfComp);
3034       return newArr.retn();
3035     }
3036   std::vector<std::string> vars2(vars.begin(),vars.end());
3037   double buff,*ptrToFill(newArr->getPointer());
3038   const double *ptr(begin());
3039   std::vector<double> stck;
3040   expr.prepareExprEvaluationDouble(vars2,1,1,0,&buff,&buff+1);
3041   expr.prepareFastEvaluator();
3042   if(!isSafe)
3043     {
3044       for(int i=0;i<nbOfTuples;i++)
3045         {
3046           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
3047             {
3048               buff=*ptr;
3049               expr.evaluateDoubleInternal(stck);
3050               *ptrToFill=stck.back();
3051               stck.pop_back();
3052             }
3053         }
3054     }
3055   else
3056     {
3057       for(int i=0;i<nbOfTuples;i++)
3058         {
3059           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
3060             {
3061               buff=*ptr;
3062               try
3063               {
3064                   expr.evaluateDoubleInternalSafe(stck);
3065               }
3066               catch(INTERP_KERNEL::Exception& e)
3067               {
3068                   std::ostringstream oss; oss << "For tuple # " << i << " component # " << iComp << " with value (";
3069                   oss << buff;
3070                   oss << ") : Evaluation of function failed !" << e.what();
3071                   throw INTERP_KERNEL::Exception(oss.str().c_str());
3072               }
3073               *ptrToFill=stck.back();
3074               stck.pop_back();
3075             }
3076         }
3077     }
3078   return newArr.retn();
3079 }
3080
3081 /*!
3082  * This method is a non const method that modify the array in \a this.
3083  * This method only works on one component array. It means that function \a func must
3084  * contain at most one variable.
3085  * This method is a specialization of applyFunc method with one parameter on one component array.
3086  *
3087  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
3088  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
3089  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
3090  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
3091  *
3092  * \sa applyFunc
3093  */
3094 void DataArrayDouble::applyFuncOnThis(const std::string& func, bool isSafe)
3095 {
3096   int nbOfComp(getNumberOfComponents());
3097   if(nbOfComp<=0)
3098     throw INTERP_KERNEL::Exception("DataArrayDouble::applyFuncOnThis : output number of component must be > 0 !");
3099   checkAllocated();
3100   int nbOfTuples(getNumberOfTuples());
3101   INTERP_KERNEL::ExprParser expr(func);
3102   expr.parse();
3103   std::set<std::string> vars;
3104   expr.getTrueSetOfVars(vars);
3105   if((int)vars.size()>1)
3106     {
3107       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 : ";
3108       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
3109       throw INTERP_KERNEL::Exception(oss.str().c_str());
3110     }
3111   if(vars.empty())
3112     {
3113       expr.prepareFastEvaluator();
3114       std::vector<std::string> compInfo(getInfoOnComponents());
3115       rearrange(1);
3116       fillWithValue(expr.evaluateDouble());
3117       rearrange(nbOfComp);
3118       setInfoOnComponents(compInfo);
3119       return ;
3120     }
3121   std::vector<std::string> vars2(vars.begin(),vars.end());
3122   double buff,*ptrToFill(getPointer());
3123   const double *ptr(begin());
3124   std::vector<double> stck;
3125   expr.prepareExprEvaluationDouble(vars2,1,1,0,&buff,&buff+1);
3126   expr.prepareFastEvaluator();
3127   if(!isSafe)
3128     {
3129       for(int i=0;i<nbOfTuples;i++)
3130         {
3131           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
3132             {
3133               buff=*ptr;
3134               expr.evaluateDoubleInternal(stck);
3135               *ptrToFill=stck.back();
3136               stck.pop_back();
3137             }
3138         }
3139     }
3140   else
3141     {
3142       for(int i=0;i<nbOfTuples;i++)
3143         {
3144           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
3145             {
3146               buff=*ptr;
3147               try
3148               {
3149                   expr.evaluateDoubleInternalSafe(stck);
3150               }
3151               catch(INTERP_KERNEL::Exception& e)
3152               {
3153                   std::ostringstream oss; oss << "For tuple # " << i << " component # " << iComp << " with value (";
3154                   oss << buff;
3155                   oss << ") : Evaluation of function failed !" << e.what();
3156                   throw INTERP_KERNEL::Exception(oss.str().c_str());
3157               }
3158               *ptrToFill=stck.back();
3159               stck.pop_back();
3160             }
3161         }
3162     }
3163 }
3164
3165 /*!
3166  * Returns a new DataArrayDouble created from \a this one by applying a function to every
3167  * tuple of \a this array. Textual data is not copied.
3168  * For more info see \ref MEDCouplingArrayApplyFunc2.
3169  *  \param [in] nbOfComp - number of components in the result array.
3170  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
3171  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
3172  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
3173  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
3174  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3175  *          same number of tuples as \a this array.
3176  *          The caller is to delete this result array using decrRef() as it is no more
3177  *          needed.
3178  *  \throw If \a this is not allocated.
3179  *  \throw If \a func contains vars that are not in \a this->getInfoOnComponent().
3180  *  \throw If computing \a func fails.
3181  */
3182 DataArrayDouble *DataArrayDouble::applyFuncCompo(int nbOfComp, const std::string& func, bool isSafe) const
3183 {
3184   return applyFuncNamedCompo(nbOfComp,getVarsOnComponent(),func,isSafe);
3185 }
3186
3187 /*!
3188  * Returns a new DataArrayDouble created from \a this one by applying a function to every
3189  * tuple of \a this array. Textual data is not copied.
3190  * For more info see \ref MEDCouplingArrayApplyFunc3.
3191  *  \param [in] nbOfComp - number of components in the result array.
3192  *  \param [in] varsOrder - sequence of vars defining their order.
3193  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
3194  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
3195  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
3196  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
3197  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3198  *          same number of tuples as \a this array.
3199  *          The caller is to delete this result array using decrRef() as it is no more
3200  *          needed.
3201  *  \throw If \a this is not allocated.
3202  *  \throw If \a func contains vars not in \a varsOrder.
3203  *  \throw If computing \a func fails.
3204  */
3205 DataArrayDouble *DataArrayDouble::applyFuncNamedCompo(int nbOfComp, const std::vector<std::string>& varsOrder, const std::string& func, bool isSafe) const
3206 {
3207   if(nbOfComp<=0)
3208     throw INTERP_KERNEL::Exception("DataArrayDouble::applyFuncNamedCompo : output number of component must be > 0 !");
3209   std::vector<std::string> varsOrder2(varsOrder);
3210   int oldNbOfComp(getNumberOfComponents());
3211   for(int i=(int)varsOrder.size();i<oldNbOfComp;i++)
3212     varsOrder2.push_back(std::string());
3213   checkAllocated();
3214   int nbOfTuples(getNumberOfTuples());
3215   INTERP_KERNEL::ExprParser expr(func);
3216   expr.parse();
3217   std::set<std::string> vars;
3218   expr.getTrueSetOfVars(vars);
3219   if((int)vars.size()>oldNbOfComp)
3220     {
3221       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
3222       oss << vars.size() << " variables : ";
3223       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
3224       throw INTERP_KERNEL::Exception(oss.str().c_str());
3225     }
3226   MCAuto<DataArrayDouble> newArr(DataArrayDouble::New());
3227   newArr->alloc(nbOfTuples,nbOfComp);
3228   INTERP_KERNEL::AutoPtr<double> buff(new double[oldNbOfComp]);
3229   double *buffPtr(buff),*ptrToFill;
3230   std::vector<double> stck;
3231   for(int iComp=0;iComp<nbOfComp;iComp++)
3232     {
3233       expr.prepareExprEvaluationDouble(varsOrder2,oldNbOfComp,nbOfComp,iComp,buffPtr,buffPtr+oldNbOfComp);
3234       expr.prepareFastEvaluator();
3235       const double *ptr(getConstPointer());
3236       ptrToFill=newArr->getPointer()+iComp;
3237       if(!isSafe)
3238         {
3239           for(int i=0;i<nbOfTuples;i++,ptrToFill+=nbOfComp,ptr+=oldNbOfComp)
3240             {
3241               std::copy(ptr,ptr+oldNbOfComp,buffPtr);
3242               expr.evaluateDoubleInternal(stck);
3243               *ptrToFill=stck.back();
3244               stck.pop_back();
3245             }
3246         }
3247       else
3248         {
3249           for(int i=0;i<nbOfTuples;i++,ptrToFill+=nbOfComp,ptr+=oldNbOfComp)
3250             {
3251               std::copy(ptr,ptr+oldNbOfComp,buffPtr);
3252               try
3253               {
3254                   expr.evaluateDoubleInternalSafe(stck);
3255                   *ptrToFill=stck.back();
3256                   stck.pop_back();
3257               }
3258               catch(INTERP_KERNEL::Exception& e)
3259               {
3260                   std::ostringstream oss; oss << "For tuple # " << i << " with value (";
3261                   std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
3262                   oss << ") : Evaluation of function failed !" << e.what();
3263                   throw INTERP_KERNEL::Exception(oss.str().c_str());
3264               }
3265             }
3266         }
3267     }
3268   return newArr.retn();
3269 }
3270
3271 void DataArrayDouble::applyFuncFast32(const std::string& func)
3272 {
3273   checkAllocated();
3274   INTERP_KERNEL::ExprParser expr(func);
3275   expr.parse();
3276   char *funcStr=expr.compileX86();
3277   MYFUNCPTR funcPtr;
3278   *((void **)&funcPtr)=funcStr;//he he...
3279   //
3280   double *ptr=getPointer();
3281   int nbOfComp=getNumberOfComponents();
3282   int nbOfTuples=getNumberOfTuples();
3283   int nbOfElems=nbOfTuples*nbOfComp;
3284   for(int i=0;i<nbOfElems;i++,ptr++)
3285     *ptr=funcPtr(*ptr);
3286   declareAsNew();
3287 }
3288
3289 void DataArrayDouble::applyFuncFast64(const std::string& func)
3290 {
3291   checkAllocated();
3292   INTERP_KERNEL::ExprParser expr(func);
3293   expr.parse();
3294   char *funcStr=expr.compileX86_64();
3295   MYFUNCPTR funcPtr;
3296   *((void **)&funcPtr)=funcStr;//he he...
3297   //
3298   double *ptr=getPointer();
3299   int nbOfComp=getNumberOfComponents();
3300   int nbOfTuples=getNumberOfTuples();
3301   int nbOfElems=nbOfTuples*nbOfComp;
3302   for(int i=0;i<nbOfElems;i++,ptr++)
3303     *ptr=funcPtr(*ptr);
3304   declareAsNew();
3305 }
3306
3307 /*!
3308  * \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.
3309  */
3310 MCAuto<DataArrayDouble> DataArrayDouble::symmetry3DPlane(const double point[3], const double normalVector[3]) const
3311 {
3312   checkAllocated();
3313   if(getNumberOfComponents()!=3)
3314     throw INTERP_KERNEL::Exception("DataArrayDouble::symmetry3DPlane : this is excepted to have 3 components !");
3315   int nbTuples(getNumberOfTuples());
3316   MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
3317   ret->alloc(nbTuples,3);
3318   Symmetry3DPlane(point,normalVector,nbTuples,begin(),ret->getPointer());
3319   return ret;
3320 }
3321
3322 DataArrayDoubleIterator *DataArrayDouble::iterator()
3323 {
3324   return new DataArrayDoubleIterator(this);
3325 }
3326
3327 /*!
3328  * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional
3329  * array whose values are within a given range. Textual data is not copied.
3330  *  \param [in] vmin - a lowest acceptable value (included).
3331  *  \param [in] vmax - a greatest acceptable value (included).
3332  *  \return DataArrayInt * - the new instance of DataArrayInt.
3333  *          The caller is to delete this result array using decrRef() as it is no more
3334  *          needed.
3335  *  \throw If \a this->getNumberOfComponents() != 1.
3336  *
3337  *  \sa DataArrayDouble::findIdsNotInRange
3338  *
3339  *  \if ENABLE_EXAMPLES
3340  *  \ref cpp_mcdataarraydouble_getidsinrange "Here is a C++ example".<br>
3341  *  \ref py_mcdataarraydouble_getidsinrange "Here is a Python example".
3342  *  \endif
3343  */
3344 DataArrayInt *DataArrayDouble::findIdsInRange(double vmin, double vmax) const
3345 {
3346   checkAllocated();
3347   if(getNumberOfComponents()!=1)
3348     throw INTERP_KERNEL::Exception("DataArrayDouble::findIdsInRange : this must have exactly one component !");
3349   const double *cptr(begin());
3350   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
3351   int nbOfTuples(getNumberOfTuples());
3352   for(int i=0;i<nbOfTuples;i++,cptr++)
3353     if(*cptr>=vmin && *cptr<=vmax)
3354       ret->pushBackSilent(i);
3355   return ret.retn();
3356 }
3357
3358 /*!
3359  * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional
3360  * array whose values are not within a given range. Textual data is not copied.
3361  *  \param [in] vmin - a lowest not acceptable value (excluded).
3362  *  \param [in] vmax - a greatest not acceptable value (excluded).
3363  *  \return DataArrayInt * - the new instance of DataArrayInt.
3364  *          The caller is to delete this result array using decrRef() as it is no more
3365  *          needed.
3366  *  \throw If \a this->getNumberOfComponents() != 1.
3367  *
3368  *  \sa DataArrayDouble::findIdsInRange
3369  */
3370 DataArrayInt *DataArrayDouble::findIdsNotInRange(double vmin, double vmax) const
3371 {
3372   checkAllocated();
3373   if(getNumberOfComponents()!=1)
3374     throw INTERP_KERNEL::Exception("DataArrayDouble::findIdsNotInRange : this must have exactly one component !");
3375   const double *cptr(begin());
3376   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
3377   int nbOfTuples(getNumberOfTuples());
3378   for(int i=0;i<nbOfTuples;i++,cptr++)
3379     if(*cptr<vmin || *cptr>vmax)
3380       ret->pushBackSilent(i);
3381   return ret.retn();
3382 }
3383
3384 /*!
3385  * Returns a new DataArrayDouble by concatenating two given arrays, so that (1) the number
3386  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
3387  * the number of component in the result array is same as that of each of given arrays.
3388  * Info on components is copied from the first of the given arrays. Number of components
3389  * in the given arrays must be  the same.
3390  *  \param [in] a1 - an array to include in the result array.
3391  *  \param [in] a2 - another array to include in the result array.
3392  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3393  *          The caller is to delete this result array using decrRef() as it is no more
3394  *          needed.
3395  *  \throw If both \a a1 and \a a2 are NULL.
3396  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
3397  */
3398 DataArrayDouble *DataArrayDouble::Aggregate(const DataArrayDouble *a1, const DataArrayDouble *a2)
3399 {
3400   std::vector<const DataArrayDouble *> tmp(2);
3401   tmp[0]=a1; tmp[1]=a2;
3402   return Aggregate(tmp);
3403 }
3404
3405 /*!
3406  * Returns a new DataArrayDouble by concatenating all given arrays, so that (1) the number
3407  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
3408  * the number of component in the result array is same as that of each of given arrays.
3409  * Info on components is copied from the first of the given arrays. Number of components
3410  * in the given arrays must be  the same.
3411  * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it
3412  * not the object itself.
3413  *  \param [in] arr - a sequence of arrays to include in the result array.
3414  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3415  *          The caller is to delete this result array using decrRef() as it is no more
3416  *          needed.
3417  *  \throw If all arrays within \a arr are NULL.
3418  *  \throw If getNumberOfComponents() of arrays within \a arr.
3419  */
3420 DataArrayDouble *DataArrayDouble::Aggregate(const std::vector<const DataArrayDouble *>& arr)
3421 {
3422   std::vector<const DataArrayDouble *> a;
3423   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
3424     if(*it4)
3425       a.push_back(*it4);
3426   if(a.empty())
3427     throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : input list must contain at least one NON EMPTY DataArrayDouble !");
3428   std::vector<const DataArrayDouble *>::const_iterator it=a.begin();
3429   int nbOfComp=(*it)->getNumberOfComponents();
3430   int nbt=(*it++)->getNumberOfTuples();
3431   for(int i=1;it!=a.end();it++,i++)
3432     {
3433       if((*it)->getNumberOfComponents()!=nbOfComp)
3434         throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : Nb of components mismatch for array aggregation !");
3435       nbt+=(*it)->getNumberOfTuples();
3436     }
3437   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
3438   ret->alloc(nbt,nbOfComp);
3439   double *pt=ret->getPointer();
3440   for(it=a.begin();it!=a.end();it++)
3441     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
3442   ret->copyStringInfoFrom(*(a[0]));
3443   return ret.retn();
3444 }
3445
3446 /*!
3447  * Returns a new DataArrayDouble by aggregating two given arrays, so that (1) the number
3448  * of components in the result array is a sum of the number of components of given arrays
3449  * and (2) the number of tuples in the result array is same as that of each of given
3450  * arrays. In other words the i-th tuple of result array includes all components of
3451  * i-th tuples of all given arrays.
3452  * Number of tuples in the given arrays must be  the same.
3453  *  \param [in] a1 - an array to include in the result array.
3454  *  \param [in] a2 - another array to include in the result array.
3455  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3456  *          The caller is to delete this result array using decrRef() as it is no more
3457  *          needed.
3458  *  \throw If both \a a1 and \a a2 are NULL.
3459  *  \throw If any given array is not allocated.
3460  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3461  */
3462 DataArrayDouble *DataArrayDouble::Meld(const DataArrayDouble *a1, const DataArrayDouble *a2)
3463 {
3464   std::vector<const DataArrayDouble *> arr(2);
3465   arr[0]=a1; arr[1]=a2;
3466   return Meld(arr);
3467 }
3468
3469 /*!
3470  * Returns a new DataArrayDouble by aggregating all given arrays, so that (1) the number
3471  * of components in the result array is a sum of the number of components of given arrays
3472  * and (2) the number of tuples in the result array is same as that of each of given
3473  * arrays. In other words the i-th tuple of result array includes all components of
3474  * i-th tuples of all given arrays.
3475  * Number of tuples in the given arrays must be  the same.
3476  *  \param [in] arr - a sequence of arrays to include in the result array.
3477  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3478  *          The caller is to delete this result array using decrRef() as it is no more
3479  *          needed.
3480  *  \throw If all arrays within \a arr are NULL.
3481  *  \throw If any given array is not allocated.
3482  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
3483  */
3484 DataArrayDouble *DataArrayDouble::Meld(const std::vector<const DataArrayDouble *>& arr)
3485 {
3486   std::vector<const DataArrayDouble *> a;
3487   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
3488     if(*it4)
3489       a.push_back(*it4);
3490   if(a.empty())
3491     throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : input list must contain at least one NON EMPTY DataArrayDouble !");
3492   std::vector<const DataArrayDouble *>::const_iterator it;
3493   for(it=a.begin();it!=a.end();it++)
3494     (*it)->checkAllocated();
3495   it=a.begin();
3496   int nbOfTuples=(*it)->getNumberOfTuples();
3497   std::vector<int> nbc(a.size());
3498   std::vector<const double *> pts(a.size());
3499   nbc[0]=(*it)->getNumberOfComponents();
3500   pts[0]=(*it++)->getConstPointer();
3501   for(int i=1;it!=a.end();it++,i++)
3502     {
3503       if(nbOfTuples!=(*it)->getNumberOfTuples())
3504         throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : mismatch of number of tuples !");
3505       nbc[i]=(*it)->getNumberOfComponents();
3506       pts[i]=(*it)->getConstPointer();
3507     }
3508   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
3509   DataArrayDouble *ret=DataArrayDouble::New();
3510   ret->alloc(nbOfTuples,totalNbOfComp);
3511   double *retPtr=ret->getPointer();
3512   for(int i=0;i<nbOfTuples;i++)
3513     for(int j=0;j<(int)a.size();j++)
3514       {
3515         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
3516         pts[j]+=nbc[j];
3517       }
3518   int k=0;
3519   for(int i=0;i<(int)a.size();i++)
3520     for(int j=0;j<nbc[i];j++,k++)
3521       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j));
3522   return ret;
3523 }
3524
3525 /*!
3526  * Returns a new DataArrayDouble containing a dot product of two given arrays, so that
3527  * the i-th tuple of the result array is a sum of products of j-th components of i-th
3528  * tuples of given arrays (\f$ a_i = \sum_{j=1}^n a1_j * a2_j \f$).
3529  * Info on components and name is copied from the first of the given arrays.
3530  * Number of tuples and components in the given arrays must be the same.
3531  *  \param [in] a1 - a given array.
3532  *  \param [in] a2 - another given array.
3533  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3534  *          The caller is to delete this result array using decrRef() as it is no more
3535  *          needed.
3536  *  \throw If either \a a1 or \a a2 is NULL.
3537  *  \throw If any given array is not allocated.
3538  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3539  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
3540  */
3541 DataArrayDouble *DataArrayDouble::Dot(const DataArrayDouble *a1, const DataArrayDouble *a2)
3542 {
3543   if(!a1 || !a2)
3544     throw INTERP_KERNEL::Exception("DataArrayDouble::Dot : input DataArrayDouble instance is NULL !");
3545   a1->checkAllocated();
3546   a2->checkAllocated();
3547   int nbOfComp=a1->getNumberOfComponents();
3548   if(nbOfComp!=a2->getNumberOfComponents())
3549     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Dot !");
3550   int nbOfTuple=a1->getNumberOfTuples();
3551   if(nbOfTuple!=a2->getNumberOfTuples())
3552     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Dot !");
3553   DataArrayDouble *ret=DataArrayDouble::New();
3554   ret->alloc(nbOfTuple,1);
3555   double *retPtr=ret->getPointer();
3556   const double *a1Ptr=a1->getConstPointer();
3557   const double *a2Ptr=a2->getConstPointer();
3558   for(int i=0;i<nbOfTuple;i++)
3559     {
3560       double sum=0.;
3561       for(int j=0;j<nbOfComp;j++)
3562         sum+=a1Ptr[i*nbOfComp+j]*a2Ptr[i*nbOfComp+j];
3563       retPtr[i]=sum;
3564     }
3565   ret->setInfoOnComponent(0,a1->getInfoOnComponent(0));
3566   ret->setName(a1->getName());
3567   return ret;
3568 }
3569
3570 /*!
3571  * Returns a new DataArrayDouble containing a cross product of two given arrays, so that
3572  * the i-th tuple of the result array contains 3 components of a vector which is a cross
3573  * product of two vectors defined by the i-th tuples of given arrays.
3574  * Info on components is copied from the first of the given arrays.
3575  * Number of tuples in the given arrays must be the same.
3576  * Number of components in the given arrays must be 3.
3577  *  \param [in] a1 - a given array.
3578  *  \param [in] a2 - another given array.
3579  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3580  *          The caller is to delete this result array using decrRef() as it is no more
3581  *          needed.
3582  *  \throw If either \a a1 or \a a2 is NULL.
3583  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3584  *  \throw If \a a1->getNumberOfComponents() != 3
3585  *  \throw If \a a2->getNumberOfComponents() != 3
3586  */
3587 DataArrayDouble *DataArrayDouble::CrossProduct(const DataArrayDouble *a1, const DataArrayDouble *a2)
3588 {
3589   if(!a1 || !a2)
3590     throw INTERP_KERNEL::Exception("DataArrayDouble::CrossProduct : input DataArrayDouble instance is NULL !");
3591   int nbOfComp=a1->getNumberOfComponents();
3592   if(nbOfComp!=a2->getNumberOfComponents())
3593     throw INTERP_KERNEL::Exception("Nb of components mismatch for array crossProduct !");
3594   if(nbOfComp!=3)
3595     throw INTERP_KERNEL::Exception("Nb of components must be equal to 3 for array crossProduct !");
3596   int nbOfTuple=a1->getNumberOfTuples();
3597   if(nbOfTuple!=a2->getNumberOfTuples())
3598     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array crossProduct !");
3599   DataArrayDouble *ret=DataArrayDouble::New();
3600   ret->alloc(nbOfTuple,3);
3601   double *retPtr=ret->getPointer();
3602   const double *a1Ptr=a1->getConstPointer();
3603   const double *a2Ptr=a2->getConstPointer();
3604   for(int i=0;i<nbOfTuple;i++)
3605     {
3606       retPtr[3*i]=a1Ptr[3*i+1]*a2Ptr[3*i+2]-a1Ptr[3*i+2]*a2Ptr[3*i+1];
3607       retPtr[3*i+1]=a1Ptr[3*i+2]*a2Ptr[3*i]-a1Ptr[3*i]*a2Ptr[3*i+2];
3608       retPtr[3*i+2]=a1Ptr[3*i]*a2Ptr[3*i+1]-a1Ptr[3*i+1]*a2Ptr[3*i];
3609     }
3610   ret->copyStringInfoFrom(*a1);
3611   return ret;
3612 }
3613
3614 /*!
3615  * Returns a new DataArrayDouble containing maximal values of two given arrays.
3616  * Info on components is copied from the first of the given arrays.
3617  * Number of tuples and components in the given arrays must be the same.
3618  *  \param [in] a1 - an array to compare values with another one.
3619  *  \param [in] a2 - another array to compare values with the first one.
3620  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3621  *          The caller is to delete this result array using decrRef() as it is no more
3622  *          needed.
3623  *  \throw If either \a a1 or \a a2 is NULL.
3624  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3625  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
3626  */
3627 DataArrayDouble *DataArrayDouble::Max(const DataArrayDouble *a1, const DataArrayDouble *a2)
3628 {
3629   if(!a1 || !a2)
3630     throw INTERP_KERNEL::Exception("DataArrayDouble::Max : input DataArrayDouble instance is NULL !");
3631   int nbOfComp=a1->getNumberOfComponents();
3632   if(nbOfComp!=a2->getNumberOfComponents())
3633     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Max !");
3634   int nbOfTuple=a1->getNumberOfTuples();
3635   if(nbOfTuple!=a2->getNumberOfTuples())
3636     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Max !");
3637   DataArrayDouble *ret=DataArrayDouble::New();
3638   ret->alloc(nbOfTuple,nbOfComp);
3639   double *retPtr=ret->getPointer();
3640   const double *a1Ptr=a1->getConstPointer();
3641   const double *a2Ptr=a2->getConstPointer();
3642   int nbElem=nbOfTuple*nbOfComp;
3643   for(int i=0;i<nbElem;i++)
3644     retPtr[i]=std::max(a1Ptr[i],a2Ptr[i]);
3645   ret->copyStringInfoFrom(*a1);
3646   return ret;
3647 }
3648
3649 /*!
3650  * Returns a new DataArrayDouble containing minimal values of two given arrays.
3651  * Info on components is copied from the first of the given arrays.
3652  * Number of tuples and components in the given arrays must be the same.
3653  *  \param [in] a1 - an array to compare values with another one.
3654  *  \param [in] a2 - another array to compare values with the first one.
3655  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3656  *          The caller is to delete this result array using decrRef() as it is no more
3657  *          needed.
3658  *  \throw If either \a a1 or \a a2 is NULL.
3659  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3660  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
3661  */
3662 DataArrayDouble *DataArrayDouble::Min(const DataArrayDouble *a1, const DataArrayDouble *a2)
3663 {
3664   if(!a1 || !a2)
3665     throw INTERP_KERNEL::Exception("DataArrayDouble::Min : input DataArrayDouble instance is NULL !");
3666   int nbOfComp=a1->getNumberOfComponents();
3667   if(nbOfComp!=a2->getNumberOfComponents())
3668     throw INTERP_KERNEL::Exception("Nb of components mismatch for array min !");
3669   int nbOfTuple=a1->getNumberOfTuples();
3670   if(nbOfTuple!=a2->getNumberOfTuples())
3671     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array min !");
3672   DataArrayDouble *ret=DataArrayDouble::New();
3673   ret->alloc(nbOfTuple,nbOfComp);
3674   double *retPtr=ret->getPointer();
3675   const double *a1Ptr=a1->getConstPointer();
3676   const double *a2Ptr=a2->getConstPointer();
3677   int nbElem=nbOfTuple*nbOfComp;
3678   for(int i=0;i<nbElem;i++)
3679     retPtr[i]=std::min(a1Ptr[i],a2Ptr[i]);
3680   ret->copyStringInfoFrom(*a1);
3681   return ret;
3682 }
3683
3684 /*!
3685  * Returns a new DataArrayDouble that is a sum of two given arrays. There are 3
3686  * valid cases.
3687  * 1.  The arrays have same number of tuples and components. Then each value of
3688  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
3689  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
3690  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
3691  *   component. Then
3692  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
3693  * 3.  The arrays have same number of components and one array, say _a2_, has one
3694  *   tuple. Then
3695  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
3696  *
3697  * Info on components is copied either from the first array (in the first case) or from
3698  * the array with maximal number of elements (getNbOfElems()).
3699  *  \param [in] a1 - an array to sum up.
3700  *  \param [in] a2 - another array to sum up.
3701  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3702  *          The caller is to delete this result array using decrRef() as it is no more
3703  *          needed.
3704  *  \throw If either \a a1 or \a a2 is NULL.
3705  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
3706  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
3707  *         none of them has number of tuples or components equal to 1.
3708  */
3709 DataArrayDouble *DataArrayDouble::Add(const DataArrayDouble *a1, const DataArrayDouble *a2)
3710 {
3711   if(!a1 || !a2)
3712     throw INTERP_KERNEL::Exception("DataArrayDouble::Add : input DataArrayDouble instance is NULL !");
3713   int nbOfTuple=a1->getNumberOfTuples();
3714   int nbOfTuple2=a2->getNumberOfTuples();
3715   int nbOfComp=a1->getNumberOfComponents();
3716   int nbOfComp2=a2->getNumberOfComponents();
3717   MCAuto<DataArrayDouble> ret=0;
3718   if(nbOfTuple==nbOfTuple2)
3719     {
3720       if(nbOfComp==nbOfComp2)
3721         {
3722           ret=DataArrayDouble::New();
3723           ret->alloc(nbOfTuple,nbOfComp);
3724           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<double>());
3725           ret->copyStringInfoFrom(*a1);
3726         }
3727       else
3728         {
3729           int nbOfCompMin,nbOfCompMax;
3730           const DataArrayDouble *aMin, *aMax;
3731           if(nbOfComp>nbOfComp2)
3732             {
3733               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
3734               aMin=a2; aMax=a1;
3735             }
3736           else
3737             {
3738               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
3739               aMin=a1; aMax=a2;
3740             }
3741           if(nbOfCompMin==1)
3742             {
3743               ret=DataArrayDouble::New();
3744               ret->alloc(nbOfTuple,nbOfCompMax);
3745               const double *aMinPtr=aMin->getConstPointer();
3746               const double *aMaxPtr=aMax->getConstPointer();
3747               double *res=ret->getPointer();
3748               for(int i=0;i<nbOfTuple;i++)
3749                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<double>(),aMinPtr[i]));
3750               ret->copyStringInfoFrom(*aMax);
3751             }
3752           else
3753             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
3754         }
3755     }
3756   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
3757     {
3758       if(nbOfComp==nbOfComp2)
3759         {
3760           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
3761           const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
3762           const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
3763           const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
3764           ret=DataArrayDouble::New();
3765           ret->alloc(nbOfTupleMax,nbOfComp);
3766           double *res=ret->getPointer();
3767           for(int i=0;i<nbOfTupleMax;i++)
3768             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<double>());
3769           ret->copyStringInfoFrom(*aMax);
3770         }
3771       else
3772         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
3773     }
3774   else
3775     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
3776   return ret.retn();
3777 }
3778
3779 /*!
3780  * Adds values of another DataArrayDouble to values of \a this one. There are 3
3781  * valid cases.
3782  * 1.  The arrays have same number of tuples and components. Then each value of
3783  *   \a other array is added to the corresponding value of \a this array, i.e.:
3784  *   _a_ [ i, j ] += _other_ [ i, j ].
3785  * 2.  The arrays have same number of tuples and \a other array has one component. Then
3786  *   _a_ [ i, j ] += _other_ [ i, 0 ].
3787  * 3.  The arrays have same number of components and \a other array has one tuple. Then
3788  *   _a_ [ i, j ] += _a2_ [ 0, j ].
3789  *
3790  *  \param [in] other - an array to add to \a this one.
3791  *  \throw If \a other is NULL.
3792  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
3793  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
3794  *         \a other has number of both tuples and components not equal to 1.
3795  */
3796 void DataArrayDouble::addEqual(const DataArrayDouble *other)
3797 {
3798   if(!other)
3799     throw INTERP_KERNEL::Exception("DataArrayDouble::addEqual : input DataArrayDouble instance is NULL !");
3800   const char *msg="Nb of tuples mismatch for DataArrayDouble::addEqual  !";
3801   checkAllocated();
3802   other->checkAllocated();
3803   int nbOfTuple=getNumberOfTuples();
3804   int nbOfTuple2=other->getNumberOfTuples();
3805   int nbOfComp=getNumberOfComponents();
3806   int nbOfComp2=other->getNumberOfComponents();
3807   if(nbOfTuple==nbOfTuple2)
3808     {
3809       if(nbOfComp==nbOfComp2)
3810         {
3811           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<double>());
3812         }
3813       else if(nbOfComp2==1)
3814         {
3815           double *ptr=getPointer();
3816           const double *ptrc=other->getConstPointer();
3817           for(int i=0;i<nbOfTuple;i++)
3818             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<double>(),*ptrc++));
3819         }
3820       else
3821         throw INTERP_KERNEL::Exception(msg);
3822     }
3823   else if(nbOfTuple2==1)
3824     {
3825       if(nbOfComp2==nbOfComp)
3826         {
3827           double *ptr=getPointer();
3828           const double *ptrc=other->getConstPointer();
3829           for(int i=0;i<nbOfTuple;i++)
3830             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<double>());
3831         }
3832       else
3833         throw INTERP_KERNEL::Exception(msg);
3834     }
3835   else
3836     throw INTERP_KERNEL::Exception(msg);
3837   declareAsNew();
3838 }
3839
3840 /*!
3841  * Returns a new DataArrayDouble that is a subtraction of two given arrays. There are 3
3842  * valid cases.
3843  * 1.  The arrays have same number of tuples and components. Then each value of
3844  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
3845  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
3846  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
3847  *   component. Then
3848  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
3849  * 3.  The arrays have same number of components and one array, say _a2_, has one
3850  *   tuple. Then
3851  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
3852  *
3853  * Info on components is copied either from the first array (in the first case) or from
3854  * the array with maximal number of elements (getNbOfElems()).
3855  *  \param [in] a1 - an array to subtract from.
3856  *  \param [in] a2 - an array to subtract.
3857  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3858  *          The caller is to delete this result array using decrRef() as it is no more
3859  *          needed.
3860  *  \throw If either \a a1 or \a a2 is NULL.
3861  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
3862  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
3863  *         none of them has number of tuples or components equal to 1.
3864  */
3865 DataArrayDouble *DataArrayDouble::Substract(const DataArrayDouble *a1, const DataArrayDouble *a2)
3866 {
3867   if(!a1 || !a2)
3868     throw INTERP_KERNEL::Exception("DataArrayDouble::Substract : input DataArrayDouble instance is NULL !");
3869   int nbOfTuple1=a1->getNumberOfTuples();
3870   int nbOfTuple2=a2->getNumberOfTuples();
3871   int nbOfComp1=a1->getNumberOfComponents();
3872   int nbOfComp2=a2->getNumberOfComponents();
3873   if(nbOfTuple2==nbOfTuple1)
3874     {
3875       if(nbOfComp1==nbOfComp2)
3876         {
3877           MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
3878           ret->alloc(nbOfTuple2,nbOfComp1);
3879           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<double>());
3880           ret->copyStringInfoFrom(*a1);
3881           return ret.retn();
3882         }
3883       else if(nbOfComp2==1)
3884         {
3885           MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
3886           ret->alloc(nbOfTuple1,nbOfComp1);
3887           const double *a2Ptr=a2->getConstPointer();
3888           const double *a1Ptr=a1->getConstPointer();
3889           double *res=ret->getPointer();
3890           for(int i=0;i<nbOfTuple1;i++)
3891             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<double>(),a2Ptr[i]));
3892           ret->copyStringInfoFrom(*a1);
3893           return ret.retn();
3894         }
3895       else
3896         {
3897           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
3898           return 0;
3899         }
3900     }
3901   else if(nbOfTuple2==1)
3902     {
3903       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
3904       MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
3905       ret->alloc(nbOfTuple1,nbOfComp1);
3906       const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
3907       double *pt=ret->getPointer();
3908       for(int i=0;i<nbOfTuple1;i++)
3909         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<double>());
3910       ret->copyStringInfoFrom(*a1);
3911       return ret.retn();
3912     }
3913   else
3914     {
3915       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
3916       return 0;
3917     }
3918 }
3919
3920 /*!
3921  * Subtract values of another DataArrayDouble from values of \a this one. There are 3
3922  * valid cases.
3923  * 1.  The arrays have same number of tuples and components. Then each value of
3924  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
3925  *   _a_ [ i, j ] -= _other_ [ i, j ].
3926  * 2.  The arrays have same number of tuples and \a other array has one component. Then
3927  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
3928  * 3.  The arrays have same number of components and \a other array has one tuple. Then
3929  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
3930  *
3931  *  \param [in] other - an array to subtract from \a this one.
3932  *  \throw If \a other is NULL.
3933  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
3934  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
3935  *         \a other has number of both tuples and components not equal to 1.
3936  */
3937 void DataArrayDouble::substractEqual(const DataArrayDouble *other)
3938 {
3939   if(!other)
3940     throw INTERP_KERNEL::Exception("DataArrayDouble::substractEqual : input DataArrayDouble instance is NULL !");
3941   const char *msg="Nb of tuples mismatch for DataArrayDouble::substractEqual  !";
3942   checkAllocated();
3943   other->checkAllocated();
3944   int nbOfTuple=getNumberOfTuples();
3945   int nbOfTuple2=other->getNumberOfTuples();
3946   int nbOfComp=getNumberOfComponents();
3947   int nbOfComp2=other->getNumberOfComponents();
3948   if(nbOfTuple==nbOfTuple2)
3949     {
3950       if(nbOfComp==nbOfComp2)
3951         {
3952           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<double>());
3953         }
3954       else if(nbOfComp2==1)
3955         {
3956           double *ptr=getPointer();
3957           const double *ptrc=other->getConstPointer();
3958           for(int i=0;i<nbOfTuple;i++)
3959             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<double>(),*ptrc++)); 
3960         }
3961       else
3962         throw INTERP_KERNEL::Exception(msg);
3963     }
3964   else if(nbOfTuple2==1)
3965     {
3966       if(nbOfComp2==nbOfComp)
3967         {
3968           double *ptr=getPointer();
3969           const double *ptrc=other->getConstPointer();
3970           for(int i=0;i<nbOfTuple;i++)
3971             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<double>());
3972         }
3973       else
3974         throw INTERP_KERNEL::Exception(msg);
3975     }
3976   else
3977     throw INTERP_KERNEL::Exception(msg);
3978   declareAsNew();
3979 }
3980
3981 /*!
3982  * Returns a new DataArrayDouble that is a product of two given arrays. There are 3
3983  * valid cases.
3984  * 1.  The arrays have same number of tuples and components. Then each value of
3985  *   the result array (_a_) is a product of the corresponding values of \a a1 and
3986  *   \a a2, i.e. _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
3987  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
3988  *   component. Then
3989  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
3990  * 3.  The arrays have same number of components and one array, say _a2_, has one
3991  *   tuple. Then
3992  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
3993  *
3994  * Info on components is copied either from the first array (in the first case) or from
3995  * the array with maximal number of elements (getNbOfElems()).
3996  *  \param [in] a1 - a factor array.
3997  *  \param [in] a2 - another factor array.
3998  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3999  *          The caller is to delete this result array using decrRef() as it is no more
4000  *          needed.
4001  *  \throw If either \a a1 or \a a2 is NULL.
4002  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
4003  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
4004  *         none of them has number of tuples or components equal to 1.
4005  */
4006 DataArrayDouble *DataArrayDouble::Multiply(const DataArrayDouble *a1, const DataArrayDouble *a2)
4007 {
4008   if(!a1 || !a2)
4009     throw INTERP_KERNEL::Exception("DataArrayDouble::Multiply : input DataArrayDouble instance is NULL !");
4010   int nbOfTuple=a1->getNumberOfTuples();
4011   int nbOfTuple2=a2->getNumberOfTuples();
4012   int nbOfComp=a1->getNumberOfComponents();
4013   int nbOfComp2=a2->getNumberOfComponents();
4014   MCAuto<DataArrayDouble> ret=0;
4015   if(nbOfTuple==nbOfTuple2)
4016     {
4017       if(nbOfComp==nbOfComp2)
4018         {
4019           ret=DataArrayDouble::New();
4020           ret->alloc(nbOfTuple,nbOfComp);
4021           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<double>());
4022           ret->copyStringInfoFrom(*a1);
4023         }
4024       else
4025         {
4026           int nbOfCompMin,nbOfCompMax;
4027           const DataArrayDouble *aMin, *aMax;
4028           if(nbOfComp>nbOfComp2)
4029             {
4030               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
4031               aMin=a2; aMax=a1;
4032             }
4033           else
4034             {
4035               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
4036               aMin=a1; aMax=a2;
4037             }
4038           if(nbOfCompMin==1)
4039             {
4040               ret=DataArrayDouble::New();
4041               ret->alloc(nbOfTuple,nbOfCompMax);
4042               const double *aMinPtr=aMin->getConstPointer();
4043               const double *aMaxPtr=aMax->getConstPointer();
4044               double *res=ret->getPointer();
4045               for(int i=0;i<nbOfTuple;i++)
4046                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<double>(),aMinPtr[i]));
4047               ret->copyStringInfoFrom(*aMax);
4048             }
4049           else
4050             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
4051         }
4052     }
4053   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
4054     {
4055       if(nbOfComp==nbOfComp2)
4056         {
4057           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
4058           const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
4059           const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
4060           const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
4061           ret=DataArrayDouble::New();
4062           ret->alloc(nbOfTupleMax,nbOfComp);
4063           double *res=ret->getPointer();
4064           for(int i=0;i<nbOfTupleMax;i++)
4065             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<double>());
4066           ret->copyStringInfoFrom(*aMax);
4067         }
4068       else
4069         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
4070     }
4071   else
4072     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
4073   return ret.retn();
4074 }
4075
4076 /*!
4077  * Multiply values of another DataArrayDouble to values of \a this one. There are 3
4078  * valid cases.
4079  * 1.  The arrays have same number of tuples and components. Then each value of
4080  *   \a other array is multiplied to the corresponding value of \a this array, i.e.
4081  *   _this_ [ i, j ] *= _other_ [ i, j ].
4082  * 2.  The arrays have same number of tuples and \a other array has one component. Then
4083  *   _this_ [ i, j ] *= _other_ [ i, 0 ].
4084  * 3.  The arrays have same number of components and \a other array has one tuple. Then
4085  *   _this_ [ i, j ] *= _a2_ [ 0, j ].
4086  *
4087  *  \param [in] other - an array to multiply to \a this one.
4088  *  \throw If \a other is NULL.
4089  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
4090  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
4091  *         \a other has number of both tuples and components not equal to 1.
4092  */
4093 void DataArrayDouble::multiplyEqual(const DataArrayDouble *other)
4094 {
4095   if(!other)
4096     throw INTERP_KERNEL::Exception("DataArrayDouble::multiplyEqual : input DataArrayDouble instance is NULL !");
4097   const char *msg="Nb of tuples mismatch for DataArrayDouble::multiplyEqual !";
4098   checkAllocated();
4099   other->checkAllocated();
4100   int nbOfTuple=getNumberOfTuples();
4101   int nbOfTuple2=other->getNumberOfTuples();
4102   int nbOfComp=getNumberOfComponents();
4103   int nbOfComp2=other->getNumberOfComponents();
4104   if(nbOfTuple==nbOfTuple2)
4105     {
4106       if(nbOfComp==nbOfComp2)
4107         {
4108           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<double>());
4109         }
4110       else if(nbOfComp2==1)
4111         {
4112           double *ptr=getPointer();
4113           const double *ptrc=other->getConstPointer();
4114           for(int i=0;i<nbOfTuple;i++)
4115             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<double>(),*ptrc++));
4116         }
4117       else
4118         throw INTERP_KERNEL::Exception(msg);
4119     }
4120   else if(nbOfTuple2==1)
4121     {
4122       if(nbOfComp2==nbOfComp)
4123         {
4124           double *ptr=getPointer();
4125           const double *ptrc=other->getConstPointer();
4126           for(int i=0;i<nbOfTuple;i++)
4127             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<double>());
4128         }
4129       else
4130         throw INTERP_KERNEL::Exception(msg);
4131     }
4132   else
4133     throw INTERP_KERNEL::Exception(msg);
4134   declareAsNew();
4135 }
4136
4137 /*!
4138  * Returns a new DataArrayDouble that is a division of two given arrays. There are 3
4139  * valid cases.
4140  * 1.  The arrays have same number of tuples and components. Then each value of
4141  *   the result array (_a_) is a division of the corresponding values of \a a1 and
4142  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
4143  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
4144  *   component. Then
4145  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
4146  * 3.  The arrays have same number of components and one array, say _a2_, has one
4147  *   tuple. Then
4148  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
4149  *
4150  * Info on components is copied either from the first array (in the first case) or from
4151  * the array with maximal number of elements (getNbOfElems()).
4152  *  \warning No check of division by zero is performed!
4153  *  \param [in] a1 - a numerator array.
4154  *  \param [in] a2 - a denominator array.
4155  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4156  *          The caller is to delete this result array using decrRef() as it is no more
4157  *          needed.
4158  *  \throw If either \a a1 or \a a2 is NULL.
4159  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
4160  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
4161  *         none of them has number of tuples or components equal to 1.
4162  */
4163 DataArrayDouble *DataArrayDouble::Divide(const DataArrayDouble *a1, const DataArrayDouble *a2)
4164 {
4165   if(!a1 || !a2)
4166     throw INTERP_KERNEL::Exception("DataArrayDouble::Divide : input DataArrayDouble instance is NULL !");
4167   int nbOfTuple1=a1->getNumberOfTuples();
4168   int nbOfTuple2=a2->getNumberOfTuples();
4169   int nbOfComp1=a1->getNumberOfComponents();
4170   int nbOfComp2=a2->getNumberOfComponents();
4171   if(nbOfTuple2==nbOfTuple1)
4172     {
4173       if(nbOfComp1==nbOfComp2)
4174         {
4175           MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
4176           ret->alloc(nbOfTuple2,nbOfComp1);
4177           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<double>());
4178           ret->copyStringInfoFrom(*a1);
4179           return ret.retn();
4180         }
4181       else if(nbOfComp2==1)
4182         {
4183           MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
4184           ret->alloc(nbOfTuple1,nbOfComp1);
4185           const double *a2Ptr=a2->getConstPointer();
4186           const double *a1Ptr=a1->getConstPointer();
4187           double *res=ret->getPointer();
4188           for(int i=0;i<nbOfTuple1;i++)
4189             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<double>(),a2Ptr[i]));
4190           ret->copyStringInfoFrom(*a1);
4191           return ret.retn();
4192         }
4193       else
4194         {
4195           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
4196           return 0;
4197         }
4198     }
4199   else if(nbOfTuple2==1)
4200     {
4201       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
4202       MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
4203       ret->alloc(nbOfTuple1,nbOfComp1);
4204       const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
4205       double *pt=ret->getPointer();
4206       for(int i=0;i<nbOfTuple1;i++)
4207         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<double>());
4208       ret->copyStringInfoFrom(*a1);
4209       return ret.retn();
4210     }
4211   else
4212     {
4213       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
4214       return 0;
4215     }
4216 }
4217
4218 /*!
4219  * Divide values of \a this array by values of another DataArrayDouble. There are 3
4220  * valid cases.
4221  * 1.  The arrays have same number of tuples and components. Then each value of
4222  *    \a this array is divided by the corresponding value of \a other one, i.e.:
4223  *   _a_ [ i, j ] /= _other_ [ i, j ].
4224  * 2.  The arrays have same number of tuples and \a other array has one component. Then
4225  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
4226  * 3.  The arrays have same number of components and \a other array has one tuple. Then
4227  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
4228  *
4229  *  \warning No check of division by zero is performed!
4230  *  \param [in] other - an array to divide \a this one by.
4231  *  \throw If \a other is NULL.
4232  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
4233  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
4234  *         \a other has number of both tuples and components not equal to 1.
4235  */
4236 void DataArrayDouble::divideEqual(const DataArrayDouble *other)
4237 {
4238   if(!other)
4239     throw INTERP_KERNEL::Exception("DataArrayDouble::divideEqual : input DataArrayDouble instance is NULL !");
4240   const char *msg="Nb of tuples mismatch for DataArrayDouble::divideEqual !";
4241   checkAllocated();
4242   other->checkAllocated();
4243   int nbOfTuple=getNumberOfTuples();
4244   int nbOfTuple2=other->getNumberOfTuples();
4245   int nbOfComp=getNumberOfComponents();
4246   int nbOfComp2=other->getNumberOfComponents();
4247   if(nbOfTuple==nbOfTuple2)
4248     {
4249       if(nbOfComp==nbOfComp2)
4250         {
4251           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<double>());
4252         }
4253       else if(nbOfComp2==1)
4254         {
4255           double *ptr=getPointer();
4256           const double *ptrc=other->getConstPointer();
4257           for(int i=0;i<nbOfTuple;i++)
4258             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<double>(),*ptrc++));
4259         }
4260       else
4261         throw INTERP_KERNEL::Exception(msg);
4262     }
4263   else if(nbOfTuple2==1)
4264     {
4265       if(nbOfComp2==nbOfComp)
4266         {
4267           double *ptr=getPointer();
4268           const double *ptrc=other->getConstPointer();
4269           for(int i=0;i<nbOfTuple;i++)
4270             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<double>());
4271         }
4272       else
4273         throw INTERP_KERNEL::Exception(msg);
4274     }
4275   else
4276     throw INTERP_KERNEL::Exception(msg);
4277   declareAsNew();
4278 }
4279
4280 /*!
4281  * Returns a new DataArrayDouble that is the result of pow of two given arrays. There are 3
4282  * valid cases.
4283  *
4284  *  \param [in] a1 - an array to pow up.
4285  *  \param [in] a2 - another array to sum up.
4286  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4287  *          The caller is to delete this result array using decrRef() as it is no more
4288  *          needed.
4289  *  \throw If either \a a1 or \a a2 is NULL.
4290  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4291  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
4292  *  \throw If there is a negative value in \a a1.
4293  */
4294 DataArrayDouble *DataArrayDouble::Pow(const DataArrayDouble *a1, const DataArrayDouble *a2)
4295 {
4296   if(!a1 || !a2)
4297     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : at least one of input instances is null !");
4298   int nbOfTuple=a1->getNumberOfTuples();
4299   int nbOfTuple2=a2->getNumberOfTuples();
4300   int nbOfComp=a1->getNumberOfComponents();
4301   int nbOfComp2=a2->getNumberOfComponents();
4302   if(nbOfTuple!=nbOfTuple2)
4303     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of tuples mismatches !");
4304   if(nbOfComp!=1 || nbOfComp2!=1)
4305     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of components of both arrays must be equal to 1 !");
4306   MCAuto<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbOfTuple,1);
4307   const double *ptr1(a1->begin()),*ptr2(a2->begin());
4308   double *ptr=ret->getPointer();
4309   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
4310     {
4311       if(*ptr1>=0)
4312         {
4313           *ptr=pow(*ptr1,*ptr2);
4314         }
4315       else
4316         {
4317           std::ostringstream oss; oss << "DataArrayDouble::Pow : on tuple #" << i << " of a1 value is < 0 (" << *ptr1 << ") !";
4318           throw INTERP_KERNEL::Exception(oss.str().c_str());
4319         }
4320     }
4321   return ret.retn();
4322 }
4323
4324 /*!
4325  * Apply pow on values of another DataArrayDouble to values of \a this one.
4326  *
4327  *  \param [in] other - an array to pow to \a this one.
4328  *  \throw If \a other is NULL.
4329  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
4330  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
4331  *  \throw If there is a negative value in \a this.
4332  */
4333 void DataArrayDouble::powEqual(const DataArrayDouble *other)
4334 {
4335   if(!other)
4336     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : input instance is null !");
4337   int nbOfTuple=getNumberOfTuples();
4338   int nbOfTuple2=other->getNumberOfTuples();
4339   int nbOfComp=getNumberOfComponents();
4340   int nbOfComp2=other->getNumberOfComponents();
4341   if(nbOfTuple!=nbOfTuple2)
4342     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of tuples mismatches !");
4343   if(nbOfComp!=1 || nbOfComp2!=1)
4344     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of components of both arrays must be equal to 1 !");
4345   double *ptr=getPointer();
4346   const double *ptrc=other->begin();
4347   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
4348     {
4349       if(*ptr>=0)
4350         *ptr=pow(*ptr,*ptrc);
4351       else
4352         {
4353           std::ostringstream oss; oss << "DataArrayDouble::powEqual : on tuple #" << i << " of this value is < 0 (" << *ptr << ") !";
4354           throw INTERP_KERNEL::Exception(oss.str().c_str());
4355         }
4356     }
4357   declareAsNew();
4358 }
4359
4360 /*!
4361  * This method is \b NOT wrapped into python because it can be useful only for performance reasons in C++ context.
4362  * All values in \a this must be 0. or 1. within eps error. 0 means false, 1 means true.
4363  * If an another value than 0 or 1 appear (within eps precision) an INTERP_KERNEL::Exception will be thrown.
4364  *
4365  * \throw if \a this is not allocated.
4366  * \throw if \a this has not exactly one component.
4367  */
4368 std::vector<bool> DataArrayDouble::toVectorOfBool(double eps) const
4369 {
4370   checkAllocated();
4371   if(getNumberOfComponents()!=1)
4372     throw INTERP_KERNEL::Exception("DataArrayDouble::toVectorOfBool : must be applied on single component array !");
4373   int nbt(getNumberOfTuples());
4374   std::vector<bool> ret(nbt);
4375   const double *pt(begin());
4376   for(int i=0;i<nbt;i++)
4377     {
4378       if(fabs(pt[i])<eps)
4379         ret[i]=false;
4380       else if(fabs(pt[i]-1.)<eps)
4381         ret[i]=true;
4382       else
4383         {
4384           std::ostringstream oss; oss << "DataArrayDouble::toVectorOfBool : the tuple #" << i << " has value " << pt[i] << " is invalid ! must be 0. or 1. !";
4385           throw INTERP_KERNEL::Exception(oss.str().c_str());
4386         }
4387     }
4388   return ret;
4389 }
4390
4391 /*!
4392  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
4393  * Server side.
4394  */
4395 void DataArrayDouble::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
4396 {
4397   tinyInfo.resize(2);
4398   if(isAllocated())
4399     {
4400       tinyInfo[0]=getNumberOfTuples();
4401       tinyInfo[1]=getNumberOfComponents();
4402     }
4403   else
4404     {
4405       tinyInfo[0]=-1;
4406       tinyInfo[1]=-1;
4407     }
4408 }
4409
4410 /*!
4411  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
4412  * Server side.
4413  */
4414 void DataArrayDouble::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
4415 {
4416   if(isAllocated())
4417     {
4418       int nbOfCompo=getNumberOfComponents();
4419       tinyInfo.resize(nbOfCompo+1);
4420       tinyInfo[0]=getName();
4421       for(int i=0;i<nbOfCompo;i++)
4422         tinyInfo[i+1]=getInfoOnComponent(i);
4423     }
4424   else
4425     {
4426       tinyInfo.resize(1);
4427       tinyInfo[0]=getName();
4428     }
4429 }
4430
4431 /*!
4432  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
4433  * This method returns if a feeding is needed.
4434  */
4435 bool DataArrayDouble::resizeForUnserialization(const std::vector<int>& tinyInfoI)
4436 {
4437   int nbOfTuple=tinyInfoI[0];
4438   int nbOfComp=tinyInfoI[1];
4439   if(nbOfTuple!=-1 || nbOfComp!=-1)
4440     {
4441       alloc(nbOfTuple,nbOfComp);
4442       return true;
4443     }
4444   return false;
4445 }
4446
4447 /*!
4448  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
4449  */
4450 void DataArrayDouble::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
4451 {
4452   setName(tinyInfoS[0]);
4453   if(isAllocated())
4454     {
4455       int nbOfCompo=getNumberOfComponents();
4456       for(int i=0;i<nbOfCompo;i++)
4457         setInfoOnComponent(i,tinyInfoS[i+1]);
4458     }
4459 }
4460
4461 /*!
4462  * Low static method that operates 3D rotation of 'nbNodes' 3D nodes whose coordinates are arranged in \a coordsIn
4463  * around an axe ( \a center, \a vect) and with angle \a angle.
4464  */
4465 void DataArrayDouble::Rotate3DAlg(const double *center, const double *vect, double angle, int nbNodes, const double *coordsIn, double *coordsOut)
4466 {
4467   if(!center || !vect)
4468     throw INTERP_KERNEL::Exception("DataArrayDouble::Rotate3DAlg : null vector in input !");
4469   double sina(sin(angle));
4470   double cosa(cos(angle));
4471   double vectorNorm[3];
4472   double matrix[9];
4473   double matrixTmp[9];
4474   double norm(sqrt(vect[0]*vect[0]+vect[1]*vect[1]+vect[2]*vect[2]));
4475   if(norm<std::numeric_limits<double>::min())
4476     throw INTERP_KERNEL::Exception("DataArrayDouble::Rotate3DAlg : magnitude of input vector is too close of 0. !");
4477   std::transform(vect,vect+3,vectorNorm,std::bind2nd(std::multiplies<double>(),1/norm));
4478   //rotation matrix computation
4479   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;
4480   matrixTmp[0]=vectorNorm[0]*vectorNorm[0]; matrixTmp[1]=vectorNorm[0]*vectorNorm[1]; matrixTmp[2]=vectorNorm[0]*vectorNorm[2];
4481   matrixTmp[3]=vectorNorm[1]*vectorNorm[0]; matrixTmp[4]=vectorNorm[1]*vectorNorm[1]; matrixTmp[5]=vectorNorm[1]*vectorNorm[2];
4482   matrixTmp[6]=vectorNorm[2]*vectorNorm[0]; matrixTmp[7]=vectorNorm[2]*vectorNorm[1]; matrixTmp[8]=vectorNorm[2]*vectorNorm[2];
4483   std::transform(matrixTmp,matrixTmp+9,matrixTmp,std::bind2nd(std::multiplies<double>(),1-cosa));
4484   std::transform(matrix,matrix+9,matrixTmp,matrix,std::plus<double>());
4485   matrixTmp[0]=0.; matrixTmp[1]=-vectorNorm[2]; matrixTmp[2]=vectorNorm[1];
4486   matrixTmp[3]=vectorNorm[2]; matrixTmp[4]=0.; matrixTmp[5]=-vectorNorm[0];
4487   matrixTmp[6]=-vectorNorm[1]; matrixTmp[7]=vectorNorm[0]; matrixTmp[8]=0.;
4488   std::transform(matrixTmp,matrixTmp+9,matrixTmp,std::bind2nd(std::multiplies<double>(),sina));
4489   std::transform(matrix,matrix+9,matrixTmp,matrix,std::plus<double>());
4490   //rotation matrix computed.
4491   double tmp[3];
4492   for(int i=0; i<nbNodes; i++)
4493     {
4494       std::transform(coordsIn+i*3,coordsIn+(i+1)*3,center,tmp,std::minus<double>());
4495       coordsOut[i*3]=matrix[0]*tmp[0]+matrix[1]*tmp[1]+matrix[2]*tmp[2]+center[0];
4496       coordsOut[i*3+1]=matrix[3]*tmp[0]+matrix[4]*tmp[1]+matrix[5]*tmp[2]+center[1];
4497       coordsOut[i*3+2]=matrix[6]*tmp[0]+matrix[7]*tmp[1]+matrix[8]*tmp[2]+center[2];
4498     }
4499 }
4500
4501 void DataArrayDouble::Symmetry3DPlane(const double point[3], const double normalVector[3], int nbNodes, const double *coordsIn, double *coordsOut)
4502 {
4503   double matrix[9],matrix2[9],matrix3[9];
4504   double vect[3],crossVect[3];
4505   INTERP_KERNEL::orthogonalVect3(normalVector,vect);
4506   crossVect[0]=normalVector[1]*vect[2]-normalVector[2]*vect[1];
4507   crossVect[1]=normalVector[2]*vect[0]-normalVector[0]*vect[2];
4508   crossVect[2]=normalVector[0]*vect[1]-normalVector[1]*vect[0];
4509   double nv(INTERP_KERNEL::norm<3>(vect)),ni(INTERP_KERNEL::norm<3>(normalVector)),nc(INTERP_KERNEL::norm<3>(crossVect));
4510   matrix[0]=vect[0]/nv; matrix[1]=crossVect[0]/nc; matrix[2]=-normalVector[0]/ni;
4511   matrix[3]=vect[1]/nv; matrix[4]=crossVect[1]/nc; matrix[5]=-normalVector[1]/ni;
4512   matrix[6]=vect[2]/nv; matrix[7]=crossVect[2]/nc; matrix[8]=-normalVector[2]/ni;
4513   matrix2[0]=vect[0]/nv; matrix2[1]=vect[1]/nv; matrix2[2]=vect[2]/nv;
4514   matrix2[3]=crossVect[0]/nc; matrix2[4]=crossVect[1]/nc; matrix2[5]=crossVect[2]/nc;
4515   matrix2[6]=normalVector[0]/ni; matrix2[7]=normalVector[1]/ni; matrix2[8]=normalVector[2]/ni;
4516   for(int i=0;i<3;i++)
4517     for(int j=0;j<3;j++)
4518       {
4519         double val(0.);
4520         for(int k=0;k<3;k++)
4521           val+=matrix[3*i+k]*matrix2[3*k+j];
4522         matrix3[3*i+j]=val;
4523       }
4524   //rotation matrix computed.
4525   double tmp[3];
4526   for(int i=0; i<nbNodes; i++)
4527     {
4528       std::transform(coordsIn+i*3,coordsIn+(i+1)*3,point,tmp,std::minus<double>());
4529       coordsOut[i*3]=matrix3[0]*tmp[0]+matrix3[1]*tmp[1]+matrix3[2]*tmp[2]+point[0];
4530       coordsOut[i*3+1]=matrix3[3]*tmp[0]+matrix3[4]*tmp[1]+matrix3[5]*tmp[2]+point[1];
4531       coordsOut[i*3+2]=matrix3[6]*tmp[0]+matrix3[7]*tmp[1]+matrix3[8]*tmp[2]+point[2];
4532     }
4533 }
4534
4535 void DataArrayDouble::GiveBaseForPlane(const double normalVector[3], double baseOfPlane[9])
4536 {
4537   double vect[3],crossVect[3];
4538   INTERP_KERNEL::orthogonalVect3(normalVector,vect);
4539   crossVect[0]=normalVector[1]*vect[2]-normalVector[2]*vect[1];
4540   crossVect[1]=normalVector[2]*vect[0]-normalVector[0]*vect[2];
4541   crossVect[2]=normalVector[0]*vect[1]-normalVector[1]*vect[0];
4542   double nv(INTERP_KERNEL::norm<3>(vect)),ni(INTERP_KERNEL::norm<3>(normalVector)),nc(INTERP_KERNEL::norm<3>(crossVect));
4543   baseOfPlane[0]=vect[0]/nv; baseOfPlane[1]=vect[1]/nv; baseOfPlane[2]=vect[2]/nv;
4544   baseOfPlane[3]=crossVect[0]/nc; baseOfPlane[4]=crossVect[1]/nc; baseOfPlane[5]=crossVect[2]/nc;
4545   baseOfPlane[6]=normalVector[0]/ni; baseOfPlane[7]=normalVector[1]/ni; baseOfPlane[8]=normalVector[2]/ni;
4546 }
4547
4548 /*!
4549  * Low static method that operates 3D rotation of \a nbNodes 3D nodes whose coordinates are arranged in \a coords
4550  * around the center point \a center and with angle \a angle.
4551  */
4552 void DataArrayDouble::Rotate2DAlg(const double *center, double angle, int nbNodes, const double *coordsIn, double *coordsOut)
4553 {
4554   double cosa=cos(angle);
4555   double sina=sin(angle);
4556   double matrix[4];
4557   matrix[0]=cosa; matrix[1]=-sina; matrix[2]=sina; matrix[3]=cosa;
4558   double tmp[2];
4559   for(int i=0; i<nbNodes; i++)
4560     {
4561       std::transform(coordsIn+i*2,coordsIn+(i+1)*2,center,tmp,std::minus<double>());
4562       coordsOut[i*2]=matrix[0]*tmp[0]+matrix[1]*tmp[1]+center[0];
4563       coordsOut[i*2+1]=matrix[2]*tmp[0]+matrix[3]*tmp[1]+center[1];
4564     }
4565 }
4566
4567 DataArrayDoubleIterator::DataArrayDoubleIterator(DataArrayDouble *da):_da(da),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
4568 {
4569   if(_da)
4570     {
4571       _da->incrRef();
4572       if(_da->isAllocated())
4573         {
4574           _nb_comp=da->getNumberOfComponents();
4575           _nb_tuple=da->getNumberOfTuples();
4576           _pt=da->getPointer();
4577         }
4578     }
4579 }
4580
4581 DataArrayDoubleIterator::~DataArrayDoubleIterator()
4582 {
4583   if(_da)
4584     _da->decrRef();
4585 }
4586
4587 DataArrayDoubleTuple *DataArrayDoubleIterator::nextt()
4588 {
4589   if(_tuple_id<_nb_tuple)
4590     {
4591       _tuple_id++;
4592       DataArrayDoubleTuple *ret=new DataArrayDoubleTuple(_pt,_nb_comp);
4593       _pt+=_nb_comp;
4594       return ret;
4595     }
4596   else
4597     return 0;
4598 }
4599
4600 DataArrayDoubleTuple::DataArrayDoubleTuple(double *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
4601 {
4602 }
4603
4604
4605 std::string DataArrayDoubleTuple::repr() const
4606 {
4607   std::ostringstream oss; oss.precision(17); oss << "(";
4608   for(int i=0;i<_nb_of_compo-1;i++)
4609     oss << _pt[i] << ", ";
4610   oss << _pt[_nb_of_compo-1] << ")";
4611   return oss.str();
4612 }
4613
4614 double DataArrayDoubleTuple::doubleValue() const
4615 {
4616   if(_nb_of_compo==1)
4617     return *_pt;
4618   throw INTERP_KERNEL::Exception("DataArrayDoubleTuple::doubleValue : DataArrayDoubleTuple instance has not exactly 1 component -> Not possible to convert it into a double precision float !");
4619 }
4620
4621 /*!
4622  * This method returns a newly allocated instance the caller should dealed with by a MEDCoupling::DataArrayDouble::decrRef.
4623  * This method performs \b no copy of data. The content is only referenced using MEDCoupling::DataArrayDouble::useArray with ownership set to \b false.
4624  * 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
4625  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
4626  */
4627 DataArrayDouble *DataArrayDoubleTuple::buildDADouble(int nbOfTuples, int nbOfCompo) const
4628 {
4629   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
4630     {
4631       DataArrayDouble *ret=DataArrayDouble::New();
4632       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
4633       return ret;
4634     }
4635   else
4636     {
4637       std::ostringstream oss; oss << "DataArrayDoubleTuple::buildDADouble : unable to build a requested DataArrayDouble instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
4638       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
4639       throw INTERP_KERNEL::Exception(oss.str().c_str());
4640     }
4641 }
4642
4643 /*!
4644  * Returns a new instance of DataArrayInt. The caller is to delete this array
4645  * using decrRef() as it is no more needed. 
4646  */
4647 DataArrayInt *DataArrayInt::New()
4648 {
4649   return new DataArrayInt;
4650 }
4651
4652 /*!
4653  * Returns the only one value in \a this, if and only if number of elements
4654  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
4655  *  \return double - the sole value stored in \a this array.
4656  *  \throw If at least one of conditions stated above is not fulfilled.
4657  */
4658 int DataArrayInt::intValue() const
4659 {
4660   if(isAllocated())
4661     {
4662       if(getNbOfElems()==1)
4663         {
4664           return *getConstPointer();
4665         }
4666       else
4667         throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is allocated but number of elements is not equal to 1 !");
4668     }
4669   else
4670     throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is not allocated !");
4671 }
4672
4673 /*!
4674  * Returns an integer value characterizing \a this array, which is useful for a quick
4675  * comparison of many instances of DataArrayInt.
4676  *  \return int - the hash value.
4677  *  \throw If \a this is not allocated.
4678  */
4679 int DataArrayInt::getHashCode() const
4680 {
4681   checkAllocated();
4682   std::size_t nbOfElems=getNbOfElems();
4683   int ret=nbOfElems*65536;
4684   int delta=3;
4685   if(nbOfElems>48)
4686     delta=nbOfElems/8;
4687   int ret0=0;
4688   const int *pt=begin();
4689   for(std::size_t i=0;i<nbOfElems;i+=delta)
4690     ret0+=pt[i] & 0x1FFF;
4691   return ret+ret0;
4692 }
4693
4694 /*!
4695  * Returns a full copy of \a this. For more info on copying data arrays see
4696  * \ref MEDCouplingArrayBasicsCopyDeep.
4697  *  \return DataArrayInt * - a new instance of DataArrayInt.
4698  */
4699 DataArrayInt *DataArrayInt::deepCopy() const
4700 {
4701   return new DataArrayInt(*this);
4702 }
4703
4704 /*!
4705  * Returns either a \a deep or \a shallow copy of this array. For more info see
4706  * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
4707  *  \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
4708  *  \return DataArrayInt * - either a new instance of DataArrayInt (if \a dCpy
4709  *          == \a true) or \a this instance (if \a dCpy == \a false).
4710  */
4711 DataArrayInt *DataArrayInt::performCopyOrIncrRef(bool dCpy) const
4712 {
4713   return DataArrayTemplateClassic<int>::PerformCopyOrIncrRef(dCpy,*this);
4714 }
4715
4716 /*!
4717  * Assign zero to all values in \a this array. To know more on filling arrays see
4718  * \ref MEDCouplingArrayFill.
4719  * \throw If \a this is not allocated.
4720  */
4721 void DataArrayInt::fillWithZero()
4722 {
4723   fillWithValue(0);
4724 }
4725
4726 /*!
4727  * Set all values in \a this array so that the i-th element equals to \a init + i
4728  * (i starts from zero). To know more on filling arrays see \ref MEDCouplingArrayFill.
4729  *  \param [in] init - value to assign to the first element of array.
4730  *  \throw If \a this->getNumberOfComponents() != 1
4731  *  \throw If \a this is not allocated.
4732  */
4733 void DataArrayInt::iota(int init)
4734 {
4735   checkAllocated();
4736   if(getNumberOfComponents()!=1)
4737     throw INTERP_KERNEL::Exception("DataArrayInt::iota : works only for arrays with only one component, you can call 'rearrange' method before !");
4738   int *ptr=getPointer();
4739   int ntuples=getNumberOfTuples();
4740   for(int i=0;i<ntuples;i++)
4741     ptr[i]=init+i;
4742   declareAsNew();
4743 }
4744
4745 /*!
4746  * Returns a textual and human readable representation of \a this instance of
4747  * DataArrayInt. This text is shown when a DataArrayInt is printed in Python.
4748  * \return std::string - text describing \a this DataArrayInt.
4749  * 
4750  * \sa reprNotTooLong, reprZip
4751  */
4752 std::string DataArrayInt::repr() const
4753 {
4754   std::ostringstream ret;
4755   reprStream(ret);
4756   return ret.str();
4757 }
4758
4759 std::string DataArrayInt::reprZip() const
4760 {
4761   std::ostringstream ret;
4762   reprZipStream(ret);
4763   return ret.str();
4764 }
4765
4766 /*!
4767  * This method is close to repr method except that when \a this has more than 1000 tuples, all tuples are not
4768  * printed out to avoid to consume too much space in interpretor.
4769  * \sa repr
4770  */
4771 std::string DataArrayInt::reprNotTooLong() const
4772 {
4773   std::ostringstream ret;
4774   reprNotTooLongStream(ret);
4775   return ret.str();
4776 }
4777
4778 void DataArrayInt::writeVTK(std::ostream& ofs, int indent, const std::string& type, const std::string& nameInFile, DataArrayByte *byteArr) const
4779 {
4780   static const char SPACE[4]={' ',' ',' ',' '};
4781   checkAllocated();
4782   std::string idt(indent,' ');
4783   ofs << idt << "<DataArray type=\"" << type << "\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
4784   if(byteArr)
4785     {
4786       ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
4787       if(std::string(type)=="Int32")
4788         {
4789           const char *data(reinterpret_cast<const char *>(begin()));
4790           std::size_t sz(getNbOfElems()*sizeof(int));
4791           byteArr->insertAtTheEnd(data,data+sz);
4792           byteArr->insertAtTheEnd(SPACE,SPACE+4);
4793         }
4794       else if(std::string(type)=="Int8")
4795         {
4796           INTERP_KERNEL::AutoPtr<char> tmp(new char[getNbOfElems()]);
4797           std::copy(begin(),end(),(char *)tmp);
4798           byteArr->insertAtTheEnd((char *)tmp,(char *)tmp+getNbOfElems());
4799           byteArr->insertAtTheEnd(SPACE,SPACE+4);
4800         }
4801       else if(std::string(type)=="UInt8")
4802         {
4803           INTERP_KERNEL::AutoPtr<unsigned char> tmp(new unsigned char[getNbOfElems()]);
4804           std::copy(begin(),end(),(unsigned char *)tmp);
4805           byteArr->insertAtTheEnd((unsigned char *)tmp,(unsigned char *)tmp+getNbOfElems());
4806           byteArr->insertAtTheEnd(SPACE,SPACE+4);
4807         }
4808       else
4809         throw INTERP_KERNEL::Exception("DataArrayInt::writeVTK : Only Int32, Int8 and UInt8 supported !");
4810     }
4811   else
4812     {
4813       ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
4814       std::copy(begin(),end(),std::ostream_iterator<int>(ofs," "));
4815     }
4816   ofs << std::endl << idt << "</DataArray>\n";
4817 }
4818
4819 void DataArrayInt::reprStream(std::ostream& stream) const
4820 {
4821   stream << "Name of int array : \"" << _name << "\"\n";
4822   reprWithoutNameStream(stream);
4823 }
4824
4825 void DataArrayInt::reprZipStream(std::ostream& stream) const
4826 {
4827   stream << "Name of int array : \"" << _name << "\"\n";
4828   reprZipWithoutNameStream(stream);
4829 }
4830
4831 void DataArrayInt::reprNotTooLongStream(std::ostream& stream) const
4832 {
4833   stream << "Name of int array : \"" << _name << "\"\n";
4834   reprNotTooLongWithoutNameStream(stream);
4835 }
4836
4837 void DataArrayInt::reprWithoutNameStream(std::ostream& stream) const
4838 {
4839   DataArray::reprWithoutNameStream(stream);
4840   _mem.repr(getNumberOfComponents(),stream);
4841 }
4842
4843 void DataArrayInt::reprZipWithoutNameStream(std::ostream& stream) const
4844 {
4845   DataArray::reprWithoutNameStream(stream);
4846   _mem.reprZip(getNumberOfComponents(),stream);
4847 }
4848
4849 void DataArrayInt::reprNotTooLongWithoutNameStream(std::ostream& stream) const
4850 {
4851   DataArray::reprWithoutNameStream(stream);
4852   stream.precision(17);
4853   _mem.reprNotTooLong(getNumberOfComponents(),stream);
4854 }
4855
4856 void DataArrayInt::reprCppStream(const std::string& varName, std::ostream& stream) const
4857 {
4858   int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
4859   const int *data=getConstPointer();
4860   stream << "DataArrayInt *" << varName << "=DataArrayInt::New();" << std::endl;
4861   if(nbTuples*nbComp>=1)
4862     {
4863       stream << "const int " << varName << "Data[" << nbTuples*nbComp << "]={";
4864       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<int>(stream,","));
4865       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
4866       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
4867     }
4868   else
4869     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
4870   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
4871 }
4872
4873 /*!
4874  * Method that gives a quick overvien of \a this for python.
4875  */
4876 void DataArrayInt::reprQuickOverview(std::ostream& stream) const
4877 {
4878   static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
4879   stream << "DataArrayInt C++ instance at " << this << ". ";
4880   if(isAllocated())
4881     {
4882       int nbOfCompo=(int)_info_on_compo.size();
4883       if(nbOfCompo>=1)
4884         {
4885           int nbOfTuples=getNumberOfTuples();
4886           stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
4887           reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
4888         }
4889       else
4890         stream << "Number of components : 0.";
4891     }
4892   else
4893     stream << "*** No data allocated ****";
4894 }
4895
4896 void DataArrayInt::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
4897 {
4898   const int *data=begin();
4899   int nbOfTuples=getNumberOfTuples();
4900   int nbOfCompo=(int)_info_on_compo.size();
4901   std::ostringstream oss2; oss2 << "[";
4902   std::string oss2Str(oss2.str());
4903   bool isFinished=true;
4904   for(int i=0;i<nbOfTuples && isFinished;i++)
4905     {
4906       if(nbOfCompo>1)
4907         {
4908           oss2 << "(";
4909           for(int j=0;j<nbOfCompo;j++,data++)
4910             {
4911               oss2 << *data;
4912               if(j!=nbOfCompo-1) oss2 << ", ";
4913             }
4914           oss2 << ")";
4915         }
4916       else
4917         oss2 << *data++;
4918       if(i!=nbOfTuples-1) oss2 << ", ";
4919       std::string oss3Str(oss2.str());
4920       if(oss3Str.length()<maxNbOfByteInRepr)
4921         oss2Str=oss3Str;
4922       else
4923         isFinished=false;
4924     }
4925   stream << oss2Str;
4926   if(!isFinished)
4927     stream << "... ";
4928   stream << "]";
4929 }
4930
4931 /*!
4932  * Modifies in place \a this one-dimensional array so that each value \a v = \a indArrBg[ \a v ],
4933  * i.e. a current value is used as in index to get a new value from \a indArrBg.
4934  *  \param [in] indArrBg - pointer to the first element of array of new values to assign
4935  *         to \a this array.
4936  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
4937  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
4938  *  \throw If \a this->getNumberOfComponents() != 1
4939  *  \throw If any value of \a this can't be used as a valid index for 
4940  *         [\a indArrBg, \a indArrEnd).
4941  *
4942  *  \sa changeValue
4943  */
4944 void DataArrayInt::transformWithIndArr(const int *indArrBg, const int *indArrEnd)
4945 {
4946   checkAllocated();
4947   if(getNumberOfComponents()!=1)
4948     throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
4949   int nbElemsIn((int)std::distance(indArrBg,indArrEnd)),nbOfTuples(getNumberOfTuples()),*pt(getPointer());
4950   for(int i=0;i<nbOfTuples;i++,pt++)
4951     {
4952       if(*pt>=0 && *pt<nbElemsIn)
4953         *pt=indArrBg[*pt];
4954       else
4955         {
4956           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " of this value is " << *pt << ", should be in [0," << nbElemsIn << ") !";
4957           throw INTERP_KERNEL::Exception(oss.str().c_str());
4958         }
4959     }
4960   declareAsNew();
4961 }
4962
4963 /*!
4964  * Computes distribution of values of \a this one-dimensional array between given value
4965  * ranges (casts). This method is typically useful for entity number spliting by types,
4966  * for example. 
4967  *  \warning The values contained in \a arrBg should be sorted ascendently. No
4968  *           check of this is be done. If not, the result is not warranted. 
4969  *  \param [in] arrBg - the array of ascending values defining the value ranges. The i-th
4970  *         value of \a arrBg (\a arrBg[ i ]) gives the lowest value of the i-th range,
4971  *         and the greatest value of the i-th range equals to \a arrBg[ i+1 ] - 1. \a
4972  *         arrBg containing \a n values defines \a n-1 ranges. The last value of \a arrBg
4973  *         should be more than every value in \a this array.
4974  *  \param [in] arrEnd - specifies the end of the array \a arrBg, so that
4975  *              the last value of \a arrBg is \a arrEnd[ -1 ].
4976  *  \param [out] castArr - a new instance of DataArrayInt, of same size as \a this array
4977  *         (same number of tuples and components), the caller is to delete 
4978  *         using decrRef() as it is no more needed.
4979  *         This array contains indices of ranges for every value of \a this array. I.e.
4980  *         the i-th value of \a castArr gives the index of range the i-th value of \a this
4981  *         belongs to. Or, in other words, this parameter contains for each tuple in \a
4982  *         this in which cast it holds.
4983  *  \param [out] rankInsideCast - a new instance of DataArrayInt, of same size as \a this
4984  *         array, the caller is to delete using decrRef() as it is no more needed.
4985  *         This array contains ranks of values of \a this array within ranges
4986  *         they belongs to. I.e. the i-th value of \a rankInsideCast gives the rank of
4987  *         the i-th value of \a this array within the \a castArr[ i ]-th range, to which
4988  *         the i-th value of \a this belongs to. Or, in other words, this param contains 
4989  *         for each tuple its rank inside its cast. The rank is computed as difference
4990  *         between the value and the lowest value of range.
4991  *  \param [out] castsPresent - a new instance of DataArrayInt, containing indices of
4992  *         ranges (casts) to which at least one value of \a this array belongs.
4993  *         Or, in other words, this param contains the casts that \a this contains.
4994  *         The caller is to delete this array using decrRef() as it is no more needed.
4995  *
4996  * \b Example: If \a this contains [6,5,0,3,2,7,8,1,4] and \a arrBg contains [0,4,9] then
4997  *            the output of this method will be : 
4998  * - \a castArr       : [1,1,0,0,0,1,1,0,1]
4999  * - \a rankInsideCast: [2,1,0,3,2,3,4,1,0]
5000  * - \a castsPresent  : [0,1]
5001  *
5002  * I.e. values of \a this array belong to 2 ranges: #0 and #1. Value 6 belongs to the
5003  * range #1 and its rank within this range is 2; etc.
5004  *
5005  *  \throw If \a this->getNumberOfComponents() != 1.
5006  *  \throw If \a arrEnd - arrBg < 2.
5007  *  \throw If any value of \a this is not less than \a arrEnd[-1].
5008  */
5009 void DataArrayInt::splitByValueRange(const int *arrBg, const int *arrEnd,
5010                                      DataArrayInt *& castArr, DataArrayInt *& rankInsideCast, DataArrayInt *& castsPresent) const
5011 {
5012   checkAllocated();
5013   if(getNumberOfComponents()!=1)
5014     throw INTERP_KERNEL::Exception("Call splitByValueRange  method on DataArrayInt with only one component, you can call 'rearrange' method before !");
5015   int nbOfTuples=getNumberOfTuples();
5016   std::size_t nbOfCast=std::distance(arrBg,arrEnd);
5017   if(nbOfCast<2)
5018     throw INTERP_KERNEL::Exception("DataArrayInt::splitByValueRange : The input array giving the cast range values should be of size >=2 !");
5019   nbOfCast--;
5020   const int *work=getConstPointer();
5021   typedef std::reverse_iterator<const int *> rintstart;
5022   rintstart bg(arrEnd);//OK no problem because size of 'arr' is greater or equal 2
5023   rintstart end2(arrBg);
5024   MCAuto<DataArrayInt> ret1=DataArrayInt::New();
5025   MCAuto<DataArrayInt> ret2=DataArrayInt::New();
5026   MCAuto<DataArrayInt> ret3=DataArrayInt::New();
5027   ret1->alloc(nbOfTuples,1);
5028   ret2->alloc(nbOfTuples,1);
5029   int *ret1Ptr=ret1->getPointer();
5030   int *ret2Ptr=ret2->getPointer();
5031   std::set<std::size_t> castsDetected;
5032   for(int i=0;i<nbOfTuples;i++)
5033     {
5034       rintstart res=std::find_if(bg,end2,std::bind2nd(std::less_equal<int>(), work[i]));
5035       std::size_t pos=std::distance(bg,res);
5036       std::size_t pos2=nbOfCast-pos;
5037       if(pos2<nbOfCast)
5038         {
5039           ret1Ptr[i]=(int)pos2;
5040           ret2Ptr[i]=work[i]-arrBg[pos2];
5041           castsDetected.insert(pos2);
5042         }
5043       else
5044         {
5045           std::ostringstream oss; oss << "DataArrayInt::splitByValueRange : At rank #" << i << " the value is " << work[i] << " should be in [0," << *bg << ") !";
5046           throw INTERP_KERNEL::Exception(oss.str().c_str());
5047         }
5048     }
5049   ret3->alloc((int)castsDetected.size(),1);
5050   std::copy(castsDetected.begin(),castsDetected.end(),ret3->getPointer());
5051   castArr=ret1.retn();
5052   rankInsideCast=ret2.retn();
5053   castsPresent=ret3.retn();
5054 }
5055
5056 /*!
5057  * 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 ).
5058  * 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 ).
5059  * This method works only if \a this is allocated and single component. If not an exception will be thrown.
5060  *
5061  * \param [out] strt - the start of the range (included) if true is returned.
5062  * \param [out] sttoopp - the end of the range (not included) if true is returned.
5063  * \param [out] stteepp - the step of the range if true is returned.
5064  * \return the verdict of the check.
5065  *
5066  * \sa DataArray::GetNumberOfItemGivenBES
5067  */
5068 bool DataArrayInt::isRange(int& strt, int& sttoopp, int& stteepp) const
5069 {
5070   checkAllocated();
5071   if(getNumberOfComponents()!=1)
5072     throw INTERP_KERNEL::Exception("DataArrayInt::isRange : this must be single component array !");
5073   int nbTuples(getNumberOfTuples());
5074   if(nbTuples==0)
5075     { strt=0; sttoopp=0; stteepp=1; return true; }
5076   const int *pt(begin());
5077   strt=*pt; 
5078   if(nbTuples==1)
5079     { sttoopp=strt+1; stteepp=1; return true; }
5080   strt=*pt; sttoopp=pt[nbTuples-1];
5081   if(strt==sttoopp)
5082     return false;
5083   if(sttoopp>strt)
5084     {
5085       sttoopp++;
5086       int a(sttoopp-1-strt),tmp(strt);
5087       if(a%(nbTuples-1)!=0)
5088         return false;
5089       stteepp=a/(nbTuples-1);
5090       for(int i=0;i<nbTuples;i++,tmp+=stteepp)
5091         if(pt[i]!=tmp)
5092           return false;
5093       return true;
5094     }
5095   else
5096     {
5097       sttoopp--;
5098       int a(strt-sttoopp-1),tmp(strt);
5099       if(a%(nbTuples-1)!=0)
5100         return false;
5101       stteepp=-(a/(nbTuples-1));
5102       for(int i=0;i<nbTuples;i++,tmp+=stteepp)
5103         if(pt[i]!=tmp)
5104           return false;
5105       return true;
5106     }
5107 }
5108
5109 /*!
5110  * Creates a one-dimensional DataArrayInt (\a res) whose contents are computed from 
5111  * values of \a this (\a a) and the given (\a indArr) arrays as follows:
5112  * \a res[ \a indArr[ \a a[ i ]]] = i. I.e. for each value in place i \a v = \a a[ i ],
5113  * new value in place \a indArr[ \a v ] is i.
5114  *  \param [in] indArrBg - the array holding indices within the result array to assign
5115  *         indices of values of \a this array pointing to values of \a indArrBg.
5116  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
5117  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
5118  *  \return DataArrayInt * - the new instance of DataArrayInt.
5119  *          The caller is to delete this result array using decrRef() as it is no more
5120  *          needed.
5121  *  \throw If \a this->getNumberOfComponents() != 1.
5122  *  \throw If any value of \a this array is not a valid index for \a indArrBg array.
5123  *  \throw If any value of \a indArrBg is not a valid index for \a this array.
5124  */
5125 DataArrayInt *DataArrayInt::transformWithIndArrR(const int *indArrBg, const int *indArrEnd) const
5126 {
5127   checkAllocated();
5128   if(getNumberOfComponents()!=1)
5129     throw INTERP_KERNEL::Exception("Call transformWithIndArrR method on DataArrayInt with only one component, you can call 'rearrange' method before !");
5130   int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
5131   int nbOfTuples=getNumberOfTuples();
5132   const int *pt=getConstPointer();
5133   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5134   ret->alloc(nbOfTuples,1);
5135   ret->fillWithValue(-1);
5136   int *tmp=ret->getPointer();
5137   for(int i=0;i<nbOfTuples;i++,pt++)
5138     {
5139       if(*pt>=0 && *pt<nbElemsIn)
5140         {
5141           int pos=indArrBg[*pt];
5142           if(pos>=0 && pos<nbOfTuples)
5143             tmp[pos]=i;
5144           else
5145             {
5146               std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value of new pos is " << pos << " ( indArrBg[" << *pt << "]) ! Should be in [0," << nbOfTuples << ") !";
5147               throw INTERP_KERNEL::Exception(oss.str().c_str());
5148             }
5149         }
5150       else
5151         {
5152           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn << " !";
5153           throw INTERP_KERNEL::Exception(oss.str().c_str());
5154         }
5155     }
5156   return ret.retn();
5157 }
5158
5159 /*!
5160  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
5161  * from values of \a this array, which is supposed to contain a renumbering map in 
5162  * "Old to New" mode. The result array contains a renumbering map in "New to Old" mode.
5163  * To know how to use the renumbering maps see \ref numbering.
5164  *  \param [in] newNbOfElem - the number of tuples in the result array.
5165  *  \return DataArrayInt * - the new instance of DataArrayInt.
5166  *          The caller is to delete this result array using decrRef() as it is no more
5167  *          needed.
5168  * 
5169  *  \if ENABLE_EXAMPLES
5170  *  \ref cpp_mcdataarrayint_invertarrayo2n2n2o "Here is a C++ example".<br>
5171  *  \ref py_mcdataarrayint_invertarrayo2n2n2o  "Here is a Python example".
5172  *  \endif
5173  */
5174 DataArrayInt *DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const
5175 {
5176   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5177   ret->alloc(newNbOfElem,1);
5178   int nbOfOldNodes=getNumberOfTuples();
5179   const int *old2New=getConstPointer();
5180   int *pt=ret->getPointer();
5181   for(int i=0;i!=nbOfOldNodes;i++)
5182     {
5183       int newp(old2New[i]);
5184       if(newp!=-1)
5185         {
5186           if(newp>=0 && newp<newNbOfElem)
5187             pt[newp]=i;
5188           else
5189             {
5190               std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2O : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
5191               throw INTERP_KERNEL::Exception(oss.str().c_str());
5192             }
5193         }
5194     }
5195   return ret.retn();
5196 }
5197
5198 /*!
5199  * This method is similar to DataArrayInt::invertArrayO2N2N2O except that 
5200  * 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]
5201  */
5202 DataArrayInt *DataArrayInt::invertArrayO2N2N2OBis(int newNbOfElem) const
5203 {
5204   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5205   ret->alloc(newNbOfElem,1);
5206   int nbOfOldNodes=getNumberOfTuples();
5207   const int *old2New=getConstPointer();
5208   int *pt=ret->getPointer();
5209   for(int i=nbOfOldNodes-1;i>=0;i--)
5210     {
5211       int newp(old2New[i]);
5212       if(newp!=-1)
5213         {
5214           if(newp>=0 && newp<newNbOfElem)
5215             pt[newp]=i;
5216           else
5217             {
5218               std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2OBis : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
5219               throw INTERP_KERNEL::Exception(oss.str().c_str());
5220             }
5221         }
5222     }
5223   return ret.retn();
5224 }
5225
5226 /*!
5227  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
5228  * from values of \a this array, which is supposed to contain a renumbering map in 
5229  * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
5230  * To know how to use the renumbering maps see \ref numbering.
5231  *  \param [in] newNbOfElem - the number of tuples in the result array.
5232  *  \return DataArrayInt * - the new instance of DataArrayInt.
5233  *          The caller is to delete this result array using decrRef() as it is no more
5234  *          needed.
5235  * 
5236  *  \if ENABLE_EXAMPLES
5237  *  \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
5238  *
5239  *  \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
5240  *  \endif
5241  */
5242 DataArrayInt *DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const
5243 {
5244   checkAllocated();
5245   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5246   ret->alloc(oldNbOfElem,1);
5247   const int *new2Old=getConstPointer();
5248   int *pt=ret->getPointer();
5249   std::fill(pt,pt+oldNbOfElem,-1);
5250   int nbOfNewElems=getNumberOfTuples();
5251   for(int i=0;i<nbOfNewElems;i++)
5252     {
5253       int v(new2Old[i]);
5254       if(v>=0 && v<oldNbOfElem)
5255         pt[v]=i;
5256       else
5257         {
5258           std::ostringstream oss; oss << "DataArrayInt::invertArrayN2O2O2N : in new id #" << i << " old value is " << v << " expected to be in [0," << oldNbOfElem << ") !";
5259           throw INTERP_KERNEL::Exception(oss.str().c_str());
5260         }
5261     }
5262   return ret.retn();
5263 }
5264
5265 /*!
5266  * Equivalent to DataArrayInt::isEqual except that if false the reason of
5267  * mismatch is given.
5268  * 
5269  * \param [in] other the instance to be compared with \a this
5270  * \param [out] reason In case of inequality returns the reason.
5271  * \sa DataArrayInt::isEqual
5272  */
5273 bool DataArrayInt::isEqualIfNotWhy(const DataArrayInt& other, std::string& reason) const
5274 {
5275   if(!areInfoEqualsIfNotWhy(other,reason))
5276     return false;
5277   return _mem.isEqual(other._mem,0,reason);
5278 }
5279
5280 /*!
5281  * Checks if \a this and another DataArrayInt are fully equal. For more info see
5282  * \ref MEDCouplingArrayBasicsCompare.
5283  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
5284  *  \return bool - \a true if the two arrays are equal, \a false else.
5285  */
5286 bool DataArrayInt::isEqual(const DataArrayInt& other) const
5287 {
5288   std::string tmp;
5289   return isEqualIfNotWhy(other,tmp);
5290 }
5291
5292 /*!
5293  * Checks if values of \a this and another DataArrayInt are equal. For more info see
5294  * \ref MEDCouplingArrayBasicsCompare.
5295  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
5296  *  \return bool - \a true if the values of two arrays are equal, \a false else.
5297  */
5298 bool DataArrayInt::isEqualWithoutConsideringStr(const DataArrayInt& other) const
5299 {
5300   std::string tmp;
5301   return _mem.isEqual(other._mem,0,tmp);
5302 }
5303
5304 /*!
5305  * Checks if values of \a this and another DataArrayInt are equal. Comparison is
5306  * performed on sorted value sequences.
5307  * For more info see\ref MEDCouplingArrayBasicsCompare.
5308  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
5309  *  \return bool - \a true if the sorted values of two arrays are equal, \a false else.
5310  */
5311 bool DataArrayInt::isEqualWithoutConsideringStrAndOrder(const DataArrayInt& other) const
5312 {
5313   MCAuto<DataArrayInt> a=deepCopy();
5314   MCAuto<DataArrayInt> b=other.deepCopy();
5315   a->sort();
5316   b->sort();
5317   return a->isEqualWithoutConsideringStr(*b);
5318 }
5319
5320 /*!
5321  * This method compares content of input vector \a v and \a this.
5322  * 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.
5323  * For performance reasons \a this is expected to be sorted ascendingly. If not an exception will be thrown.
5324  *
5325  * \param [in] v - the vector of 'flags' to be compared with \a this.
5326  *
5327  * \throw If \a this is not sorted ascendingly.
5328  * \throw If \a this has not exactly one component.
5329  * \throw If \a this is not allocated.
5330  */
5331 bool DataArrayInt::isFittingWith(const std::vector<bool>& v) const
5332 {
5333   checkAllocated();
5334   if(getNumberOfComponents()!=1)
5335     throw INTERP_KERNEL::Exception("DataArrayInt::isFittingWith : number of components of this should be equal to one !");
5336   const int *w(begin()),*end2(end());
5337   int refVal=-std::numeric_limits<int>::max();
5338   int i=0;
5339   std::vector<bool>::const_iterator it(v.begin());
5340   for(;it!=v.end();it++,i++)
5341     {
5342       if(*it)
5343         {
5344           if(w!=end2)
5345             {
5346               if(*w++==i)
5347                 {
5348                   if(i>refVal)
5349                     refVal=i;
5350                   else
5351                     {
5352                       std::ostringstream oss; oss << "DataArrayInt::isFittingWith : At pos #" << std::distance(begin(),w-1) << " this is not sorted ascendingly !";
5353                       throw INTERP_KERNEL::Exception(oss.str().c_str());
5354                     }
5355                 }
5356               else
5357                 return false;
5358             }
5359           else
5360             return false;
5361         }
5362     }
5363   return w==end2;
5364 }
5365
5366 /*!
5367  * 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
5368  * put True to the corresponding entry in \a vec.
5369  * \a vec is expected to be with the same size than the number of tuples of \a this.
5370  *
5371  *  \sa DataArrayInt::switchOnTupleNotEqualTo.
5372  */
5373 void DataArrayInt::switchOnTupleEqualTo(int val, std::vector<bool>& vec) const
5374 {
5375   checkAllocated();
5376   if(getNumberOfComponents()!=1)
5377     throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleEqualTo : number of components of this should be equal to one !");
5378   int nbOfTuples(getNumberOfTuples());
5379   if(nbOfTuples!=(int)vec.size())
5380     throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleEqualTo : number of tuples of this should be equal to size of input vector of bool !");
5381   const int *pt(begin());
5382   for(int i=0;i<nbOfTuples;i++)
5383     if(pt[i]==val)
5384       vec[i]=true;
5385 }
5386
5387 /*!
5388  * 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
5389  * put True to the corresponding entry in \a vec.
5390  * \a vec is expected to be with the same size than the number of tuples of \a this.
5391  * 
5392  *  \sa DataArrayInt::switchOnTupleEqualTo.
5393  */
5394 void DataArrayInt::switchOnTupleNotEqualTo(int val, std::vector<bool>& vec) const
5395 {
5396   checkAllocated();
5397   if(getNumberOfComponents()!=1)
5398     throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleNotEqualTo : number of components of this should be equal to one !");
5399   int nbOfTuples(getNumberOfTuples());
5400   if(nbOfTuples!=(int)vec.size())
5401     throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleNotEqualTo : number of tuples of this should be equal to size of input vector of bool !");
5402   const int *pt(begin());
5403   for(int i=0;i<nbOfTuples;i++)
5404     if(pt[i]!=val)
5405       vec[i]=true;
5406 }
5407
5408 /*!
5409  * Computes for each tuple the sum of number of components values in the tuple and return it.
5410  * 
5411  * \return DataArrayInt * - the new instance of DataArrayInt containing the
5412  *          same number of tuples as \a this array and one component.
5413  *          The caller is to delete this result array using decrRef() as it is no more
5414  *          needed.
5415  *  \throw If \a this is not allocated.
5416  */
5417 DataArrayInt *DataArrayInt::sumPerTuple() const
5418 {
5419   checkAllocated();
5420   int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
5421   MCAuto<DataArrayInt> ret(DataArrayInt::New());
5422   ret->alloc(nbOfTuple,1);
5423   const int *src(getConstPointer());
5424   int *dest(ret->getPointer());
5425   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
5426     *dest=std::accumulate(src,src+nbOfComp,0);
5427   return ret.retn();
5428 }
5429
5430 /*!
5431  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
5432  * If not an exception is thrown.
5433  *  \param [in] increasing - if \a true, the array values should be increasing.
5434  *  \throw If sequence of values is not strictly monotonic in agreement with \a
5435  *         increasing arg.
5436  *  \throw If \a this->getNumberOfComponents() != 1.
5437  *  \throw If \a this is not allocated.
5438  */
5439 void DataArrayInt::checkMonotonic(bool increasing) const
5440 {
5441   if(!isMonotonic(increasing))
5442     {
5443       if (increasing)
5444         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not INCREASING monotonic !");
5445       else
5446         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not DECREASING monotonic !");
5447     }
5448 }
5449
5450 /*!
5451  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
5452  *  \param [in] increasing - if \a true, array values should be increasing.
5453  *  \return bool - \a true if values change in accordance with \a increasing arg.
5454  *  \throw If \a this->getNumberOfComponents() != 1.
5455  *  \throw If \a this is not allocated.
5456  */
5457 bool DataArrayInt::isMonotonic(bool increasing) const
5458 {
5459   checkAllocated();
5460   if(getNumberOfComponents()!=1)
5461     throw INTERP_KERNEL::Exception("DataArrayInt::isMonotonic : only supported with 'this' array with ONE component !");
5462   int nbOfElements=getNumberOfTuples();
5463   const int *ptr=getConstPointer();
5464   if(nbOfElements==0)
5465     return true;
5466   int ref=ptr[0];
5467   if(increasing)
5468     {
5469       for(int i=1;i<nbOfElements;i++)
5470         {
5471           if(ptr[i]>=ref)
5472             ref=ptr[i];
5473           else
5474             return false;
5475         }
5476     }
5477   else
5478     {
5479       for(int i=1;i<nbOfElements;i++)
5480         {
5481           if(ptr[i]<=ref)
5482             ref=ptr[i];
5483           else
5484             return false;
5485         }
5486     }
5487   return true;
5488 }
5489
5490 /*!
5491  * This method check that array consistently INCREASING or DECREASING in value.
5492  */
5493 bool DataArrayInt::isStrictlyMonotonic(bool increasing) const
5494 {
5495   checkAllocated();
5496   if(getNumberOfComponents()!=1)
5497     throw INTERP_KERNEL::Exception("DataArrayInt::isStrictlyMonotonic : only supported with 'this' array with ONE component !");
5498   int nbOfElements=getNumberOfTuples();
5499   const int *ptr=getConstPointer();
5500   if(nbOfElements==0)
5501     return true;
5502   int ref=ptr[0];
5503   if(increasing)
5504     {
5505       for(int i=1;i<nbOfElements;i++)
5506         {
5507           if(ptr[i]>ref)
5508             ref=ptr[i];
5509           else
5510             return false;
5511         }
5512     }
5513   else
5514     {
5515       for(int i=1;i<nbOfElements;i++)
5516         {
5517           if(ptr[i]<ref)
5518             ref=ptr[i];
5519           else
5520             return false;
5521         }
5522     }
5523   return true;
5524 }
5525
5526 /*!
5527  * This method check that array consistently INCREASING or DECREASING in value.
5528  */
5529 void DataArrayInt::checkStrictlyMonotonic(bool increasing) const
5530 {
5531   if(!isStrictlyMonotonic(increasing))
5532     {
5533       if (increasing)
5534         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly INCREASING monotonic !");
5535       else
5536         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly DECREASING monotonic !");
5537     }
5538 }
5539
5540 /*!
5541  * Creates a new one-dimensional DataArrayInt of the same size as \a this and a given
5542  * one-dimensional arrays that must be of the same length. The result array describes
5543  * correspondence between \a this and \a other arrays, so that 
5544  * <em> other.getIJ(i,0) == this->getIJ(ret->getIJ(i),0)</em>. If such a permutation is
5545  * not possible because some element in \a other is not in \a this, an exception is thrown.
5546  *  \param [in] other - an array to compute permutation to.
5547  *  \return DataArrayInt * - a new instance of DataArrayInt, which is a permutation array
5548  * from \a this to \a other. The caller is to delete this array using decrRef() as it is
5549  * no more needed.
5550  *  \throw If \a this->getNumberOfComponents() != 1.
5551  *  \throw If \a other->getNumberOfComponents() != 1.
5552  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples().
5553  *  \throw If \a other includes a value which is not in \a this array.
5554  * 
5555  *  \if ENABLE_EXAMPLES
5556  *  \ref cpp_mcdataarrayint_buildpermutationarr "Here is a C++ example".
5557  *
5558  *  \ref py_mcdataarrayint_buildpermutationarr "Here is a Python example".
5559  *  \endif
5560  */
5561 DataArrayInt *DataArrayInt::buildPermutationArr(const DataArrayInt& other) const
5562 {
5563   checkAllocated();
5564   if(getNumberOfComponents()!=1 || other.getNumberOfComponents()!=1)
5565     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' have to have exactly ONE component !");
5566   int nbTuple=getNumberOfTuples();
5567   other.checkAllocated();
5568   if(nbTuple!=other.getNumberOfTuples())
5569     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' must have the same number of tuple !");
5570   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5571   ret->alloc(nbTuple,1);
5572   ret->fillWithValue(-1);
5573   const int *pt=getConstPointer();
5574   std::map<int,int> mm;
5575   for(int i=0;i<nbTuple;i++)
5576     mm[pt[i]]=i;
5577   pt=other.getConstPointer();
5578   int *retToFill=ret->getPointer();
5579   for(int i=0;i<nbTuple;i++)
5580     {
5581       std::map<int,int>::const_iterator it=mm.find(pt[i]);
5582       if(it==mm.end())
5583         {
5584           std::ostringstream oss; oss << "DataArrayInt::buildPermutationArr : Arrays mismatch : element (" << pt[i] << ") in 'other' not findable in 'this' !";
5585           throw INTERP_KERNEL::Exception(oss.str().c_str());
5586         }
5587       retToFill[i]=(*it).second;
5588     }
5589   return ret.retn();
5590 }
5591
5592 /*!
5593  * Elements of \a partOfThis are expected to be included in \a this.
5594  * The returned array \a ret is so that this[ret]==partOfThis
5595  *
5596  * 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]
5597  * the return array will contain [3,2,5,7].
5598  *
5599  * \a this is expected to be a 1 compo allocated array.
5600  * \param [in] partOfThis - A 1 compo allocated array
5601  * \return - A newly allocated array to be dealed by caller having the same number of tuples than \a partOfThis.
5602  * \throw if two same element is present twice in \a this
5603  * \throw if an element in \a partOfThis is \b NOT in \a this.
5604  */
5605 DataArrayInt *DataArrayInt::indicesOfSubPart(const DataArrayInt& partOfThis) const
5606 {
5607   if(getNumberOfComponents()!=1 || partOfThis.getNumberOfComponents()!=1)
5608     throw INTERP_KERNEL::Exception("DataArrayInt::indicesOfSubPart : this and input array must be one component array !");
5609   checkAllocated(); partOfThis.checkAllocated();
5610   int thisNbTuples(getNumberOfTuples()),nbTuples(partOfThis.getNumberOfTuples());
5611   const int *thisPt(begin()),*pt(partOfThis.begin());
5612   MCAuto<DataArrayInt> ret(DataArrayInt::New());
5613   ret->alloc(nbTuples,1);
5614   int *retPt(ret->getPointer());
5615   std::map<int,int> m;
5616   for(int i=0;i<thisNbTuples;i++,thisPt++)
5617     m[*thisPt]=i;
5618   if(m.size()!=thisNbTuples)
5619     throw INTERP_KERNEL::Exception("DataArrayInt::indicesOfSubPart : some elements appears more than once !");
5620   for(int i=0;i<nbTuples;i++,retPt++,pt++)
5621     {
5622       std::map<int,int>::const_iterator it(m.find(*pt));
5623       if(it!=m.end())
5624         *retPt=(*it).second;
5625       else
5626         {
5627           std::ostringstream oss; oss << "DataArrayInt::indicesOfSubPart : At pos #" << i << " of input array value is " << *pt << " not in this !";
5628           throw INTERP_KERNEL::Exception(oss.str());
5629         }
5630     }
5631   return ret.retn();
5632 }
5633
5634 void DataArrayInt::aggregate(const DataArrayInt *other)
5635 {
5636   if(!other)
5637     throw INTERP_KERNEL::Exception("DataArrayInt::aggregate : null pointer !");
5638   if(getNumberOfComponents()!=other->getNumberOfComponents())
5639     throw INTERP_KERNEL::Exception("DataArrayInt::aggregate : mismatch number of components !");
5640   _mem.insertAtTheEnd(other->begin(),other->end());
5641 }
5642
5643 /*!
5644  * Returns a new DataArrayInt holding the same values as \a this array but differently
5645  * arranged in memory. If \a this array holds 2 components of 3 values:
5646  * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
5647  * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
5648  *  \warning Do not confuse this method with transpose()!
5649  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
5650  *          is to delete using decrRef() as it is no more needed.
5651  *  \throw If \a this is not allocated.
5652  */
5653 DataArrayInt *DataArrayInt::fromNoInterlace() const
5654 {
5655   checkAllocated();
5656   if(_mem.isNull())
5657     throw INTERP_KERNEL::Exception("DataArrayInt::fromNoInterlace : Not defined array !");
5658   int *tab=_mem.fromNoInterlace(getNumberOfComponents());
5659   DataArrayInt *ret=DataArrayInt::New();
5660   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
5661   return ret;
5662 }
5663
5664 /*!
5665  * Returns a new DataArrayInt holding the same values as \a this array but differently
5666  * arranged in memory. If \a this array holds 2 components of 3 values:
5667  * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
5668  * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
5669  *  \warning Do not confuse this method with transpose()!
5670  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
5671  *          is to delete using decrRef() as it is no more needed.
5672  *  \throw If \a this is not allocated.
5673  */
5674 DataArrayInt *DataArrayInt::toNoInterlace() const
5675 {
5676   checkAllocated();
5677   if(_mem.isNull())
5678     throw INTERP_KERNEL::Exception("DataArrayInt::toNoInterlace : Not defined array !");
5679   int *tab=_mem.toNoInterlace(getNumberOfComponents());
5680   DataArrayInt *ret=DataArrayInt::New();
5681   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
5682   return ret;
5683 }
5684
5685 /*!
5686  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode.
5687  * This map, if applied to \a this array, would make it sorted. For example, if
5688  * \a this array contents are [9,10,0,6,4,11,3,7] then the contents of the result array
5689  * are [5,6,0,3,2,7,1,4]; if this result array (\a res) is used as an argument in call
5690  * \a this->renumber(\a res) then the returned array contains [0,3,4,6,7,9,10,11].
5691  * This method is useful for renumbering (in MED file for example). For more info
5692  * on renumbering see \ref numbering.
5693  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5694  *          array using decrRef() as it is no more needed.
5695  *  \throw If \a this is not allocated.
5696  *  \throw If \a this->getNumberOfComponents() != 1.
5697  *  \throw If there are equal values in \a this array.
5698  */
5699 DataArrayInt *DataArrayInt::checkAndPreparePermutation() const
5700 {
5701   checkAllocated();
5702   if(getNumberOfComponents()!=1)
5703     throw INTERP_KERNEL::Exception("DataArrayInt::checkAndPreparePermutation : number of components must == 1 !");
5704   int nbTuples=getNumberOfTuples();
5705   const int *pt=getConstPointer();
5706   int *pt2=CheckAndPreparePermutation(pt,pt+nbTuples);
5707   DataArrayInt *ret=DataArrayInt::New();
5708   ret->useArray(pt2,true,C_DEALLOC,nbTuples,1);
5709   return ret;
5710 }
5711
5712 /*!
5713  * 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
5714  * input array \a ids2.
5715  * \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.
5716  * 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
5717  * inversely.
5718  * In case of success (no throw) : \c ids1->renumber(ret)->isEqual(ids2) where \a ret is the return of this method.
5719  *
5720  * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5721  *          array using decrRef() as it is no more needed.
5722  * \throw If either ids1 or ids2 is null not allocated or not with one components.
5723  * 
5724  */
5725 DataArrayInt *DataArrayInt::FindPermutationFromFirstToSecond(const DataArrayInt *ids1, const DataArrayInt *ids2)
5726 {
5727   if(!ids1 || !ids2)
5728     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be not null !");
5729   if(!ids1->isAllocated() || !ids2->isAllocated())
5730     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be allocated !");
5731   if(ids1->getNumberOfComponents()!=1 || ids2->getNumberOfComponents()!=1)
5732     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays have exactly one component !");
5733   if(ids1->getNumberOfTuples()!=ids2->getNumberOfTuples())
5734     {
5735       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 !";
5736       throw INTERP_KERNEL::Exception(oss.str().c_str());
5737     }
5738   MCAuto<DataArrayInt> p1(ids1->deepCopy());
5739   MCAuto<DataArrayInt> p2(ids2->deepCopy());
5740   p1->sort(true); p2->sort(true);
5741   if(!p1->isEqualWithoutConsideringStr(*p2))
5742     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two arrays are not lying on same ids ! Impossible to find a permutation between the 2 arrays !");
5743   p1=ids1->checkAndPreparePermutation();
5744   p2=ids2->checkAndPreparePermutation();
5745   p2=p2->invertArrayO2N2N2O(p2->getNumberOfTuples());
5746   p2=p2->selectByTupleIdSafe(p1->begin(),p1->end());
5747   return p2.retn();
5748 }
5749
5750 /*!
5751  * Returns two arrays describing a surjective mapping from \a this set of values (\a A)
5752  * onto a set of values of size \a targetNb (\a B). The surjective function is 
5753  * \a B[ \a A[ i ]] = i. That is to say that for each \a id in [0,\a targetNb), where \a
5754  * targetNb < \a this->getNumberOfTuples(), there exists at least one tupleId (\a tid) so
5755  * that <em> this->getIJ( tid, 0 ) == id</em>. <br>
5756  * The first of out arrays returns indices of elements of \a this array, grouped by their
5757  * place in the set \a B. The second out array is the index of the first one; it shows how
5758  * many elements of \a A are mapped into each element of \a B. <br>
5759  * For more info on
5760  * mapping and its usage in renumbering see \ref numbering. <br>
5761  * \b Example:
5762  * - \a this: [0,3,2,3,2,2,1,2]
5763  * - \a targetNb: 4
5764  * - \a arr:  [0,  6,  2,4,5,7,  1,3]
5765  * - \a arrI: [0,1,2,6,8]
5766  *
5767  * This result means: <br>
5768  * the element of \a B 0 encounters within \a A once (\a arrI[ 0+1 ] - \a arrI[ 0 ]) and
5769  * its index within \a A is 0 ( \a arr[ 0:1 ] == \a arr[ \a arrI[ 0 ] : \a arrI[ 0+1 ]]);<br>
5770  * the element of \a B 2 encounters within \a A 4 times (\a arrI[ 2+1 ] - \a arrI[ 2 ]) and
5771  * its indices within \a A are [2,4,5,7] ( \a arr[ 2:6 ] == \a arr[ \a arrI[ 2 ] : 
5772  * \a arrI[ 2+1 ]]); <br> etc.
5773  *  \param [in] targetNb - the size of the set \a B. \a targetNb must be equal or more
5774  *         than the maximal value of \a A.
5775  *  \param [out] arr - a new instance of DataArrayInt returning indices of
5776  *         elements of \a this, grouped by their place in the set \a B. The caller is to delete
5777  *         this array using decrRef() as it is no more needed.
5778  *  \param [out] arrI - a new instance of DataArrayInt returning size of groups of equal
5779  *         elements of \a this. The caller is to delete this array using decrRef() as it
5780  *         is no more needed.
5781  *  \throw If \a this is not allocated.
5782  *  \throw If \a this->getNumberOfComponents() != 1.
5783  *  \throw If any value in \a this is more or equal to \a targetNb.
5784  */
5785 void DataArrayInt::changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, DataArrayInt *&arrI) const
5786 {
5787   checkAllocated();
5788   if(getNumberOfComponents()!=1)
5789     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : number of components must == 1 !");
5790   int nbOfTuples=getNumberOfTuples();
5791   MCAuto<DataArrayInt> ret(DataArrayInt::New());
5792   MCAuto<DataArrayInt> retI(DataArrayInt::New());
5793   retI->alloc(targetNb+1,1);
5794   const int *input=getConstPointer();
5795   std::vector< std::vector<int> > tmp(targetNb);
5796   for(int i=0;i<nbOfTuples;i++)
5797     {
5798       int tmp2=input[i];
5799       if(tmp2>=0 && tmp2<targetNb)
5800         tmp[tmp2].push_back(i);
5801       else
5802         {
5803           std::ostringstream oss; oss << "DataArrayInt::changeSurjectiveFormat : At pos " << i << " presence of element " << tmp2 << " ! should be in [0," << targetNb << ") !";
5804           throw INTERP_KERNEL::Exception(oss.str().c_str());
5805         }
5806     }
5807   int *retIPtr=retI->getPointer();
5808   *retIPtr=0;
5809   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++,retIPtr++)
5810     retIPtr[1]=retIPtr[0]+(int)((*it1).size());
5811   if(nbOfTuples!=retI->getIJ(targetNb,0))
5812     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : big problem should never happen !");
5813   ret->alloc(nbOfTuples,1);
5814   int *retPtr=ret->getPointer();
5815   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++)
5816     retPtr=std::copy((*it1).begin(),(*it1).end(),retPtr);
5817   arr=ret.retn();
5818   arrI=retI.retn();
5819 }
5820
5821
5822 /*!
5823  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode computed
5824  * from a zip representation of a surjective format (returned e.g. by
5825  * \ref MEDCoupling::DataArrayDouble::findCommonTuples() "DataArrayDouble::findCommonTuples()"
5826  * for example). The result array minimizes the permutation. <br>
5827  * For more info on renumbering see \ref numbering. <br>
5828  * \b Example: <br>
5829  * - \a nbOfOldTuples: 10 
5830  * - \a arr          : [0,3, 5,7,9]
5831  * - \a arrIBg       : [0,2,5]
5832  * - \a newNbOfTuples: 7
5833  * - result array    : [0,1,2,0,3,4,5,4,6,4]
5834  *
5835  *  \param [in] nbOfOldTuples - number of tuples in the initial array \a arr.
5836  *  \param [in] arr - the array of tuple indices grouped by \a arrIBg array.
5837  *  \param [in] arrIBg - the array dividing all indices stored in \a arr into groups of
5838  *         (indices of) equal values. Its every element (except the last one) points to
5839  *         the first element of a group of equal values.
5840  *  \param [in] arrIEnd - specifies the end of \a arrIBg, so that the last element of \a
5841  *          arrIBg is \a arrIEnd[ -1 ].
5842  *  \param [out] newNbOfTuples - number of tuples after surjection application.
5843  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5844  *          array using decrRef() as it is no more needed.
5845  *  \throw If any value of \a arr breaks condition ( 0 <= \a arr[ i ] < \a nbOfOldTuples ).
5846  */
5847 DataArrayInt *DataArrayInt::ConvertIndexArrayToO2N(int nbOfOldTuples, const int *arr, const int *arrIBg, const int *arrIEnd, int &newNbOfTuples)
5848 {
5849   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5850   ret->alloc(nbOfOldTuples,1);
5851   int *pt=ret->getPointer();
5852   std::fill(pt,pt+nbOfOldTuples,-1);
5853   int nbOfGrps=((int)std::distance(arrIBg,arrIEnd))-1;
5854   const int *cIPtr=arrIBg;
5855   for(int i=0;i<nbOfGrps;i++)
5856     pt[arr[cIPtr[i]]]=-(i+2);
5857   int newNb=0;
5858   for(int iNode=0;iNode<nbOfOldTuples;iNode++)
5859     {
5860       if(pt[iNode]<0)
5861         {
5862           if(pt[iNode]==-1)
5863             pt[iNode]=newNb++;
5864           else
5865             {
5866               int grpId=-(pt[iNode]+2);
5867               for(int j=cIPtr[grpId];j<cIPtr[grpId+1];j++)
5868                 {
5869                   if(arr[j]>=0 && arr[j]<nbOfOldTuples)
5870                     pt[arr[j]]=newNb;
5871                   else
5872                     {
5873                       std::ostringstream oss; oss << "DataArrayInt::ConvertIndexArrayToO2N : With element #" << j << " value is " << arr[j] << " should be in [0," << nbOfOldTuples << ") !";
5874                       throw INTERP_KERNEL::Exception(oss.str().c_str());
5875                     }
5876                 }
5877               newNb++;
5878             }
5879         }
5880     }
5881   newNbOfTuples=newNb;
5882   return ret.retn();
5883 }
5884
5885 /*!
5886  * Returns a new DataArrayInt containing a renumbering map in "New to Old" mode,
5887  * which if applied to \a this array would make it sorted ascendingly.
5888  * For more info on renumbering see \ref numbering. <br>
5889  * \b Example: <br>
5890  * - \a this: [2,0,1,1,0,1,2,0,1,1,0,0]
5891  * - result: [10,0,5,6,1,7,11,2,8,9,3,4]
5892  * - after applying result to \a this: [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2] 
5893  *
5894  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5895  *          array using decrRef() as it is no more needed.
5896  *  \throw If \a this is not allocated.
5897  *  \throw If \a this->getNumberOfComponents() != 1.
5898  */
5899 DataArrayInt *DataArrayInt::buildPermArrPerLevel() const
5900 {
5901   checkAllocated();
5902   if(getNumberOfComponents()!=1)
5903     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermArrPerLevel : number of components must == 1 !");
5904   int nbOfTuples=getNumberOfTuples();
5905   const int *pt=getConstPointer();
5906   std::map<int,int> m;
5907   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5908   ret->alloc(nbOfTuples,1);
5909   int *opt=ret->getPointer();
5910   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
5911     {
5912       int val=*pt;
5913       std::map<int,int>::iterator it=m.find(val);
5914       if(it!=m.end())
5915         {
5916           *opt=(*it).second;
5917           (*it).second++;
5918         }
5919       else
5920         {
5921           *opt=0;
5922           m.insert(std::pair<int,int>(val,1));
5923         }
5924     }
5925   int sum=0;
5926   for(std::map<int,int>::iterator it=m.begin();it!=m.end();it++)
5927     {
5928       int vt=(*it).second;
5929       (*it).second=sum;
5930       sum+=vt;
5931     }
5932   pt=getConstPointer();
5933   opt=ret->getPointer();
5934   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
5935     *opt+=m[*pt];
5936   //
5937   return ret.retn();
5938 }
5939
5940 /*!
5941  * Checks if \a this array has the given size, and if its contents is equal to an array filled with
5942  * iota(). This method is particularly useful for DataArrayInt instances that represent
5943  * a renumbering array, to check if there is a real need in renumbering.
5944  * This method checks than \a this can be considered as an identity mapping
5945  * of a set having \a sizeExpected elements into itself.
5946  *
5947  *  \param [in] sizeExpected - The number of elements expected.
5948  *  \return bool - \a true if \a this array contents == \a range( \a this->getNumberOfTuples())
5949  *  \throw If \a this is not allocated.
5950  *  \throw If \a this->getNumberOfComponents() != 1.
5951  */
5952 bool DataArrayInt::isIota(int sizeExpected) const
5953 {
5954   checkAllocated();
5955   if(getNumberOfComponents()!=1)
5956     return false;
5957   int nbOfTuples(getNumberOfTuples());
5958   if(nbOfTuples!=sizeExpected)
5959     return false;
5960   const int *pt=getConstPointer();
5961   for(int i=0;i<nbOfTuples;i++,pt++)
5962     if(*pt!=i)
5963       return false;
5964   return true;
5965 }
5966
5967 /*!
5968  * Checks if all values in \a this array are equal to \a val.
5969  *  \param [in] val - value to check equality of array values to.
5970  *  \return bool - \a true if all values are \a val.
5971  *  \throw If \a this is not allocated.
5972  *  \throw If \a this->getNumberOfComponents() != 1
5973  */
5974 bool DataArrayInt::isUniform(int val) const
5975 {
5976   checkAllocated();
5977   if(getNumberOfComponents()!=1)
5978     throw INTERP_KERNEL::Exception("DataArrayInt::isUniform : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
5979   int nbOfTuples=getNumberOfTuples();
5980   const int *w=getConstPointer();
5981   const int *end2=w+nbOfTuples;
5982   for(;w!=end2;w++)
5983     if(*w!=val)
5984       return false;
5985   return true;
5986 }
5987
5988 /*!
5989  * Checks if all values in \a this array are unique.
5990  *  \return bool - \a true if condition above is true
5991  *  \throw If \a this is not allocated.
5992  *  \throw If \a this->getNumberOfComponents() != 1
5993  */
5994 bool DataArrayInt::hasUniqueValues() const
5995 {
5996   checkAllocated();
5997   if(getNumberOfComponents()!=1)
5998     throw INTERP_KERNEL::Exception("DataArrayInt::hasOnlyUniqueValues: must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
5999   int nbOfTuples(getNumberOfTuples());
6000   std::set<int> s(begin(),end());  // in C++11, should use unordered_set (O(1) complexity)
6001   if (s.size() != nbOfTuples)
6002     return false;
6003   return true;
6004 }
6005
6006 /*!
6007  * Appends components of another array to components of \a this one, tuple by tuple.
6008  * So that the number of tuples of \a this array remains the same and the number of 
6009  * components increases.
6010  *  \param [in] other - the DataArrayInt to append to \a this one.
6011  *  \throw If \a this is not allocated.
6012  *  \throw If \a this and \a other arrays have different number of tuples.
6013  *
6014  *  \if ENABLE_EXAMPLES
6015  *  \ref cpp_mcdataarrayint_meldwith "Here is a C++ example".
6016  *
6017  *  \ref py_mcdataarrayint_meldwith "Here is a Python example".
6018  *  \endif
6019  */
6020 void DataArrayInt::meldWith(const DataArrayInt *other)
6021 {
6022   if(!other)
6023     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : DataArrayInt pointer in input is NULL !");
6024   checkAllocated();
6025   other->checkAllocated();
6026   int nbOfTuples=getNumberOfTuples();
6027   if(nbOfTuples!=other->getNumberOfTuples())
6028     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : mismatch of number of tuples !");
6029   int nbOfComp1=getNumberOfComponents();
6030   int nbOfComp2=other->getNumberOfComponents();
6031   int *newArr=(int *)malloc(nbOfTuples*(nbOfComp1+nbOfComp2)*sizeof(int));
6032   int *w=newArr;
6033   const int *inp1=getConstPointer();
6034   const int *inp2=other->getConstPointer();
6035   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
6036     {
6037       w=std::copy(inp1,inp1+nbOfComp1,w);
6038       w=std::copy(inp2,inp2+nbOfComp2,w);
6039     }
6040   useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
6041   std::vector<int> compIds(nbOfComp2);
6042   for(int i=0;i<nbOfComp2;i++)
6043     compIds[i]=nbOfComp1+i;
6044   copyPartOfStringInfoFrom2(compIds,*other);
6045 }
6046
6047 /*!
6048  * Copy all components in a specified order from another DataArrayInt.
6049  * The specified components become the first ones in \a this array.
6050  * Both numerical and textual data is copied. The number of tuples in \a this and
6051  * the other array can be different.
6052  *  \param [in] a - the array to copy data from.
6053  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
6054  *              to be copied.
6055  *  \throw If \a a is NULL.
6056  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
6057  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
6058  *
6059  *  \if ENABLE_EXAMPLES
6060  *  \ref py_mcdataarrayint_setselectedcomponents "Here is a Python example".
6061  *  \endif
6062  */
6063 void DataArrayInt::setSelectedComponents(const DataArrayInt *a, const std::vector<int>& compoIds)
6064 {
6065   if(!a)
6066     throw INTERP_KERNEL::Exception("DataArrayInt::setSelectedComponents : input DataArrayInt is NULL !");
6067   checkAllocated();
6068   a->checkAllocated();
6069   copyPartOfStringInfoFrom2(compoIds,*a);
6070   std::size_t partOfCompoSz=compoIds.size();
6071   int nbOfCompo=getNumberOfComponents();
6072   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
6073   const int *ac=a->getConstPointer();
6074   int *nc=getPointer();
6075   for(int i=0;i<nbOfTuples;i++)
6076     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
6077       nc[nbOfCompo*i+compoIds[j]]=*ac;
6078 }
6079
6080 /*!
6081  * Assign pointer to one array to a pointer to another appay. Reference counter of
6082  * \a arrayToSet is incremented / decremented.
6083  *  \param [in] newArray - the pointer to array to assign to \a arrayToSet.
6084  *  \param [in,out] arrayToSet - the pointer to array to assign to.
6085  */
6086 void DataArrayInt::SetArrayIn(DataArrayInt *newArray, DataArrayInt* &arrayToSet)
6087 {
6088   if(newArray!=arrayToSet)
6089     {
6090       if(arrayToSet)
6091         arrayToSet->decrRef();
6092       arrayToSet=newArray;
6093       if(arrayToSet)
6094         arrayToSet->incrRef();
6095     }
6096 }
6097
6098 DataArrayIntIterator *DataArrayInt::iterator()
6099 {
6100   return new DataArrayIntIterator(this);
6101 }
6102
6103 /*!
6104  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to a
6105  * given one. The ids are sorted in the ascending order.
6106  *  \param [in] val - the value to find within \a this.
6107  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6108  *          array using decrRef() as it is no more needed.
6109  *  \throw If \a this is not allocated.
6110  *  \throw If \a this->getNumberOfComponents() != 1.
6111  *  \sa DataArrayInt::findIdsEqualTuple
6112  */
6113 DataArrayInt *DataArrayInt::findIdsEqual(int val) const
6114 {
6115   checkAllocated();
6116   if(getNumberOfComponents()!=1)
6117     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqual : the array must have only one component, you can call 'rearrange' method before !");
6118   const int *cptr(getConstPointer());
6119   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6120   int nbOfTuples=getNumberOfTuples();
6121   for(int i=0;i<nbOfTuples;i++,cptr++)
6122     if(*cptr==val)
6123       ret->pushBackSilent(i);
6124   return ret.retn();
6125 }
6126
6127 /*!
6128  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value \b not
6129  * equal to a given one. 
6130  *  \param [in] val - the value to ignore within \a this.
6131  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6132  *          array using decrRef() as it is no more needed.
6133  *  \throw If \a this is not allocated.
6134  *  \throw If \a this->getNumberOfComponents() != 1.
6135  */
6136 DataArrayInt *DataArrayInt::findIdsNotEqual(int val) const
6137 {
6138   checkAllocated();
6139   if(getNumberOfComponents()!=1)
6140     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotEqual : the array must have only one component, you can call 'rearrange' method before !");
6141   const int *cptr(getConstPointer());
6142   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6143   int nbOfTuples=getNumberOfTuples();
6144   for(int i=0;i<nbOfTuples;i++,cptr++)
6145     if(*cptr!=val)
6146       ret->pushBackSilent(i);
6147   return ret.retn();
6148 }
6149
6150 /*!
6151  * Creates a new DataArrayInt containing IDs (indices) of tuples holding tuple equal to those defined by [ \a tupleBg , \a tupleEnd )
6152  * This method is an extension of  DataArrayInt::findIdsEqual method.
6153  *
6154  *  \param [in] tupleBg - the begin (included) of the input tuple to find within \a this.
6155  *  \param [in] tupleEnd - the end (excluded) of the input tuple to find within \a this.
6156  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6157  *          array using decrRef() as it is no more needed.
6158  *  \throw If \a this is not allocated.
6159  *  \throw If \a this->getNumberOfComponents() != std::distance(tupleBg,tupleEnd).
6160  * \throw If \a this->getNumberOfComponents() is equal to 0.
6161  * \sa DataArrayInt::findIdsEqual
6162  */
6163 DataArrayInt *DataArrayInt::findIdsEqualTuple(const int *tupleBg, const int *tupleEnd) const
6164 {
6165   std::size_t nbOfCompoExp(std::distance(tupleBg,tupleEnd));
6166   checkAllocated();
6167   if(getNumberOfComponents()!=(int)nbOfCompoExp)
6168     {
6169       std::ostringstream oss; oss << "DataArrayInt::findIdsEqualTuple : mismatch of number of components. Input tuple has " << nbOfCompoExp << " whereas this array has " << getNumberOfComponents() << " components !";
6170       throw INTERP_KERNEL::Exception(oss.str().c_str());
6171     }
6172   if(nbOfCompoExp==0)
6173     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqualTuple : number of components should be > 0 !");
6174   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6175   const int *bg(begin()),*end2(end()),*work(begin());
6176   while(work!=end2)
6177     {
6178       work=std::search(work,end2,tupleBg,tupleEnd);
6179       if(work!=end2)
6180         {
6181           std::size_t pos(std::distance(bg,work));
6182           if(pos%nbOfCompoExp==0)
6183             ret->pushBackSilent(pos/nbOfCompoExp);
6184           work++;
6185         }
6186     }
6187   return ret.retn();
6188 }
6189
6190 /*!
6191  * Assigns \a newValue to all elements holding \a oldValue within \a this
6192  * one-dimensional array.
6193  *  \param [in] oldValue - the value to replace.
6194  *  \param [in] newValue - the value to assign.
6195  *  \return int - number of replacements performed.
6196  *  \throw If \a this is not allocated.
6197  *  \throw If \a this->getNumberOfComponents() != 1.
6198  */
6199 int DataArrayInt::changeValue(int oldValue, int newValue)
6200 {
6201   checkAllocated();
6202   if(getNumberOfComponents()!=1)
6203     throw INTERP_KERNEL::Exception("DataArrayInt::changeValue : the array must have only one component, you can call 'rearrange' method before !");
6204   if(oldValue==newValue)
6205     return 0;
6206   int *start(getPointer()),*end2(start+getNbOfElems());
6207   int ret(0);
6208   for(int *val=start;val!=end2;val++)
6209     {
6210       if(*val==oldValue)
6211         {
6212           *val=newValue;
6213           ret++;
6214         }
6215     }
6216   if(ret>0)
6217     declareAsNew();
6218   return ret;
6219 }
6220
6221 /*!
6222  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to
6223  * one of given values.
6224  *  \param [in] valsBg - an array of values to find within \a this array.
6225  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
6226  *              the last value of \a valsBg is \a valsEnd[ -1 ].
6227  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6228  *          array using decrRef() as it is no more needed.
6229  *  \throw If \a this->getNumberOfComponents() != 1.
6230  */
6231 DataArrayInt *DataArrayInt::findIdsEqualList(const int *valsBg, const int *valsEnd) const
6232 {
6233   if(getNumberOfComponents()!=1)
6234     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqualList : the array must have only one component, you can call 'rearrange' method before !");
6235   std::set<int> vals2(valsBg,valsEnd);
6236   const int *cptr(getConstPointer());
6237   std::vector<int> res;
6238   int nbOfTuples(getNumberOfTuples());
6239   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6240   for(int i=0;i<nbOfTuples;i++,cptr++)
6241     if(vals2.find(*cptr)!=vals2.end())
6242       ret->pushBackSilent(i);
6243   return ret.retn();
6244 }
6245
6246 /*!
6247  * Creates a new DataArrayInt containing IDs (indices) of tuples holding values \b not
6248  * equal to any of given values.
6249  *  \param [in] valsBg - an array of values to ignore within \a this array.
6250  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
6251  *              the last value of \a valsBg is \a valsEnd[ -1 ].
6252  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6253  *          array using decrRef() as it is no more needed.
6254  *  \throw If \a this->getNumberOfComponents() != 1.
6255  */
6256 DataArrayInt *DataArrayInt::findIdsNotEqualList(const int *valsBg, const int *valsEnd) const
6257 {
6258   if(getNumberOfComponents()!=1)
6259     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotEqualList : the array must have only one component, you can call 'rearrange' method before !");
6260   std::set<int> vals2(valsBg,valsEnd);
6261   const int *cptr=getConstPointer();
6262   std::vector<int> res;
6263   int nbOfTuples=getNumberOfTuples();
6264   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6265   for(int i=0;i<nbOfTuples;i++,cptr++)
6266     if(vals2.find(*cptr)==vals2.end())
6267       ret->pushBackSilent(i);
6268   return ret.retn();
6269 }
6270
6271 /*!
6272  * This method is an extension of DataArrayInt::findIdFirstEqual method because this method works for DataArrayInt with
6273  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
6274  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
6275  * If any the tuple id is returned. If not -1 is returned.
6276  * 
6277  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
6278  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
6279  *
6280  * \return tuple id where \b tupl is. -1 if no such tuple exists in \b this.
6281  * \sa DataArrayInt::findIdSequence, DataArrayInt::presenceOfTuple.
6282  */
6283 int DataArrayInt::findIdFirstEqualTuple(const std::vector<int>& tupl) const
6284 {
6285   checkAllocated();
6286   int nbOfCompo=getNumberOfComponents();
6287   if(nbOfCompo==0)
6288     throw INTERP_KERNEL::Exception("DataArrayInt::findIdFirstEqualTuple : 0 components in 'this' !");
6289   if(nbOfCompo!=(int)tupl.size())
6290     {
6291       std::ostringstream oss; oss << "DataArrayInt::findIdFirstEqualTuple : 'this' contains " << nbOfCompo << " components and searching for a tuple of length " << tupl.size() << " !";
6292       throw INTERP_KERNEL::Exception(oss.str().c_str());
6293     }
6294   const int *cptr=getConstPointer();
6295   std::size_t nbOfVals=getNbOfElems();
6296   for(const int *work=cptr;work!=cptr+nbOfVals;)
6297     {
6298       work=std::search(work,cptr+nbOfVals,tupl.begin(),tupl.end());
6299       if(work!=cptr+nbOfVals)
6300         {
6301           if(std::distance(cptr,work)%nbOfCompo!=0)
6302             work++;
6303           else
6304             return std::distance(cptr,work)/nbOfCompo;
6305         }
6306     }
6307   return -1;
6308 }
6309
6310 /*!
6311  * This method searches the sequence specified in input parameter \b vals in \b this.
6312  * This works only for DataArrayInt having number of components equal to one (if not an INTERP_KERNEL::Exception will be thrown).
6313  * This method differs from DataArrayInt::findIdFirstEqualTuple in that the position is internal raw data is not considered here contrary to DataArrayInt::findIdFirstEqualTuple.
6314  * \sa DataArrayInt::findIdFirstEqualTuple
6315  */
6316 int DataArrayInt::findIdSequence(const std::vector<int>& vals) const
6317 {
6318   checkAllocated();
6319   int nbOfCompo=getNumberOfComponents();
6320   if(nbOfCompo!=1)
6321     throw INTERP_KERNEL::Exception("DataArrayInt::findIdSequence : works only for DataArrayInt instance with one component !");
6322   const int *cptr=getConstPointer();
6323   std::size_t nbOfVals=getNbOfElems();
6324   const int *loc=std::search(cptr,cptr+nbOfVals,vals.begin(),vals.end());
6325   if(loc!=cptr+nbOfVals)
6326     return std::distance(cptr,loc);
6327   return -1;
6328 }
6329
6330 /*!
6331  * This method expects to be called when number of components of this is equal to one.
6332  * This method returns the tuple id, if it exists, of the first tuple equal to \b value.
6333  * If not any tuple contains \b value -1 is returned.
6334  * \sa DataArrayInt::presenceOfValue
6335  */
6336 int DataArrayInt::findIdFirstEqual(int value) const
6337 {
6338   checkAllocated();
6339   if(getNumberOfComponents()!=1)
6340     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
6341   const int *cptr=getConstPointer();
6342   int nbOfTuples=getNumberOfTuples();
6343   const int *ret=std::find(cptr,cptr+nbOfTuples,value);
6344   if(ret!=cptr+nbOfTuples)
6345     return std::distance(cptr,ret);
6346   return -1;
6347 }
6348
6349 /*!
6350  * This method expects to be called when number of components of this is equal to one.
6351  * This method returns the tuple id, if it exists, of the first tuple so that the value is contained in \b vals.
6352  * If not any tuple contains one of the values contained in 'vals' -1 is returned.
6353  * \sa DataArrayInt::presenceOfValue
6354  */
6355 int DataArrayInt::findIdFirstEqual(const std::vector<int>& vals) const
6356 {
6357   checkAllocated();
6358   if(getNumberOfComponents()!=1)
6359     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
6360   std::set<int> vals2(vals.begin(),vals.end());
6361   const int *cptr=getConstPointer();
6362   int nbOfTuples=getNumberOfTuples();
6363   for(const int *w=cptr;w!=cptr+nbOfTuples;w++)
6364     if(vals2.find(*w)!=vals2.end())
6365       return std::distance(cptr,w);
6366   return -1;
6367 }
6368
6369 /*!
6370  * This method returns the number of values in \a this that are equals to input parameter \a value.
6371  * This method only works for single component array.
6372  *
6373  * \return a value in [ 0, \c this->getNumberOfTuples() )
6374  *
6375  * \throw If \a this is not allocated
6376  *
6377  */
6378 int DataArrayInt::count(int value) const
6379 {
6380   int ret=0;
6381   checkAllocated();
6382   if(getNumberOfComponents()!=1)
6383     throw INTERP_KERNEL::Exception("DataArrayInt::count : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
6384   const int *vals=begin();
6385   int nbOfTuples=getNumberOfTuples();
6386   for(int i=0;i<nbOfTuples;i++,vals++)
6387     if(*vals==value)
6388       ret++;
6389   return ret;
6390 }
6391
6392 /*!
6393  * This method is an extension of DataArrayInt::presenceOfValue method because this method works for DataArrayInt with
6394  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
6395  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
6396  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
6397  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
6398  * \sa DataArrayInt::findIdFirstEqualTuple
6399  */
6400 bool DataArrayInt::presenceOfTuple(const std::vector<int>& tupl) const
6401 {
6402   return findIdFirstEqualTuple(tupl)!=-1;
6403 }
6404
6405
6406 /*!
6407  * Returns \a true if a given value is present within \a this one-dimensional array.
6408  *  \param [in] value - the value to find within \a this array.
6409  *  \return bool - \a true in case if \a value is present within \a this array.
6410  *  \throw If \a this is not allocated.
6411  *  \throw If \a this->getNumberOfComponents() != 1.
6412  *  \sa findIdFirstEqual()
6413  */
6414 bool DataArrayInt::presenceOfValue(int value) const
6415 {
6416   return findIdFirstEqual(value)!=-1;
6417 }
6418
6419 /*!
6420  * This method expects to be called when number of components of this is equal to one.
6421  * This method returns true if it exists a tuple so that the value is contained in \b vals.
6422  * If not any tuple contains one of the values contained in 'vals' false is returned.
6423  * \sa DataArrayInt::findIdFirstEqual
6424  */
6425 bool DataArrayInt::presenceOfValue(const std::vector<int>& vals) const
6426 {
6427   return findIdFirstEqual(vals)!=-1;
6428 }
6429
6430 /*!
6431  * Accumulates values of each component of \a this array.
6432  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
6433  *         by the caller, that is filled by this method with sum value for each
6434  *         component.
6435  *  \throw If \a this is not allocated.
6436  */
6437 void DataArrayInt::accumulate(int *res) const
6438 {
6439   checkAllocated();
6440   const int *ptr=getConstPointer();
6441   int nbTuple=getNumberOfTuples();
6442   int nbComps=getNumberOfComponents();
6443   std::fill(res,res+nbComps,0);
6444   for(int i=0;i<nbTuple;i++)
6445     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<int>());
6446 }
6447
6448 int DataArrayInt::accumulate(int compId) const
6449 {
6450   checkAllocated();
6451   const int *ptr=getConstPointer();
6452   int nbTuple=getNumberOfTuples();
6453   int nbComps=getNumberOfComponents();
6454   if(compId<0 || compId>=nbComps)
6455     throw INTERP_KERNEL::Exception("DataArrayInt::accumulate : Invalid compId specified : No such nb of components !");
6456   int ret=0;
6457   for(int i=0;i<nbTuple;i++)
6458     ret+=ptr[i*nbComps+compId];
6459   return ret;
6460 }
6461
6462 /*!
6463  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
6464  * The returned array will have same number of components than \a this and number of tuples equal to
6465  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
6466  *
6467  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
6468  *
6469  * \param [in] bgOfIndex - begin (included) of the input index array.
6470  * \param [in] endOfIndex - end (excluded) of the input index array.
6471  * \return DataArrayInt * - the new instance having the same number of components than \a this.
6472  * 
6473  * \throw If bgOfIndex or end is NULL.
6474  * \throw If input index array is not ascendingly sorted.
6475  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
6476  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
6477  */
6478 DataArrayInt *DataArrayInt::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
6479 {
6480   if(!bgOfIndex || !endOfIndex)
6481     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : input pointer NULL !");
6482   checkAllocated();
6483   int nbCompo=getNumberOfComponents();
6484   int nbOfTuples=getNumberOfTuples();
6485   int sz=(int)std::distance(bgOfIndex,endOfIndex);
6486   if(sz<1)
6487     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : invalid size of input index array !");
6488   sz--;
6489   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(sz,nbCompo);
6490   const int *w=bgOfIndex;
6491   if(*w<0 || *w>=nbOfTuples)
6492     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
6493   const int *srcPt=begin()+(*w)*nbCompo;
6494   int *tmp=ret->getPointer();
6495   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
6496     {
6497       std::fill(tmp,tmp+nbCompo,0);
6498       if(w[1]>=w[0])
6499         {
6500           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
6501             {
6502               if(j>=0 && j<nbOfTuples)
6503                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<int>());
6504               else
6505                 {
6506                   std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
6507                   throw INTERP_KERNEL::Exception(oss.str().c_str());
6508                 }
6509             }
6510         }
6511       else
6512         {
6513           std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
6514           throw INTERP_KERNEL::Exception(oss.str().c_str());
6515         }
6516     }
6517   ret->copyStringInfoFrom(*this);
6518   return ret.retn();
6519 }
6520
6521 /*!
6522  * Returns a new DataArrayInt by concatenating two given arrays, so that (1) the number
6523  * of tuples in the result array is <em> a1->getNumberOfTuples() + a2->getNumberOfTuples() -
6524  * offsetA2</em> and (2)
6525  * the number of component in the result array is same as that of each of given arrays.
6526  * First \a offsetA2 tuples of \a a2 are skipped and thus are missing from the result array.
6527  * Info on components is copied from the first of the given arrays. Number of components
6528  * in the given arrays must be the same.
6529  *  \param [in] a1 - an array to include in the result array.
6530  *  \param [in] a2 - another array to include in the result array.
6531  *  \param [in] offsetA2 - number of tuples of \a a2 to skip.
6532  *  \return DataArrayInt * - the new instance of DataArrayInt.
6533  *          The caller is to delete this result array using decrRef() as it is no more
6534  *          needed.
6535  *  \throw If either \a a1 or \a a2 is NULL.
6536  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
6537  */
6538 DataArrayInt *DataArrayInt::Aggregate(const DataArrayInt *a1, const DataArrayInt *a2, int offsetA2)
6539 {
6540   if(!a1 || !a2)
6541     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input DataArrayInt instance is NULL !");
6542   int nbOfComp=a1->getNumberOfComponents();
6543   if(nbOfComp!=a2->getNumberOfComponents())
6544     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Aggregation !");
6545   int nbOfTuple1=a1->getNumberOfTuples();
6546   int nbOfTuple2=a2->getNumberOfTuples();
6547   DataArrayInt *ret=DataArrayInt::New();
6548   ret->alloc(nbOfTuple1+nbOfTuple2-offsetA2,nbOfComp);
6549   int *pt=std::copy(a1->getConstPointer(),a1->getConstPointer()+nbOfTuple1*nbOfComp,ret->getPointer());
6550   std::copy(a2->getConstPointer()+offsetA2*nbOfComp,a2->getConstPointer()+nbOfTuple2*nbOfComp,pt);
6551   ret->copyStringInfoFrom(*a1);
6552   return ret;
6553 }
6554
6555 /*!
6556  * Returns a new DataArrayInt by concatenating all given arrays, so that (1) the number
6557  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
6558  * the number of component in the result array is same as that of each of given arrays.
6559  * Info on components is copied from the first of the given arrays. Number of components
6560  * in the given arrays must be  the same.
6561  * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it
6562  * not the object itself.
6563  *  \param [in] arr - a sequence of arrays to include in the result array.
6564  *  \return DataArrayInt * - the new instance of DataArrayInt.
6565  *          The caller is to delete this result array using decrRef() as it is no more
6566  *          needed.
6567  *  \throw If all arrays within \a arr are NULL.
6568  *  \throw If getNumberOfComponents() of arrays within \a arr.
6569  */
6570 DataArrayInt *DataArrayInt::Aggregate(const std::vector<const DataArrayInt *>& arr)
6571 {
6572   std::vector<const DataArrayInt *> a;
6573   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
6574     if(*it4)
6575       a.push_back(*it4);
6576   if(a.empty())
6577     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input list must be NON EMPTY !");
6578   std::vector<const DataArrayInt *>::const_iterator it=a.begin();
6579   int nbOfComp=(*it)->getNumberOfComponents();
6580   int nbt=(*it++)->getNumberOfTuples();
6581   for(int i=1;it!=a.end();it++,i++)
6582     {
6583       if((*it)->getNumberOfComponents()!=nbOfComp)
6584         throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : Nb of components mismatch for array aggregation !");
6585       nbt+=(*it)->getNumberOfTuples();
6586     }
6587   MCAuto<DataArrayInt> ret=DataArrayInt::New();
6588   ret->alloc(nbt,nbOfComp);
6589   int *pt=ret->getPointer();
6590   for(it=a.begin();it!=a.end();it++)
6591     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
6592   ret->copyStringInfoFrom(*(a[0]));
6593   return ret.retn();
6594 }
6595
6596 /*!
6597  * This method takes as input a list of DataArrayInt instances \a arrs that represent each a packed index arrays.
6598  * A packed index array is an allocated array with one component, and at least one tuple. The first element
6599  * of each array in \a arrs must be 0. Each array in \a arrs is expected to be increasingly monotonic.
6600  * 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.
6601  * 
6602  * \return DataArrayInt * - a new object to be managed by the caller.
6603  */
6604 DataArrayInt *DataArrayInt::AggregateIndexes(const std::vector<const DataArrayInt *>& arrs)
6605 {
6606   int retSz=1;
6607   for(std::vector<const DataArrayInt *>::const_iterator it4=arrs.begin();it4!=arrs.end();it4++)
6608     {
6609       if(*it4)
6610         {
6611           (*it4)->checkAllocated();
6612           if((*it4)->getNumberOfComponents()!=1)
6613             {
6614               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of compo != 1 at pos " << std::distance(arrs.begin(),it4) << " !";
6615               throw INTERP_KERNEL::Exception(oss.str().c_str());
6616             }
6617           int nbTupl=(*it4)->getNumberOfTuples();
6618           if(nbTupl<1)
6619             {
6620               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of tuples < 1 at pos " << std::distance(arrs.begin(),it4) << " !";
6621               throw INTERP_KERNEL::Exception(oss.str().c_str());
6622             }
6623           if((*it4)->front()!=0)
6624             {
6625               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with front value != 0 at pos " << std::distance(arrs.begin(),it4) << " !";
6626               throw INTERP_KERNEL::Exception(oss.str().c_str());
6627             }
6628           retSz+=nbTupl-1;
6629         }
6630       else
6631         {
6632           std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a null instance at pos " << std::distance(arrs.begin(),it4) << " !";
6633           throw INTERP_KERNEL::Exception(oss.str().c_str());
6634         }
6635     }
6636   if(arrs.empty())
6637     throw INTERP_KERNEL::Exception("DataArrayInt::AggregateIndexes : input list must be NON EMPTY !");
6638   MCAuto<DataArrayInt> ret=DataArrayInt::New();
6639   ret->alloc(retSz,1);
6640   int *pt=ret->getPointer(); *pt++=0;
6641   for(std::vector<const DataArrayInt *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
6642     pt=std::transform((*it)->begin()+1,(*it)->end(),pt,std::bind2nd(std::plus<int>(),pt[-1]));
6643   ret->copyStringInfoFrom(*(arrs[0]));
6644   return ret.retn();
6645 }
6646
6647 /*!
6648  * Returns in a single walk in \a this the min value and the max value in \a this.
6649  * \a this is expected to be single component array.
6650  *
6651  * \param [out] minValue - the min value in \a this.
6652  * \param [out] maxValue - the max value in \a this.
6653  *
6654  * \sa getMinValueInArray, getMinValue, getMaxValueInArray, getMaxValue
6655  */
6656 void DataArrayInt::getMinMaxValues(int& minValue, int& maxValue) const
6657 {
6658   checkAllocated();
6659   if(getNumberOfComponents()!=1)
6660     throw INTERP_KERNEL::Exception("DataArrayInt::getMinMaxValues : must be applied on DataArrayInt with only one component !");
6661   int nbTuples(getNumberOfTuples());
6662   const int *pt(begin());
6663   minValue=std::numeric_limits<int>::max(); maxValue=-std::numeric_limits<int>::max();
6664   for(int i=0;i<nbTuples;i++,pt++)
6665     {
6666       if(*pt<minValue)
6667         minValue=*pt;
6668       if(*pt>maxValue)
6669         maxValue=*pt;
6670     }
6671 }
6672
6673 /*!
6674  * Converts every value of \a this array to its absolute value.
6675  * \b WARNING this method is non const. If a new DataArrayInt instance should be built containing the result of abs DataArrayInt::computeAbs
6676  * should be called instead.
6677  *
6678  * \throw If \a this is not allocated.
6679  * \sa DataArrayInt::computeAbs
6680  */
6681 void DataArrayInt::abs()
6682 {
6683   checkAllocated();
6684   int *ptr(getPointer());
6685   std::size_t nbOfElems(getNbOfElems());
6686   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<int,int>(std::abs));
6687   declareAsNew();
6688 }
6689
6690 /*!
6691  * This method builds a new instance of \a this object containing the result of std::abs applied of all elements in \a this.
6692  * This method is a const method (that do not change any values in \a this) contrary to  DataArrayInt::abs method.
6693  *
6694  * \return DataArrayInt * - the new instance of DataArrayInt containing the
6695  *         same number of tuples and component as \a this array.
6696  *         The caller is to delete this result array using decrRef() as it is no more
6697  *         needed.
6698  * \throw If \a this is not allocated.
6699  * \sa DataArrayInt::abs
6700  */
6701 DataArrayInt *DataArrayInt::computeAbs() const
6702 {
6703   checkAllocated();
6704   DataArrayInt *newArr(DataArrayInt::New());
6705   int nbOfTuples(getNumberOfTuples());
6706   int nbOfComp(getNumberOfComponents());
6707   newArr->alloc(nbOfTuples,nbOfComp);
6708   std::transform(begin(),end(),newArr->getPointer(),std::ptr_fun<int,int>(std::abs));
6709   newArr->copyStringInfoFrom(*this);
6710   return newArr;
6711 }
6712
6713 /*!
6714  * Apply a liner function to a given component of \a this array, so that
6715  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
6716  *  \param [in] a - the first coefficient of the function.
6717  *  \param [in] b - the second coefficient of the function.
6718  *  \param [in] compoId - the index of component to modify.
6719  *  \throw If \a this is not allocated.
6720  */
6721 void DataArrayInt::applyLin(int a, int b, int compoId)
6722 {
6723   checkAllocated();
6724   int *ptr=getPointer()+compoId;
6725   int nbOfComp=getNumberOfComponents();
6726   int nbOfTuple=getNumberOfTuples();
6727   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
6728     *ptr=a*(*ptr)+b;
6729   declareAsNew();
6730 }
6731
6732 /*!
6733  * Apply a liner function to all elements of \a this array, so that
6734  * an element _x_ becomes \f$ a * x + b \f$.
6735  *  \param [in] a - the first coefficient of the function.
6736  *  \param [in] b - the second coefficient of the function.
6737  *  \throw If \a this is not allocated.
6738  */
6739 void DataArrayInt::applyLin(int a, int b)
6740 {
6741   checkAllocated();
6742   int *ptr=getPointer();
6743   std::size_t nbOfElems=getNbOfElems();
6744   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
6745     *ptr=a*(*ptr)+b;
6746   declareAsNew();
6747 }
6748
6749 /*!
6750  * Returns a full copy of \a this array except that sign of all elements is reversed.
6751  *  \return DataArrayInt * - the new instance of DataArrayInt containing the
6752  *          same number of tuples and component as \a this array.
6753  *          The caller is to delete this result array using decrRef() as it is no more
6754  *          needed.
6755  *  \throw If \a this is not allocated.
6756  */
6757 DataArrayInt *DataArrayInt::negate() const
6758 {
6759   checkAllocated();
6760   DataArrayInt *newArr=DataArrayInt::New();
6761   int nbOfTuples=getNumberOfTuples();
6762   int nbOfComp=getNumberOfComponents();
6763   newArr->alloc(nbOfTuples,nbOfComp);
6764   const int *cptr=getConstPointer();
6765   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<int>());
6766   newArr->copyStringInfoFrom(*this);
6767   return newArr;
6768 }
6769
6770 /*!
6771  * Modify all elements of \a this array, so that
6772  * an element _x_ becomes \f$ numerator / x \f$.
6773  *  \warning If an exception is thrown because of presence of 0 element in \a this 
6774  *           array, all elements processed before detection of the zero element remain
6775  *           modified.
6776  *  \param [in] numerator - the numerator used to modify array elements.
6777  *  \throw If \a this is not allocated.
6778  *  \throw If there is an element equal to 0 in \a this array.
6779  */
6780 void DataArrayInt::applyInv(int numerator)
6781 {
6782   checkAllocated();
6783   int *ptr=getPointer();
6784   std::size_t nbOfElems=getNbOfElems();
6785   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
6786     {
6787       if(*ptr!=0)
6788         {
6789           *ptr=numerator/(*ptr);
6790         }
6791       else
6792         {
6793           std::ostringstream oss; oss << "DataArrayInt::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
6794           oss << " !";
6795           throw INTERP_KERNEL::Exception(oss.str().c_str());
6796         }
6797     }
6798   declareAsNew();
6799 }
6800
6801 /*!
6802  * Modify all elements of \a this array, so that
6803  * an element _x_ becomes \f$ x / val \f$.
6804  *  \param [in] val - the denominator used to modify array elements.
6805  *  \throw If \a this is not allocated.
6806  *  \throw If \a val == 0.
6807  */
6808 void DataArrayInt::applyDivideBy(int val)
6809 {
6810   if(val==0)
6811     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to divide by 0 !");
6812   checkAllocated();
6813   int *ptr=getPointer();
6814   std::size_t nbOfElems=getNbOfElems();
6815   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::divides<int>(),val));
6816   declareAsNew();
6817 }
6818
6819 /*!
6820  * Modify all elements of \a this array, so that
6821  * an element _x_ becomes  <em> x % val </em>.
6822  *  \param [in] val - the divisor used to modify array elements.
6823  *  \throw If \a this is not allocated.
6824  *  \throw If \a val <= 0.
6825  */
6826 void DataArrayInt::applyModulus(int val)
6827 {
6828   if(val<=0)
6829     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to operate modulus on value <= 0 !");
6830   checkAllocated();
6831   int *ptr=getPointer();
6832   std::size_t nbOfElems=getNbOfElems();
6833   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::modulus<int>(),val));
6834   declareAsNew();
6835 }
6836
6837 struct GreatEqual
6838 {
6839   GreatEqual(int v):_v(v) { }
6840   bool operator()(int v) const { return v>=_v; }
6841   int _v;
6842 };
6843
6844 struct GreaterThan
6845 {
6846   GreaterThan(int v):_v(v) { }
6847   bool operator()(int v) const { return v>_v; }
6848   int _v;
6849 };
6850
6851 struct LowerEqual
6852 {
6853   LowerEqual(int v):_v(v) { }
6854   bool operator()(int v) const { return v<=_v; }
6855   int _v;
6856 };
6857
6858 struct LowerThan
6859 {
6860   LowerThan(int v):_v(v) { }
6861   bool operator()(int v) const { return v<_v; }
6862   int _v;
6863 };
6864
6865 struct InRange
6866 {
6867   InRange(int a, int b):_a(a),_b(b) { }
6868   bool operator()(int v) const { return v>=_a && v<_b; }
6869   int _a,_b;
6870 };
6871
6872 /*!
6873  * This method works only on data array with one component.
6874  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
6875  * this[*id] in [\b vmin,\b vmax)
6876  * 
6877  * \param [in] vmin begin of range. This value is included in range (included).
6878  * \param [in] vmax end of range. This value is \b not included in range (excluded).
6879  * \return a newly allocated data array that the caller should deal with.
6880  *
6881  * \sa DataArrayInt::findIdsNotInRange , DataArrayInt::findIdsStricltyNegative
6882  */
6883 DataArrayInt *DataArrayInt::findIdsInRange(int vmin, int vmax) const
6884 {
6885   InRange ir(vmin,vmax);
6886   MCAuto<DataArrayInt> ret(findIdsAdv(ir));
6887   return ret.retn();
6888 }
6889
6890 struct NotInRange
6891 {
6892   NotInRange(int a, int b):_a(a),_b(b) { }
6893   bool operator()(int v) const { return v<_a || v>=_b; }
6894   int _a,_b;
6895 };
6896
6897 /*!
6898  * This method works only on data array with one component.
6899  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
6900  * this[*id] \b not in [\b vmin,\b vmax)
6901  * 
6902  * \param [in] vmin begin of range. This value is \b not included in range (excluded).
6903  * \param [in] vmax end of range. This value is included in range (included).
6904  * \return a newly allocated data array that the caller should deal with.
6905  * 
6906  * \sa DataArrayInt::findIdsInRange , DataArrayInt::findIdsStricltyNegative
6907  */
6908 DataArrayInt *DataArrayInt::findIdsNotInRange(int vmin, int vmax) const
6909 {
6910   NotInRange nir(vmin,vmax);
6911   MCAuto<DataArrayInt> ret(findIdsAdv(nir));
6912   return ret.retn();
6913 }
6914
6915 /*!
6916  * 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.
6917  *
6918  * \return a newly allocated data array that the caller should deal with.
6919  * \sa DataArrayInt::findIdsInRange
6920  */
6921 DataArrayInt *DataArrayInt::findIdsStricltyNegative() const
6922 {
6923   LowerThan lt(0);
6924   MCAuto<DataArrayInt> ret(findIdsAdv(lt));
6925   return ret.retn();
6926 }
6927
6928 MCAuto<DataArrayInt> DataArrayInt::findIdsGreaterOrEqualTo(int val) const
6929 {
6930   GreatEqual ge(val);
6931   return findIdsAdv(ge);
6932 }
6933
6934 MCAuto<DataArrayInt> DataArrayInt::findIdsGreaterThan(int val) const
6935 {
6936   GreaterThan gt(val);
6937   return findIdsAdv(gt);
6938 }
6939
6940 MCAuto<DataArrayInt> DataArrayInt::findIdsLowerOrEqualTo(int val) const
6941 {
6942   LowerEqual le(val);
6943   return findIdsAdv(le);
6944 }
6945
6946 MCAuto<DataArrayInt> DataArrayInt::findIdsLowerThan(int val) const
6947 {
6948   LowerThan lt(val);
6949   return findIdsAdv(lt);
6950 }
6951
6952 /*!
6953  * This method works only on data array with one component.
6954  * 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.
6955  * 
6956  * \param [in] vmin begin of range. This value is included in range (included).
6957  * \param [in] vmax end of range. This value is \b not included in range (excluded).
6958  * \return if all ids in \a this are so that (*this)[i]==i for all i in [ 0, \c this->getNumberOfTuples() ). */
6959 bool DataArrayInt::checkAllIdsInRange(int vmin, int vmax) const
6960 {
6961   checkAllocated();
6962   if(getNumberOfComponents()!=1)
6963     throw INTERP_KERNEL::Exception("DataArrayInt::checkAllIdsInRange : this must have exactly one component !");
6964   int nbOfTuples=getNumberOfTuples();
6965   bool ret=true;
6966   const int *cptr=getConstPointer();
6967   for(int i=0;i<nbOfTuples;i++,cptr++)
6968     {
6969       if(*cptr>=vmin && *cptr<vmax)
6970         { ret=ret && *cptr==i; }
6971       else
6972         {
6973           std::ostringstream oss; oss << "DataArrayInt::checkAllIdsInRange : tuple #" << i << " has value " << *cptr << " should be in [" << vmin << "," << vmax << ") !";
6974           throw INTERP_KERNEL::Exception(oss.str().c_str());
6975         }
6976     }
6977   return ret;
6978 }
6979
6980 /*!
6981  * Modify all elements of \a this array, so that
6982  * an element _x_ becomes <em> val % x </em>.
6983  *  \warning If an exception is thrown because of presence of an element <= 0 in \a this 
6984  *           array, all elements processed before detection of the zero element remain
6985  *           modified.
6986  *  \param [in] val - the divident used to modify array elements.
6987  *  \throw If \a this is not allocated.
6988  *  \throw If there is an element equal to or less than 0 in \a this array.
6989  */
6990 void DataArrayInt::applyRModulus(int val)
6991 {
6992   checkAllocated();
6993   int *ptr=getPointer();
6994   std::size_t nbOfElems=getNbOfElems();
6995   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
6996     {
6997       if(*ptr>0)
6998         {
6999           *ptr=val%(*ptr);
7000         }
7001       else
7002         {
7003           std::ostringstream oss; oss << "DataArrayInt::applyRModulus : presence of value <=0 in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
7004           oss << " !";
7005           throw INTERP_KERNEL::Exception(oss.str().c_str());
7006         }
7007     }
7008   declareAsNew();
7009 }
7010
7011 /*!
7012  * Modify all elements of \a this array, so that
7013  * an element _x_ becomes <em> val ^ x </em>.
7014  *  \param [in] val - the value used to apply pow on all array elements.
7015  *  \throw If \a this is not allocated.
7016  *  \throw If \a val < 0.
7017  */
7018 void DataArrayInt::applyPow(int val)
7019 {
7020   checkAllocated();
7021   if(val<0)
7022     throw INTERP_KERNEL::Exception("DataArrayInt::applyPow : input pow in < 0 !");
7023   int *ptr=getPointer();
7024   std::size_t nbOfElems=getNbOfElems();
7025   if(val==0)
7026     {
7027       std::fill(ptr,ptr+nbOfElems,1);
7028       return ;
7029     }
7030   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
7031     {
7032       int tmp=1;
7033       for(int j=0;j<val;j++)
7034         tmp*=*ptr;
7035       *ptr=tmp;
7036     }
7037   declareAsNew();
7038 }
7039
7040 /*!
7041  * Modify all elements of \a this array, so that
7042  * an element _x_ becomes \f$ val ^ x \f$.
7043  *  \param [in] val - the value used to apply pow on all array elements.
7044  *  \throw If \a this is not allocated.
7045  *  \throw If there is an element < 0 in \a this array.
7046  *  \warning If an exception is thrown because of presence of 0 element in \a this 
7047  *           array, all elements processed before detection of the zero element remain
7048  *           modified.
7049  */
7050 void DataArrayInt::applyRPow(int val)
7051 {
7052   checkAllocated();
7053   int *ptr=getPointer();
7054   std::size_t nbOfElems=getNbOfElems();
7055   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
7056     {
7057       if(*ptr>=0)
7058         {
7059           int tmp=1;
7060           for(int j=0;j<*ptr;j++)
7061             tmp*=val;
7062           *ptr=tmp;
7063         }
7064       else
7065         {
7066           std::ostringstream oss; oss << "DataArrayInt::applyRPow : presence of negative value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
7067           oss << " !";
7068           throw INTERP_KERNEL::Exception(oss.str().c_str());
7069         }
7070     }
7071   declareAsNew();
7072 }
7073
7074 /*!
7075  * Returns a new DataArrayInt by aggregating two given arrays, so that (1) the number
7076  * of components in the result array is a sum of the number of components of given arrays
7077  * and (2) the number of tuples in the result array is same as that of each of given
7078  * arrays. In other words the i-th tuple of result array includes all components of
7079  * i-th tuples of all given arrays.
7080  * Number of tuples in the given arrays must be the same.
7081  *  \param [in] a1 - an array to include in the result array.
7082  *  \param [in] a2 - another array to include in the result array.
7083  *  \return DataArrayInt * - the new instance of DataArrayInt.
7084  *          The caller is to delete this result array using decrRef() as it is no more
7085  *          needed.
7086  *  \throw If both \a a1 and \a a2 are NULL.
7087  *  \throw If any given array is not allocated.
7088  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
7089  */
7090 DataArrayInt *DataArrayInt::Meld(const DataArrayInt *a1, const DataArrayInt *a2)
7091 {
7092   std::vector<const DataArrayInt *> arr(2);
7093   arr[0]=a1; arr[1]=a2;
7094   return Meld(arr);
7095 }
7096
7097 /*!
7098  * Returns a new DataArrayInt by aggregating all given arrays, so that (1) the number
7099  * of components in the result array is a sum of the number of components of given arrays
7100  * and (2) the number of tuples in the result array is same as that of each of given
7101  * arrays. In other words the i-th tuple of result array includes all components of
7102  * i-th tuples of all given arrays.
7103  * Number of tuples in the given arrays must be  the same.
7104  *  \param [in] arr - a sequence of arrays 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 all arrays within \a arr are NULL.
7109  *  \throw If any given array is not allocated.
7110  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
7111  */
7112 DataArrayInt *DataArrayInt::Meld(const std::vector<const DataArrayInt *>& arr)
7113 {
7114   std::vector<const DataArrayInt *> a;
7115   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
7116     if(*it4)
7117       a.push_back(*it4);
7118   if(a.empty())
7119     throw INTERP_KERNEL::Exception("DataArrayInt::Meld : array must be NON empty !");
7120   std::vector<const DataArrayInt *>::const_iterator it;
7121   for(it=a.begin();it!=a.end();it++)
7122     (*it)->checkAllocated();
7123   it=a.begin();
7124   int nbOfTuples=(*it)->getNumberOfTuples();
7125   std::vector<int> nbc(a.size());
7126   std::vector<const int *> pts(a.size());
7127   nbc[0]=(*it)->getNumberOfComponents();
7128   pts[0]=(*it++)->getConstPointer();
7129   for(int i=1;it!=a.end();it++,i++)
7130     {
7131       if(nbOfTuples!=(*it)->getNumberOfTuples())
7132         throw INTERP_KERNEL::Exception("DataArrayInt::meld : mismatch of number of tuples !");
7133       nbc[i]=(*it)->getNumberOfComponents();
7134       pts[i]=(*it)->getConstPointer();
7135     }
7136   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
7137   DataArrayInt *ret=DataArrayInt::New();
7138   ret->alloc(nbOfTuples,totalNbOfComp);
7139   int *retPtr=ret->getPointer();
7140   for(int i=0;i<nbOfTuples;i++)
7141     for(int j=0;j<(int)a.size();j++)
7142       {
7143         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
7144         pts[j]+=nbc[j];
7145       }
7146   int k=0;
7147   for(int i=0;i<(int)a.size();i++)
7148     for(int j=0;j<nbc[i];j++,k++)
7149       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j));
7150   return ret;
7151 }
7152
7153 /*!
7154  * Returns a new DataArrayInt which is a minimal partition of elements of \a groups.
7155  * The i-th item of the result array is an ID of a set of elements belonging to a
7156  * unique set of groups, which the i-th element is a part of. This set of elements
7157  * belonging to a unique set of groups is called \a family, so the result array contains
7158  * IDs of families each element belongs to.
7159  *
7160  * \b Example: if we have two groups of elements: \a group1 [0,4] and \a group2 [ 0,1,2 ],
7161  * then there are 3 families:
7162  * - \a family1 (with ID 1) contains element [0] belonging to ( \a group1 + \a group2 ),
7163  * - \a family2 (with ID 2) contains elements [4] belonging to ( \a group1 ),
7164  * - \a family3 (with ID 3) contains element [1,2] belonging to ( \a group2 ), <br>
7165  * and the result array contains IDs of families [ 1,3,3,0,2 ]. <br> Note a family ID 0 which
7166  * stands for the element #3 which is in none of groups.
7167  *
7168  *  \param [in] groups - sequence of groups of element IDs.
7169  *  \param [in] newNb - total number of elements; it must be more than max ID of element
7170  *         in \a groups.
7171  *  \param [out] fidsOfGroups - IDs of families the elements of each group belong to.
7172  *  \return DataArrayInt * - a new instance of DataArrayInt containing IDs of families
7173  *         each element with ID from range [0, \a newNb ) belongs to. The caller is to
7174  *         delete this array using decrRef() as it is no more needed.
7175  *  \throw If any element ID in \a groups violates condition ( 0 <= ID < \a newNb ).
7176  */
7177 DataArrayInt *DataArrayInt::MakePartition(const std::vector<const DataArrayInt *>& groups, int newNb, std::vector< std::vector<int> >& fidsOfGroups)
7178 {
7179   std::vector<const DataArrayInt *> groups2;
7180   for(std::vector<const DataArrayInt *>::const_iterator it4=groups.begin();it4!=groups.end();it4++)
7181     if(*it4)
7182       groups2.push_back(*it4);
7183   MCAuto<DataArrayInt> ret=DataArrayInt::New();
7184   ret->alloc(newNb,1);
7185   int *retPtr=ret->getPointer();
7186   std::fill(retPtr,retPtr+newNb,0);
7187   int fid=1;
7188   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++)
7189     {
7190       const int *ptr=(*iter)->getConstPointer();
7191       std::size_t nbOfElem=(*iter)->getNbOfElems();
7192       int sfid=fid;
7193       for(int j=0;j<sfid;j++)
7194         {
7195           bool found=false;
7196           for(std::size_t i=0;i<nbOfElem;i++)
7197             {
7198               if(ptr[i]>=0 && ptr[i]<newNb)
7199                 {
7200                   if(retPtr[ptr[i]]==j)
7201                     {
7202                       retPtr[ptr[i]]=fid;
7203                       found=true;
7204                     }
7205                 }
7206               else
7207                 {
7208                   std::ostringstream oss; oss << "DataArrayInt::MakePartition : In group \"" << (*iter)->getName() << "\" in tuple #" << i << " value = " << ptr[i] << " ! Should be in [0," << newNb;
7209                   oss << ") !";
7210                   throw INTERP_KERNEL::Exception(oss.str().c_str());
7211                 }
7212             }
7213           if(found)
7214             fid++;
7215         }
7216     }
7217   fidsOfGroups.clear();
7218   fidsOfGroups.resize(groups2.size());
7219   int grId=0;
7220   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++,grId++)
7221     {
7222       std::set<int> tmp;
7223       const int *ptr=(*iter)->getConstPointer();
7224       std::size_t nbOfElem=(*iter)->getNbOfElems();
7225       for(const int *p=ptr;p!=ptr+nbOfElem;p++)
7226         tmp.insert(retPtr[*p]);
7227       fidsOfGroups[grId].insert(fidsOfGroups[grId].end(),tmp.begin(),tmp.end());
7228     }
7229   return ret.retn();
7230 }
7231
7232 /*!
7233  * Returns a new DataArrayInt which contains all elements of given one-dimensional
7234  * arrays. The result array does not contain any duplicates and its values
7235  * are sorted in ascending order.
7236  *  \param [in] arr - sequence of DataArrayInt's to unite.
7237  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7238  *         array using decrRef() as it is no more needed.
7239  *  \throw If any \a arr[i] is not allocated.
7240  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
7241  */
7242 DataArrayInt *DataArrayInt::BuildUnion(const std::vector<const DataArrayInt *>& arr)
7243 {
7244   std::vector<const DataArrayInt *> a;
7245   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
7246     if(*it4)
7247       a.push_back(*it4);
7248   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
7249     {
7250       (*it)->checkAllocated();
7251       if((*it)->getNumberOfComponents()!=1)
7252         throw INTERP_KERNEL::Exception("DataArrayInt::BuildUnion : only single component allowed !");
7253     }
7254   //
7255   std::set<int> r;
7256   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
7257     {
7258       const int *pt=(*it)->getConstPointer();
7259       int nbOfTuples=(*it)->getNumberOfTuples();
7260       r.insert(pt,pt+nbOfTuples);
7261     }
7262   DataArrayInt *ret=DataArrayInt::New();
7263   ret->alloc((int)r.size(),1);
7264   std::copy(r.begin(),r.end(),ret->getPointer());
7265   return ret;
7266 }
7267
7268 /*!
7269  * Returns a new DataArrayInt which contains elements present in each of given one-dimensional
7270  * arrays. The result array does not contain any duplicates and its values
7271  * are sorted in ascending order.
7272  *  \param [in] arr - sequence of DataArrayInt's to intersect.
7273  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7274  *         array using decrRef() as it is no more needed.
7275  *  \throw If any \a arr[i] is not allocated.
7276  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
7277  */
7278 DataArrayInt *DataArrayInt::BuildIntersection(const std::vector<const DataArrayInt *>& arr)
7279 {
7280   std::vector<const DataArrayInt *> a;
7281   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
7282     if(*it4)
7283       a.push_back(*it4);
7284   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
7285     {
7286       (*it)->checkAllocated();
7287       if((*it)->getNumberOfComponents()!=1)
7288         throw INTERP_KERNEL::Exception("DataArrayInt::BuildIntersection : only single component allowed !");
7289     }
7290   //
7291   std::set<int> r;
7292   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
7293     {
7294       const int *pt=(*it)->getConstPointer();
7295       int nbOfTuples=(*it)->getNumberOfTuples();
7296       std::set<int> s1(pt,pt+nbOfTuples);
7297       if(it!=a.begin())
7298         {
7299           std::set<int> r2;
7300           std::set_intersection(r.begin(),r.end(),s1.begin(),s1.end(),inserter(r2,r2.end()));
7301           r=r2;
7302         }
7303       else
7304         r=s1;
7305     }
7306   DataArrayInt *ret(DataArrayInt::New());
7307   ret->alloc((int)r.size(),1);
7308   std::copy(r.begin(),r.end(),ret->getPointer());
7309   return ret;
7310 }
7311
7312 /// @cond INTERNAL
7313 namespace MEDCouplingImpl
7314 {
7315   class OpSwitchedOn
7316   {
7317   public:
7318     OpSwitchedOn(int *pt):_pt(pt),_cnt(0) { }
7319     void operator()(const bool& b) { if(b) *_pt++=_cnt; _cnt++; }
7320   private:
7321     int *_pt;
7322     int _cnt;
7323   };
7324
7325   class OpSwitchedOff
7326   {
7327   public:
7328     OpSwitchedOff(int *pt):_pt(pt),_cnt(0) { }
7329     void operator()(const bool& b) { if(!b) *_pt++=_cnt; _cnt++; }
7330   private:
7331     int *_pt;
7332     int _cnt;
7333   };
7334 }
7335 /// @endcond
7336
7337 /*!
7338  * This method returns the list of ids in ascending mode so that v[id]==true.
7339  */
7340 DataArrayInt *DataArrayInt::BuildListOfSwitchedOn(const std::vector<bool>& v)
7341 {
7342   int sz((int)std::count(v.begin(),v.end(),true));
7343   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
7344   std::for_each(v.begin(),v.end(),MEDCouplingImpl::OpSwitchedOn(ret->getPointer()));
7345   return ret.retn();
7346 }
7347
7348 /*!
7349  * This method returns the list of ids in ascending mode so that v[id]==false.
7350  */
7351 DataArrayInt *DataArrayInt::BuildListOfSwitchedOff(const std::vector<bool>& v)
7352 {
7353   int sz((int)std::count(v.begin(),v.end(),false));
7354   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
7355   std::for_each(v.begin(),v.end(),MEDCouplingImpl::OpSwitchedOff(ret->getPointer()));
7356   return ret.retn();
7357 }
7358
7359 /*!
7360  * This method allows to put a vector of vector of integer into a more compact data stucture (skyline). 
7361  * This method is not available into python because no available optimized data structure available to map std::vector< std::vector<int> >.
7362  *
7363  * \param [in] v the input data structure to be translate into skyline format.
7364  * \param [out] data the first element of the skyline format. The user is expected to deal with newly allocated array.
7365  * \param [out] dataIndex the second element of the skyline format.
7366  */
7367 void DataArrayInt::PutIntoToSkylineFrmt(const std::vector< std::vector<int> >& v, DataArrayInt *& data, DataArrayInt *& dataIndex)
7368 {
7369   int sz((int)v.size());
7370   MCAuto<DataArrayInt> ret0(DataArrayInt::New()),ret1(DataArrayInt::New());
7371   ret1->alloc(sz+1,1);
7372   int *pt(ret1->getPointer()); *pt=0;
7373   for(int i=0;i<sz;i++,pt++)
7374     pt[1]=pt[0]+(int)v[i].size();
7375   ret0->alloc(ret1->back(),1);
7376   pt=ret0->getPointer();
7377   for(int i=0;i<sz;i++)
7378     pt=std::copy(v[i].begin(),v[i].end(),pt);
7379   data=ret0.retn(); dataIndex=ret1.retn();
7380 }
7381
7382 /*!
7383  * Returns a new DataArrayInt which contains a complement of elements of \a this
7384  * one-dimensional array. I.e. the result array contains all elements from the range [0,
7385  * \a nbOfElement) not present in \a this array.
7386  *  \param [in] nbOfElement - maximal size of the result array.
7387  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7388  *         array using decrRef() as it is no more needed.
7389  *  \throw If \a this is not allocated.
7390  *  \throw If \a this->getNumberOfComponents() != 1.
7391  *  \throw If any element \a x of \a this array violates condition ( 0 <= \a x < \a
7392  *         nbOfElement ).
7393  */
7394 DataArrayInt *DataArrayInt::buildComplement(int nbOfElement) const
7395 {
7396   checkAllocated();
7397   if(getNumberOfComponents()!=1)
7398     throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : only single component allowed !");
7399   std::vector<bool> tmp(nbOfElement);
7400   const int *pt=getConstPointer();
7401   int nbOfTuples=getNumberOfTuples();
7402   for(const int *w=pt;w!=pt+nbOfTuples;w++)
7403     if(*w>=0 && *w<nbOfElement)
7404       tmp[*w]=true;
7405     else
7406       throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : an element is not in valid range : [0,nbOfElement) !");
7407   int nbOfRetVal=(int)std::count(tmp.begin(),tmp.end(),false);
7408   DataArrayInt *ret=DataArrayInt::New();
7409   ret->alloc(nbOfRetVal,1);
7410   int j=0;
7411   int *retPtr=ret->getPointer();
7412   for(int i=0;i<nbOfElement;i++)
7413     if(!tmp[i])
7414       retPtr[j++]=i;
7415   return ret;
7416 }
7417
7418 /*!
7419  * Returns a new DataArrayInt containing elements of \a this one-dimensional missing
7420  * from an \a other one-dimensional array.
7421  *  \param [in] other - a DataArrayInt containing elements not to include in the result array.
7422  *  \return DataArrayInt * - a new instance of DataArrayInt with one component. The
7423  *         caller is to delete this array using decrRef() as it is no more needed.
7424  *  \throw If \a other is NULL.
7425  *  \throw If \a other is not allocated.
7426  *  \throw If \a other->getNumberOfComponents() != 1.
7427  *  \throw If \a this is not allocated.
7428  *  \throw If \a this->getNumberOfComponents() != 1.
7429  *  \sa DataArrayInt::buildSubstractionOptimized()
7430  */
7431 DataArrayInt *DataArrayInt::buildSubstraction(const DataArrayInt *other) const
7432 {
7433   if(!other)
7434     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : DataArrayInt pointer in input is NULL !");
7435   checkAllocated();
7436   other->checkAllocated();
7437   if(getNumberOfComponents()!=1)
7438     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed !");
7439   if(other->getNumberOfComponents()!=1)
7440     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed for other type !");
7441   const int *pt=getConstPointer();
7442   int nbOfTuples=getNumberOfTuples();
7443   std::set<int> s1(pt,pt+nbOfTuples);
7444   pt=other->getConstPointer();
7445   nbOfTuples=other->getNumberOfTuples();
7446   std::set<int> s2(pt,pt+nbOfTuples);
7447   std::vector<int> r;
7448   std::set_difference(s1.begin(),s1.end(),s2.begin(),s2.end(),std::back_insert_iterator< std::vector<int> >(r));
7449   DataArrayInt *ret=DataArrayInt::New();
7450   ret->alloc((int)r.size(),1);
7451   std::copy(r.begin(),r.end(),ret->getPointer());
7452   return ret;
7453 }
7454
7455 /*!
7456  * \a this is expected to have one component and to be sorted ascendingly (as for \a other).
7457  * \a other is expected to be a part of \a this. If not DataArrayInt::buildSubstraction should be called instead.
7458  * 
7459  * \param [in] other an array with one component and expected to be sorted ascendingly.
7460  * \ret list of ids in \a this but not in \a other.
7461  * \sa DataArrayInt::buildSubstraction
7462  */
7463 DataArrayInt *DataArrayInt::buildSubstractionOptimized(const DataArrayInt *other) const
7464 {
7465   static const char *MSG="DataArrayInt::buildSubstractionOptimized : only single component allowed !";
7466   if(!other) throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstractionOptimized : NULL input array !");
7467   checkAllocated(); other->checkAllocated();
7468   if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
7469   if(other->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
7470   const int *pt1Bg(begin()),*pt1End(end()),*pt2Bg(other->begin()),*pt2End(other->end());
7471   const int *work1(pt1Bg),*work2(pt2Bg);
7472   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
7473   for(;work1!=pt1End;work1++)
7474     {
7475       if(work2!=pt2End && *work1==*work2)
7476         work2++;
7477       else
7478         ret->pushBackSilent(*work1);
7479     }
7480   return ret.retn();
7481 }
7482
7483
7484 /*!
7485  * Returns a new DataArrayInt which contains all elements of \a this and a given
7486  * one-dimensional arrays. The result array does not contain any duplicates
7487  * and its values are sorted in ascending order.
7488  *  \param [in] other - an array to unite with \a this one.
7489  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7490  *         array using decrRef() as it is no more needed.
7491  *  \throw If \a this or \a other is not allocated.
7492  *  \throw If \a this->getNumberOfComponents() != 1.
7493  *  \throw If \a other->getNumberOfComponents() != 1.
7494  */
7495 DataArrayInt *DataArrayInt::buildUnion(const DataArrayInt *other) const
7496 {
7497   std::vector<const DataArrayInt *>arrs(2);
7498   arrs[0]=this; arrs[1]=other;
7499   return BuildUnion(arrs);
7500 }
7501
7502
7503 /*!
7504  * Returns a new DataArrayInt which contains elements present in both \a this and a given
7505  * one-dimensional arrays. The result array does not contain any duplicates
7506  * and its values are sorted in ascending order.
7507  *  \param [in] other - an array to intersect with \a this one.
7508  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7509  *         array using decrRef() as it is no more needed.
7510  *  \throw If \a this or \a other is not allocated.
7511  *  \throw If \a this->getNumberOfComponents() != 1.
7512  *  \throw If \a other->getNumberOfComponents() != 1.
7513  */
7514 DataArrayInt *DataArrayInt::buildIntersection(const DataArrayInt *other) const
7515 {
7516   std::vector<const DataArrayInt *>arrs(2);
7517   arrs[0]=this; arrs[1]=other;
7518   return BuildIntersection(arrs);
7519 }
7520
7521 /*!
7522  * This method can be applied on allocated with one component DataArrayInt instance.
7523  * This method is typically relevant for sorted arrays. All consecutive duplicated items in \a this will appear only once in returned DataArrayInt instance.
7524  * 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]
7525  * 
7526  * \return a newly allocated array that contain the result of the unique operation applied on \a this.
7527  * \throw if \a this is not allocated or if \a this has not exactly one component.
7528  * \sa DataArrayInt::buildUniqueNotSorted
7529  */
7530 DataArrayInt *DataArrayInt::buildUnique() const
7531 {
7532   checkAllocated();
7533   if(getNumberOfComponents()!=1)
7534     throw INTERP_KERNEL::Exception("DataArrayInt::buildUnique : only single component allowed !");
7535   int nbOfTuples=getNumberOfTuples();
7536   MCAuto<DataArrayInt> tmp=deepCopy();
7537   int *data=tmp->getPointer();
7538   int *last=std::unique(data,data+nbOfTuples);
7539   MCAuto<DataArrayInt> ret=DataArrayInt::New();
7540   ret->alloc(std::distance(data,last),1);
7541   std::copy(data,last,ret->getPointer());
7542   return ret.retn();
7543 }
7544
7545 /*!
7546  * This method can be applied on allocated with one component DataArrayInt instance.
7547  * This method keep elements only once by keeping the same order in \a this that is not expected to be sorted.
7548  *
7549  * \return a newly allocated array that contain the result of the unique operation applied on \a this.
7550  *
7551  * \throw if \a this is not allocated or if \a this has not exactly one component.
7552  *
7553  * \sa DataArrayInt::buildUnique
7554  */
7555 DataArrayInt *DataArrayInt::buildUniqueNotSorted() const
7556 {
7557   checkAllocated();
7558     if(getNumberOfComponents()!=1)
7559       throw INTERP_KERNEL::Exception("DataArrayInt::buildUniqueNotSorted : only single component allowed !");
7560   int minVal,maxVal;
7561   getMinMaxValues(minVal,maxVal);
7562   std::vector<bool> b(maxVal-minVal+1,false);
7563   const int *ptBg(begin()),*endBg(end());
7564   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
7565   for(const int *pt=ptBg;pt!=endBg;pt++)
7566     {
7567       if(!b[*pt-minVal])
7568         {
7569           ret->pushBackSilent(*pt);
7570           b[*pt-minVal]=true;
7571         }
7572     }
7573   ret->copyStringInfoFrom(*this);
7574   return ret.retn();
7575 }
7576
7577 /*!
7578  * Returns a new DataArrayInt which contains size of every of groups described by \a this
7579  * "index" array. Such "index" array is returned for example by 
7580  * \ref MEDCoupling::MEDCouplingUMesh::buildDescendingConnectivity
7581  * "MEDCouplingUMesh::buildDescendingConnectivity" and
7582  * \ref MEDCoupling::MEDCouplingUMesh::getNodalConnectivityIndex
7583  * "MEDCouplingUMesh::getNodalConnectivityIndex" etc.
7584  * This method preforms the reverse operation of DataArrayInt::computeOffsetsFull.
7585  *  \return DataArrayInt * - a new instance of DataArrayInt, whose number of tuples
7586  *          equals to \a this->getNumberOfComponents() - 1, and number of components is 1.
7587  *          The caller is to delete this array using decrRef() as it is no more needed. 
7588  *  \throw If \a this is not allocated.
7589  *  \throw If \a this->getNumberOfComponents() != 1.
7590  *  \throw If \a this->getNumberOfTuples() < 2.
7591  *
7592  *  \b Example: <br> 
7593  *         - this contains [1,3,6,7,7,9,15]
7594  *         - result array contains [2,3,1,0,2,6],
7595  *          where 2 = 3 - 1, 3 = 6 - 3, 1 = 7 - 6 etc.
7596  *
7597  * \sa DataArrayInt::computeOffsetsFull
7598  */
7599 DataArrayInt *DataArrayInt::deltaShiftIndex() const
7600 {
7601   checkAllocated();
7602   if(getNumberOfComponents()!=1)
7603     throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : only single component allowed !");
7604   int nbOfTuples=getNumberOfTuples();
7605   if(nbOfTuples<2)
7606     throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : 1 tuple at least must be present in 'this' !");
7607   const int *ptr=getConstPointer();
7608   DataArrayInt *ret=DataArrayInt::New();
7609   ret->alloc(nbOfTuples-1,1);
7610   int *out=ret->getPointer();
7611   std::transform(ptr+1,ptr+nbOfTuples,ptr,out,std::minus<int>());
7612   return ret;
7613 }
7614
7615 /*!
7616  * Modifies \a this one-dimensional array so that value of each element \a x
7617  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
7618  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number of tuples
7619  * and components remains the same.<br>
7620  * This method is useful for allToAllV in MPI with contiguous policy. This method
7621  * differs from computeOffsetsFull() in that the number of tuples is \b not changed by
7622  * this one.
7623  *  \throw If \a this is not allocated.
7624  *  \throw If \a this->getNumberOfComponents() != 1.
7625  *
7626  *  \b Example: <br>
7627  *          - Before \a this contains [3,5,1,2,0,8]
7628  *          - After \a this contains  [0,3,8,9,11,11]<br>
7629  *          Note that the last element 19 = 11 + 8 is missing because size of \a this
7630  *          array is retained and thus there is no space to store the last element.
7631  */
7632 void DataArrayInt::computeOffsets()
7633 {
7634   checkAllocated();
7635   if(getNumberOfComponents()!=1)
7636     throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets : only single component allowed !");
7637   int nbOfTuples=getNumberOfTuples();
7638   if(nbOfTuples==0)
7639     return ;
7640   int *work=getPointer();
7641   int tmp=work[0];
7642   work[0]=0;
7643   for(int i=1;i<nbOfTuples;i++)
7644     {
7645       int tmp2=work[i];
7646       work[i]=work[i-1]+tmp;
7647       tmp=tmp2;
7648     }
7649   declareAsNew();
7650 }
7651
7652
7653 /*!
7654  * Modifies \a this one-dimensional array so that value of each element \a x
7655  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
7656  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number
7657  * components remains the same and number of tuples is inceamented by one.<br>
7658  * This method is useful for allToAllV in MPI with contiguous policy. This method
7659  * differs from computeOffsets() in that the number of tuples is changed by this one.
7660  * This method preforms the reverse operation of DataArrayInt::deltaShiftIndex.
7661  *  \throw If \a this is not allocated.
7662  *  \throw If \a this->getNumberOfComponents() != 1.
7663  *
7664  *  \b Example: <br>
7665  *          - Before \a this contains [3,5,1,2,0,8]
7666  *          - After \a this contains  [0,3,8,9,11,11,19]<br>
7667  * \sa DataArrayInt::deltaShiftIndex
7668  */
7669 void DataArrayInt::computeOffsetsFull()
7670 {
7671   checkAllocated();
7672   if(getNumberOfComponents()!=1)
7673     throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsetsFull : only single component allowed !");
7674   int nbOfTuples=getNumberOfTuples();
7675   int *ret=(int *)malloc((nbOfTuples+1)*sizeof(int));
7676   const int *work=getConstPointer();
7677   ret[0]=0;
7678   for(int i=0;i<nbOfTuples;i++)
7679     ret[i+1]=work[i]+ret[i];
7680   useArray(ret,true,C_DEALLOC,nbOfTuples+1,1);
7681   declareAsNew();
7682 }
7683
7684 /*!
7685  * Returns two new DataArrayInt instances whose contents is computed from that of \a this and \a listOfIds arrays as follows.
7686  * \a this is expected to be an offset format ( as returned by DataArrayInt::computeOffsetsFull ) that is to say with one component
7687  * and ** sorted strictly increasingly **. \a listOfIds is expected to be sorted ascendingly (not strictly needed for \a listOfIds).
7688  * This methods searches in \a this, considered as a set of contiguous \c this->getNumberOfComponents() ranges, all ids in \a listOfIds
7689  * filling completely one of the ranges in \a this.
7690  *
7691  * \param [in] listOfIds a list of ids that has to be sorted ascendingly.
7692  * \param [out] rangeIdsFetched the range ids fetched
7693  * \param [out] idsInInputListThatFetch contains the list of ids in \a listOfIds that are \b fully included in a range in \a this. So
7694  *              \a idsInInputListThatFetch is a part of input \a listOfIds.
7695  *
7696  * \sa DataArrayInt::computeOffsetsFull
7697  *
7698  *  \b Example: <br>
7699  *          - \a this : [0,3,7,9,15,18]
7700  *          - \a listOfIds contains  [0,1,2,3,7,8,15,16,17]
7701  *          - \a rangeIdsFetched result array: [0,2,4]
7702  *          - \a idsInInputListThatFetch result array: [0,1,2,7,8,15,16,17]
7703  * In this example id 3 in input \a listOfIds is alone so it do not appear in output \a idsInInputListThatFetch.
7704  * <br>
7705  */
7706 void DataArrayInt::findIdsRangesInListOfIds(const DataArrayInt *listOfIds, DataArrayInt *& rangeIdsFetched, DataArrayInt *& idsInInputListThatFetch) const
7707 {
7708   if(!listOfIds)
7709     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : input list of ids is null !");
7710   listOfIds->checkAllocated(); checkAllocated();
7711   if(listOfIds->getNumberOfComponents()!=1)
7712     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : input list of ids must have exactly one component !");
7713   if(getNumberOfComponents()!=1)
7714     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : this must have exactly one component !");
7715   MCAuto<DataArrayInt> ret0=DataArrayInt::New(); ret0->alloc(0,1);
7716   MCAuto<DataArrayInt> ret1=DataArrayInt::New(); ret1->alloc(0,1);
7717   const int *tupEnd(listOfIds->end()),*offBg(begin()),*offEnd(end()-1);
7718   const int *tupPtr(listOfIds->begin()),*offPtr(offBg);
7719   while(tupPtr!=tupEnd && offPtr!=offEnd)
7720     {
7721       if(*tupPtr==*offPtr)
7722         {
7723           int i=offPtr[0];
7724           while(i<offPtr[1] && *tupPtr==i && tupPtr!=tupEnd) { i++; tupPtr++; }
7725           if(i==offPtr[1])
7726             {
7727               ret0->pushBackSilent((int)std::distance(offBg,offPtr));
7728               ret1->pushBackValsSilent(tupPtr-(offPtr[1]-offPtr[0]),tupPtr);
7729               offPtr++;
7730             }
7731         }
7732       else
7733         { if(*tupPtr<*offPtr) tupPtr++; else offPtr++; }
7734     }
7735   rangeIdsFetched=ret0.retn();
7736   idsInInputListThatFetch=ret1.retn();
7737 }
7738
7739 /*!
7740  * Returns a new DataArrayInt whose contents is computed from that of \a this and \a
7741  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
7742  * "index" array of a "iota" array, thus, whose each element gives an index of a group
7743  * beginning within the "iota" array. And \a this is a one-dimensional array
7744  * considered as a selector of groups described by \a offsets to include into the result array.
7745  *  \throw If \a offsets is NULL.
7746  *  \throw If \a offsets is not allocated.
7747  *  \throw If \a offsets->getNumberOfComponents() != 1.
7748  *  \throw If \a offsets is not monotonically increasing.
7749  *  \throw If \a this is not allocated.
7750  *  \throw If \a this->getNumberOfComponents() != 1.
7751  *  \throw If any element of \a this is not a valid index for \a offsets array.
7752  *
7753  *  \b Example: <br>
7754  *          - \a this: [0,2,3]
7755  *          - \a offsets: [0,3,6,10,14,20]
7756  *          - result array: [0,1,2,6,7,8,9,10,11,12,13] == <br>
7757  *            \c range(0,3) + \c range(6,10) + \c range(10,14) ==<br>
7758  *            \c range( \a offsets[ \a this[0] ], offsets[ \a this[0]+1 ]) + 
7759  *            \c range( \a offsets[ \a this[1] ], offsets[ \a this[1]+1 ]) + 
7760  *            \c range( \a offsets[ \a this[2] ], offsets[ \a this[2]+1 ])
7761  */
7762 DataArrayInt *DataArrayInt::buildExplicitArrByRanges(const DataArrayInt *offsets) const
7763 {
7764   if(!offsets)
7765     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : DataArrayInt pointer in input is NULL !");
7766   checkAllocated();
7767   if(getNumberOfComponents()!=1)
7768     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : only single component allowed !");
7769   offsets->checkAllocated();
7770   if(offsets->getNumberOfComponents()!=1)
7771     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : input array should have only single component !");
7772   int othNbTuples=offsets->getNumberOfTuples()-1;
7773   int nbOfTuples=getNumberOfTuples();
7774   int retNbOftuples=0;
7775   const int *work=getConstPointer();
7776   const int *offPtr=offsets->getConstPointer();
7777   for(int i=0;i<nbOfTuples;i++)
7778     {
7779       int val=work[i];
7780       if(val>=0 && val<othNbTuples)
7781         {
7782           int delta=offPtr[val+1]-offPtr[val];
7783           if(delta>=0)
7784             retNbOftuples+=delta;
7785           else
7786             {
7787               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << val << " of offset array has a delta < 0 !";
7788               throw INTERP_KERNEL::Exception(oss.str().c_str());
7789             }
7790         }
7791       else
7792         {
7793           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << i << " in this contains " << val;
7794           oss << " whereas offsets array is of size " << othNbTuples+1 << " !";
7795           throw INTERP_KERNEL::Exception(oss.str().c_str());
7796         }
7797     }
7798   MCAuto<DataArrayInt> ret=DataArrayInt::New();
7799   ret->alloc(retNbOftuples,1);
7800   int *retPtr=ret->getPointer();
7801   for(int i=0;i<nbOfTuples;i++)
7802     {
7803       int val=work[i];
7804       int start=offPtr[val];
7805       int off=offPtr[val+1]-start;
7806       for(int j=0;j<off;j++,retPtr++)
7807         *retPtr=start+j;
7808     }
7809   return ret.retn();
7810 }
7811
7812 /*!
7813  * Returns a new DataArrayInt whose contents is computed using \a this that must be a 
7814  * scaled array (monotonically increasing).
7815 from that of \a this and \a
7816  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
7817  * "index" array of a "iota" array, thus, whose each element gives an index of a group
7818  * beginning within the "iota" array. And \a this is a one-dimensional array
7819  * considered as a selector of groups described by \a offsets to include into the result array.
7820  *  \throw If \a  is NULL.
7821  *  \throw If \a this is not allocated.
7822  *  \throw If \a this->getNumberOfComponents() != 1.
7823  *  \throw If \a this->getNumberOfTuples() == 0.
7824  *  \throw If \a this is not monotonically increasing.
7825  *  \throw If any element of ids in ( \a bg \a stop \a step ) points outside the scale in \a this.
7826  *
7827  *  \b Example: <br>
7828  *          - \a bg , \a stop and \a step : (0,5,2)
7829  *          - \a this: [0,3,6,10,14,20]
7830  *          - result array: [0,0,0, 2,2,2,2, 4,4,4,4,4,4] == <br>
7831  */
7832 DataArrayInt *DataArrayInt::buildExplicitArrOfSliceOnScaledArr(int bg, int stop, int step) const
7833 {
7834   if(!isAllocated())
7835     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : not allocated array !");
7836   if(getNumberOfComponents()!=1)
7837     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of components is expected to be equal to one !");
7838   int nbOfTuples(getNumberOfTuples());
7839   if(nbOfTuples==0)
7840     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of tuples must be != 0 !");
7841   const int *ids(begin());
7842   int nbOfEltsInSlc(GetNumberOfItemGivenBESRelative(bg,stop,step,"DataArrayInt::buildExplicitArrOfSliceOnScaledArr")),sz(0),pos(bg);
7843   for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
7844     {
7845       if(pos>=0 && pos<nbOfTuples-1)
7846         {
7847           int delta(ids[pos+1]-ids[pos]);
7848           sz+=delta;
7849           if(delta<0)
7850             {
7851               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " and at this pos this is not monotonically increasing !";
7852               throw INTERP_KERNEL::Exception(oss.str().c_str());
7853             }          
7854         }
7855       else
7856         {
7857           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " should be in [0," << nbOfTuples-1 << ") !";  
7858           throw INTERP_KERNEL::Exception(oss.str().c_str());
7859         }
7860     }
7861   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
7862   int *retPtr(ret->getPointer());
7863   pos=bg;
7864   for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
7865     {
7866       int delta(ids[pos+1]-ids[pos]);
7867       for(int j=0;j<delta;j++,retPtr++)
7868         *retPtr=pos;
7869     }
7870   return ret.retn();
7871 }
7872
7873 /*!
7874  * 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.
7875  * 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
7876  * in tuple **i** of returned DataArrayInt.
7877  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the first range.
7878  *
7879  * 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)]
7880  * The return DataArrayInt will contain : **[0,4,1,2,2,3]**
7881  * 
7882  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
7883  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
7884  * \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
7885  *        is thrown if no ranges in \a ranges contains value in \a this.
7886  * 
7887  * \sa DataArrayInt::findIdInRangeForEachTuple
7888  */
7889 DataArrayInt *DataArrayInt::findRangeIdForEachTuple(const DataArrayInt *ranges) const
7890 {
7891   if(!ranges)
7892     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : null input pointer !");
7893   if(ranges->getNumberOfComponents()!=2)
7894     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : input DataArrayInt instance should have 2 components !");
7895   checkAllocated();
7896   if(getNumberOfComponents()!=1)
7897     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : this should have only one component !");
7898   int nbTuples=getNumberOfTuples();
7899   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
7900   int nbOfRanges=ranges->getNumberOfTuples();
7901   const int *rangesPtr=ranges->getConstPointer();
7902   int *retPtr=ret->getPointer();
7903   const int *inPtr=getConstPointer();
7904   for(int i=0;i<nbTuples;i++,retPtr++)
7905     {
7906       int val=inPtr[i];
7907       bool found=false;
7908       for(int j=0;j<nbOfRanges && !found;j++)
7909         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
7910           { *retPtr=j; found=true; }
7911       if(found)
7912         continue;
7913       else
7914         {
7915           std::ostringstream oss; oss << "DataArrayInt::findRangeIdForEachTuple : tuple #" << i << " not found by any ranges !";
7916           throw INTERP_KERNEL::Exception(oss.str().c_str());
7917         }
7918     }
7919   return ret.retn();
7920 }
7921
7922 /*!
7923  * 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.
7924  * 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
7925  * in tuple **i** of returned DataArrayInt.
7926  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the sub position of the first range.
7927  *
7928  * 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)]
7929  * The return DataArrayInt will contain : **[1,2,4,0,2,2]**
7930  * This method is often called in pair with DataArrayInt::findRangeIdForEachTuple method.
7931  * 
7932  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
7933  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
7934  * \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
7935  *        is thrown if no ranges in \a ranges contains value in \a this.
7936  * \sa DataArrayInt::findRangeIdForEachTuple
7937  */
7938 DataArrayInt *DataArrayInt::findIdInRangeForEachTuple(const DataArrayInt *ranges) const
7939 {
7940   if(!ranges)
7941     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : null input pointer !");
7942   if(ranges->getNumberOfComponents()!=2)
7943     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : input DataArrayInt instance should have 2 components !");
7944   checkAllocated();
7945   if(getNumberOfComponents()!=1)
7946     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : this should have only one component !");
7947   int nbTuples=getNumberOfTuples();
7948   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
7949   int nbOfRanges=ranges->getNumberOfTuples();
7950   const int *rangesPtr=ranges->getConstPointer();
7951   int *retPtr=ret->getPointer();
7952   const int *inPtr=getConstPointer();
7953   for(int i=0;i<nbTuples;i++,retPtr++)
7954     {
7955       int val=inPtr[i];
7956       bool found=false;
7957       for(int j=0;j<nbOfRanges && !found;j++)
7958         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
7959           { *retPtr=val-rangesPtr[2*j]; found=true; }
7960       if(found)
7961         continue;
7962       else
7963         {
7964           std::ostringstream oss; oss << "DataArrayInt::findIdInRangeForEachTuple : tuple #" << i << " not found by any ranges !";
7965           throw INTERP_KERNEL::Exception(oss.str().c_str());
7966         }
7967     }
7968   return ret.retn();
7969 }
7970
7971 /*!
7972  * \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).
7973  * 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).
7974  * 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 !
7975  * If this method has correctly worked, \a this will be able to be considered as a linked list.
7976  * This method does nothing if number of tuples is lower of equal to 1.
7977  *
7978  * This method is useful for users having an unstructured mesh having only SEG2 to rearrange internaly the connectibity without any coordinates consideration.
7979  *
7980  * \sa MEDCouplingUMesh::orderConsecutiveCells1D, DataArrayInt::fromLinkedListOfPairToList
7981  */
7982 void DataArrayInt::sortEachPairToMakeALinkedList()
7983 {
7984   checkAllocated();
7985   if(getNumberOfComponents()!=2)
7986     throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : Only works on DataArrayInt instance with nb of components equal to 2 !");
7987   int nbOfTuples(getNumberOfTuples());
7988   if(nbOfTuples<=1)
7989     return ;
7990   int *conn(getPointer());
7991   for(int i=1;i<nbOfTuples;i++,conn+=2)
7992     {
7993       if(i>1)
7994         {
7995           if(conn[2]==conn[3])
7996             {
7997               std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " presence of a pair filled with same ids !";
7998               throw INTERP_KERNEL::Exception(oss.str().c_str());
7999             }
8000           if(conn[2]!=conn[1] && conn[3]==conn[1] && conn[2]!=conn[0])
8001             std::swap(conn[2],conn[3]);
8002           //not(conn[2]==conn[1] && conn[3]!=conn[1] && conn[3]!=conn[0])
8003           if(conn[2]!=conn[1] || conn[3]==conn[1] || conn[3]==conn[0])
8004             {
8005               std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " something is invalid !";
8006               throw INTERP_KERNEL::Exception(oss.str().c_str());
8007             }
8008         }
8009       else
8010         {
8011           if(conn[0]==conn[1] || conn[2]==conn[3])
8012             throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : In the 2 first tuples presence of a pair filled with same ids !");
8013           int tmp[4];
8014           std::set<int> s;
8015           s.insert(conn,conn+4);
8016           if(s.size()!=3)
8017             throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : This can't be considered as a linked list regarding 2 first tuples !");
8018           if(std::count(conn,conn+4,conn[0])==2)
8019             {
8020               tmp[0]=conn[1];
8021               tmp[1]=conn[0];
8022               tmp[2]=conn[0];
8023               if(conn[2]==conn[0])
8024                 { tmp[3]=conn[3]; }
8025               else
8026                 { tmp[3]=conn[2];}
8027               std::copy(tmp,tmp+4,conn);
8028             }
8029           else
8030             {//here we are sure to have (std::count(conn,conn+4,conn[1])==2)
8031               if(conn[1]==conn[3])
8032                 std::swap(conn[2],conn[3]);
8033             }
8034         }
8035     }
8036 }
8037
8038 /*!
8039  * \a this is expected to be a correctly linked list of pairs.
8040  * 
8041  * \sa DataArrayInt::sortEachPairToMakeALinkedList
8042  */
8043 MCAuto<DataArrayInt> DataArrayInt::fromLinkedListOfPairToList() const
8044 {
8045   checkAllocated();
8046   checkNbOfComps(2,"DataArrayInt::fromLinkedListOfPairToList : this is expected to have 2 components");
8047   int nbTuples(getNumberOfTuples());
8048   if(nbTuples<1)
8049     throw INTERP_KERNEL::Exception("DataArrayInt::fromLinkedListOfPairToList : no tuples in this ! Not a linked list !");
8050   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbTuples+1,1);
8051   const int *thisPtr(begin());
8052   int *retPtr(ret->getPointer());
8053   retPtr[0]=thisPtr[0];
8054   for(int i=0;i<nbTuples;i++)
8055     {
8056       retPtr[i+1]=thisPtr[2*i+1];
8057       if(i<nbTuples-1)
8058         if(thisPtr[2*i+1]!=thisPtr[2*(i+1)+0])
8059           {
8060             std::ostringstream oss; oss << "DataArrayInt::fromLinkedListOfPairToList : this is not a proper linked list of pair. The link is broken between tuple #" << i << " and tuple #" << i+1 << " ! Call sortEachPairToMakeALinkedList ?";
8061             throw INTERP_KERNEL::Exception(oss.str());
8062           }
8063     }
8064   return ret;
8065 }
8066
8067 /*!
8068  * 
8069  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayInt instance.
8070  *             \a nbTimes  should be at least equal to 1.
8071  * \return a newly allocated DataArrayInt having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
8072  * \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.
8073  */
8074 DataArrayInt *DataArrayInt::duplicateEachTupleNTimes(int nbTimes) const
8075 {
8076   checkAllocated();
8077   if(getNumberOfComponents()!=1)
8078     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : this should have only one component !");
8079   if(nbTimes<1)
8080     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : nb times should be >= 1 !");
8081   int nbTuples=getNumberOfTuples();
8082   const int *inPtr=getConstPointer();
8083   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTimes*nbTuples,1);
8084   int *retPtr=ret->getPointer();
8085   for(int i=0;i<nbTuples;i++,inPtr++)
8086     {
8087       int val=*inPtr;
8088       for(int j=0;j<nbTimes;j++,retPtr++)
8089         *retPtr=val;
8090     }
8091   ret->copyStringInfoFrom(*this);
8092   return ret.retn();
8093 }
8094
8095 /*!
8096  * This method returns all different values found in \a this. This method throws if \a this has not been allocated.
8097  * But the number of components can be different from one.
8098  * \return a newly allocated array (that should be dealt by the caller) containing different values in \a this.
8099  */
8100 DataArrayInt *DataArrayInt::getDifferentValues() const
8101 {
8102   checkAllocated();
8103   std::set<int> ret;
8104   ret.insert(begin(),end());
8105   MCAuto<DataArrayInt> ret2=DataArrayInt::New(); ret2->alloc((int)ret.size(),1);
8106   std::copy(ret.begin(),ret.end(),ret2->getPointer());
8107   return ret2.retn();
8108 }
8109
8110 /*!
8111  * This method is a refinement of DataArrayInt::getDifferentValues because it returns not only different values in \a this but also, for each of
8112  * them it tells which tuple id have this id.
8113  * This method works only on arrays with one component (if it is not the case call DataArrayInt::rearrange(1) ).
8114  * This method returns two arrays having same size.
8115  * 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.
8116  * 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]]
8117  */
8118 std::vector<DataArrayInt *> DataArrayInt::partitionByDifferentValues(std::vector<int>& differentIds) const
8119 {
8120   checkAllocated();
8121   if(getNumberOfComponents()!=1)
8122     throw INTERP_KERNEL::Exception("DataArrayInt::partitionByDifferentValues : this should have only one component !");
8123   int id=0;
8124   std::map<int,int> m,m2,m3;
8125   for(const int *w=begin();w!=end();w++)
8126     m[*w]++;
8127   differentIds.resize(m.size());
8128   std::vector<DataArrayInt *> ret(m.size());
8129   std::vector<int *> retPtr(m.size());
8130   for(std::map<int,int>::const_iterator it=m.begin();it!=m.end();it++,id++)
8131     {
8132       m2[(*it).first]=id;
8133       ret[id]=DataArrayInt::New();
8134       ret[id]->alloc((*it).second,1);
8135       retPtr[id]=ret[id]->getPointer();
8136       differentIds[id]=(*it).first;
8137     }
8138   id=0;
8139   for(const int *w=begin();w!=end();w++,id++)
8140     {
8141       retPtr[m2[*w]][m3[*w]++]=id;
8142     }
8143   return ret;
8144 }
8145
8146 /*!
8147  * This method split ids in [0, \c this->getNumberOfTuples() ) using \a this array as a field of weight (>=0 each).
8148  * The aim of this method is to return a set of \a nbOfSlices chunk of contiguous ids as balanced as possible.
8149  *
8150  * \param [in] nbOfSlices - number of slices expected.
8151  * \return - a vector having a size equal to \a nbOfSlices giving the start (included) and the stop (excluded) of each chunks.
8152  * 
8153  * \sa DataArray::GetSlice
8154  * \throw If \a this is not allocated or not with exactly one component.
8155  * \throw If an element in \a this if < 0.
8156  */
8157 std::vector< std::pair<int,int> > DataArrayInt::splitInBalancedSlices(int nbOfSlices) const
8158 {
8159   if(!isAllocated() || getNumberOfComponents()!=1)
8160     throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : this array should have number of components equal to one and must be allocated !");
8161   if(nbOfSlices<=0)
8162     throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : number of slices must be >= 1 !");
8163   int sum(accumulate(0)),nbOfTuples(getNumberOfTuples());
8164   int sumPerSlc(sum/nbOfSlices),pos(0);
8165   const int *w(begin());
8166   std::vector< std::pair<int,int> > ret(nbOfSlices);
8167   for(int i=0;i<nbOfSlices;i++)
8168     {
8169       std::pair<int,int> p(pos,-1);
8170       int locSum(0);
8171       while(locSum<sumPerSlc && pos<nbOfTuples) { pos++; locSum+=*w++; }
8172       if(i!=nbOfSlices-1)
8173         p.second=pos;
8174       else
8175         p.second=nbOfTuples;
8176       ret[i]=p;
8177     }
8178   return ret;
8179 }
8180
8181 /*!
8182  * Returns a new DataArrayInt that is a sum of two given arrays. There are 3
8183  * valid cases.
8184  * 1.  The arrays have same number of tuples and components. Then each value of
8185  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
8186  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
8187  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
8188  *   component. Then
8189  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
8190  * 3.  The arrays have same number of components and one array, say _a2_, has one
8191  *   tuple. Then
8192  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
8193  *
8194  * Info on components is copied either from the first array (in the first case) or from
8195  * the array with maximal number of elements (getNbOfElems()).
8196  *  \param [in] a1 - an array to sum up.
8197  *  \param [in] a2 - another array to sum up.
8198  *  \return DataArrayInt * - the new instance of DataArrayInt.
8199  *          The caller is to delete this result array using decrRef() as it is no more
8200  *          needed.
8201  *  \throw If either \a a1 or \a a2 is NULL.
8202  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
8203  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
8204  *         none of them has number of tuples or components equal to 1.
8205  */
8206 DataArrayInt *DataArrayInt::Add(const DataArrayInt *a1, const DataArrayInt *a2)
8207 {
8208   if(!a1 || !a2)
8209     throw INTERP_KERNEL::Exception("DataArrayInt::Add : input DataArrayInt instance is NULL !");
8210   int nbOfTuple=a1->getNumberOfTuples();
8211   int nbOfTuple2=a2->getNumberOfTuples();
8212   int nbOfComp=a1->getNumberOfComponents();
8213   int nbOfComp2=a2->getNumberOfComponents();
8214   MCAuto<DataArrayInt> ret=0;
8215   if(nbOfTuple==nbOfTuple2)
8216     {
8217       if(nbOfComp==nbOfComp2)
8218         {
8219           ret=DataArrayInt::New();
8220           ret->alloc(nbOfTuple,nbOfComp);
8221           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<int>());
8222           ret->copyStringInfoFrom(*a1);
8223         }
8224       else
8225         {
8226           int nbOfCompMin,nbOfCompMax;
8227           const DataArrayInt *aMin, *aMax;
8228           if(nbOfComp>nbOfComp2)
8229             {
8230               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
8231               aMin=a2; aMax=a1;
8232             }
8233           else
8234             {
8235               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
8236               aMin=a1; aMax=a2;
8237             }
8238           if(nbOfCompMin==1)
8239             {
8240               ret=DataArrayInt::New();
8241               ret->alloc(nbOfTuple,nbOfCompMax);
8242               const int *aMinPtr=aMin->getConstPointer();
8243               const int *aMaxPtr=aMax->getConstPointer();
8244               int *res=ret->getPointer();
8245               for(int i=0;i<nbOfTuple;i++)
8246                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<int>(),aMinPtr[i]));
8247               ret->copyStringInfoFrom(*aMax);
8248             }
8249           else
8250             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
8251         }
8252     }
8253   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
8254     {
8255       if(nbOfComp==nbOfComp2)
8256         {
8257           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
8258           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
8259           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
8260           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
8261           ret=DataArrayInt::New();
8262           ret->alloc(nbOfTupleMax,nbOfComp);
8263           int *res=ret->getPointer();
8264           for(int i=0;i<nbOfTupleMax;i++)
8265             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<int>());
8266           ret->copyStringInfoFrom(*aMax);
8267         }
8268       else
8269         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
8270     }
8271   else
8272     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
8273   return ret.retn();
8274 }
8275
8276 /*!
8277  * Adds values of another DataArrayInt to values of \a this one. There are 3
8278  * valid cases.
8279  * 1.  The arrays have same number of tuples and components. Then each value of
8280  *   \a other array is added to the corresponding value of \a this array, i.e.:
8281  *   _a_ [ i, j ] += _other_ [ i, j ].
8282  * 2.  The arrays have same number of tuples and \a other array has one component. Then
8283  *   _a_ [ i, j ] += _other_ [ i, 0 ].
8284  * 3.  The arrays have same number of components and \a other array has one tuple. Then
8285  *   _a_ [ i, j ] += _a2_ [ 0, j ].
8286  *
8287  *  \param [in] other - an array to add to \a this one.
8288  *  \throw If \a other is NULL.
8289  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
8290  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
8291  *         \a other has number of both tuples and components not equal to 1.
8292  */
8293 void DataArrayInt::addEqual(const DataArrayInt *other)
8294 {
8295   if(!other)
8296     throw INTERP_KERNEL::Exception("DataArrayInt::addEqual : input DataArrayInt instance is NULL !");
8297   const char *msg="Nb of tuples mismatch for DataArrayInt::addEqual  !";
8298   checkAllocated(); other->checkAllocated();
8299   int nbOfTuple=getNumberOfTuples();
8300   int nbOfTuple2=other->getNumberOfTuples();
8301   int nbOfComp=getNumberOfComponents();
8302   int nbOfComp2=other->getNumberOfComponents();
8303   if(nbOfTuple==nbOfTuple2)
8304     {
8305       if(nbOfComp==nbOfComp2)
8306         {
8307           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<int>());
8308         }
8309       else if(nbOfComp2==1)
8310         {
8311           int *ptr=getPointer();
8312           const int *ptrc=other->getConstPointer();
8313           for(int i=0;i<nbOfTuple;i++)
8314             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<int>(),*ptrc++));
8315         }
8316       else
8317         throw INTERP_KERNEL::Exception(msg);
8318     }
8319   else if(nbOfTuple2==1)
8320     {
8321       if(nbOfComp2==nbOfComp)
8322         {
8323           int *ptr=getPointer();
8324           const int *ptrc=other->getConstPointer();
8325           for(int i=0;i<nbOfTuple;i++)
8326             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<int>());
8327         }
8328       else
8329         throw INTERP_KERNEL::Exception(msg);
8330     }
8331   else
8332     throw INTERP_KERNEL::Exception(msg);
8333   declareAsNew();
8334 }
8335
8336 /*!
8337  * Returns a new DataArrayInt that is a subtraction of two given arrays. There are 3
8338  * valid cases.
8339  * 1.  The arrays have same number of tuples and components. Then each value of
8340  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
8341  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
8342  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
8343  *   component. Then
8344  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
8345  * 3.  The arrays have same number of components and one array, say _a2_, has one
8346  *   tuple. Then
8347  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
8348  *
8349  * Info on components is copied either from the first array (in the first case) or from
8350  * the array with maximal number of elements (getNbOfElems()).
8351  *  \param [in] a1 - an array to subtract from.
8352  *  \param [in] a2 - an array to subtract.
8353  *  \return DataArrayInt * - the new instance of DataArrayInt.
8354  *          The caller is to delete this result array using decrRef() as it is no more
8355  *          needed.
8356  *  \throw If either \a a1 or \a a2 is NULL.
8357  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
8358  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
8359  *         none of them has number of tuples or components equal to 1.
8360  */
8361 DataArrayInt *DataArrayInt::Substract(const DataArrayInt *a1, const DataArrayInt *a2)
8362 {
8363   if(!a1 || !a2)
8364     throw INTERP_KERNEL::Exception("DataArrayInt::Substract : input DataArrayInt instance is NULL !");
8365   int nbOfTuple1=a1->getNumberOfTuples();
8366   int nbOfTuple2=a2->getNumberOfTuples();
8367   int nbOfComp1=a1->getNumberOfComponents();
8368   int nbOfComp2=a2->getNumberOfComponents();
8369   if(nbOfTuple2==nbOfTuple1)
8370     {
8371       if(nbOfComp1==nbOfComp2)
8372         {
8373           MCAuto<DataArrayInt> ret=DataArrayInt::New();
8374           ret->alloc(nbOfTuple2,nbOfComp1);
8375           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<int>());
8376           ret->copyStringInfoFrom(*a1);
8377           return ret.retn();
8378         }
8379       else if(nbOfComp2==1)
8380         {
8381           MCAuto<DataArrayInt> ret=DataArrayInt::New();
8382           ret->alloc(nbOfTuple1,nbOfComp1);
8383           const int *a2Ptr=a2->getConstPointer();
8384           const int *a1Ptr=a1->getConstPointer();
8385           int *res=ret->getPointer();
8386           for(int i=0;i<nbOfTuple1;i++)
8387             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<int>(),a2Ptr[i]));
8388           ret->copyStringInfoFrom(*a1);
8389           return ret.retn();
8390         }
8391       else
8392         {
8393           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
8394           return 0;
8395         }
8396     }
8397   else if(nbOfTuple2==1)
8398     {
8399       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
8400       MCAuto<DataArrayInt> ret=DataArrayInt::New();
8401       ret->alloc(nbOfTuple1,nbOfComp1);
8402       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
8403       int *pt=ret->getPointer();
8404       for(int i=0;i<nbOfTuple1;i++)
8405         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<int>());
8406       ret->copyStringInfoFrom(*a1);
8407       return ret.retn();
8408     }
8409   else
8410     {
8411       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
8412       return 0;
8413     }
8414 }
8415
8416 /*!
8417  * Subtract values of another DataArrayInt from values of \a this one. There are 3
8418  * valid cases.
8419  * 1.  The arrays have same number of tuples and components. Then each value of
8420  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
8421  *   _a_ [ i, j ] -= _other_ [ i, j ].
8422  * 2.  The arrays have same number of tuples and \a other array has one component. Then
8423  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
8424  * 3.  The arrays have same number of components and \a other array has one tuple. Then
8425  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
8426  *
8427  *  \param [in] other - an array to subtract from \a this one.
8428  *  \throw If \a other is NULL.
8429  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
8430  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
8431  *         \a other has number of both tuples and components not equal to 1.
8432  */
8433 void DataArrayInt::substractEqual(const DataArrayInt *other)
8434 {
8435   if(!other)
8436     throw INTERP_KERNEL::Exception("DataArrayInt::substractEqual : input DataArrayInt instance is NULL !");
8437   const char *msg="Nb of tuples mismatch for DataArrayInt::substractEqual  !";
8438   checkAllocated(); other->checkAllocated();
8439   int nbOfTuple=getNumberOfTuples();
8440   int nbOfTuple2=other->getNumberOfTuples();
8441   int nbOfComp=getNumberOfComponents();
8442   int nbOfComp2=other->getNumberOfComponents();
8443   if(nbOfTuple==nbOfTuple2)
8444     {
8445       if(nbOfComp==nbOfComp2)
8446         {
8447           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<int>());
8448         }
8449       else if(nbOfComp2==1)
8450         {
8451           int *ptr=getPointer();
8452           const int *ptrc=other->getConstPointer();
8453           for(int i=0;i<nbOfTuple;i++)
8454             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<int>(),*ptrc++));
8455         }
8456       else
8457         throw INTERP_KERNEL::Exception(msg);
8458     }
8459   else if(nbOfTuple2==1)
8460     {
8461       int *ptr=getPointer();
8462       const int *ptrc=other->getConstPointer();
8463       for(int i=0;i<nbOfTuple;i++)
8464         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<int>());
8465     }
8466   else
8467     throw INTERP_KERNEL::Exception(msg);
8468   declareAsNew();
8469 }
8470
8471 /*!
8472  * Returns a new DataArrayInt that is a product of two given arrays. There are 3
8473  * valid cases.
8474  * 1.  The arrays have same number of tuples and components. Then each value of
8475  *   the result array (_a_) is a product of the corresponding values of \a a1 and
8476  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
8477  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
8478  *   component. Then
8479  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
8480  * 3.  The arrays have same number of components and one array, say _a2_, has one
8481  *   tuple. Then
8482  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
8483  *
8484  * Info on components is copied either from the first array (in the first case) or from
8485  * the array with maximal number of elements (getNbOfElems()).
8486  *  \param [in] a1 - a factor array.
8487  *  \param [in] a2 - another factor array.
8488  *  \return DataArrayInt * - the new instance of DataArrayInt.
8489  *          The caller is to delete this result array using decrRef() as it is no more
8490  *          needed.
8491  *  \throw If either \a a1 or \a a2 is NULL.
8492  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
8493  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
8494  *         none of them has number of tuples or components equal to 1.
8495  */
8496 DataArrayInt *DataArrayInt::Multiply(const DataArrayInt *a1, const DataArrayInt *a2)
8497 {
8498   if(!a1 || !a2)
8499     throw INTERP_KERNEL::Exception("DataArrayInt::Multiply : input DataArrayInt instance is NULL !");
8500   int nbOfTuple=a1->getNumberOfTuples();
8501   int nbOfTuple2=a2->getNumberOfTuples();
8502   int nbOfComp=a1->getNumberOfComponents();
8503   int nbOfComp2=a2->getNumberOfComponents();
8504   MCAuto<DataArrayInt> ret=0;
8505   if(nbOfTuple==nbOfTuple2)
8506     {
8507       if(nbOfComp==nbOfComp2)
8508         {
8509           ret=DataArrayInt::New();
8510           ret->alloc(nbOfTuple,nbOfComp);
8511           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<int>());
8512           ret->copyStringInfoFrom(*a1);
8513         }
8514       else
8515         {
8516           int nbOfCompMin,nbOfCompMax;
8517           const DataArrayInt *aMin, *aMax;
8518           if(nbOfComp>nbOfComp2)
8519             {
8520               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
8521               aMin=a2; aMax=a1;
8522             }
8523           else
8524             {
8525               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
8526               aMin=a1; aMax=a2;
8527             }
8528           if(nbOfCompMin==1)
8529             {
8530               ret=DataArrayInt::New();
8531               ret->alloc(nbOfTuple,nbOfCompMax);
8532               const int *aMinPtr=aMin->getConstPointer();
8533               const int *aMaxPtr=aMax->getConstPointer();
8534               int *res=ret->getPointer();
8535               for(int i=0;i<nbOfTuple;i++)
8536                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<int>(),aMinPtr[i]));
8537               ret->copyStringInfoFrom(*aMax);
8538             }
8539           else
8540             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
8541         }
8542     }
8543   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
8544     {
8545       if(nbOfComp==nbOfComp2)
8546         {
8547           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
8548           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
8549           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
8550           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
8551           ret=DataArrayInt::New();
8552           ret->alloc(nbOfTupleMax,nbOfComp);
8553           int *res=ret->getPointer();
8554           for(int i=0;i<nbOfTupleMax;i++)
8555             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<int>());
8556           ret->copyStringInfoFrom(*aMax);
8557         }
8558       else
8559         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
8560     }
8561   else
8562     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
8563   return ret.retn();
8564 }
8565
8566
8567 /*!
8568  * Multiply values of another DataArrayInt to values of \a this one. There are 3
8569  * valid cases.
8570  * 1.  The arrays have same number of tuples and components. Then each value of
8571  *   \a other array is multiplied to the corresponding value of \a this array, i.e.:
8572  *   _a_ [ i, j ] *= _other_ [ i, j ].
8573  * 2.  The arrays have same number of tuples and \a other array has one component. Then
8574  *   _a_ [ i, j ] *= _other_ [ i, 0 ].
8575  * 3.  The arrays have same number of components and \a other array has one tuple. Then
8576  *   _a_ [ i, j ] *= _a2_ [ 0, j ].
8577  *
8578  *  \param [in] other - an array to multiply to \a this one.
8579  *  \throw If \a other is NULL.
8580  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
8581  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
8582  *         \a other has number of both tuples and components not equal to 1.
8583  */
8584 void DataArrayInt::multiplyEqual(const DataArrayInt *other)
8585 {
8586   if(!other)
8587     throw INTERP_KERNEL::Exception("DataArrayInt::multiplyEqual : input DataArrayInt instance is NULL !");
8588   const char *msg="Nb of tuples mismatch for DataArrayInt::multiplyEqual !";
8589   checkAllocated(); other->checkAllocated();
8590   int nbOfTuple=getNumberOfTuples();
8591   int nbOfTuple2=other->getNumberOfTuples();
8592   int nbOfComp=getNumberOfComponents();
8593   int nbOfComp2=other->getNumberOfComponents();
8594   if(nbOfTuple==nbOfTuple2)
8595     {
8596       if(nbOfComp==nbOfComp2)
8597         {
8598           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<int>());
8599         }
8600       else if(nbOfComp2==1)
8601         {
8602           int *ptr=getPointer();
8603           const int *ptrc=other->getConstPointer();
8604           for(int i=0;i<nbOfTuple;i++)
8605             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<int>(),*ptrc++));    
8606         }
8607       else
8608         throw INTERP_KERNEL::Exception(msg);
8609     }
8610   else if(nbOfTuple2==1)
8611     {
8612       if(nbOfComp2==nbOfComp)
8613         {
8614           int *ptr=getPointer();
8615           const int *ptrc=other->getConstPointer();
8616           for(int i=0;i<nbOfTuple;i++)
8617             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<int>());
8618         }
8619       else
8620         throw INTERP_KERNEL::Exception(msg);
8621     }
8622   else
8623     throw INTERP_KERNEL::Exception(msg);
8624   declareAsNew();
8625 }
8626
8627
8628 /*!
8629  * Returns a new DataArrayInt that is a division of two given arrays. There are 3
8630  * valid cases.
8631  * 1.  The arrays have same number of tuples and components. Then each value of
8632  *   the result array (_a_) is a division of the corresponding values of \a a1 and
8633  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
8634  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
8635  *   component. Then
8636  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
8637  * 3.  The arrays have same number of components and one array, say _a2_, has one
8638  *   tuple. Then
8639  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
8640  *
8641  * Info on components is copied either from the first array (in the first case) or from
8642  * the array with maximal number of elements (getNbOfElems()).
8643  *  \warning No check of division by zero is performed!
8644  *  \param [in] a1 - a numerator array.
8645  *  \param [in] a2 - a denominator array.
8646  *  \return DataArrayInt * - the new instance of DataArrayInt.
8647  *          The caller is to delete this result array using decrRef() as it is no more
8648  *          needed.
8649  *  \throw If either \a a1 or \a a2 is NULL.
8650  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
8651  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
8652  *         none of them has number of tuples or components equal to 1.
8653  */
8654 DataArrayInt *DataArrayInt::Divide(const DataArrayInt *a1, const DataArrayInt *a2)
8655 {
8656   if(!a1 || !a2)
8657     throw INTERP_KERNEL::Exception("DataArrayInt::Divide : input DataArrayInt instance is NULL !");
8658   int nbOfTuple1=a1->getNumberOfTuples();
8659   int nbOfTuple2=a2->getNumberOfTuples();
8660   int nbOfComp1=a1->getNumberOfComponents();
8661   int nbOfComp2=a2->getNumberOfComponents();
8662   if(nbOfTuple2==nbOfTuple1)
8663     {
8664       if(nbOfComp1==nbOfComp2)
8665         {
8666           MCAuto<DataArrayInt> ret=DataArrayInt::New();
8667           ret->alloc(nbOfTuple2,nbOfComp1);
8668           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<int>());
8669           ret->copyStringInfoFrom(*a1);
8670           return ret.retn();
8671         }
8672       else if(nbOfComp2==1)
8673         {
8674           MCAuto<DataArrayInt> ret=DataArrayInt::New();
8675           ret->alloc(nbOfTuple1,nbOfComp1);
8676           const int *a2Ptr=a2->getConstPointer();
8677           const int *a1Ptr=a1->getConstPointer();
8678           int *res=ret->getPointer();
8679           for(int i=0;i<nbOfTuple1;i++)
8680             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<int>(),a2Ptr[i]));
8681           ret->copyStringInfoFrom(*a1);
8682           return ret.retn();
8683         }
8684       else
8685         {
8686           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
8687           return 0;
8688         }
8689     }
8690   else if(nbOfTuple2==1)
8691     {
8692       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
8693       MCAuto<DataArrayInt> ret=DataArrayInt::New();
8694       ret->alloc(nbOfTuple1,nbOfComp1);
8695       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
8696       int *pt=ret->getPointer();
8697       for(int i=0;i<nbOfTuple1;i++)
8698         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<int>());
8699       ret->copyStringInfoFrom(*a1);
8700       return ret.retn();
8701     }
8702   else
8703     {
8704       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
8705       return 0;
8706     }
8707 }
8708
8709 /*!
8710  * Divide values of \a this array by values of another DataArrayInt. There are 3
8711  * valid cases.
8712  * 1.  The arrays have same number of tuples and components. Then each value of
8713  *    \a this array is divided by the corresponding value of \a other one, i.e.:
8714  *   _a_ [ i, j ] /= _other_ [ i, j ].
8715  * 2.  The arrays have same number of tuples and \a other array has one component. Then
8716  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
8717  * 3.  The arrays have same number of components and \a other array has one tuple. Then
8718  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
8719  *
8720  *  \warning No check of division by zero is performed!
8721  *  \param [in] other - an array to divide \a this one by.
8722  *  \throw If \a other is NULL.
8723  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
8724  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
8725  *         \a other has number of both tuples and components not equal to 1.
8726  */
8727 void DataArrayInt::divideEqual(const DataArrayInt *other)
8728 {
8729   if(!other)
8730     throw INTERP_KERNEL::Exception("DataArrayInt::divideEqual : input DataArrayInt instance is NULL !");
8731   const char *msg="Nb of tuples mismatch for DataArrayInt::divideEqual !";
8732   checkAllocated(); other->checkAllocated();
8733   int nbOfTuple=getNumberOfTuples();
8734   int nbOfTuple2=other->getNumberOfTuples();
8735   int nbOfComp=getNumberOfComponents();
8736   int nbOfComp2=other->getNumberOfComponents();
8737   if(nbOfTuple==nbOfTuple2)
8738     {
8739       if(nbOfComp==nbOfComp2)
8740         {
8741           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<int>());
8742         }
8743       else if(nbOfComp2==1)
8744         {
8745           int *ptr=getPointer();
8746           const int *ptrc=other->getConstPointer();
8747           for(int i=0;i<nbOfTuple;i++)
8748             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<int>(),*ptrc++));
8749         }
8750       else
8751         throw INTERP_KERNEL::Exception(msg);
8752     }
8753   else if(nbOfTuple2==1)
8754     {
8755       if(nbOfComp2==nbOfComp)
8756         {
8757           int *ptr=getPointer();
8758           const int *ptrc=other->getConstPointer();
8759           for(int i=0;i<nbOfTuple;i++)
8760             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<int>());
8761         }
8762       else
8763         throw INTERP_KERNEL::Exception(msg);
8764     }
8765   else
8766     throw INTERP_KERNEL::Exception(msg);
8767   declareAsNew();
8768 }
8769
8770
8771 /*!
8772  * Returns a new DataArrayInt that is a modulus of two given arrays. There are 3
8773  * valid cases.
8774  * 1.  The arrays have same number of tuples and components. Then each value of
8775  *   the result array (_a_) is a division of the corresponding values of \a a1 and
8776  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, j ].
8777  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
8778  *   component. Then
8779  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, 0 ].
8780  * 3.  The arrays have same number of components and one array, say _a2_, has one
8781  *   tuple. Then
8782  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ 0, j ].
8783  *
8784  * Info on components is copied either from the first array (in the first case) or from
8785  * the array with maximal number of elements (getNbOfElems()).
8786  *  \warning No check of division by zero is performed!
8787  *  \param [in] a1 - a dividend array.
8788  *  \param [in] a2 - a divisor array.
8789  *  \return DataArrayInt * - the new instance of DataArrayInt.
8790  *          The caller is to delete this result array using decrRef() as it is no more
8791  *          needed.
8792  *  \throw If either \a a1 or \a a2 is NULL.
8793  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
8794  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
8795  *         none of them has number of tuples or components equal to 1.
8796  */
8797 DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt *a2)
8798 {
8799   if(!a1 || !a2)
8800     throw INTERP_KERNEL::Exception("DataArrayInt::Modulus : input DataArrayInt instance is NULL !");
8801   int nbOfTuple1=a1->getNumberOfTuples();
8802   int nbOfTuple2=a2->getNumberOfTuples();
8803   int nbOfComp1=a1->getNumberOfComponents();
8804   int nbOfComp2=a2->getNumberOfComponents();
8805   if(nbOfTuple2==nbOfTuple1)
8806     {
8807       if(nbOfComp1==nbOfComp2)
8808         {
8809           MCAuto<DataArrayInt> ret=DataArrayInt::New();
8810           ret->alloc(nbOfTuple2,nbOfComp1);
8811           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::modulus<int>());
8812           ret->copyStringInfoFrom(*a1);
8813           return ret.retn();
8814         }
8815       else if(nbOfComp2==1)
8816         {
8817           MCAuto<DataArrayInt> ret=DataArrayInt::New();
8818           ret->alloc(nbOfTuple1,nbOfComp1);
8819           const int *a2Ptr=a2->getConstPointer();
8820           const int *a1Ptr=a1->getConstPointer();
8821           int *res=ret->getPointer();
8822           for(int i=0;i<nbOfTuple1;i++)
8823             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::modulus<int>(),a2Ptr[i]));
8824           ret->copyStringInfoFrom(*a1);
8825           return ret.retn();
8826         }
8827       else
8828         {
8829           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
8830           return 0;
8831         }
8832     }
8833   else if(nbOfTuple2==1)
8834     {
8835       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
8836       MCAuto<DataArrayInt> ret=DataArrayInt::New();
8837       ret->alloc(nbOfTuple1,nbOfComp1);
8838       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
8839       int *pt=ret->getPointer();
8840       for(int i=0;i<nbOfTuple1;i++)
8841         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::modulus<int>());
8842       ret->copyStringInfoFrom(*a1);
8843       return ret.retn();
8844     }
8845   else
8846     {
8847       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Modulus !");//will always throw an exception
8848       return 0;
8849     }
8850 }
8851
8852 /*!
8853  * Modify \a this array so that each value becomes a modulus of division of this value by
8854  * a value of another DataArrayInt. There are 3 valid cases.
8855  * 1.  The arrays have same number of tuples and components. Then each value of
8856  *    \a this array is divided by the corresponding value of \a other one, i.e.:
8857  *   _a_ [ i, j ] %= _other_ [ i, j ].
8858  * 2.  The arrays have same number of tuples and \a other array has one component. Then
8859  *   _a_ [ i, j ] %= _other_ [ i, 0 ].
8860  * 3.  The arrays have same number of components and \a other array has one tuple. Then
8861  *   _a_ [ i, j ] %= _a2_ [ 0, j ].
8862  *
8863  *  \warning No check of division by zero is performed!
8864  *  \param [in] other - a divisor array.
8865  *  \throw If \a other is NULL.
8866  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
8867  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
8868  *         \a other has number of both tuples and components not equal to 1.
8869  */
8870 void DataArrayInt::modulusEqual(const DataArrayInt *other)
8871 {
8872   if(!other)
8873     throw INTERP_KERNEL::Exception("DataArrayInt::modulusEqual : input DataArrayInt instance is NULL !");
8874   const char *msg="Nb of tuples mismatch for DataArrayInt::modulusEqual !";
8875   checkAllocated(); other->checkAllocated();
8876   int nbOfTuple=getNumberOfTuples();
8877   int nbOfTuple2=other->getNumberOfTuples();
8878   int nbOfComp=getNumberOfComponents();
8879   int nbOfComp2=other->getNumberOfComponents();
8880   if(nbOfTuple==nbOfTuple2)
8881     {
8882       if(nbOfComp==nbOfComp2)
8883         {
8884           std::transform(begin(),end(),other->begin(),getPointer(),std::modulus<int>());
8885         }
8886       else if(nbOfComp2==1)
8887         {
8888           if(nbOfComp2==nbOfComp)
8889             {
8890               int *ptr=getPointer();
8891               const int *ptrc=other->getConstPointer();
8892               for(int i=0;i<nbOfTuple;i++)
8893                 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::modulus<int>(),*ptrc++));
8894             }
8895           else
8896             throw INTERP_KERNEL::Exception(msg);
8897         }
8898       else
8899         throw INTERP_KERNEL::Exception(msg);
8900     }
8901   else if(nbOfTuple2==1)
8902     {
8903       int *ptr=getPointer();
8904       const int *ptrc=other->getConstPointer();
8905       for(int i=0;i<nbOfTuple;i++)
8906         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::modulus<int>());
8907     }
8908   else
8909     throw INTERP_KERNEL::Exception(msg);
8910   declareAsNew();
8911 }
8912
8913 /*!
8914  * Returns a new DataArrayInt that is the result of pow of two given arrays. There are 3
8915  * valid cases.
8916  *
8917  *  \param [in] a1 - an array to pow up.
8918  *  \param [in] a2 - another array to sum up.
8919  *  \return DataArrayInt * - the new instance of DataArrayInt.
8920  *          The caller is to delete this result array using decrRef() as it is no more
8921  *          needed.
8922  *  \throw If either \a a1 or \a a2 is NULL.
8923  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
8924  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
8925  *  \throw If there is a negative value in \a a2.
8926  */
8927 DataArrayInt *DataArrayInt::Pow(const DataArrayInt *a1, const DataArrayInt *a2)
8928 {
8929   if(!a1 || !a2)
8930     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : at least one of input instances is null !");
8931   int nbOfTuple=a1->getNumberOfTuples();
8932   int nbOfTuple2=a2->getNumberOfTuples();
8933   int nbOfComp=a1->getNumberOfComponents();
8934   int nbOfComp2=a2->getNumberOfComponents();
8935   if(nbOfTuple!=nbOfTuple2)
8936     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of tuples mismatches !");
8937   if(nbOfComp!=1 || nbOfComp2!=1)
8938     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of components of both arrays must be equal to 1 !");
8939   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuple,1);
8940   const int *ptr1(a1->begin()),*ptr2(a2->begin());
8941   int *ptr=ret->getPointer();
8942   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
8943     {
8944       if(*ptr2>=0)
8945         {
8946           int tmp=1;
8947           for(int j=0;j<*ptr2;j++)
8948             tmp*=*ptr1;
8949           *ptr=tmp;
8950         }
8951       else
8952         {
8953           std::ostringstream oss; oss << "DataArrayInt::Pow : on tuple #" << i << " of a2 value is < 0 (" << *ptr2 << ") !";
8954           throw INTERP_KERNEL::Exception(oss.str().c_str());
8955         }
8956     }
8957   return ret.retn();
8958 }
8959
8960 /*!
8961  * Apply pow on values of another DataArrayInt to values of \a this one.
8962  *
8963  *  \param [in] other - an array to pow to \a this one.
8964  *  \throw If \a other is NULL.
8965  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
8966  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
8967  *  \throw If there is a negative value in \a other.
8968  */
8969 void DataArrayInt::powEqual(const DataArrayInt *other)
8970 {
8971   if(!other)
8972     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : input instance is null !");
8973   int nbOfTuple=getNumberOfTuples();
8974   int nbOfTuple2=other->getNumberOfTuples();
8975   int nbOfComp=getNumberOfComponents();
8976   int nbOfComp2=other->getNumberOfComponents();
8977   if(nbOfTuple!=nbOfTuple2)
8978     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of tuples mismatches !");
8979   if(nbOfComp!=1 || nbOfComp2!=1)
8980     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of components of both arrays must be equal to 1 !");
8981   int *ptr=getPointer();
8982   const int *ptrc=other->begin();
8983   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
8984     {
8985       if(*ptrc>=0)
8986         {
8987           int tmp=1;
8988           for(int j=0;j<*ptrc;j++)
8989             tmp*=*ptr;
8990           *ptr=tmp;
8991         }
8992       else
8993         {
8994           std::ostringstream oss; oss << "DataArrayInt::powEqual : on tuple #" << i << " of other value is < 0 (" << *ptrc << ") !";
8995           throw INTERP_KERNEL::Exception(oss.str().c_str());
8996         }
8997     }
8998   declareAsNew();
8999 }
9000
9001 /*!
9002  * Returns a C array which is a renumbering map in "Old to New" mode for the input array.
9003  * This map, if applied to \a start array, would make it sorted. For example, if
9004  * \a start array contents are [9,10,0,6,4,11,3,7] then the contents of the result array is
9005  * [5,6,0,3,2,7,1,4].
9006  *  \param [in] start - pointer to the first element of the array for which the
9007  *         permutation map is computed.
9008  *  \param [in] end - pointer specifying the end of the array \a start, so that
9009  *         the last value of \a start is \a end[ -1 ].
9010  *  \return int * - the result permutation array that the caller is to delete as it is no
9011  *         more needed.
9012  *  \throw If there are equal values in the input array.
9013  */
9014 int *DataArrayInt::CheckAndPreparePermutation(const int *start, const int *end)
9015 {
9016   std::size_t sz=std::distance(start,end);
9017   int *ret=(int *)malloc(sz*sizeof(int));
9018   int *work=new int[sz];
9019   std::copy(start,end,work);
9020   std::sort(work,work+sz);
9021   if(std::unique(work,work+sz)!=work+sz)
9022     {
9023       delete [] work;
9024       free(ret);
9025       throw INTERP_KERNEL::Exception("Some elements are equals in the specified array !");
9026     }
9027   std::map<int,int> m;
9028   for(int *workPt=work;workPt!=work+sz;workPt++)
9029     m[*workPt]=(int)std::distance(work,workPt);
9030   int *iter2=ret;
9031   for(const int *iter=start;iter!=end;iter++,iter2++)
9032     *iter2=m[*iter];
9033   delete [] work;
9034   return ret;
9035 }
9036
9037 /*!
9038  * Returns a new DataArrayInt containing an arithmetic progression
9039  * that is equal to the sequence returned by Python \c range(\a begin,\a  end,\a  step )
9040  * function.
9041  *  \param [in] begin - the start value of the result sequence.
9042  *  \param [in] end - limiting value, so that every value of the result array is less than
9043  *              \a end.
9044  *  \param [in] step - specifies the increment or decrement.
9045  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9046  *          array using decrRef() as it is no more needed.
9047  *  \throw If \a step == 0.
9048  *  \throw If \a end < \a begin && \a step > 0.
9049  *  \throw If \a end > \a begin && \a step < 0.
9050  */
9051 DataArrayInt *DataArrayInt::Range(int begin, int end, int step)
9052 {
9053   int nbOfTuples=GetNumberOfItemGivenBESRelative(begin,end,step,"DataArrayInt::Range");
9054   MCAuto<DataArrayInt> ret=DataArrayInt::New();
9055   ret->alloc(nbOfTuples,1);
9056   int *ptr=ret->getPointer();
9057   if(step>0)
9058     {
9059       for(int i=begin;i<end;i+=step,ptr++)
9060         *ptr=i;
9061     }
9062   else
9063     {
9064       for(int i=begin;i>end;i+=step,ptr++)
9065         *ptr=i;
9066     }
9067   return ret.retn();
9068 }
9069
9070 /*!
9071  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
9072  * Server side.
9073  */
9074 void DataArrayInt::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
9075 {
9076   tinyInfo.resize(2);
9077   if(isAllocated())
9078     {
9079       tinyInfo[0]=getNumberOfTuples();
9080       tinyInfo[1]=getNumberOfComponents();
9081     }
9082   else
9083     {
9084       tinyInfo[0]=-1;
9085       tinyInfo[1]=-1;
9086     }
9087 }
9088
9089 /*!
9090  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
9091  * Server side.
9092  */
9093 void DataArrayInt::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
9094 {
9095   if(isAllocated())
9096     {
9097       int nbOfCompo=getNumberOfComponents();
9098       tinyInfo.resize(nbOfCompo+1);
9099       tinyInfo[0]=getName();
9100       for(int i=0;i<nbOfCompo;i++)
9101         tinyInfo[i+1]=getInfoOnComponent(i);
9102     }
9103   else
9104     {
9105       tinyInfo.resize(1);
9106       tinyInfo[0]=getName();
9107     }
9108 }
9109
9110 /*!
9111  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
9112  * This method returns if a feeding is needed.
9113  */
9114 bool DataArrayInt::resizeForUnserialization(const std::vector<int>& tinyInfoI)
9115 {
9116   int nbOfTuple=tinyInfoI[0];
9117   int nbOfComp=tinyInfoI[1];
9118   if(nbOfTuple!=-1 || nbOfComp!=-1)
9119     {
9120       alloc(nbOfTuple,nbOfComp);
9121       return true;
9122     }
9123   return false;
9124 }
9125
9126 /*!
9127  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
9128  * This method returns if a feeding is needed.
9129  */
9130 void DataArrayInt::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
9131 {
9132   setName(tinyInfoS[0]);
9133   if(isAllocated())
9134     {
9135       int nbOfCompo=tinyInfoI[1];
9136       for(int i=0;i<nbOfCompo;i++)
9137         setInfoOnComponent(i,tinyInfoS[i+1]);
9138     }
9139 }
9140
9141 DataArrayIntIterator::DataArrayIntIterator(DataArrayInt *da):_da(da),_pt(0),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
9142 {
9143   if(_da)
9144     {
9145       _da->incrRef();
9146       if(_da->isAllocated())
9147         {
9148           _nb_comp=da->getNumberOfComponents();
9149           _nb_tuple=da->getNumberOfTuples();
9150           _pt=da->getPointer();
9151         }
9152     }
9153 }
9154
9155 DataArrayIntIterator::~DataArrayIntIterator()
9156 {
9157   if(_da)
9158     _da->decrRef();
9159 }
9160
9161 DataArrayIntTuple *DataArrayIntIterator::nextt()
9162 {
9163   if(_tuple_id<_nb_tuple)
9164     {
9165       _tuple_id++;
9166       DataArrayIntTuple *ret=new DataArrayIntTuple(_pt,_nb_comp);
9167       _pt+=_nb_comp;
9168       return ret;
9169     }
9170   else
9171     return 0;
9172 }
9173
9174 DataArrayIntTuple::DataArrayIntTuple(int *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
9175 {
9176 }
9177
9178 std::string DataArrayIntTuple::repr() const
9179 {
9180   std::ostringstream oss; oss << "(";
9181   for(int i=0;i<_nb_of_compo-1;i++)
9182     oss << _pt[i] << ", ";
9183   oss << _pt[_nb_of_compo-1] << ")";
9184   return oss.str();
9185 }
9186
9187 int DataArrayIntTuple::intValue() const
9188 {
9189   if(_nb_of_compo==1)
9190     return *_pt;
9191   throw INTERP_KERNEL::Exception("DataArrayIntTuple::intValue : DataArrayIntTuple instance has not exactly 1 component -> Not possible to convert it into an integer !");
9192 }
9193
9194 /*!
9195  * This method returns a newly allocated instance the caller should dealed with by a MEDCoupling::DataArrayInt::decrRef.
9196  * This method performs \b no copy of data. The content is only referenced using MEDCoupling::DataArrayInt::useArray with ownership set to \b false.
9197  * 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
9198  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
9199  */
9200 DataArrayInt *DataArrayIntTuple::buildDAInt(int nbOfTuples, int nbOfCompo) const
9201 {
9202   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
9203     {
9204       DataArrayInt *ret=DataArrayInt::New();
9205       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
9206       return ret;
9207     }
9208   else
9209     {
9210       std::ostringstream oss; oss << "DataArrayIntTuple::buildDAInt : unable to build a requested DataArrayInt instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
9211       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
9212       throw INTERP_KERNEL::Exception(oss.str().c_str());
9213     }
9214 }