Salome HOME
bd33d07853440ce11f3a900f94c439327db27160
[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 template class MEDCoupling::DataArrayIterator<double>;
47
48 template<int SPACEDIM>
49 void DataArrayDouble::findCommonTuplesAlg(const double *bbox, int nbNodes, int limitNodeId, double prec, DataArrayInt *c, DataArrayInt *cI) const
50 {
51   const double *coordsPtr=getConstPointer();
52   BBTreePts<SPACEDIM,int> myTree(bbox,0,0,nbNodes,prec);
53   std::vector<bool> isDone(nbNodes);
54   for(int i=0;i<nbNodes;i++)
55     {
56       if(!isDone[i])
57         {
58           std::vector<int> intersectingElems;
59           myTree.getElementsAroundPoint(coordsPtr+i*SPACEDIM,intersectingElems);
60           if(intersectingElems.size()>1)
61             {
62               std::vector<int> commonNodes;
63               for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
64                 if(*it!=i)
65                   if(*it>=limitNodeId)
66                     {
67                       commonNodes.push_back(*it);
68                       isDone[*it]=true;
69                     }
70               if(!commonNodes.empty())
71                 {
72                   cI->pushBackSilent(cI->back()+(int)commonNodes.size()+1);
73                   c->pushBackSilent(i);
74                   c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
75                 }
76             }
77         }
78     }
79 }
80
81 template<int SPACEDIM>
82 void DataArrayDouble::FindTupleIdsNearTuplesAlg(const BBTreePts<SPACEDIM,int>& myTree, const double *pos, int nbOfTuples, double eps,
83                                                 DataArrayInt *c, DataArrayInt *cI)
84 {
85   for(int i=0;i<nbOfTuples;i++)
86     {
87       std::vector<int> intersectingElems;
88       myTree.getElementsAroundPoint(pos+i*SPACEDIM,intersectingElems);
89       std::vector<int> commonNodes;
90       for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
91         commonNodes.push_back(*it);
92       cI->pushBackSilent(cI->back()+(int)commonNodes.size());
93       c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
94     }
95 }
96
97 template<int SPACEDIM>
98 void DataArrayDouble::FindClosestTupleIdAlg(const BBTreePts<SPACEDIM,int>& myTree, double dist, const double *pos, int nbOfTuples, const double *thisPt, int thisNbOfTuples, int *res)
99 {
100   double distOpt(dist);
101   const double *p(pos);
102   int *r(res);
103   for(int i=0;i<nbOfTuples;i++,p+=SPACEDIM,r++)
104     {
105       while(true)
106         {
107           int elem=-1;
108           double ret=myTree.getElementsAroundPoint2(p,distOpt,elem);
109           if(ret!=std::numeric_limits<double>::max())
110             {
111               distOpt=std::max(ret,1e-4);
112               *r=elem;
113               break;
114             }
115           else
116             { distOpt=2*distOpt; continue; }
117         }
118     }
119 }
120
121 int DataArray::EffectiveCircPerm(int nbOfShift, int nbOfTuples)
122 {
123   if(nbOfTuples<=0)
124     throw INTERP_KERNEL::Exception("DataArray::EffectiveCircPerm : number of tuples is expected to be > 0 !");
125   if(nbOfShift>=0)
126     {
127       return nbOfShift%nbOfTuples;
128     }
129   else
130     {
131       int tmp(-nbOfShift);
132       tmp=tmp%nbOfTuples;
133       return nbOfTuples-tmp;
134     }
135 }
136
137 std::size_t DataArray::getHeapMemorySizeWithoutChildren() const
138 {
139   std::size_t sz1=_name.capacity();
140   std::size_t sz2=_info_on_compo.capacity();
141   std::size_t sz3=0;
142   for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
143     sz3+=(*it).capacity();
144   return sz1+sz2+sz3;
145 }
146
147 std::vector<const BigMemoryObject *> DataArray::getDirectChildrenWithNull() const
148 {
149   return std::vector<const BigMemoryObject *>();
150 }
151
152 /*!
153  * Sets the attribute \a _name of \a this array.
154  * See \ref MEDCouplingArrayBasicsName "DataArrays infos" for more information.
155  *  \param [in] name - new array name
156  */
157 void DataArray::setName(const std::string& name)
158 {
159   _name=name;
160 }
161
162 /*!
163  * Copies textual data from an \a other DataArray. The copied data are
164  * - the name attribute,
165  * - the information of components.
166  *
167  * For more information on these data see \ref MEDCouplingArrayBasicsName "DataArrays infos".
168  *
169  *  \param [in] other - another instance of DataArray to copy the textual data from.
170  *  \throw If number of components of \a this array differs from that of the \a other.
171  */
172 void DataArray::copyStringInfoFrom(const DataArray& other)
173 {
174   if(_info_on_compo.size()!=other._info_on_compo.size())
175     throw INTERP_KERNEL::Exception("Size of arrays mismatches on copyStringInfoFrom !");
176   _name=other._name;
177   _info_on_compo=other._info_on_compo;
178 }
179
180 void DataArray::copyPartOfStringInfoFrom(const DataArray& other, const std::vector<int>& compoIds)
181 {
182   int nbOfCompoOth=other.getNumberOfComponents();
183   std::size_t newNbOfCompo=compoIds.size();
184   for(std::size_t i=0;i<newNbOfCompo;i++)
185     if(compoIds[i]>=nbOfCompoOth || compoIds[i]<0)
186       {
187         std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompoOth << ")";
188         throw INTERP_KERNEL::Exception(oss.str().c_str());
189       }
190   for(std::size_t i=0;i<newNbOfCompo;i++)
191     setInfoOnComponent((int)i,other.getInfoOnComponent(compoIds[i]));
192 }
193
194 void DataArray::copyPartOfStringInfoFrom2(const std::vector<int>& compoIds, const DataArray& other)
195 {
196   int nbOfCompo=getNumberOfComponents();
197   std::size_t partOfCompoToSet=compoIds.size();
198   if((int)partOfCompoToSet!=other.getNumberOfComponents())
199     throw INTERP_KERNEL::Exception("Given compoIds has not the same size as number of components of given array !");
200   for(std::size_t i=0;i<partOfCompoToSet;i++)
201     if(compoIds[i]>=nbOfCompo || compoIds[i]<0)
202       {
203         std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompo << ")";
204         throw INTERP_KERNEL::Exception(oss.str().c_str());
205       }
206   for(std::size_t i=0;i<partOfCompoToSet;i++)
207     setInfoOnComponent(compoIds[i],other.getInfoOnComponent((int)i));
208 }
209
210 bool DataArray::areInfoEqualsIfNotWhy(const DataArray& other, std::string& reason) const
211 {
212   std::ostringstream oss;
213   if(_name!=other._name)
214     {
215       oss << "Names DataArray mismatch : this name=\"" << _name << " other name=\"" << other._name << "\" !";
216       reason=oss.str();
217       return false;
218     }
219   if(_info_on_compo!=other._info_on_compo)
220     {
221       oss << "Components DataArray mismatch : \nThis components=";
222       for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
223         oss << "\"" << *it << "\",";
224       oss << "\nOther components=";
225       for(std::vector<std::string>::const_iterator it=other._info_on_compo.begin();it!=other._info_on_compo.end();it++)
226         oss << "\"" << *it << "\",";
227       reason=oss.str();
228       return false;
229     }
230   return true;
231 }
232
233 /*!
234  * Compares textual information of \a this DataArray with that of an \a other one.
235  * The compared data are
236  * - the name attribute,
237  * - the information of components.
238  *
239  * For more information on these data see \ref MEDCouplingArrayBasicsName "DataArrays infos".
240  *  \param [in] other - another instance of DataArray to compare the textual data of.
241  *  \return bool - \a true if the textual information is same, \a false else.
242  */
243 bool DataArray::areInfoEquals(const DataArray& other) const
244 {
245   std::string tmp;
246   return areInfoEqualsIfNotWhy(other,tmp);
247 }
248
249 void DataArray::reprWithoutNameStream(std::ostream& stream) const
250 {
251   stream << "Number of components : "<< getNumberOfComponents() << "\n";
252   stream << "Info of these components : ";
253   for(std::vector<std::string>::const_iterator iter=_info_on_compo.begin();iter!=_info_on_compo.end();iter++)
254     stream << "\"" << *iter << "\"   ";
255   stream << "\n";
256 }
257
258 std::string DataArray::cppRepr(const std::string& varName) const
259 {
260   std::ostringstream ret;
261   reprCppStream(varName,ret);
262   return ret.str();
263 }
264
265 /*!
266  * Sets information on all components. To know more on format of this information
267  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
268  *  \param [in] info - a vector of strings.
269  *  \throw If size of \a info differs from the number of components of \a this.
270  */
271 void DataArray::setInfoOnComponents(const std::vector<std::string>& info)
272 {
273   if(getNumberOfComponents()!=(int)info.size())
274     {
275       std::ostringstream oss; oss << "DataArray::setInfoOnComponents : input is of size " << info.size() << " whereas number of components is equal to " << getNumberOfComponents() << " !";
276       throw INTERP_KERNEL::Exception(oss.str().c_str());
277     }
278   _info_on_compo=info;
279 }
280
281 /*!
282  * This method is only a dispatcher towards DataArrayDouble::setPartOfValues3, DataArrayInt::setPartOfValues3, DataArrayChar::setPartOfValues3 depending on the true
283  * type of \a this and \a aBase.
284  *
285  * \throw If \a aBase and \a this do not have the same type.
286  *
287  * \sa DataArrayDouble::setPartOfValues3, DataArrayInt::setPartOfValues3, DataArrayChar::setPartOfValues3.
288  */
289 void DataArray::setPartOfValuesBase3(const DataArray *aBase, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
290 {
291   if(!aBase)
292     throw INTERP_KERNEL::Exception("DataArray::setPartOfValuesBase3 : input aBase object is NULL !");
293   DataArrayDouble *this1(dynamic_cast<DataArrayDouble *>(this));
294   DataArrayInt *this2(dynamic_cast<DataArrayInt *>(this));
295   DataArrayChar *this3(dynamic_cast<DataArrayChar *>(this));
296   const DataArrayDouble *a1(dynamic_cast<const DataArrayDouble *>(aBase));
297   const DataArrayInt *a2(dynamic_cast<const DataArrayInt *>(aBase));
298   const DataArrayChar *a3(dynamic_cast<const DataArrayChar *>(aBase));
299   if(this1 && a1)
300     {
301       this1->setPartOfValues3(a1,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
302       return ;
303     }
304   if(this2 && a2)
305     {
306       this2->setPartOfValues3(a2,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
307       return ;
308     }
309   if(this3 && a3)
310     {
311       this3->setPartOfValues3(a3,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
312       return ;
313     }
314   throw INTERP_KERNEL::Exception("DataArray::setPartOfValuesBase3 : input aBase object and this do not have the same type !");
315 }
316
317 std::vector<std::string> DataArray::getVarsOnComponent() const
318 {
319   int nbOfCompo=(int)_info_on_compo.size();
320   std::vector<std::string> ret(nbOfCompo);
321   for(int i=0;i<nbOfCompo;i++)
322     ret[i]=getVarOnComponent(i);
323   return ret;
324 }
325
326 std::vector<std::string> DataArray::getUnitsOnComponent() const
327 {
328   int nbOfCompo=(int)_info_on_compo.size();
329   std::vector<std::string> ret(nbOfCompo);
330   for(int i=0;i<nbOfCompo;i++)
331     ret[i]=getUnitOnComponent(i);
332   return ret;
333 }
334
335 /*!
336  * Returns information on a component specified by an index.
337  * To know more on format of this information
338  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
339  *  \param [in] i - the index (zero based) of the component of interest.
340  *  \return std::string - a string containing the information on \a i-th component.
341  *  \throw If \a i is not a valid component index.
342  */
343 std::string DataArray::getInfoOnComponent(int i) const
344 {
345   if(i<(int)_info_on_compo.size() && i>=0)
346     return _info_on_compo[i];
347   else
348     {
349       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();
350       throw INTERP_KERNEL::Exception(oss.str().c_str());
351     }
352 }
353
354 /*!
355  * Returns the var part of the full information of the \a i-th component.
356  * For example, if \c getInfoOnComponent(0) returns "SIGXY [N/m^2]", then
357  * \c getVarOnComponent(0) returns "SIGXY".
358  * If a unit part of information is not detected by presence of
359  * two square brackets, then the full information is returned.
360  * To read more about the component information format, see
361  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
362  *  \param [in] i - the index (zero based) of the component of interest.
363  *  \return std::string - a string containing the var information, or the full info.
364  *  \throw If \a i is not a valid component index.
365  */
366 std::string DataArray::getVarOnComponent(int i) const
367 {
368   if(i<(int)_info_on_compo.size() && i>=0)
369     {
370       return GetVarNameFromInfo(_info_on_compo[i]);
371     }
372   else
373     {
374       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();
375       throw INTERP_KERNEL::Exception(oss.str().c_str());
376     }
377 }
378
379 /*!
380  * Returns the unit part of the full information of the \a i-th component.
381  * For example, if \c getInfoOnComponent(0) returns "SIGXY [ N/m^2]", then
382  * \c getUnitOnComponent(0) returns " N/m^2".
383  * If a unit part of information is not detected by presence of
384  * two square brackets, then an empty string is returned.
385  * To read more about the component information format, see
386  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
387  *  \param [in] i - the index (zero based) of the component of interest.
388  *  \return std::string - a string containing the unit information, if any, or "".
389  *  \throw If \a i is not a valid component index.
390  */
391 std::string DataArray::getUnitOnComponent(int i) const
392 {
393   if(i<(int)_info_on_compo.size() && i>=0)
394     {
395       return GetUnitFromInfo(_info_on_compo[i]);
396     }
397   else
398     {
399       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();
400       throw INTERP_KERNEL::Exception(oss.str().c_str());
401     }
402 }
403
404 /*!
405  * Returns the var part of the full component information.
406  * For example, if \a info == "SIGXY [N/m^2]", then this method returns "SIGXY".
407  * If a unit part of information is not detected by presence of
408  * two square brackets, then the whole \a info is returned.
409  * To read more about the component information format, see
410  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
411  *  \param [in] info - the full component information.
412  *  \return std::string - a string containing only var information, or the \a info.
413  */
414 std::string DataArray::GetVarNameFromInfo(const std::string& info)
415 {
416   std::size_t p1=info.find_last_of('[');
417   std::size_t p2=info.find_last_of(']');
418   if(p1==std::string::npos || p2==std::string::npos)
419     return info;
420   if(p1>p2)
421     return info;
422   if(p1==0)
423     return std::string();
424   std::size_t p3=info.find_last_not_of(' ',p1-1);
425   return info.substr(0,p3+1);
426 }
427
428 /*!
429  * Returns the unit part of the full component information.
430  * For example, if \a info == "SIGXY [ N/m^2]", then this method returns " N/m^2".
431  * If a unit part of information is not detected by presence of
432  * two square brackets, then an empty string is returned.
433  * To read more about the component information format, see
434  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
435  *  \param [in] info - the full component information.
436  *  \return std::string - a string containing only unit information, if any, or "".
437  */
438 std::string DataArray::GetUnitFromInfo(const std::string& info)
439 {
440   std::size_t p1=info.find_last_of('[');
441   std::size_t p2=info.find_last_of(']');
442   if(p1==std::string::npos || p2==std::string::npos)
443     return std::string();
444   if(p1>p2)
445     return std::string();
446   return info.substr(p1+1,p2-p1-1);
447 }
448
449 /*!
450  * This method put in info format the result of the merge of \a var and \a unit.
451  * The standard format for that is "var [unit]".
452  * Inversely you can retrieve the var part or the unit part of info string using resp. GetVarNameFromInfo and GetUnitFromInfo.
453  */
454 std::string DataArray::BuildInfoFromVarAndUnit(const std::string& var, const std::string& unit)
455 {
456   std::ostringstream oss;
457   oss << var << " [" << unit << "]";
458   return oss.str();
459 }
460
461 std::string DataArray::GetAxisTypeRepr(MEDCouplingAxisType at)
462 {
463   switch(at)
464     {
465     case AX_CART:
466       return std::string("AX_CART");
467     case AX_CYL:
468       return std::string("AX_CYL");
469     case AX_SPHER:
470       return std::string("AX_SPHER");
471     default:
472       throw INTERP_KERNEL::Exception("DataArray::GetAxisTypeRepr : unrecognized axis type enum !");
473     }
474 }
475
476 /*!
477  * Returns a new DataArray by concatenating all given arrays, so that (1) the number
478  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
479  * the number of component in the result array is same as that of each of given arrays.
480  * Info on components is copied from the first of the given arrays. Number of components
481  * in the given arrays must be  the same.
482  *  \param [in] arrs - a sequence of arrays to include in the result array. All arrays must have the same type.
483  *  \return DataArray * - the new instance of DataArray (that can be either DataArrayInt, DataArrayDouble, DataArrayChar).
484  *          The caller is to delete this result array using decrRef() as it is no more
485  *          needed.
486  *  \throw If all arrays within \a arrs are NULL.
487  *  \throw If all not null arrays in \a arrs have not the same type.
488  *  \throw If getNumberOfComponents() of arrays within \a arrs.
489  */
490 DataArray *DataArray::Aggregate(const std::vector<const DataArray *>& arrs)
491 {
492   std::vector<const DataArray *> arr2;
493   for(std::vector<const DataArray *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
494     if(*it)
495       arr2.push_back(*it);
496   if(arr2.empty())
497     throw INTERP_KERNEL::Exception("DataArray::Aggregate : only null instance in input vector !");
498   std::vector<const DataArrayDouble *> arrd;
499   std::vector<const DataArrayInt *> arri;
500   std::vector<const DataArrayChar *> arrc;
501   for(std::vector<const DataArray *>::const_iterator it=arr2.begin();it!=arr2.end();it++)
502     {
503       const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(*it);
504       if(a)
505         { arrd.push_back(a); continue; }
506       const DataArrayInt *b=dynamic_cast<const DataArrayInt *>(*it);
507       if(b)
508         { arri.push_back(b); continue; }
509       const DataArrayChar *c=dynamic_cast<const DataArrayChar *>(*it);
510       if(c)
511         { arrc.push_back(c); continue; }
512       throw INTERP_KERNEL::Exception("DataArray::Aggregate : presence of not null instance in inuput that is not in [DataArrayDouble, DataArrayInt, DataArrayChar] !");
513     }
514   if(arr2.size()==arrd.size())
515     return DataArrayDouble::Aggregate(arrd);
516   if(arr2.size()==arri.size())
517     return DataArrayInt::Aggregate(arri);
518   if(arr2.size()==arrc.size())
519     return DataArrayChar::Aggregate(arrc);
520   throw INTERP_KERNEL::Exception("DataArray::Aggregate : all input arrays must have the same type !");
521 }
522
523 /*!
524  * Sets information on a component specified by an index.
525  * To know more on format of this information
526  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
527  *  \warning Don't pass NULL as \a info!
528  *  \param [in] i - the index (zero based) of the component of interest.
529  *  \param [in] info - the string containing the information.
530  *  \throw If \a i is not a valid component index.
531  */
532 void DataArray::setInfoOnComponent(int i, const std::string& info)
533 {
534   if(i<(int)_info_on_compo.size() && i>=0)
535     _info_on_compo[i]=info;
536   else
537     {
538       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();
539       throw INTERP_KERNEL::Exception(oss.str().c_str());
540     }
541 }
542
543 /*!
544  * Sets information on all components. This method can change number of components
545  * at certain conditions; if the conditions are not respected, an exception is thrown.
546  * The number of components can be changed in \a this only if \a this is not allocated.
547  * The condition of number of components must not be changed.
548  *
549  * To know more on format of the component information see
550  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
551  *  \param [in] info - a vector of component infos.
552  *  \throw If \a this->getNumberOfComponents() != \a info.size() && \a this->isAllocated()
553  */
554 void DataArray::setInfoAndChangeNbOfCompo(const std::vector<std::string>& info)
555 {
556   if(getNumberOfComponents()!=(int)info.size())
557     {
558       if(!isAllocated())
559         _info_on_compo=info;
560       else
561         {
562           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 !";
563           throw INTERP_KERNEL::Exception(oss.str().c_str());
564         }
565     }
566   else
567     _info_on_compo=info;
568 }
569
570 void DataArray::checkNbOfTuples(int nbOfTuples, const std::string& msg) const
571 {
572   if(getNumberOfTuples()!=nbOfTuples)
573     {
574       std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " <<  nbOfTuples << " having " << getNumberOfTuples() << " !";
575       throw INTERP_KERNEL::Exception(oss.str().c_str());
576     }
577 }
578
579 void DataArray::checkNbOfComps(int nbOfCompo, const std::string& msg) const
580 {
581   if(getNumberOfComponents()!=nbOfCompo)
582     {
583       std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << nbOfCompo << " having " << getNumberOfComponents() << " !";
584       throw INTERP_KERNEL::Exception(oss.str().c_str());
585     }
586 }
587
588 void DataArray::checkNbOfElems(std::size_t nbOfElems, const std::string& msg) const
589 {
590   if(getNbOfElems()!=nbOfElems)
591     {
592       std::ostringstream oss; oss << msg << " : mismatch number of elems : Expected " << nbOfElems << " having " << getNbOfElems() << " !";
593       throw INTERP_KERNEL::Exception(oss.str().c_str());
594     }
595 }
596
597 void DataArray::checkNbOfTuplesAndComp(const DataArray& other, const std::string& msg) const
598 {
599   if(getNumberOfTuples()!=other.getNumberOfTuples())
600     {
601       std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " <<  other.getNumberOfTuples() << " having " << getNumberOfTuples() << " !";
602       throw INTERP_KERNEL::Exception(oss.str().c_str());
603     }
604   if(getNumberOfComponents()!=other.getNumberOfComponents())
605     {
606       std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << other.getNumberOfComponents() << " having " << getNumberOfComponents() << " !";
607       throw INTERP_KERNEL::Exception(oss.str().c_str());
608     }
609 }
610
611 void DataArray::checkNbOfTuplesAndComp(int nbOfTuples, int nbOfCompo, const std::string& msg) const
612 {
613   checkNbOfTuples(nbOfTuples,msg);
614   checkNbOfComps(nbOfCompo,msg);
615 }
616
617 /*!
618  * Simply this method checks that \b value is in [0,\b ref).
619  */
620 void DataArray::CheckValueInRange(int ref, int value, const std::string& msg)
621 {
622   if(value<0 || value>=ref)
623     {
624       std::ostringstream oss; oss << "DataArray::CheckValueInRange : " << msg  << " ! Expected in range [0," << ref << "[ having " << value << " !";
625       throw INTERP_KERNEL::Exception(oss.str().c_str());
626     }
627 }
628
629 /*!
630  * This method checks that [\b start, \b end) is compliant with ref length \b value.
631  * typicaly start in [0,\b value) and end in [0,\b value). If value==start and start==end, it is supported.
632  */
633 void DataArray::CheckValueInRangeEx(int value, int start, int end, const std::string& msg)
634 {
635   if(start<0 || start>=value)
636     {
637       if(value!=start || end!=start)
638         {
639           std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg  << " ! Expected start " << start << " of input range, in [0," << value << "[ !";
640           throw INTERP_KERNEL::Exception(oss.str().c_str());
641         }
642     }
643   if(end<0 || end>value)
644     {
645       std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg  << " ! Expected end " << end << " of input range, in [0," << value << "] !";
646       throw INTERP_KERNEL::Exception(oss.str().c_str());
647     }
648 }
649
650 void DataArray::CheckClosingParInRange(int ref, int value, const std::string& msg)
651 {
652   if(value<0 || value>ref)
653     {
654       std::ostringstream oss; oss << "DataArray::CheckClosingParInRange : " << msg  << " ! Expected input range in [0," << ref << "] having closing open parenthesis " << value << " !";
655       throw INTERP_KERNEL::Exception(oss.str().c_str());
656     }
657 }
658
659 /*!
660  * 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, 
661  * typically it is a whole slice of tuples of DataArray or cells, nodes of a mesh...
662  *
663  * The input \a sliceId should be an id in [0, \a nbOfSlices) that specifies the slice of work.
664  *
665  * \param [in] start - the start of the input slice of the whole work to perform splitted into slices.
666  * \param [in] stop - the stop of the input slice of the whole work to perform splitted into slices.
667  * \param [in] step - the step (that can be <0) of the input slice of the whole work to perform splitted into slices.
668  * \param [in] sliceId - the slice id considered
669  * \param [in] nbOfSlices - the number of slices (typically the number of cores on which the work is expected to be sliced)
670  * \param [out] startSlice - the start of the slice considered
671  * \param [out] stopSlice - the stop of the slice consided
672  * 
673  * \throw If \a step == 0
674  * \throw If \a nbOfSlices not > 0
675  * \throw If \a sliceId not in [0,nbOfSlices)
676  */
677 void DataArray::GetSlice(int start, int stop, int step, int sliceId, int nbOfSlices, int& startSlice, int& stopSlice)
678 {
679   if(nbOfSlices<=0)
680     {
681       std::ostringstream oss; oss << "DataArray::GetSlice : nbOfSlices (" << nbOfSlices << ") must be > 0 !";
682       throw INTERP_KERNEL::Exception(oss.str().c_str());
683     }
684   if(sliceId<0 || sliceId>=nbOfSlices)
685     {
686       std::ostringstream oss; oss << "DataArray::GetSlice : sliceId (" << nbOfSlices << ") must be in [0 , nbOfSlices (" << nbOfSlices << ") ) !";
687       throw INTERP_KERNEL::Exception(oss.str().c_str());
688     }
689   int nbElems=GetNumberOfItemGivenBESRelative(start,stop,step,"DataArray::GetSlice");
690   int minNbOfElemsPerSlice=nbElems/nbOfSlices;
691   startSlice=start+minNbOfElemsPerSlice*step*sliceId;
692   if(sliceId<nbOfSlices-1)
693     stopSlice=start+minNbOfElemsPerSlice*step*(sliceId+1);
694   else
695     stopSlice=stop;
696 }
697
698 int DataArray::GetNumberOfItemGivenBES(int begin, int end, int step, const std::string& msg)
699 {
700   if(end<begin)
701     {
702       std::ostringstream oss; oss << msg << " : end before begin !";
703       throw INTERP_KERNEL::Exception(oss.str().c_str());
704     }
705   if(end==begin)
706     return 0;
707   if(step<=0)
708     {
709       std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
710       throw INTERP_KERNEL::Exception(oss.str().c_str());
711     }
712   return (end-1-begin)/step+1;
713 }
714
715 int DataArray::GetNumberOfItemGivenBESRelative(int begin, int end, int step, const std::string& msg)
716 {
717   if(step==0)
718     throw INTERP_KERNEL::Exception("DataArray::GetNumberOfItemGivenBES : step=0 is not allowed !");
719   if(end<begin && step>0)
720     {
721       std::ostringstream oss; oss << msg << " : end before begin whereas step is positive !";
722       throw INTERP_KERNEL::Exception(oss.str().c_str());
723     }
724   if(begin<end && step<0)
725     {
726       std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
727       throw INTERP_KERNEL::Exception(oss.str().c_str());
728     }
729   if(begin!=end)
730     return (std::max(begin,end)-1-std::min(begin,end))/std::abs(step)+1;
731   else
732     return 0;
733 }
734
735 int DataArray::GetPosOfItemGivenBESRelativeNoThrow(int value, int begin, int end, int step)
736 {
737   if(step!=0)
738     {
739       if(step>0)
740         {
741           if(begin<=value && value<end)
742             {
743               if((value-begin)%step==0)
744                 return (value-begin)/step;
745               else
746                 return -1;
747             }
748           else
749             return -1;
750         }
751       else
752         {
753           if(begin>=value && value>end)
754             {
755               if((begin-value)%(-step)==0)
756                 return (begin-value)/(-step);
757               else
758                 return -1;
759             }
760           else
761             return -1;
762         }
763     }
764   else
765     return -1;
766 }
767
768 /*!
769  * Returns a new instance of DataArrayDouble. The caller is to delete this array
770  * using decrRef() as it is no more needed. 
771  */
772 DataArrayDouble *DataArrayDouble::New()
773 {
774   return new DataArrayDouble;
775 }
776
777 /*!
778  * Returns the only one value in \a this, if and only if number of elements
779  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
780  *  \return double - the sole value stored in \a this array.
781  *  \throw If at least one of conditions stated above is not fulfilled.
782  */
783 double DataArrayDouble::doubleValue() const
784 {
785   if(isAllocated())
786     {
787       if(getNbOfElems()==1)
788         {
789           return *getConstPointer();
790         }
791       else
792         throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is allocated but number of elements is not equal to 1 !");
793     }
794   else
795     throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is not allocated !");
796 }
797
798 /*!
799  * Returns a full copy of \a this. For more info on copying data arrays see
800  * \ref MEDCouplingArrayBasicsCopyDeep.
801  *  \return DataArrayDouble * - a new instance of DataArrayDouble. The caller is to
802  *          delete this array using decrRef() as it is no more needed. 
803  */
804 DataArrayDouble *DataArrayDouble::deepCopy() const
805 {
806   return new DataArrayDouble(*this);
807 }
808
809 /*!
810  * Returns either a \a deep or \a shallow copy of this array. For more info see
811  * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
812  *  \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
813  *  \return DataArrayDouble * - either a new instance of DataArrayDouble (if \a dCpy
814  *          == \a true) or \a this instance (if \a dCpy == \a false).
815  */
816 DataArrayDouble *DataArrayDouble::performCopyOrIncrRef(bool dCpy) const
817 {
818   return DataArrayTemplateClassic<double>::PerformCopyOrIncrRef(dCpy,*this);
819 }
820
821 /*!
822  * Assign zero to all values in \a this array. To know more on filling arrays see
823  * \ref MEDCouplingArrayFill.
824  * \throw If \a this is not allocated.
825  */
826 void DataArrayDouble::fillWithZero()
827 {
828   fillWithValue(0.);
829 }
830
831 /*!
832  * Checks that \a this array is consistently **increasing** or **decreasing** in value,
833  * with at least absolute difference value of |\a eps| at each step.
834  * If not an exception is thrown.
835  *  \param [in] increasing - if \a true, the array values should be increasing.
836  *  \param [in] eps - minimal absolute difference between the neighbor values at which 
837  *                    the values are considered different.
838  *  \throw If sequence of values is not strictly monotonic in agreement with \a
839  *         increasing arg.
840  *  \throw If \a this->getNumberOfComponents() != 1.
841  *  \throw If \a this is not allocated.
842  */
843 void DataArrayDouble::checkMonotonic(bool increasing, double eps) const
844 {
845   if(!isMonotonic(increasing,eps))
846     {
847       if (increasing)
848         throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not INCREASING monotonic !");
849       else
850         throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not DECREASING monotonic !");
851     }
852 }
853
854 /*!
855  * Checks that \a this array is consistently **increasing** or **decreasing** in value,
856  * with at least absolute difference value of |\a eps| at each step.
857  *  \param [in] increasing - if \a true, array values should be increasing.
858  *  \param [in] eps - minimal absolute difference between the neighbor values at which 
859  *                    the values are considered different.
860  *  \return bool - \a true if values change in accordance with \a increasing arg.
861  *  \throw If \a this->getNumberOfComponents() != 1.
862  *  \throw If \a this is not allocated.
863  */
864 bool DataArrayDouble::isMonotonic(bool increasing, double eps) const
865 {
866   checkAllocated();
867   if(getNumberOfComponents()!=1)
868     throw INTERP_KERNEL::Exception("DataArrayDouble::isMonotonic : only supported with 'this' array with ONE component !");
869   int nbOfElements=getNumberOfTuples();
870   const double *ptr=getConstPointer();
871   if(nbOfElements==0)
872     return true;
873   double ref=ptr[0];
874   double absEps=fabs(eps);
875   if(increasing)
876     {
877       for(int i=1;i<nbOfElements;i++)
878         {
879           if(ptr[i]<(ref+absEps))
880             return false;
881           ref=ptr[i];
882         }
883       return true;
884     }
885   else
886     {
887       for(int i=1;i<nbOfElements;i++)
888         {
889           if(ptr[i]>(ref-absEps))
890             return false;
891           ref=ptr[i];
892         }
893       return true;
894     }
895 }
896
897 /*!
898  * Returns a textual and human readable representation of \a this instance of
899  * DataArrayDouble. This text is shown when a DataArrayDouble is printed in Python.
900  * \return std::string - text describing \a this DataArrayDouble.
901  *
902  * \sa reprNotTooLong, reprZip
903  */
904 std::string DataArrayDouble::repr() const
905 {
906   std::ostringstream ret;
907   reprStream(ret);
908   return ret.str();
909 }
910
911 std::string DataArrayDouble::reprZip() const
912 {
913   std::ostringstream ret;
914   reprZipStream(ret);
915   return ret.str();
916 }
917
918 /*!
919  * This method is close to repr method except that when \a this has more than 1000 tuples, all tuples are not
920  * printed out to avoid to consume too much space in interpretor.
921  * \sa repr
922  */
923 std::string DataArrayDouble::reprNotTooLong() const
924 {
925   std::ostringstream ret;
926   reprNotTooLongStream(ret);
927   return ret.str();
928 }
929
930 void DataArrayDouble::writeVTK(std::ostream& ofs, int indent, const std::string& nameInFile, DataArrayByte *byteArr) const
931 {
932   static const char SPACE[4]={' ',' ',' ',' '};
933   checkAllocated();
934   std::string idt(indent,' ');
935   ofs.precision(17);
936   ofs << idt << "<DataArray type=\"Float32\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
937   //
938   bool areAllEmpty(true);
939   for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
940     if(!(*it).empty())
941       areAllEmpty=false;
942   if(!areAllEmpty)
943     for(std::size_t i=0;i<_info_on_compo.size();i++)
944       ofs << " ComponentName" << i << "=\"" << _info_on_compo[i] << "\"";
945   //
946   if(byteArr)
947     {
948       ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
949       INTERP_KERNEL::AutoPtr<float> tmp(new float[getNbOfElems()]);
950       float *pt(tmp);
951       // to make Visual C++ happy : instead of std::copy(begin(),end(),(float *)tmp);
952       for(const double *src=begin();src!=end();src++,pt++)
953         *pt=float(*src);
954       const char *data(reinterpret_cast<const char *>((float *)tmp));
955       std::size_t sz(getNbOfElems()*sizeof(float));
956       byteArr->insertAtTheEnd(data,data+sz);
957       byteArr->insertAtTheEnd(SPACE,SPACE+4);
958     }
959   else
960     {
961       ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
962       std::copy(begin(),end(),std::ostream_iterator<double>(ofs," "));
963     }
964   ofs << std::endl << idt << "</DataArray>\n";
965 }
966
967 void DataArrayDouble::reprStream(std::ostream& stream) const
968 {
969   stream << "Name of double array : \"" << _name << "\"\n";
970   reprWithoutNameStream(stream);
971 }
972
973 void DataArrayDouble::reprZipStream(std::ostream& stream) const
974 {
975   stream << "Name of double array : \"" << _name << "\"\n";
976   reprZipWithoutNameStream(stream);
977 }
978
979 void DataArrayDouble::reprNotTooLongStream(std::ostream& stream) const
980 {
981   stream << "Name of double array : \"" << _name << "\"\n";
982   reprNotTooLongWithoutNameStream(stream);
983 }
984
985 void DataArrayDouble::reprWithoutNameStream(std::ostream& stream) const
986 {
987   DataArray::reprWithoutNameStream(stream);
988   stream.precision(17);
989   _mem.repr(getNumberOfComponents(),stream);
990 }
991
992 void DataArrayDouble::reprZipWithoutNameStream(std::ostream& stream) const
993 {
994   DataArray::reprWithoutNameStream(stream);
995   stream.precision(17);
996   _mem.reprZip(getNumberOfComponents(),stream);
997 }
998
999 void DataArrayDouble::reprNotTooLongWithoutNameStream(std::ostream& stream) const
1000 {
1001   DataArray::reprWithoutNameStream(stream);
1002   stream.precision(17);
1003   _mem.reprNotTooLong(getNumberOfComponents(),stream);
1004 }
1005
1006 void DataArrayDouble::reprCppStream(const std::string& varName, std::ostream& stream) const
1007 {
1008   int nbTuples(getNumberOfTuples()),nbComp(getNumberOfComponents());
1009   const double *data(getConstPointer());
1010   stream.precision(17);
1011   stream << "DataArrayDouble *" << varName << "=DataArrayDouble::New();" << std::endl;
1012   if(nbTuples*nbComp>=1)
1013     {
1014       stream << "const double " << varName << "Data[" << nbTuples*nbComp << "]={";
1015       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<double>(stream,","));
1016       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
1017       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
1018     }
1019   else
1020     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
1021   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
1022 }
1023
1024 /*!
1025  * Method that gives a quick overvien of \a this for python.
1026  */
1027 void DataArrayDouble::reprQuickOverview(std::ostream& stream) const
1028 {
1029   static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
1030   stream << "DataArrayDouble C++ instance at " << this << ". ";
1031   if(isAllocated())
1032     {
1033       int nbOfCompo=(int)_info_on_compo.size();
1034       if(nbOfCompo>=1)
1035         {
1036           int nbOfTuples=getNumberOfTuples();
1037           stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
1038           reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
1039         }
1040       else
1041         stream << "Number of components : 0.";
1042     }
1043   else
1044     stream << "*** No data allocated ****";
1045 }
1046
1047 void DataArrayDouble::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
1048 {
1049   const double *data=begin();
1050   int nbOfTuples=getNumberOfTuples();
1051   int nbOfCompo=(int)_info_on_compo.size();
1052   std::ostringstream oss2; oss2 << "[";
1053   oss2.precision(17);
1054   std::string oss2Str(oss2.str());
1055   bool isFinished=true;
1056   for(int i=0;i<nbOfTuples && isFinished;i++)
1057     {
1058       if(nbOfCompo>1)
1059         {
1060           oss2 << "(";
1061           for(int j=0;j<nbOfCompo;j++,data++)
1062             {
1063               oss2 << *data;
1064               if(j!=nbOfCompo-1) oss2 << ", ";
1065             }
1066           oss2 << ")";
1067         }
1068       else
1069         oss2 << *data++;
1070       if(i!=nbOfTuples-1) oss2 << ", ";
1071       std::string oss3Str(oss2.str());
1072       if(oss3Str.length()<maxNbOfByteInRepr)
1073         oss2Str=oss3Str;
1074       else
1075         isFinished=false;
1076     }
1077   stream << oss2Str;
1078   if(!isFinished)
1079     stream << "... ";
1080   stream << "]";
1081 }
1082
1083 /*!
1084  * Equivalent to DataArrayDouble::isEqual except that if false the reason of
1085  * mismatch is given.
1086  * 
1087  * \param [in] other the instance to be compared with \a this
1088  * \param [in] prec the precision to compare numeric data of the arrays.
1089  * \param [out] reason In case of inequality returns the reason.
1090  * \sa DataArrayDouble::isEqual
1091  */
1092 bool DataArrayDouble::isEqualIfNotWhy(const DataArrayDouble& other, double prec, std::string& reason) const
1093 {
1094   if(!areInfoEqualsIfNotWhy(other,reason))
1095     return false;
1096   return _mem.isEqual(other._mem,prec,reason);
1097 }
1098
1099 /*!
1100  * Checks if \a this and another DataArrayDouble are fully equal. For more info see
1101  * \ref MEDCouplingArrayBasicsCompare.
1102  *  \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1103  *  \param [in] prec - precision value to compare numeric data of the arrays.
1104  *  \return bool - \a true if the two arrays are equal, \a false else.
1105  */
1106 bool DataArrayDouble::isEqual(const DataArrayDouble& other, double prec) const
1107 {
1108   std::string tmp;
1109   return isEqualIfNotWhy(other,prec,tmp);
1110 }
1111
1112 /*!
1113  * Checks if values of \a this and another DataArrayDouble are equal. For more info see
1114  * \ref MEDCouplingArrayBasicsCompare.
1115  *  \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1116  *  \param [in] prec - precision value to compare numeric data of the arrays.
1117  *  \return bool - \a true if the values of two arrays are equal, \a false else.
1118  */
1119 bool DataArrayDouble::isEqualWithoutConsideringStr(const DataArrayDouble& other, double prec) const
1120 {
1121   std::string tmp;
1122   return _mem.isEqual(other._mem,prec,tmp);
1123 }
1124
1125 /*!
1126  * Returns a new DataArrayDouble holding the same values as \a this array but differently
1127  * arranged in memory. If \a this array holds 2 components of 3 values:
1128  * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
1129  * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
1130  *  \warning Do not confuse this method with transpose()!
1131  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1132  *          is to delete using decrRef() as it is no more needed.
1133  *  \throw If \a this is not allocated.
1134  */
1135 DataArrayDouble *DataArrayDouble::fromNoInterlace() const
1136 {
1137   if(_mem.isNull())
1138     throw INTERP_KERNEL::Exception("DataArrayDouble::fromNoInterlace : Not defined array !");
1139   double *tab=_mem.fromNoInterlace(getNumberOfComponents());
1140   DataArrayDouble *ret=DataArrayDouble::New();
1141   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
1142   return ret;
1143 }
1144
1145 /*!
1146  * Returns a new DataArrayDouble holding the same values as \a this array but differently
1147  * arranged in memory. If \a this array holds 2 components of 3 values:
1148  * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
1149  * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
1150  *  \warning Do not confuse this method with transpose()!
1151  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1152  *          is to delete using decrRef() as it is no more needed.
1153  *  \throw If \a this is not allocated.
1154  */
1155 DataArrayDouble *DataArrayDouble::toNoInterlace() const
1156 {
1157   if(_mem.isNull())
1158     throw INTERP_KERNEL::Exception("DataArrayDouble::toNoInterlace : Not defined array !");
1159   double *tab=_mem.toNoInterlace(getNumberOfComponents());
1160   DataArrayDouble *ret=DataArrayDouble::New();
1161   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
1162   return ret;
1163 }
1164
1165 /*!
1166  * Appends components of another array to components of \a this one, tuple by tuple.
1167  * So that the number of tuples of \a this array remains the same and the number of 
1168  * components increases.
1169  *  \param [in] other - the DataArrayDouble to append to \a this one.
1170  *  \throw If \a this is not allocated.
1171  *  \throw If \a this and \a other arrays have different number of tuples.
1172  *
1173  *  \if ENABLE_EXAMPLES
1174  *  \ref cpp_mcdataarraydouble_meldwith "Here is a C++ example".
1175  *
1176  *  \ref py_mcdataarraydouble_meldwith "Here is a Python example".
1177  *  \endif
1178  */
1179 void DataArrayDouble::meldWith(const DataArrayDouble *other)
1180 {
1181   checkAllocated();
1182   other->checkAllocated();
1183   int nbOfTuples=getNumberOfTuples();
1184   if(nbOfTuples!=other->getNumberOfTuples())
1185     throw INTERP_KERNEL::Exception("DataArrayDouble::meldWith : mismatch of number of tuples !");
1186   int nbOfComp1=getNumberOfComponents();
1187   int nbOfComp2=other->getNumberOfComponents();
1188   double *newArr=(double *)malloc((nbOfTuples*(nbOfComp1+nbOfComp2))*sizeof(double));
1189   double *w=newArr;
1190   const double *inp1=getConstPointer();
1191   const double *inp2=other->getConstPointer();
1192   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
1193     {
1194       w=std::copy(inp1,inp1+nbOfComp1,w);
1195       w=std::copy(inp2,inp2+nbOfComp2,w);
1196     }
1197   useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
1198   std::vector<int> compIds(nbOfComp2);
1199   for(int i=0;i<nbOfComp2;i++)
1200     compIds[i]=nbOfComp1+i;
1201   copyPartOfStringInfoFrom2(compIds,*other);
1202 }
1203
1204 /*!
1205  * This method checks that all tuples in \a other are in \a this.
1206  * If true, the output param \a tupleIds contains the tuples ids of \a this that correspond to tupes in \a this.
1207  * 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.
1208  *
1209  * \param [in] other - the array having the same number of components than \a this.
1210  * \param [out] tupleIds - the tuple ids containing the same number of tuples than \a other has.
1211  * \sa DataArrayDouble::findCommonTuples
1212  */
1213 bool DataArrayDouble::areIncludedInMe(const DataArrayDouble *other, double prec, DataArrayInt *&tupleIds) const
1214 {
1215   if(!other)
1216     throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : input array is NULL !");
1217   checkAllocated(); other->checkAllocated();
1218   if(getNumberOfComponents()!=other->getNumberOfComponents())
1219     throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : the number of components does not match !");
1220   MCAuto<DataArrayDouble> a=DataArrayDouble::Aggregate(this,other);
1221   DataArrayInt *c=0,*ci=0;
1222   a->findCommonTuples(prec,getNumberOfTuples(),c,ci);
1223   MCAuto<DataArrayInt> cSafe(c),ciSafe(ci);
1224   int newNbOfTuples=-1;
1225   MCAuto<DataArrayInt> ids=DataArrayInt::ConvertIndexArrayToO2N(a->getNumberOfTuples(),c->begin(),ci->begin(),ci->end(),newNbOfTuples);
1226   MCAuto<DataArrayInt> ret1=ids->selectByTupleIdSafeSlice(getNumberOfTuples(),a->getNumberOfTuples(),1);
1227   tupleIds=ret1.retn();
1228   return newNbOfTuples==getNumberOfTuples();
1229 }
1230
1231 /*!
1232  * Searches for tuples coincident within \a prec tolerance. Each tuple is considered
1233  * as coordinates of a point in getNumberOfComponents()-dimensional space. The
1234  * distance separating two points is computed with the infinite norm.
1235  *
1236  * Indices of coincident tuples are stored in output arrays.
1237  * A pair of arrays (\a comm, \a commIndex) is called "Surjective Format 2".
1238  *
1239  * This method is typically used by MEDCouplingPointSet::findCommonNodes() and
1240  * MEDCouplingUMesh::mergeNodes().
1241  *  \param [in] prec - minimal absolute distance between two tuples (infinite norm) at which they are
1242  *              considered not coincident.
1243  *  \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
1244  *              tuples have id strictly lower than \a limitTupleId then they are not returned.
1245  *  \param [out] comm - the array holding ids (== indices) of coincident tuples. 
1246  *               \a comm->getNumberOfComponents() == 1. 
1247  *               \a comm->getNumberOfTuples() == \a commIndex->back().
1248  *  \param [out] commIndex - the array dividing all indices stored in \a comm into
1249  *               groups of (indices of) coincident tuples. Its every value is a tuple
1250  *               index where a next group of tuples begins. For example the second
1251  *               group of tuples in \a comm is described by following range of indices:
1252  *               [ \a commIndex[1], \a commIndex[2] ). \a commIndex->getNumberOfTuples()-1
1253  *               gives the number of groups of coincident tuples.
1254  *  \throw If \a this is not allocated.
1255  *  \throw If the number of components is not in [1,2,3,4].
1256  *
1257  *  \if ENABLE_EXAMPLES
1258  *  \ref cpp_mcdataarraydouble_findcommontuples "Here is a C++ example".
1259  *
1260  *  \ref py_mcdataarraydouble_findcommontuples  "Here is a Python example".
1261  *  \endif
1262  *  \sa DataArrayInt::ConvertIndexArrayToO2N(), DataArrayDouble::areIncludedInMe
1263  */
1264 void DataArrayDouble::findCommonTuples(double prec, int limitTupleId, DataArrayInt *&comm, DataArrayInt *&commIndex) const
1265 {
1266   checkAllocated();
1267   int nbOfCompo=getNumberOfComponents();
1268   if ((nbOfCompo<1) || (nbOfCompo>4)) //test before work
1269     throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : Unexpected spacedim of coords. Must be 1, 2, 3 or 4.");
1270
1271   int nbOfTuples=getNumberOfTuples();
1272   //
1273   MCAuto<DataArrayInt> c(DataArrayInt::New()),cI(DataArrayInt::New()); c->alloc(0,1); cI->pushBackSilent(0);
1274   switch(nbOfCompo)
1275   {
1276     case 4:
1277       findCommonTuplesAlg<4>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1278       break;
1279     case 3:
1280       findCommonTuplesAlg<3>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1281       break;
1282     case 2:
1283       findCommonTuplesAlg<2>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1284       break;
1285     case 1:
1286       findCommonTuplesAlg<1>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1287       break;
1288     default:
1289       throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : nb of components managed are 1,2,3 and 4 ! not implemented for other number of components !");
1290   }
1291   comm=c.retn();
1292   commIndex=cI.retn();
1293 }
1294
1295 /*!
1296  * 
1297  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayDouble instance.
1298  *             \a nbTimes  should be at least equal to 1.
1299  * \return a newly allocated DataArrayDouble having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
1300  * \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.
1301  */
1302 DataArrayDouble *DataArrayDouble::duplicateEachTupleNTimes(int nbTimes) const
1303 {
1304   checkAllocated();
1305   if(getNumberOfComponents()!=1)
1306     throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : this should have only one component !");
1307   if(nbTimes<1)
1308     throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : nb times should be >= 1 !");
1309   int nbTuples=getNumberOfTuples();
1310   const double *inPtr=getConstPointer();
1311   MCAuto<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbTimes*nbTuples,1);
1312   double *retPtr=ret->getPointer();
1313   for(int i=0;i<nbTuples;i++,inPtr++)
1314     {
1315       double val=*inPtr;
1316       for(int j=0;j<nbTimes;j++,retPtr++)
1317         *retPtr=val;
1318     }
1319   ret->copyStringInfoFrom(*this);
1320   return ret.retn();
1321 }
1322
1323 /*!
1324  * This methods returns the minimal distance between the two set of points \a this and \a other.
1325  * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
1326  * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
1327  *
1328  * \param [out] thisTupleId the tuple id in \a this corresponding to the returned minimal distance
1329  * \param [out] otherTupleId the tuple id in \a other corresponding to the returned minimal distance
1330  * \return the minimal distance between the two set of points \a this and \a other.
1331  * \sa DataArrayDouble::findClosestTupleId
1332  */
1333 double DataArrayDouble::minimalDistanceTo(const DataArrayDouble *other, int& thisTupleId, int& otherTupleId) const
1334 {
1335   MCAuto<DataArrayInt> part1=findClosestTupleId(other);
1336   int nbOfCompo(getNumberOfComponents());
1337   int otherNbTuples(other->getNumberOfTuples());
1338   const double *thisPt(begin()),*otherPt(other->begin());
1339   const int *part1Pt(part1->begin());
1340   double ret=std::numeric_limits<double>::max();
1341   for(int i=0;i<otherNbTuples;i++,part1Pt++,otherPt+=nbOfCompo)
1342     {
1343       double tmp(0.);
1344       for(int j=0;j<nbOfCompo;j++)
1345         tmp+=(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j])*(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j]);
1346       if(tmp<ret)
1347         { ret=tmp; thisTupleId=*part1Pt; otherTupleId=i; }
1348     }
1349   return sqrt(ret);
1350 }
1351
1352 /*!
1353  * This methods returns for each tuple in \a other which tuple in \a this is the closest.
1354  * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
1355  * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
1356  *
1357  * \return a newly allocated (new object to be dealt by the caller) DataArrayInt having \c other->getNumberOfTuples() tuples and one components.
1358  * \sa DataArrayDouble::minimalDistanceTo
1359  */
1360 DataArrayInt *DataArrayDouble::findClosestTupleId(const DataArrayDouble *other) const
1361 {
1362   if(!other)
1363     throw INTERP_KERNEL::Exception("DataArrayDouble::findClosestTupleId : other instance is NULL !");
1364   checkAllocated(); other->checkAllocated();
1365   int nbOfCompo=getNumberOfComponents();
1366   if(nbOfCompo!=other->getNumberOfComponents())
1367     {
1368       std::ostringstream oss; oss << "DataArrayDouble::findClosestTupleId : number of components in this is " << nbOfCompo;
1369       oss << ", whereas number of components in other is " << other->getNumberOfComponents() << "! Should be equal !";
1370       throw INTERP_KERNEL::Exception(oss.str().c_str());
1371     }
1372   int nbOfTuples=other->getNumberOfTuples();
1373   int thisNbOfTuples=getNumberOfTuples();
1374   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuples,1);
1375   double bounds[6];
1376   getMinMaxPerComponent(bounds);
1377   switch(nbOfCompo)
1378   {
1379     case 3:
1380       {
1381         double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2])),zDelta(fabs(bounds[5]-bounds[4]));
1382         double delta=std::max(xDelta,yDelta); delta=std::max(delta,zDelta);
1383         double characSize=pow((delta*delta*delta)/((double)thisNbOfTuples),1./3.);
1384         BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1385         FindClosestTupleIdAlg<3>(myTree,3.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1386         break;
1387       }
1388     case 2:
1389       {
1390         double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2]));
1391         double delta=std::max(xDelta,yDelta);
1392         double characSize=sqrt(delta/(double)thisNbOfTuples);
1393         BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1394         FindClosestTupleIdAlg<2>(myTree,2.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1395         break;
1396       }
1397     case 1:
1398       {
1399         double characSize=fabs(bounds[1]-bounds[0])/thisNbOfTuples;
1400         BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1401         FindClosestTupleIdAlg<1>(myTree,1.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1402         break;
1403       }
1404     default:
1405       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for findClosestTupleId. Must be 1, 2 or 3.");
1406   }
1407   return ret.retn();
1408 }
1409
1410 /*!
1411  * This method expects that \a this and \a otherBBoxFrmt arrays are bounding box arrays ( as the output of MEDCouplingPointSet::getBoundingBoxForBBTree method ).
1412  * 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
1413  * how many bounding boxes in \a otherBBoxFrmt.
1414  * So, this method expects that \a this and \a otherBBoxFrmt have the same number of components.
1415  *
1416  * \param [in] otherBBoxFrmt - It is an array .
1417  * \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.
1418  * \sa MEDCouplingPointSet::getBoundingBoxForBBTree
1419  * \throw If \a this and \a otherBBoxFrmt have not the same number of components.
1420  * \throw If \a this and \a otherBBoxFrmt number of components is not even (BBox format).
1421  */
1422 DataArrayInt *DataArrayDouble::computeNbOfInteractionsWith(const DataArrayDouble *otherBBoxFrmt, double eps) const
1423 {
1424   if(!otherBBoxFrmt)
1425     throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : input array is NULL !");
1426   if(!isAllocated() || !otherBBoxFrmt->isAllocated())
1427     throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : this and input array must be allocated !");
1428   int nbOfComp(getNumberOfComponents()),nbOfTuples(getNumberOfTuples());
1429   if(nbOfComp!=otherBBoxFrmt->getNumberOfComponents())
1430     {
1431       std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : this number of components (" << nbOfComp << ") must be equal to the number of components of input array (" << otherBBoxFrmt->getNumberOfComponents() << ") !";
1432       throw INTERP_KERNEL::Exception(oss.str().c_str());
1433     }
1434   if(nbOfComp%2!=0)
1435     {
1436       std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : Number of components (" << nbOfComp << ") is not even ! It should be to be compatible with bbox format !";
1437       throw INTERP_KERNEL::Exception(oss.str().c_str());
1438     }
1439   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbOfTuples,1);
1440   const double *thisBBPtr(begin());
1441   int *retPtr(ret->getPointer());
1442   switch(nbOfComp/2)
1443   {
1444     case 3:
1445       {
1446         BBTree<3,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
1447         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
1448           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
1449         break;
1450       }
1451     case 2:
1452       {
1453         BBTree<2,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
1454         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
1455           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
1456         break;
1457       }
1458     case 1:
1459       {
1460         BBTree<1,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
1461         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
1462           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
1463         break;
1464       }
1465     default:
1466       throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : space dimension supported are [1,2,3] !");
1467   }
1468
1469   return ret.retn();
1470 }
1471
1472 /*!
1473  * Returns a copy of \a this array by excluding coincident tuples. Each tuple is
1474  * considered as coordinates of a point in getNumberOfComponents()-dimensional
1475  * space. The distance between tuples is computed using norm2. If several tuples are
1476  * not far each from other than \a prec, only one of them remains in the result
1477  * array. The order of tuples in the result array is same as in \a this one except
1478  * that coincident tuples are excluded.
1479  *  \param [in] prec - minimal absolute distance between two tuples at which they are
1480  *              considered not coincident.
1481  *  \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
1482  *              tuples have id strictly lower than \a limitTupleId then they are not excluded.
1483  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1484  *          is to delete using decrRef() as it is no more needed.
1485  *  \throw If \a this is not allocated.
1486  *  \throw If the number of components is not in [1,2,3,4].
1487  *
1488  *  \if ENABLE_EXAMPLES
1489  *  \ref py_mcdataarraydouble_getdifferentvalues "Here is a Python example".
1490  *  \endif
1491  */
1492 DataArrayDouble *DataArrayDouble::getDifferentValues(double prec, int limitTupleId) const
1493 {
1494   checkAllocated();
1495   DataArrayInt *c0=0,*cI0=0;
1496   findCommonTuples(prec,limitTupleId,c0,cI0);
1497   MCAuto<DataArrayInt> c(c0),cI(cI0);
1498   int newNbOfTuples=-1;
1499   MCAuto<DataArrayInt> o2n=DataArrayInt::ConvertIndexArrayToO2N(getNumberOfTuples(),c0->begin(),cI0->begin(),cI0->end(),newNbOfTuples);
1500   return renumberAndReduce(o2n->getConstPointer(),newNbOfTuples);
1501 }
1502
1503 /*!
1504  * Copy all components in a specified order from another DataArrayDouble.
1505  * Both numerical and textual data is copied. The number of tuples in \a this and
1506  * the other array can be different.
1507  *  \param [in] a - the array to copy data from.
1508  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
1509  *              to be copied.
1510  *  \throw If \a a is NULL.
1511  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
1512  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
1513  *
1514  *  \if ENABLE_EXAMPLES
1515  *  \ref py_mcdataarraydouble_setselectedcomponents "Here is a Python example".
1516  *  \endif
1517  */
1518 void DataArrayDouble::setSelectedComponents(const DataArrayDouble *a, const std::vector<int>& compoIds)
1519 {
1520   if(!a)
1521     throw INTERP_KERNEL::Exception("DataArrayDouble::setSelectedComponents : input DataArrayDouble is NULL !");
1522   checkAllocated();
1523   copyPartOfStringInfoFrom2(compoIds,*a);
1524   std::size_t partOfCompoSz=compoIds.size();
1525   int nbOfCompo=getNumberOfComponents();
1526   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
1527   const double *ac=a->getConstPointer();
1528   double *nc=getPointer();
1529   for(int i=0;i<nbOfTuples;i++)
1530     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
1531       nc[nbOfCompo*i+compoIds[j]]=*ac;
1532 }
1533
1534 void DataArrayDouble::SetArrayIn(DataArrayDouble *newArray, DataArrayDouble* &arrayToSet)
1535 {
1536   if(newArray!=arrayToSet)
1537     {
1538       if(arrayToSet)
1539         arrayToSet->decrRef();
1540       arrayToSet=newArray;
1541       if(arrayToSet)
1542         arrayToSet->incrRef();
1543     }
1544 }
1545
1546 void DataArrayDouble::aggregate(const DataArrayDouble *other)
1547 {
1548   if(!other)
1549     throw INTERP_KERNEL::Exception("DataArrayDouble::aggregate : null pointer !");
1550   if(getNumberOfComponents()!=other->getNumberOfComponents())
1551     throw INTERP_KERNEL::Exception("DataArrayDouble::aggregate : mismatch number of components !");
1552   _mem.insertAtTheEnd(other->begin(),other->end());
1553 }
1554
1555 /*!
1556  * Checks if 0.0 value is present in \a this array. If it is the case, an exception
1557  * is thrown.
1558  * \throw If zero is found in \a this array.
1559  */
1560 void DataArrayDouble::checkNoNullValues() const
1561 {
1562   const double *tmp=getConstPointer();
1563   std::size_t nbOfElems=getNbOfElems();
1564   const double *where=std::find(tmp,tmp+nbOfElems,0.);
1565   if(where!=tmp+nbOfElems)
1566     throw INTERP_KERNEL::Exception("A value 0.0 have been detected !");
1567 }
1568
1569 /*!
1570  * Computes minimal and maximal value in each component. An output array is filled
1571  * with \c 2 * \a this->getNumberOfComponents() values, so the caller is to allocate
1572  * enough memory before calling this method.
1573  *  \param [out] bounds - array of size at least 2 *\a this->getNumberOfComponents().
1574  *               It is filled as follows:<br>
1575  *               \a bounds[0] = \c min_of_component_0 <br>
1576  *               \a bounds[1] = \c max_of_component_0 <br>
1577  *               \a bounds[2] = \c min_of_component_1 <br>
1578  *               \a bounds[3] = \c max_of_component_1 <br>
1579  *               ...
1580  */
1581 void DataArrayDouble::getMinMaxPerComponent(double *bounds) const
1582 {
1583   checkAllocated();
1584   int dim=getNumberOfComponents();
1585   for (int idim=0; idim<dim; idim++)
1586     {
1587       bounds[idim*2]=std::numeric_limits<double>::max();
1588       bounds[idim*2+1]=-std::numeric_limits<double>::max();
1589     } 
1590   const double *ptr=getConstPointer();
1591   int nbOfTuples=getNumberOfTuples();
1592   for(int i=0;i<nbOfTuples;i++)
1593     {
1594       for(int idim=0;idim<dim;idim++)
1595         {
1596           if(bounds[idim*2]>ptr[i*dim+idim])
1597             {
1598               bounds[idim*2]=ptr[i*dim+idim];
1599             }
1600           if(bounds[idim*2+1]<ptr[i*dim+idim])
1601             {
1602               bounds[idim*2+1]=ptr[i*dim+idim];
1603             }
1604         }
1605     }
1606 }
1607
1608 /*!
1609  * This method retrieves a newly allocated DataArrayDouble instance having same number of tuples than \a this and twice number of components than \a this
1610  * to store both the min and max per component of each tuples. 
1611  * \param [in] epsilon the width of the bbox (identical in each direction) - 0.0 by default
1612  *
1613  * \return a newly created DataArrayDouble instance having \c this->getNumberOfTuples() tuples and 2 * \c this->getNumberOfComponent() components
1614  *
1615  * \throw If \a this is not allocated yet.
1616  */
1617 DataArrayDouble *DataArrayDouble::computeBBoxPerTuple(double epsilon) const
1618 {
1619   checkAllocated();
1620   const double *dataPtr=getConstPointer();
1621   int nbOfCompo=getNumberOfComponents();
1622   int nbTuples=getNumberOfTuples();
1623   MCAuto<DataArrayDouble> bbox=DataArrayDouble::New();
1624   bbox->alloc(nbTuples,2*nbOfCompo);
1625   double *bboxPtr=bbox->getPointer();
1626   for(int i=0;i<nbTuples;i++)
1627     {
1628       for(int j=0;j<nbOfCompo;j++)
1629         {
1630           bboxPtr[2*nbOfCompo*i+2*j]=dataPtr[nbOfCompo*i+j]-epsilon;
1631           bboxPtr[2*nbOfCompo*i+2*j+1]=dataPtr[nbOfCompo*i+j]+epsilon;
1632         }
1633     }
1634   return bbox.retn();
1635 }
1636
1637 /*!
1638  * For each tuples **t** in \a other, this method retrieves tuples in \a this that are equal to **t**.
1639  * Two tuples are considered equal if the euclidian distance between the two tuples is lower than \a eps.
1640  * 
1641  * \param [in] other a DataArrayDouble having same number of components than \a this.
1642  * \param [in] eps absolute precision representing distance (using infinite norm) between 2 tuples behind which 2 tuples are considered equal.
1643  * \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.
1644  *             \a cI allows to extract information in \a c.
1645  * \param [out] cI is an indirection array that allows to extract the data contained in \a c.
1646  *
1647  * \throw In case of:
1648  *  - \a this is not allocated
1649  *  - \a other is not allocated or null
1650  *  - \a this and \a other do not have the same number of components
1651  *  - if number of components of \a this is not in [1,2,3]
1652  *
1653  * \sa MEDCouplingPointSet::getNodeIdsNearPoints, DataArrayDouble::getDifferentValues
1654  */
1655 void DataArrayDouble::computeTupleIdsNearTuples(const DataArrayDouble *other, double eps, DataArrayInt *& c, DataArrayInt *& cI) const
1656 {
1657   if(!other)
1658     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : input pointer other is null !");
1659   checkAllocated();
1660   other->checkAllocated();
1661   int nbOfCompo=getNumberOfComponents();
1662   int otherNbOfCompo=other->getNumberOfComponents();
1663   if(nbOfCompo!=otherNbOfCompo)
1664     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : number of components should be equal between this and other !");
1665   int nbOfTuplesOther=other->getNumberOfTuples();
1666   MCAuto<DataArrayInt> cArr(DataArrayInt::New()),cIArr(DataArrayInt::New()); cArr->alloc(0,1); cIArr->pushBackSilent(0);
1667   switch(nbOfCompo)
1668   {
1669     case 3:
1670       {
1671         BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
1672         FindTupleIdsNearTuplesAlg<3>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
1673         break;
1674       }
1675     case 2:
1676       {
1677         BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
1678         FindTupleIdsNearTuplesAlg<2>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
1679         break;
1680       }
1681     case 1:
1682       {
1683         BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
1684         FindTupleIdsNearTuplesAlg<1>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
1685         break;
1686       }
1687     default:
1688       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for computeTupleIdsNearTuples. Must be 1, 2 or 3.");
1689   }
1690   c=cArr.retn(); cI=cIArr.retn();
1691 }
1692
1693 /*!
1694  * 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
1695  * around origin of 'radius' 1.
1696  * 
1697  * \param [in] eps absolute epsilon. under that value of delta between max and min no scale is performed.
1698  */
1699 void DataArrayDouble::recenterForMaxPrecision(double eps)
1700 {
1701   checkAllocated();
1702   int dim=getNumberOfComponents();
1703   std::vector<double> bounds(2*dim);
1704   getMinMaxPerComponent(&bounds[0]);
1705   for(int i=0;i<dim;i++)
1706     {
1707       double delta=bounds[2*i+1]-bounds[2*i];
1708       double offset=(bounds[2*i]+bounds[2*i+1])/2.;
1709       if(delta>eps)
1710         applyLin(1./delta,-offset/delta,i);
1711       else
1712         applyLin(1.,-offset,i);
1713     }
1714 }
1715
1716 /*!
1717  * Returns the maximal value and all its locations within \a this one-dimensional array.
1718  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
1719  *               tuples holding the maximal value. The caller is to delete it using
1720  *               decrRef() as it is no more needed.
1721  *  \return double - the maximal value among all values of \a this array.
1722  *  \throw If \a this->getNumberOfComponents() != 1
1723  *  \throw If \a this->getNumberOfTuples() < 1
1724  */
1725 double DataArrayDouble::getMaxValue2(DataArrayInt*& tupleIds) const
1726 {
1727   int tmp;
1728   tupleIds=0;
1729   double ret=getMaxValue(tmp);
1730   tupleIds=findIdsInRange(ret,ret);
1731   return ret;
1732 }
1733
1734 /*!
1735  * Returns the minimal value and all its locations within \a this one-dimensional array.
1736  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
1737  *               tuples holding the minimal value. The caller is to delete it using
1738  *               decrRef() as it is no more needed.
1739  *  \return double - the minimal value among all values of \a this array.
1740  *  \throw If \a this->getNumberOfComponents() != 1
1741  *  \throw If \a this->getNumberOfTuples() < 1
1742  */
1743 double DataArrayDouble::getMinValue2(DataArrayInt*& tupleIds) const
1744 {
1745   int tmp;
1746   tupleIds=0;
1747   double ret=getMinValue(tmp);
1748   tupleIds=findIdsInRange(ret,ret);
1749   return ret;
1750 }
1751
1752 /*!
1753  * 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.
1754  * This method only works for single component array.
1755  *
1756  * \return a value in [ 0, \c this->getNumberOfTuples() )
1757  *
1758  * \throw If \a this is not allocated
1759  *
1760  */
1761 int DataArrayDouble::count(double value, double eps) const
1762 {
1763   int ret=0;
1764   checkAllocated();
1765   if(getNumberOfComponents()!=1)
1766     throw INTERP_KERNEL::Exception("DataArrayDouble::count : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
1767   const double *vals=begin();
1768   int nbOfTuples=getNumberOfTuples();
1769   for(int i=0;i<nbOfTuples;i++,vals++)
1770     if(fabs(*vals-value)<=eps)
1771       ret++;
1772   return ret;
1773 }
1774
1775 /*!
1776  * Returns the average value of \a this one-dimensional array.
1777  *  \return double - the average value over all values of \a this array.
1778  *  \throw If \a this->getNumberOfComponents() != 1
1779  *  \throw If \a this->getNumberOfTuples() < 1
1780  */
1781 double DataArrayDouble::getAverageValue() const
1782 {
1783   if(getNumberOfComponents()!=1)
1784     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
1785   int nbOfTuples=getNumberOfTuples();
1786   if(nbOfTuples<=0)
1787     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : array exists but number of tuples must be > 0 !");
1788   const double *vals=getConstPointer();
1789   double ret=std::accumulate(vals,vals+nbOfTuples,0.);
1790   return ret/nbOfTuples;
1791 }
1792
1793 /*!
1794  * Returns the Euclidean norm of the vector defined by \a this array.
1795  *  \return double - the value of the Euclidean norm, i.e.
1796  *          the square root of the inner product of vector.
1797  *  \throw If \a this is not allocated.
1798  */
1799 double DataArrayDouble::norm2() const
1800 {
1801   checkAllocated();
1802   double ret=0.;
1803   std::size_t nbOfElems=getNbOfElems();
1804   const double *pt=getConstPointer();
1805   for(std::size_t i=0;i<nbOfElems;i++,pt++)
1806     ret+=(*pt)*(*pt);
1807   return sqrt(ret);
1808 }
1809
1810 /*!
1811  * Returns the maximum norm of the vector defined by \a this array.
1812  * This method works even if the number of components is diferent from one.
1813  * If the number of elements in \a this is 0, -1. is returned.
1814  *  \return double - the value of the maximum norm, i.e.
1815  *          the maximal absolute value among values of \a this array (whatever its number of components).
1816  *  \throw If \a this is not allocated.
1817  */
1818 double DataArrayDouble::normMax() const
1819 {
1820   checkAllocated();
1821   double ret(-1.);
1822   std::size_t nbOfElems(getNbOfElems());
1823   const double *pt(getConstPointer());
1824   for(std::size_t i=0;i<nbOfElems;i++,pt++)
1825     {
1826       double val(std::abs(*pt));
1827       if(val>ret)
1828         ret=val;
1829     }
1830   return ret;
1831 }
1832
1833 /*!
1834  * Returns the minimum norm (absolute value) of the vector defined by \a this array.
1835  * This method works even if the number of components is diferent from one.
1836  * If the number of elements in \a this is 0, std::numeric_limits<double>::max() is returned.
1837  *  \return double - the value of the minimum norm, i.e.
1838  *          the minimal absolute value among values of \a this array (whatever its number of components).
1839  *  \throw If \a this is not allocated.
1840  */
1841 double DataArrayDouble::normMin() const
1842 {
1843   checkAllocated();
1844   double ret(std::numeric_limits<double>::max());
1845   std::size_t nbOfElems(getNbOfElems());
1846   const double *pt(getConstPointer());
1847   for(std::size_t i=0;i<nbOfElems;i++,pt++)
1848     {
1849       double val(std::abs(*pt));
1850       if(val<ret)
1851         ret=val;
1852     }
1853   return ret;
1854 }
1855
1856 /*!
1857  * Accumulates values of each component of \a this array.
1858  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
1859  *         by the caller, that is filled by this method with sum value for each
1860  *         component.
1861  *  \throw If \a this is not allocated.
1862  */
1863 void DataArrayDouble::accumulate(double *res) const
1864 {
1865   checkAllocated();
1866   const double *ptr=getConstPointer();
1867   int nbTuple=getNumberOfTuples();
1868   int nbComps=getNumberOfComponents();
1869   std::fill(res,res+nbComps,0.);
1870   for(int i=0;i<nbTuple;i++)
1871     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<double>());
1872 }
1873
1874 /*!
1875  * This method returns the min distance from an external tuple defined by [ \a tupleBg , \a tupleEnd ) to \a this and
1876  * the first tuple in \a this that matches the returned distance. If there is no tuples in \a this an exception will be thrown.
1877  *
1878  *
1879  * \a this is expected to be allocated and expected to have a number of components equal to the distance from \a tupleBg to
1880  * \a tupleEnd. If not an exception will be thrown.
1881  *
1882  * \param [in] tupleBg start pointer (included) of input external tuple
1883  * \param [in] tupleEnd end pointer (not included) of input external tuple
1884  * \param [out] tupleId the tuple id in \a this that matches the min of distance between \a this and input external tuple
1885  * \return the min distance.
1886  * \sa MEDCouplingUMesh::distanceToPoint
1887  */
1888 double DataArrayDouble::distanceToTuple(const double *tupleBg, const double *tupleEnd, int& tupleId) const
1889 {
1890   checkAllocated();
1891   int nbTuple=getNumberOfTuples();
1892   int nbComps=getNumberOfComponents();
1893   if(nbComps!=(int)std::distance(tupleBg,tupleEnd))
1894     { 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()); }
1895   if(nbTuple==0)
1896     throw INTERP_KERNEL::Exception("DataArrayDouble::distanceToTuple : no tuple in this ! No distance to compute !");
1897   double ret0=std::numeric_limits<double>::max();
1898   tupleId=-1;
1899   const double *work=getConstPointer();
1900   for(int i=0;i<nbTuple;i++)
1901     {
1902       double val=0.;
1903       for(int j=0;j<nbComps;j++,work++) 
1904         val+=(*work-tupleBg[j])*((*work-tupleBg[j]));
1905       if(val>=ret0)
1906         continue;
1907       else
1908         { ret0=val; tupleId=i; }
1909     }
1910   return sqrt(ret0);
1911 }
1912
1913 /*!
1914  * Accumulate values of the given component of \a this array.
1915  *  \param [in] compId - the index of the component of interest.
1916  *  \return double - a sum value of \a compId-th component.
1917  *  \throw If \a this is not allocated.
1918  *  \throw If \a the condition ( 0 <= \a compId < \a this->getNumberOfComponents() ) is
1919  *         not respected.
1920  */
1921 double DataArrayDouble::accumulate(int compId) const
1922 {
1923   checkAllocated();
1924   const double *ptr=getConstPointer();
1925   int nbTuple=getNumberOfTuples();
1926   int nbComps=getNumberOfComponents();
1927   if(compId<0 || compId>=nbComps)
1928     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulate : Invalid compId specified : No such nb of components !");
1929   double ret=0.;
1930   for(int i=0;i<nbTuple;i++)
1931     ret+=ptr[i*nbComps+compId];
1932   return ret;
1933 }
1934
1935 /*!
1936  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
1937  * The returned array will have same number of components than \a this and number of tuples equal to
1938  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
1939  *
1940  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
1941  * 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.
1942  *
1943  * \param [in] bgOfIndex - begin (included) of the input index array.
1944  * \param [in] endOfIndex - end (excluded) of the input index array.
1945  * \return DataArrayDouble * - the new instance having the same number of components than \a this.
1946  * 
1947  * \throw If bgOfIndex or end is NULL.
1948  * \throw If input index array is not ascendingly sorted.
1949  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
1950  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
1951  */
1952 DataArrayDouble *DataArrayDouble::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
1953 {
1954   if(!bgOfIndex || !endOfIndex)
1955     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : input pointer NULL !");
1956   checkAllocated();
1957   int nbCompo=getNumberOfComponents();
1958   int nbOfTuples=getNumberOfTuples();
1959   int sz=(int)std::distance(bgOfIndex,endOfIndex);
1960   if(sz<1)
1961     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : invalid size of input index array !");
1962   sz--;
1963   MCAuto<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(sz,nbCompo);
1964   const int *w=bgOfIndex;
1965   if(*w<0 || *w>=nbOfTuples)
1966     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
1967   const double *srcPt=begin()+(*w)*nbCompo;
1968   double *tmp=ret->getPointer();
1969   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
1970     {
1971       std::fill(tmp,tmp+nbCompo,0.);
1972       if(w[1]>=w[0])
1973         {
1974           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
1975             {
1976               if(j>=0 && j<nbOfTuples)
1977                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<double>());
1978               else
1979                 {
1980                   std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
1981                   throw INTERP_KERNEL::Exception(oss.str().c_str());
1982                 }
1983             }
1984         }
1985       else
1986         {
1987           std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
1988           throw INTERP_KERNEL::Exception(oss.str().c_str());
1989         }
1990     }
1991   ret->copyStringInfoFrom(*this);
1992   return ret.retn();
1993 }
1994
1995 /*!
1996  * 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.
1997  * This method expects that \a this as only one component. The returned array will have \a this->getNumberOfTuples()+1 tuple with also one component.
1998  * The ith element of returned array is equal to the sum of elements in \a this with rank strictly lower than i.
1999  *
2000  * \return DataArrayDouble - A newly built array containing cum sum of \a this.
2001  */
2002 MCAuto<DataArrayDouble> DataArrayDouble::cumSum() const
2003 {
2004   checkAllocated();
2005   checkNbOfComps(1,"DataArrayDouble::cumSum : this is expected to be single component");
2006   int nbOfTuple(getNumberOfTuples());
2007   MCAuto<DataArrayDouble> ret(DataArrayDouble::New()); ret->alloc(nbOfTuple+1,1);
2008   double *ptr(ret->getPointer());
2009   ptr[0]=0.;
2010   const double *thisPtr(begin());
2011   for(int i=0;i<nbOfTuple;i++)
2012     ptr[i+1]=ptr[i]+thisPtr[i];
2013   return ret;
2014 }
2015
2016 /*!
2017  * Converts each 2D point defined by the tuple of \a this array from the Polar to the
2018  * Cartesian coordinate system. The two components of the tuple of \a this array are 
2019  * considered to contain (1) radius and (2) angle of the point in the Polar CS.
2020  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
2021  *          contains X and Y coordinates of the point in the Cartesian CS. The caller
2022  *          is to delete this array using decrRef() as it is no more needed. The array
2023  *          does not contain any textual info on components.
2024  *  \throw If \a this->getNumberOfComponents() != 2.
2025  * \sa fromCartToPolar
2026  */
2027 DataArrayDouble *DataArrayDouble::fromPolarToCart() const
2028 {
2029   checkAllocated();
2030   int nbOfComp(getNumberOfComponents());
2031   if(nbOfComp!=2)
2032     throw INTERP_KERNEL::Exception("DataArrayDouble::fromPolarToCart : must be an array with exactly 2 components !");
2033   int nbOfTuple(getNumberOfTuples());
2034   DataArrayDouble *ret(DataArrayDouble::New());
2035   ret->alloc(nbOfTuple,2);
2036   double *w(ret->getPointer());
2037   const double *wIn(getConstPointer());
2038   for(int i=0;i<nbOfTuple;i++,w+=2,wIn+=2)
2039     {
2040       w[0]=wIn[0]*cos(wIn[1]);
2041       w[1]=wIn[0]*sin(wIn[1]);
2042     }
2043   return ret;
2044 }
2045
2046 /*!
2047  * Converts each 3D point defined by the tuple of \a this array from the Cylindrical to
2048  * the Cartesian coordinate system. The three components of the tuple of \a this array 
2049  * are considered to contain (1) radius, (2) azimuth and (3) altitude of the point in
2050  * the Cylindrical CS.
2051  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
2052  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
2053  *          on the third component is copied from \a this array. The caller
2054  *          is to delete this array using decrRef() as it is no more needed. 
2055  *  \throw If \a this->getNumberOfComponents() != 3.
2056  * \sa fromCartToCyl
2057  */
2058 DataArrayDouble *DataArrayDouble::fromCylToCart() const
2059 {
2060   checkAllocated();
2061   int nbOfComp(getNumberOfComponents());
2062   if(nbOfComp!=3)
2063     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCylToCart : must be an array with exactly 3 components !");
2064   int nbOfTuple(getNumberOfTuples());
2065   DataArrayDouble *ret(DataArrayDouble::New());
2066   ret->alloc(getNumberOfTuples(),3);
2067   double *w(ret->getPointer());
2068   const double *wIn(getConstPointer());
2069   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
2070     {
2071       w[0]=wIn[0]*cos(wIn[1]);
2072       w[1]=wIn[0]*sin(wIn[1]);
2073       w[2]=wIn[2];
2074     }
2075   ret->setInfoOnComponent(2,getInfoOnComponent(2));
2076   return ret;
2077 }
2078
2079 /*!
2080  * Converts each 3D point defined by the tuple of \a this array from the Spherical to
2081  * the Cartesian coordinate system. The three components of the tuple of \a this array 
2082  * are considered to contain (1) radius, (2) polar angle and (3) azimuthal angle of the
2083  * point in the Cylindrical CS.
2084  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
2085  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
2086  *          on the third component is copied from \a this array. The caller
2087  *          is to delete this array using decrRef() as it is no more needed.
2088  *  \throw If \a this->getNumberOfComponents() != 3.
2089  * \sa fromCartToSpher
2090  */
2091 DataArrayDouble *DataArrayDouble::fromSpherToCart() const
2092 {
2093   checkAllocated();
2094   int nbOfComp(getNumberOfComponents());
2095   if(nbOfComp!=3)
2096     throw INTERP_KERNEL::Exception("DataArrayDouble::fromSpherToCart : must be an array with exactly 3 components !");
2097   int nbOfTuple(getNumberOfTuples());
2098   DataArrayDouble *ret(DataArrayDouble::New());
2099   ret->alloc(getNumberOfTuples(),3);
2100   double *w(ret->getPointer());
2101   const double *wIn(getConstPointer());
2102   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
2103     {
2104       w[0]=wIn[0]*cos(wIn[2])*sin(wIn[1]);
2105       w[1]=wIn[0]*sin(wIn[2])*sin(wIn[1]);
2106       w[2]=wIn[0]*cos(wIn[1]);
2107     }
2108   return ret;
2109 }
2110
2111 /*!
2112  * 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.
2113  * 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.
2114  * If \a at equals to AX_CYL the returned array will be the result of operation cylindric to cartesian of \a this...
2115  *
2116  * \param [in] atOfThis - The axis type of \a this.
2117  * \return DataArrayDouble * - the new instance of DataArrayDouble (that must be dealed by caller) containing the result of the cartesianizification of \a this.
2118  */
2119 DataArrayDouble *DataArrayDouble::cartesianize(MEDCouplingAxisType atOfThis) const
2120 {
2121   checkAllocated();
2122   int nbOfComp(getNumberOfComponents());
2123   MCAuto<DataArrayDouble> ret;
2124   switch(atOfThis)
2125     {
2126     case AX_CART:
2127       ret=deepCopy();
2128     case AX_CYL:
2129       if(nbOfComp==3)
2130         {
2131           ret=fromCylToCart();
2132           break;
2133         }
2134       if(nbOfComp==2)
2135         {
2136           ret=fromPolarToCart();
2137           break;
2138         }
2139       else
2140         throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : For AX_CYL, number of components must be in [2,3] !");
2141     case AX_SPHER:
2142       if(nbOfComp==3)
2143         {
2144           ret=fromSpherToCart();
2145           break;
2146         }
2147       if(nbOfComp==2)
2148         {
2149           ret=fromPolarToCart();
2150           break;
2151         }
2152       else
2153         throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : For AX_CYL, number of components must be in [2,3] !");
2154     default:
2155       throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : not recognized axis type ! Only AX_CART, AX_CYL and AX_SPHER supported !");
2156     }
2157   ret->copyStringInfoFrom(*this);
2158   return ret.retn();
2159 }
2160
2161 /*!
2162  * This method returns a newly created array to be deallocated that contains the result of conversion from cartesian to polar.
2163  * This method expects that \a this has exactly 2 components.
2164  * \sa fromPolarToCart
2165  */
2166 DataArrayDouble *DataArrayDouble::fromCartToPolar() const
2167 {
2168   MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2169   checkAllocated();
2170   int nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2171   if(nbOfComp!=2)
2172     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToPolar : must be an array with exactly 2 components !");
2173   ret->alloc(nbTuples,2);
2174   double *retPtr(ret->getPointer());
2175   const double *ptr(begin());
2176   for(int i=0;i<nbTuples;i++,ptr+=2,retPtr+=2)
2177     {
2178       retPtr[0]=sqrt(ptr[0]*ptr[0]+ptr[1]*ptr[1]);
2179       retPtr[1]=atan2(ptr[1],ptr[0]);
2180     }
2181   return ret.retn();
2182 }
2183
2184 /*!
2185  * This method returns a newly created array to be deallocated that contains the result of conversion from cartesian to cylindrical.
2186  * This method expects that \a this has exactly 3 components.
2187  * \sa fromCylToCart
2188  */
2189 DataArrayDouble *DataArrayDouble::fromCartToCyl() const
2190 {
2191   MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2192   checkAllocated();
2193   int nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2194   if(nbOfComp!=3)
2195     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCyl : must be an array with exactly 3 components !");
2196   ret->alloc(nbTuples,3);
2197   double *retPtr(ret->getPointer());
2198   const double *ptr(begin());
2199   for(int i=0;i<nbTuples;i++,ptr+=3,retPtr+=3)
2200     {
2201       retPtr[0]=sqrt(ptr[0]*ptr[0]+ptr[1]*ptr[1]);
2202       retPtr[1]=atan2(ptr[1],ptr[0]);
2203       retPtr[2]=ptr[2];
2204     }
2205   return ret.retn();
2206 }
2207
2208 /*!
2209  * This method returns a newly created array to be deallocated that contains the result of conversion from cartesian to spherical coordinates.
2210  * \sa fromSpherToCart
2211  */
2212 DataArrayDouble *DataArrayDouble::fromCartToSpher() const
2213 {
2214   MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2215   checkAllocated();
2216   int nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2217   if(nbOfComp!=3)
2218     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToSpher : must be an array with exactly 3 components !");
2219   ret->alloc(nbTuples,3);
2220   double *retPtr(ret->getPointer());
2221   const double *ptr(begin());
2222   for(int i=0;i<nbTuples;i++,ptr+=3,retPtr+=3)
2223     {
2224       retPtr[0]=sqrt(ptr[0]*ptr[0]+ptr[1]*ptr[1]+ptr[2]*ptr[2]);
2225       retPtr[1]=acos(ptr[2]/retPtr[0]);
2226       retPtr[2]=atan2(ptr[1],ptr[0]);
2227     }
2228   return ret.retn();
2229 }
2230
2231 /*!
2232  * 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.
2233  * This method expects that \a this has exactly 3 components.
2234  * \sa MEDCouplingFieldDouble::computeVectorFieldCyl
2235  */
2236 DataArrayDouble *DataArrayDouble::fromCartToCylGiven(const DataArrayDouble *coords, const double center[3], const double vect[3]) const
2237 {
2238   if(!coords)
2239     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : input coords are NULL !");
2240   MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2241   checkAllocated(); coords->checkAllocated();
2242   int nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2243   if(nbOfComp!=3)
2244     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : must be an array with exactly 3 components !");
2245   if(coords->getNumberOfComponents()!=3)
2246     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : coords array must have exactly 3 components !");
2247   if(coords->getNumberOfTuples()!=nbTuples)
2248     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : coords array must have the same number of tuples !");
2249   ret->alloc(nbTuples,nbOfComp);
2250   double magOfVect(sqrt(vect[0]*vect[0]+vect[1]*vect[1]+vect[2]*vect[2]));
2251   if(magOfVect<1e-12)
2252     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : magnitude of vect is too low !");
2253   double Ur[3],Uteta[3],Uz[3],*retPtr(ret->getPointer());
2254   const double *coo(coords->begin()),*vectField(begin());
2255   std::transform(vect,vect+3,Uz,std::bind2nd(std::multiplies<double>(),1./magOfVect));
2256   for(int i=0;i<nbTuples;i++,vectField+=3,retPtr+=3,coo+=3)
2257     {
2258       std::transform(coo,coo+3,center,Ur,std::minus<double>());
2259       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];
2260       double magOfTeta(sqrt(Uteta[0]*Uteta[0]+Uteta[1]*Uteta[1]+Uteta[2]*Uteta[2]));
2261       std::transform(Uteta,Uteta+3,Uteta,std::bind2nd(std::multiplies<double>(),1./magOfTeta));
2262       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];
2263       retPtr[0]=Ur[0]*vectField[0]+Ur[1]*vectField[1]+Ur[2]*vectField[2];
2264       retPtr[1]=Uteta[0]*vectField[0]+Uteta[1]*vectField[1]+Uteta[2]*vectField[2];
2265       retPtr[2]=Uz[0]*vectField[0]+Uz[1]*vectField[1]+Uz[2]*vectField[2];
2266     }
2267   ret->copyStringInfoFrom(*this);
2268   return ret.retn();
2269 }
2270
2271 /*!
2272  * Computes the doubly contracted product of every tensor defined by the tuple of \a this
2273  * array contating 6 components.
2274  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
2275  *          is calculated from the tuple <em>(t)</em> of \a this array as follows:
2276  *          \f$ t[0]^2+t[1]^2+t[2]^2+2*t[3]^2+2*t[4]^2+2*t[5]^2\f$.
2277  *         The caller is to delete this result array using decrRef() as it is no more needed. 
2278  *  \throw If \a this->getNumberOfComponents() != 6.
2279  */
2280 DataArrayDouble *DataArrayDouble::doublyContractedProduct() const
2281 {
2282   checkAllocated();
2283   int nbOfComp(getNumberOfComponents());
2284   if(nbOfComp!=6)
2285     throw INTERP_KERNEL::Exception("DataArrayDouble::doublyContractedProduct : must be an array with exactly 6 components !");
2286   DataArrayDouble *ret=DataArrayDouble::New();
2287   int nbOfTuple=getNumberOfTuples();
2288   ret->alloc(nbOfTuple,1);
2289   const double *src=getConstPointer();
2290   double *dest=ret->getPointer();
2291   for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
2292     *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];
2293   return ret;
2294 }
2295
2296 /*!
2297  * Computes the determinant of every square matrix defined by the tuple of \a this
2298  * array, which contains either 4, 6 or 9 components. The case of 6 components
2299  * corresponds to that of the upper triangular matrix.
2300  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
2301  *          is the determinant of matrix of the corresponding tuple of \a this array.
2302  *          The caller is to delete this result array using decrRef() as it is no more
2303  *          needed. 
2304  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2305  */
2306 DataArrayDouble *DataArrayDouble::determinant() const
2307 {
2308   checkAllocated();
2309   DataArrayDouble *ret=DataArrayDouble::New();
2310   int nbOfTuple=getNumberOfTuples();
2311   ret->alloc(nbOfTuple,1);
2312   const double *src=getConstPointer();
2313   double *dest=ret->getPointer();
2314   switch(getNumberOfComponents())
2315   {
2316     case 6:
2317       for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
2318         *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];
2319       return ret;
2320     case 4:
2321       for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
2322         *dest=src[0]*src[3]-src[1]*src[2];
2323       return ret;
2324     case 9:
2325       for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
2326         *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];
2327       return ret;
2328     default:
2329       ret->decrRef();
2330       throw INTERP_KERNEL::Exception("DataArrayDouble::determinant : Invalid number of components ! must be in 4,6,9 !");
2331   }
2332 }
2333
2334 /*!
2335  * Computes 3 eigenvalues of every upper triangular matrix defined by the tuple of
2336  * \a this array, which contains 6 components.
2337  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 3
2338  *          components, whose each tuple contains the eigenvalues of the matrix of
2339  *          corresponding tuple of \a this array. 
2340  *          The caller is to delete this result array using decrRef() as it is no more
2341  *          needed. 
2342  *  \throw If \a this->getNumberOfComponents() != 6.
2343  */
2344 DataArrayDouble *DataArrayDouble::eigenValues() const
2345 {
2346   checkAllocated();
2347   int nbOfComp=getNumberOfComponents();
2348   if(nbOfComp!=6)
2349     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenValues : must be an array with exactly 6 components !");
2350   DataArrayDouble *ret=DataArrayDouble::New();
2351   int nbOfTuple=getNumberOfTuples();
2352   ret->alloc(nbOfTuple,3);
2353   const double *src=getConstPointer();
2354   double *dest=ret->getPointer();
2355   for(int i=0;i<nbOfTuple;i++,dest+=3,src+=6)
2356     INTERP_KERNEL::computeEigenValues6(src,dest);
2357   return ret;
2358 }
2359
2360 /*!
2361  * Computes 3 eigenvectors of every upper triangular matrix defined by the tuple of
2362  * \a this array, which contains 6 components.
2363  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 9
2364  *          components, whose each tuple contains 3 eigenvectors of the matrix of
2365  *          corresponding tuple of \a this array.
2366  *          The caller is to delete this result array using decrRef() as it is no more
2367  *          needed.
2368  *  \throw If \a this->getNumberOfComponents() != 6.
2369  */
2370 DataArrayDouble *DataArrayDouble::eigenVectors() const
2371 {
2372   checkAllocated();
2373   int nbOfComp=getNumberOfComponents();
2374   if(nbOfComp!=6)
2375     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenVectors : must be an array with exactly 6 components !");
2376   DataArrayDouble *ret=DataArrayDouble::New();
2377   int nbOfTuple=getNumberOfTuples();
2378   ret->alloc(nbOfTuple,9);
2379   const double *src=getConstPointer();
2380   double *dest=ret->getPointer();
2381   for(int i=0;i<nbOfTuple;i++,src+=6)
2382     {
2383       double tmp[3];
2384       INTERP_KERNEL::computeEigenValues6(src,tmp);
2385       for(int j=0;j<3;j++,dest+=3)
2386         INTERP_KERNEL::computeEigenVectorForEigenValue6(src,tmp[j],1e-12,dest);
2387     }
2388   return ret;
2389 }
2390
2391 /*!
2392  * Computes the inverse matrix of every matrix defined by the tuple of \a this
2393  * array, which contains either 4, 6 or 9 components. The case of 6 components
2394  * corresponds to that of the upper triangular matrix.
2395  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2396  *          same number of components as \a this one, whose each tuple is the inverse
2397  *          matrix of the matrix of corresponding tuple of \a this array. 
2398  *          The caller is to delete this result array using decrRef() as it is no more
2399  *          needed. 
2400  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2401  */
2402 DataArrayDouble *DataArrayDouble::inverse() const
2403 {
2404   checkAllocated();
2405   int nbOfComp=getNumberOfComponents();
2406   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
2407     throw INTERP_KERNEL::Exception("DataArrayDouble::inversion : must be an array with 4,6 or 9 components !");
2408   DataArrayDouble *ret=DataArrayDouble::New();
2409   int nbOfTuple=getNumberOfTuples();
2410   ret->alloc(nbOfTuple,nbOfComp);
2411   const double *src=getConstPointer();
2412   double *dest=ret->getPointer();
2413   if(nbOfComp==6)
2414     for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
2415       {
2416         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];
2417         dest[0]=(src[1]*src[2]-src[4]*src[4])/det;
2418         dest[1]=(src[0]*src[2]-src[5]*src[5])/det;
2419         dest[2]=(src[0]*src[1]-src[3]*src[3])/det;
2420         dest[3]=(src[5]*src[4]-src[3]*src[2])/det;
2421         dest[4]=(src[5]*src[3]-src[0]*src[4])/det;
2422         dest[5]=(src[3]*src[4]-src[1]*src[5])/det;
2423       }
2424   else if(nbOfComp==4)
2425     for(int i=0;i<nbOfTuple;i++,dest+=4,src+=4)
2426       {
2427         double det=src[0]*src[3]-src[1]*src[2];
2428         dest[0]=src[3]/det;
2429         dest[1]=-src[1]/det;
2430         dest[2]=-src[2]/det;
2431         dest[3]=src[0]/det;
2432       }
2433   else
2434     for(int i=0;i<nbOfTuple;i++,dest+=9,src+=9)
2435       {
2436         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];
2437         dest[0]=(src[4]*src[8]-src[7]*src[5])/det;
2438         dest[1]=(src[7]*src[2]-src[1]*src[8])/det;
2439         dest[2]=(src[1]*src[5]-src[4]*src[2])/det;
2440         dest[3]=(src[6]*src[5]-src[3]*src[8])/det;
2441         dest[4]=(src[0]*src[8]-src[6]*src[2])/det;
2442         dest[5]=(src[2]*src[3]-src[0]*src[5])/det;
2443         dest[6]=(src[3]*src[7]-src[6]*src[4])/det;
2444         dest[7]=(src[6]*src[1]-src[0]*src[7])/det;
2445         dest[8]=(src[0]*src[4]-src[1]*src[3])/det;
2446       }
2447   return ret;
2448 }
2449
2450 /*!
2451  * Computes the trace of every matrix defined by the tuple of \a this
2452  * array, which contains either 4, 6 or 9 components. The case of 6 components
2453  * corresponds to that of the upper triangular matrix.
2454  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 
2455  *          1 component, whose each tuple is the trace of
2456  *          the matrix of corresponding tuple of \a this array. 
2457  *          The caller is to delete this result array using decrRef() as it is no more
2458  *          needed. 
2459  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2460  */
2461 DataArrayDouble *DataArrayDouble::trace() const
2462 {
2463   checkAllocated();
2464   int nbOfComp=getNumberOfComponents();
2465   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
2466     throw INTERP_KERNEL::Exception("DataArrayDouble::trace : must be an array with 4,6 or 9 components !");
2467   DataArrayDouble *ret=DataArrayDouble::New();
2468   int nbOfTuple=getNumberOfTuples();
2469   ret->alloc(nbOfTuple,1);
2470   const double *src=getConstPointer();
2471   double *dest=ret->getPointer();
2472   if(nbOfComp==6)
2473     for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
2474       *dest=src[0]+src[1]+src[2];
2475   else if(nbOfComp==4)
2476     for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
2477       *dest=src[0]+src[3];
2478   else
2479     for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
2480       *dest=src[0]+src[4]+src[8];
2481   return ret;
2482 }
2483
2484 /*!
2485  * Computes the stress deviator tensor of every stress tensor defined by the tuple of
2486  * \a this array, which contains 6 components.
2487  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2488  *          same number of components and tuples as \a this array.
2489  *          The caller is to delete this result array using decrRef() as it is no more
2490  *          needed.
2491  *  \throw If \a this->getNumberOfComponents() != 6.
2492  */
2493 DataArrayDouble *DataArrayDouble::deviator() const
2494 {
2495   checkAllocated();
2496   int nbOfComp=getNumberOfComponents();
2497   if(nbOfComp!=6)
2498     throw INTERP_KERNEL::Exception("DataArrayDouble::deviator : must be an array with exactly 6 components !");
2499   DataArrayDouble *ret=DataArrayDouble::New();
2500   int nbOfTuple=getNumberOfTuples();
2501   ret->alloc(nbOfTuple,6);
2502   const double *src=getConstPointer();
2503   double *dest=ret->getPointer();
2504   for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
2505     {
2506       double tr=(src[0]+src[1]+src[2])/3.;
2507       dest[0]=src[0]-tr;
2508       dest[1]=src[1]-tr;
2509       dest[2]=src[2]-tr;
2510       dest[3]=src[3];
2511       dest[4]=src[4];
2512       dest[5]=src[5];
2513     }
2514   return ret;
2515 }
2516
2517 /*!
2518  * Computes the magnitude of every vector defined by the tuple of
2519  * \a this array.
2520  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2521  *          same number of tuples as \a this array and one component.
2522  *          The caller is to delete this result array using decrRef() as it is no more
2523  *          needed.
2524  *  \throw If \a this is not allocated.
2525  */
2526 DataArrayDouble *DataArrayDouble::magnitude() const
2527 {
2528   checkAllocated();
2529   int nbOfComp=getNumberOfComponents();
2530   DataArrayDouble *ret=DataArrayDouble::New();
2531   int nbOfTuple=getNumberOfTuples();
2532   ret->alloc(nbOfTuple,1);
2533   const double *src=getConstPointer();
2534   double *dest=ret->getPointer();
2535   for(int i=0;i<nbOfTuple;i++,dest++)
2536     {
2537       double sum=0.;
2538       for(int j=0;j<nbOfComp;j++,src++)
2539         sum+=(*src)*(*src);
2540       *dest=sqrt(sum);
2541     }
2542   return ret;
2543 }
2544
2545 /*!
2546  * Computes for each tuple the sum of number of components values in the tuple and return it.
2547  * 
2548  * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2549  *          same number of tuples as \a this array and one component.
2550  *          The caller is to delete this result array using decrRef() as it is no more
2551  *          needed.
2552  *  \throw If \a this is not allocated.
2553  */
2554 DataArrayDouble *DataArrayDouble::sumPerTuple() const
2555 {
2556   checkAllocated();
2557   int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
2558   MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2559   ret->alloc(nbOfTuple,1);
2560   const double *src(getConstPointer());
2561   double *dest(ret->getPointer());
2562   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
2563     *dest=std::accumulate(src,src+nbOfComp,0.);
2564   return ret.retn();
2565 }
2566
2567 /*!
2568  * Computes the maximal value within every tuple of \a this array.
2569  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2570  *          same number of tuples as \a this array and one component.
2571  *          The caller is to delete this result array using decrRef() as it is no more
2572  *          needed.
2573  *  \throw If \a this is not allocated.
2574  *  \sa DataArrayDouble::maxPerTupleWithCompoId
2575  */
2576 DataArrayDouble *DataArrayDouble::maxPerTuple() const
2577 {
2578   checkAllocated();
2579   int nbOfComp=getNumberOfComponents();
2580   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
2581   int nbOfTuple=getNumberOfTuples();
2582   ret->alloc(nbOfTuple,1);
2583   const double *src=getConstPointer();
2584   double *dest=ret->getPointer();
2585   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
2586     *dest=*std::max_element(src,src+nbOfComp);
2587   return ret.retn();
2588 }
2589
2590 /*!
2591  * Computes the maximal value within every tuple of \a this array and it returns the first component
2592  * id for each tuple that corresponds to the maximal value within the tuple.
2593  * 
2594  *  \param [out] compoIdOfMaxPerTuple - the new new instance of DataArrayInt containing the
2595  *          same number of tuples and only one component.
2596  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2597  *          same number of tuples as \a this array and one component.
2598  *          The caller is to delete this result array using decrRef() as it is no more
2599  *          needed.
2600  *  \throw If \a this is not allocated.
2601  *  \sa DataArrayDouble::maxPerTuple
2602  */
2603 DataArrayDouble *DataArrayDouble::maxPerTupleWithCompoId(DataArrayInt* &compoIdOfMaxPerTuple) const
2604 {
2605   checkAllocated();
2606   int nbOfComp=getNumberOfComponents();
2607   MCAuto<DataArrayDouble> ret0=DataArrayDouble::New();
2608   MCAuto<DataArrayInt> ret1=DataArrayInt::New();
2609   int nbOfTuple=getNumberOfTuples();
2610   ret0->alloc(nbOfTuple,1); ret1->alloc(nbOfTuple,1);
2611   const double *src=getConstPointer();
2612   double *dest=ret0->getPointer(); int *dest1=ret1->getPointer();
2613   for(int i=0;i<nbOfTuple;i++,dest++,dest1++,src+=nbOfComp)
2614     {
2615       const double *loc=std::max_element(src,src+nbOfComp);
2616       *dest=*loc;
2617       *dest1=(int)std::distance(src,loc);
2618     }
2619   compoIdOfMaxPerTuple=ret1.retn();
2620   return ret0.retn();
2621 }
2622
2623 /*!
2624  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c this->getNumberOfTuples() tuples.
2625  * \n This returned array contains the euclidian distance for each tuple in \a this. 
2626  * \n So the returned array can be seen as a dense symmetrical matrix whose diagonal elements are equal to 0.
2627  * \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)
2628  *
2629  * \warning use this method with care because it can leads to big amount of consumed memory !
2630  * 
2631  * \return A newly allocated (huge) MEDCoupling::DataArrayDouble instance that the caller should deal with.
2632  *
2633  * \throw If \a this is not allocated.
2634  *
2635  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrixWith
2636  */
2637 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrix() const
2638 {
2639   checkAllocated();
2640   int nbOfComp=getNumberOfComponents();
2641   int nbOfTuples=getNumberOfTuples();
2642   const double *inData=getConstPointer();
2643   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
2644   ret->alloc(nbOfTuples*nbOfTuples,1);
2645   double *outData=ret->getPointer();
2646   for(int i=0;i<nbOfTuples;i++)
2647     {
2648       outData[i*nbOfTuples+i]=0.;
2649       for(int j=i+1;j<nbOfTuples;j++)
2650         {
2651           double dist=0.;
2652           for(int k=0;k<nbOfComp;k++)
2653             { double delta=inData[i*nbOfComp+k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
2654           dist=sqrt(dist);
2655           outData[i*nbOfTuples+j]=dist;
2656           outData[j*nbOfTuples+i]=dist;
2657         }
2658     }
2659   return ret.retn();
2660 }
2661
2662 /*!
2663  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c other->getNumberOfTuples() tuples.
2664  * \n This returned array contains the euclidian distance for each tuple in \a other with each tuple in \a this. 
2665  * \n So the returned array can be seen as a dense rectangular matrix with \c other->getNumberOfTuples() rows and \c this->getNumberOfTuples() columns.
2666  * \n Output rectangular matrix is sorted along rows.
2667  * \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)
2668  *
2669  * \warning use this method with care because it can leads to big amount of consumed memory !
2670  * 
2671  * \param [in] other DataArrayDouble instance having same number of components than \a this.
2672  * \return A newly allocated (huge) MEDCoupling::DataArrayDouble instance that the caller should deal with.
2673  *
2674  * \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.
2675  *
2676  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrix
2677  */
2678 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrixWith(const DataArrayDouble *other) const
2679 {
2680   if(!other)
2681     throw INTERP_KERNEL::Exception("DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : input parameter is null !");
2682   checkAllocated();
2683   other->checkAllocated();
2684   int nbOfComp=getNumberOfComponents();
2685   int otherNbOfComp=other->getNumberOfComponents();
2686   if(nbOfComp!=otherNbOfComp)
2687     {
2688       std::ostringstream oss; oss << "DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : this nb of compo=" << nbOfComp << " and other nb of compo=" << otherNbOfComp << ". It should match !";
2689       throw INTERP_KERNEL::Exception(oss.str().c_str());
2690     }
2691   int nbOfTuples=getNumberOfTuples();
2692   int otherNbOfTuples=other->getNumberOfTuples();
2693   const double *inData=getConstPointer();
2694   const double *inDataOther=other->getConstPointer();
2695   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
2696   ret->alloc(otherNbOfTuples*nbOfTuples,1);
2697   double *outData=ret->getPointer();
2698   for(int i=0;i<otherNbOfTuples;i++,inDataOther+=nbOfComp)
2699     {
2700       for(int j=0;j<nbOfTuples;j++)
2701         {
2702           double dist=0.;
2703           for(int k=0;k<nbOfComp;k++)
2704             { double delta=inDataOther[k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
2705           dist=sqrt(dist);
2706           outData[i*nbOfTuples+j]=dist;
2707         }
2708     }
2709   return ret.retn();
2710 }
2711
2712 /*!
2713  * Sorts value within every tuple of \a this array.
2714  *  \param [in] asc - if \a true, the values are sorted in ascending order, else,
2715  *              in descending order.
2716  *  \throw If \a this is not allocated.
2717  */
2718 void DataArrayDouble::sortPerTuple(bool asc)
2719 {
2720   checkAllocated();
2721   double *pt=getPointer();
2722   int nbOfTuple=getNumberOfTuples();
2723   int nbOfComp=getNumberOfComponents();
2724   if(asc)
2725     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
2726       std::sort(pt,pt+nbOfComp);
2727   else
2728     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
2729       std::sort(pt,pt+nbOfComp,std::greater<double>());
2730   declareAsNew();
2731 }
2732
2733 /*!
2734  * Converts every value of \a this array to its absolute value.
2735  * \b WARNING this method is non const. If a new DataArrayDouble instance should be built containing the result of abs DataArrayDouble::computeAbs
2736  * should be called instead.
2737  *
2738  * \throw If \a this is not allocated.
2739  * \sa DataArrayDouble::computeAbs
2740  */
2741 void DataArrayDouble::abs()
2742 {
2743   checkAllocated();
2744   double *ptr(getPointer());
2745   std::size_t nbOfElems(getNbOfElems());
2746   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<double,double>(fabs));
2747   declareAsNew();
2748 }
2749
2750 /*!
2751  * This method builds a new instance of \a this object containing the result of std::abs applied of all elements in \a this.
2752  * This method is a const method (that do not change any values in \a this) contrary to  DataArrayDouble::abs method.
2753  *
2754  * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2755  *         same number of tuples and component as \a this array.
2756  *         The caller is to delete this result array using decrRef() as it is no more
2757  *         needed.
2758  * \throw If \a this is not allocated.
2759  * \sa DataArrayDouble::abs
2760  */
2761 DataArrayDouble *DataArrayDouble::computeAbs() const
2762 {
2763   checkAllocated();
2764   DataArrayDouble *newArr(DataArrayDouble::New());
2765   int nbOfTuples(getNumberOfTuples());
2766   int nbOfComp(getNumberOfComponents());
2767   newArr->alloc(nbOfTuples,nbOfComp);
2768   std::transform(begin(),end(),newArr->getPointer(),std::ptr_fun<double,double>(fabs));
2769   newArr->copyStringInfoFrom(*this);
2770   return newArr;
2771 }
2772
2773 /*!
2774  * Apply a linear function to a given component of \a this array, so that
2775  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
2776  *  \param [in] a - the first coefficient of the function.
2777  *  \param [in] b - the second coefficient of the function.
2778  *  \param [in] compoId - the index of component to modify.
2779  *  \throw If \a this is not allocated, or \a compoId is not in [0,\c this->getNumberOfComponents() ).
2780  */
2781 void DataArrayDouble::applyLin(double a, double b, int compoId)
2782 {
2783   checkAllocated();
2784   double *ptr(getPointer()+compoId);
2785   int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
2786   if(compoId<0 || compoId>=nbOfComp)
2787     {
2788       std::ostringstream oss; oss << "DataArrayDouble::applyLin : The compoId requested (" << compoId << ") is not valid ! Must be in [0," << nbOfComp << ") !";
2789       throw INTERP_KERNEL::Exception(oss.str().c_str());
2790     }
2791   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
2792     *ptr=a*(*ptr)+b;
2793   declareAsNew();
2794 }
2795
2796 /*!
2797  * Apply a linear function to all elements of \a this array, so that
2798  * an element _x_ becomes \f$ a * x + b \f$.
2799  *  \param [in] a - the first coefficient of the function.
2800  *  \param [in] b - the second coefficient of the function.
2801  *  \throw If \a this is not allocated.
2802  */
2803 void DataArrayDouble::applyLin(double a, double b)
2804 {
2805   checkAllocated();
2806   double *ptr=getPointer();
2807   std::size_t nbOfElems=getNbOfElems();
2808   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2809     *ptr=a*(*ptr)+b;
2810   declareAsNew();
2811 }
2812
2813 /*!
2814  * Modify all elements of \a this array, so that
2815  * an element _x_ becomes \f$ numerator / x \f$.
2816  *  \warning If an exception is thrown because of presence of 0.0 element in \a this 
2817  *           array, all elements processed before detection of the zero element remain
2818  *           modified.
2819  *  \param [in] numerator - the numerator used to modify array elements.
2820  *  \throw If \a this is not allocated.
2821  *  \throw If there is an element equal to 0.0 in \a this array.
2822  */
2823 void DataArrayDouble::applyInv(double numerator)
2824 {
2825   checkAllocated();
2826   double *ptr=getPointer();
2827   std::size_t nbOfElems=getNbOfElems();
2828   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2829     {
2830       if(std::abs(*ptr)>std::numeric_limits<double>::min())
2831         {
2832           *ptr=numerator/(*ptr);
2833         }
2834       else
2835         {
2836           std::ostringstream oss; oss << "DataArrayDouble::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
2837           oss << " !";
2838           throw INTERP_KERNEL::Exception(oss.str().c_str());
2839         }
2840     }
2841   declareAsNew();
2842 }
2843
2844 /*!
2845  * Returns a full copy of \a this array except that sign of all elements is reversed.
2846  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2847  *          same number of tuples and component as \a this array.
2848  *          The caller is to delete this result array using decrRef() as it is no more
2849  *          needed.
2850  *  \throw If \a this is not allocated.
2851  */
2852 DataArrayDouble *DataArrayDouble::negate() const
2853 {
2854   checkAllocated();
2855   DataArrayDouble *newArr=DataArrayDouble::New();
2856   int nbOfTuples=getNumberOfTuples();
2857   int nbOfComp=getNumberOfComponents();
2858   newArr->alloc(nbOfTuples,nbOfComp);
2859   const double *cptr=getConstPointer();
2860   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<double>());
2861   newArr->copyStringInfoFrom(*this);
2862   return newArr;
2863 }
2864
2865 /*!
2866  * Modify all elements of \a this array, so that
2867  * an element _x_ becomes <em> val ^ x </em>. Contrary to DataArrayInt::applyPow
2868  * all values in \a this have to be >= 0 if val is \b not integer.
2869  *  \param [in] val - the value used to apply pow on all array elements.
2870  *  \throw If \a this is not allocated.
2871  *  \warning If an exception is thrown because of presence of 0 element in \a this 
2872  *           array and \a val is \b not integer, all elements processed before detection of the zero element remain
2873  *           modified.
2874  */
2875 void DataArrayDouble::applyPow(double val)
2876 {
2877   checkAllocated();
2878   double *ptr=getPointer();
2879   std::size_t nbOfElems=getNbOfElems();
2880   int val2=(int)val;
2881   bool isInt=((double)val2)==val;
2882   if(!isInt)
2883     {
2884       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2885         {
2886           if(*ptr>=0)
2887             *ptr=pow(*ptr,val);
2888           else
2889             {
2890               std::ostringstream oss; oss << "DataArrayDouble::applyPow (double) : At elem # " << i << " value is " << *ptr << " ! must be >=0. !";
2891               throw INTERP_KERNEL::Exception(oss.str().c_str());
2892             }
2893         }
2894     }
2895   else
2896     {
2897       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2898         *ptr=pow(*ptr,val2);
2899     }
2900   declareAsNew();
2901 }
2902
2903 /*!
2904  * Modify all elements of \a this array, so that
2905  * an element _x_ becomes \f$ val ^ x \f$.
2906  *  \param [in] val - the value used to apply pow on all array elements.
2907  *  \throw If \a this is not allocated.
2908  *  \throw If \a val < 0.
2909  *  \warning If an exception is thrown because of presence of 0 element in \a this 
2910  *           array, all elements processed before detection of the zero element remain
2911  *           modified.
2912  */
2913 void DataArrayDouble::applyRPow(double val)
2914 {
2915   checkAllocated();
2916   if(val<0.)
2917     throw INTERP_KERNEL::Exception("DataArrayDouble::applyRPow : the input value has to be >= 0 !");
2918   double *ptr=getPointer();
2919   std::size_t nbOfElems=getNbOfElems();
2920   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2921     *ptr=pow(val,*ptr);
2922   declareAsNew();
2923 }
2924
2925 /*!
2926  * Returns a new DataArrayDouble created from \a this one by applying \a
2927  * FunctionToEvaluate to every tuple of \a this array. Textual data is not copied.
2928  * For more info see \ref MEDCouplingArrayApplyFunc
2929  *  \param [in] nbOfComp - number of components in the result array.
2930  *  \param [in] func - the \a FunctionToEvaluate declared as 
2931  *              \c bool (*\a func)(\c const \c double *\a pos, \c double *\a res), 
2932  *              where \a pos points to the first component of a tuple of \a this array
2933  *              and \a res points to the first component of a tuple of the result array.
2934  *              Note that length (number of components) of \a pos can differ from
2935  *              that of \a res.
2936  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2937  *          same number of tuples as \a this array.
2938  *          The caller is to delete this result array using decrRef() as it is no more
2939  *          needed.
2940  *  \throw If \a this is not allocated.
2941  *  \throw If \a func returns \a false.
2942  */
2943 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, FunctionToEvaluate func) const
2944 {
2945   checkAllocated();
2946   DataArrayDouble *newArr=DataArrayDouble::New();
2947   int nbOfTuples=getNumberOfTuples();
2948   int oldNbOfComp=getNumberOfComponents();
2949   newArr->alloc(nbOfTuples,nbOfComp);
2950   const double *ptr=getConstPointer();
2951   double *ptrToFill=newArr->getPointer();
2952   for(int i=0;i<nbOfTuples;i++)
2953     {
2954       if(!func(ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp))
2955         {
2956           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
2957           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
2958           oss << ") : Evaluation of function failed !";
2959           newArr->decrRef();
2960           throw INTERP_KERNEL::Exception(oss.str().c_str());
2961         }
2962     }
2963   return newArr;
2964 }
2965
2966 /*!
2967  * Returns a new DataArrayDouble created from \a this one by applying a function to every
2968  * tuple of \a this array. Textual data is not copied.
2969  * For more info see \ref MEDCouplingArrayApplyFunc1.
2970  *  \param [in] nbOfComp - number of components in the result array.
2971  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
2972  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
2973  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
2974  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
2975  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2976  *          same number of tuples as \a this array and \a nbOfComp components.
2977  *          The caller is to delete this result array using decrRef() as it is no more
2978  *          needed.
2979  *  \throw If \a this is not allocated.
2980  *  \throw If computing \a func fails.
2981  */
2982 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, const std::string& func, bool isSafe) const
2983 {
2984   INTERP_KERNEL::ExprParser expr(func);
2985   expr.parse();
2986   std::set<std::string> vars;
2987   expr.getTrueSetOfVars(vars);
2988   std::vector<std::string> varsV(vars.begin(),vars.end());
2989   return applyFuncNamedCompo(nbOfComp,varsV,func,isSafe);
2990 }
2991
2992 /*!
2993  * Returns a new DataArrayDouble created from \a this one by applying a function to every
2994  * tuple of \a this array. Textual data is not copied. This method works by tuples (whatever its size).
2995  * If \a this is a one component array, call applyFuncOnThis instead that performs the same work faster.
2996  *
2997  * For more info see \ref MEDCouplingArrayApplyFunc0.
2998  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
2999  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
3000  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
3001  *                       If false the computation is carried on without any notification. When false the evaluation is a little faster.
3002  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3003  *          same number of tuples and components as \a this array.
3004  *          The caller is to delete this result array using decrRef() as it is no more
3005  *          needed.
3006  *  \sa applyFuncOnThis
3007  *  \throw If \a this is not allocated.
3008  *  \throw If computing \a func fails.
3009  */
3010 DataArrayDouble *DataArrayDouble::applyFunc(const std::string& func, bool isSafe) const
3011 {
3012   int nbOfComp(getNumberOfComponents());
3013   if(nbOfComp<=0)
3014     throw INTERP_KERNEL::Exception("DataArrayDouble::applyFunc : output number of component must be > 0 !");
3015   checkAllocated();
3016   int nbOfTuples(getNumberOfTuples());
3017   MCAuto<DataArrayDouble> newArr(DataArrayDouble::New());
3018   newArr->alloc(nbOfTuples,nbOfComp);
3019   INTERP_KERNEL::ExprParser expr(func);
3020   expr.parse();
3021   std::set<std::string> vars;
3022   expr.getTrueSetOfVars(vars);
3023   if((int)vars.size()>1)
3024     {
3025       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 : ";
3026       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
3027       throw INTERP_KERNEL::Exception(oss.str().c_str());
3028     }
3029   if(vars.empty())
3030     {
3031       expr.prepareFastEvaluator();
3032       newArr->rearrange(1);
3033       newArr->fillWithValue(expr.evaluateDouble());
3034       newArr->rearrange(nbOfComp);
3035       return newArr.retn();
3036     }
3037   std::vector<std::string> vars2(vars.begin(),vars.end());
3038   double buff,*ptrToFill(newArr->getPointer());
3039   const double *ptr(begin());
3040   std::vector<double> stck;
3041   expr.prepareExprEvaluationDouble(vars2,1,1,0,&buff,&buff+1);
3042   expr.prepareFastEvaluator();
3043   if(!isSafe)
3044     {
3045       for(int i=0;i<nbOfTuples;i++)
3046         {
3047           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
3048             {
3049               buff=*ptr;
3050               expr.evaluateDoubleInternal(stck);
3051               *ptrToFill=stck.back();
3052               stck.pop_back();
3053             }
3054         }
3055     }
3056   else
3057     {
3058       for(int i=0;i<nbOfTuples;i++)
3059         {
3060           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
3061             {
3062               buff=*ptr;
3063               try
3064               {
3065                   expr.evaluateDoubleInternalSafe(stck);
3066               }
3067               catch(INTERP_KERNEL::Exception& e)
3068               {
3069                   std::ostringstream oss; oss << "For tuple # " << i << " component # " << iComp << " with value (";
3070                   oss << buff;
3071                   oss << ") : Evaluation of function failed !" << e.what();
3072                   throw INTERP_KERNEL::Exception(oss.str().c_str());
3073               }
3074               *ptrToFill=stck.back();
3075               stck.pop_back();
3076             }
3077         }
3078     }
3079   return newArr.retn();
3080 }
3081
3082 /*!
3083  * This method is a non const method that modify the array in \a this.
3084  * This method only works on one component array. It means that function \a func must
3085  * contain at most one variable.
3086  * This method is a specialization of applyFunc method with one parameter on one component array.
3087  *
3088  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
3089  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
3090  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
3091  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
3092  *
3093  * \sa applyFunc
3094  */
3095 void DataArrayDouble::applyFuncOnThis(const std::string& func, bool isSafe)
3096 {
3097   int nbOfComp(getNumberOfComponents());
3098   if(nbOfComp<=0)
3099     throw INTERP_KERNEL::Exception("DataArrayDouble::applyFuncOnThis : output number of component must be > 0 !");
3100   checkAllocated();
3101   int nbOfTuples(getNumberOfTuples());
3102   INTERP_KERNEL::ExprParser expr(func);
3103   expr.parse();
3104   std::set<std::string> vars;
3105   expr.getTrueSetOfVars(vars);
3106   if((int)vars.size()>1)
3107     {
3108       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 : ";
3109       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
3110       throw INTERP_KERNEL::Exception(oss.str().c_str());
3111     }
3112   if(vars.empty())
3113     {
3114       expr.prepareFastEvaluator();
3115       std::vector<std::string> compInfo(getInfoOnComponents());
3116       rearrange(1);
3117       fillWithValue(expr.evaluateDouble());
3118       rearrange(nbOfComp);
3119       setInfoOnComponents(compInfo);
3120       return ;
3121     }
3122   std::vector<std::string> vars2(vars.begin(),vars.end());
3123   double buff,*ptrToFill(getPointer());
3124   const double *ptr(begin());
3125   std::vector<double> stck;
3126   expr.prepareExprEvaluationDouble(vars2,1,1,0,&buff,&buff+1);
3127   expr.prepareFastEvaluator();
3128   if(!isSafe)
3129     {
3130       for(int i=0;i<nbOfTuples;i++)
3131         {
3132           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
3133             {
3134               buff=*ptr;
3135               expr.evaluateDoubleInternal(stck);
3136               *ptrToFill=stck.back();
3137               stck.pop_back();
3138             }
3139         }
3140     }
3141   else
3142     {
3143       for(int i=0;i<nbOfTuples;i++)
3144         {
3145           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
3146             {
3147               buff=*ptr;
3148               try
3149               {
3150                   expr.evaluateDoubleInternalSafe(stck);
3151               }
3152               catch(INTERP_KERNEL::Exception& e)
3153               {
3154                   std::ostringstream oss; oss << "For tuple # " << i << " component # " << iComp << " with value (";
3155                   oss << buff;
3156                   oss << ") : Evaluation of function failed !" << e.what();
3157                   throw INTERP_KERNEL::Exception(oss.str().c_str());
3158               }
3159               *ptrToFill=stck.back();
3160               stck.pop_back();
3161             }
3162         }
3163     }
3164 }
3165
3166 /*!
3167  * Returns a new DataArrayDouble created from \a this one by applying a function to every
3168  * tuple of \a this array. Textual data is not copied.
3169  * For more info see \ref MEDCouplingArrayApplyFunc2.
3170  *  \param [in] nbOfComp - number of components in the result array.
3171  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
3172  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
3173  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
3174  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
3175  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3176  *          same number of tuples as \a this array.
3177  *          The caller is to delete this result array using decrRef() as it is no more
3178  *          needed.
3179  *  \throw If \a this is not allocated.
3180  *  \throw If \a func contains vars that are not in \a this->getInfoOnComponent().
3181  *  \throw If computing \a func fails.
3182  */
3183 DataArrayDouble *DataArrayDouble::applyFuncCompo(int nbOfComp, const std::string& func, bool isSafe) const
3184 {
3185   return applyFuncNamedCompo(nbOfComp,getVarsOnComponent(),func,isSafe);
3186 }
3187
3188 /*!
3189  * Returns a new DataArrayDouble created from \a this one by applying a function to every
3190  * tuple of \a this array. Textual data is not copied.
3191  * For more info see \ref MEDCouplingArrayApplyFunc3.
3192  *  \param [in] nbOfComp - number of components in the result array.
3193  *  \param [in] varsOrder - sequence of vars defining their order.
3194  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
3195  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
3196  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
3197  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
3198  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3199  *          same number of tuples as \a this array.
3200  *          The caller is to delete this result array using decrRef() as it is no more
3201  *          needed.
3202  *  \throw If \a this is not allocated.
3203  *  \throw If \a func contains vars not in \a varsOrder.
3204  *  \throw If computing \a func fails.
3205  */
3206 DataArrayDouble *DataArrayDouble::applyFuncNamedCompo(int nbOfComp, const std::vector<std::string>& varsOrder, const std::string& func, bool isSafe) const
3207 {
3208   if(nbOfComp<=0)
3209     throw INTERP_KERNEL::Exception("DataArrayDouble::applyFuncNamedCompo : output number of component must be > 0 !");
3210   std::vector<std::string> varsOrder2(varsOrder);
3211   int oldNbOfComp(getNumberOfComponents());
3212   for(int i=(int)varsOrder.size();i<oldNbOfComp;i++)
3213     varsOrder2.push_back(std::string());
3214   checkAllocated();
3215   int nbOfTuples(getNumberOfTuples());
3216   INTERP_KERNEL::ExprParser expr(func);
3217   expr.parse();
3218   std::set<std::string> vars;
3219   expr.getTrueSetOfVars(vars);
3220   if((int)vars.size()>oldNbOfComp)
3221     {
3222       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
3223       oss << vars.size() << " variables : ";
3224       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
3225       throw INTERP_KERNEL::Exception(oss.str().c_str());
3226     }
3227   MCAuto<DataArrayDouble> newArr(DataArrayDouble::New());
3228   newArr->alloc(nbOfTuples,nbOfComp);
3229   INTERP_KERNEL::AutoPtr<double> buff(new double[oldNbOfComp]);
3230   double *buffPtr(buff),*ptrToFill;
3231   std::vector<double> stck;
3232   for(int iComp=0;iComp<nbOfComp;iComp++)
3233     {
3234       expr.prepareExprEvaluationDouble(varsOrder2,oldNbOfComp,nbOfComp,iComp,buffPtr,buffPtr+oldNbOfComp);
3235       expr.prepareFastEvaluator();
3236       const double *ptr(getConstPointer());
3237       ptrToFill=newArr->getPointer()+iComp;
3238       if(!isSafe)
3239         {
3240           for(int i=0;i<nbOfTuples;i++,ptrToFill+=nbOfComp,ptr+=oldNbOfComp)
3241             {
3242               std::copy(ptr,ptr+oldNbOfComp,buffPtr);
3243               expr.evaluateDoubleInternal(stck);
3244               *ptrToFill=stck.back();
3245               stck.pop_back();
3246             }
3247         }
3248       else
3249         {
3250           for(int i=0;i<nbOfTuples;i++,ptrToFill+=nbOfComp,ptr+=oldNbOfComp)
3251             {
3252               std::copy(ptr,ptr+oldNbOfComp,buffPtr);
3253               try
3254               {
3255                   expr.evaluateDoubleInternalSafe(stck);
3256                   *ptrToFill=stck.back();
3257                   stck.pop_back();
3258               }
3259               catch(INTERP_KERNEL::Exception& e)
3260               {
3261                   std::ostringstream oss; oss << "For tuple # " << i << " with value (";
3262                   std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
3263                   oss << ") : Evaluation of function failed !" << e.what();
3264                   throw INTERP_KERNEL::Exception(oss.str().c_str());
3265               }
3266             }
3267         }
3268     }
3269   return newArr.retn();
3270 }
3271
3272 void DataArrayDouble::applyFuncFast32(const std::string& func)
3273 {
3274   checkAllocated();
3275   INTERP_KERNEL::ExprParser expr(func);
3276   expr.parse();
3277   char *funcStr=expr.compileX86();
3278   MYFUNCPTR funcPtr;
3279   *((void **)&funcPtr)=funcStr;//he he...
3280   //
3281   double *ptr=getPointer();
3282   int nbOfComp=getNumberOfComponents();
3283   int nbOfTuples=getNumberOfTuples();
3284   int nbOfElems=nbOfTuples*nbOfComp;
3285   for(int i=0;i<nbOfElems;i++,ptr++)
3286     *ptr=funcPtr(*ptr);
3287   declareAsNew();
3288 }
3289
3290 void DataArrayDouble::applyFuncFast64(const std::string& func)
3291 {
3292   checkAllocated();
3293   INTERP_KERNEL::ExprParser expr(func);
3294   expr.parse();
3295   char *funcStr=expr.compileX86_64();
3296   MYFUNCPTR funcPtr;
3297   *((void **)&funcPtr)=funcStr;//he he...
3298   //
3299   double *ptr=getPointer();
3300   int nbOfComp=getNumberOfComponents();
3301   int nbOfTuples=getNumberOfTuples();
3302   int nbOfElems=nbOfTuples*nbOfComp;
3303   for(int i=0;i<nbOfElems;i++,ptr++)
3304     *ptr=funcPtr(*ptr);
3305   declareAsNew();
3306 }
3307
3308 /*!
3309  * \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.
3310  */
3311 MCAuto<DataArrayDouble> DataArrayDouble::symmetry3DPlane(const double point[3], const double normalVector[3]) const
3312 {
3313   checkAllocated();
3314   if(getNumberOfComponents()!=3)
3315     throw INTERP_KERNEL::Exception("DataArrayDouble::symmetry3DPlane : this is excepted to have 3 components !");
3316   int nbTuples(getNumberOfTuples());
3317   MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
3318   ret->alloc(nbTuples,3);
3319   Symmetry3DPlane(point,normalVector,nbTuples,begin(),ret->getPointer());
3320   return ret;
3321 }
3322
3323 DataArrayDoubleIterator *DataArrayDouble::iterator()
3324 {
3325   return new DataArrayDoubleIterator(this);
3326 }
3327
3328 /*!
3329  * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional
3330  * array whose values are within a given range. Textual data is not copied.
3331  *  \param [in] vmin - a lowest acceptable value (included).
3332  *  \param [in] vmax - a greatest acceptable value (included).
3333  *  \return DataArrayInt * - the new instance of DataArrayInt.
3334  *          The caller is to delete this result array using decrRef() as it is no more
3335  *          needed.
3336  *  \throw If \a this->getNumberOfComponents() != 1.
3337  *
3338  *  \sa DataArrayDouble::findIdsNotInRange
3339  *
3340  *  \if ENABLE_EXAMPLES
3341  *  \ref cpp_mcdataarraydouble_getidsinrange "Here is a C++ example".<br>
3342  *  \ref py_mcdataarraydouble_getidsinrange "Here is a Python example".
3343  *  \endif
3344  */
3345 DataArrayInt *DataArrayDouble::findIdsInRange(double vmin, double vmax) const
3346 {
3347   checkAllocated();
3348   if(getNumberOfComponents()!=1)
3349     throw INTERP_KERNEL::Exception("DataArrayDouble::findIdsInRange : this must have exactly one component !");
3350   const double *cptr(begin());
3351   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
3352   int nbOfTuples(getNumberOfTuples());
3353   for(int i=0;i<nbOfTuples;i++,cptr++)
3354     if(*cptr>=vmin && *cptr<=vmax)
3355       ret->pushBackSilent(i);
3356   return ret.retn();
3357 }
3358
3359 /*!
3360  * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional
3361  * array whose values are not within a given range. Textual data is not copied.
3362  *  \param [in] vmin - a lowest not acceptable value (excluded).
3363  *  \param [in] vmax - a greatest not acceptable value (excluded).
3364  *  \return DataArrayInt * - the new instance of DataArrayInt.
3365  *          The caller is to delete this result array using decrRef() as it is no more
3366  *          needed.
3367  *  \throw If \a this->getNumberOfComponents() != 1.
3368  *
3369  *  \sa DataArrayDouble::findIdsInRange
3370  */
3371 DataArrayInt *DataArrayDouble::findIdsNotInRange(double vmin, double vmax) const
3372 {
3373   checkAllocated();
3374   if(getNumberOfComponents()!=1)
3375     throw INTERP_KERNEL::Exception("DataArrayDouble::findIdsNotInRange : this must have exactly one component !");
3376   const double *cptr(begin());
3377   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
3378   int nbOfTuples(getNumberOfTuples());
3379   for(int i=0;i<nbOfTuples;i++,cptr++)
3380     if(*cptr<vmin || *cptr>vmax)
3381       ret->pushBackSilent(i);
3382   return ret.retn();
3383 }
3384
3385 /*!
3386  * Returns a new DataArrayDouble by concatenating two given arrays, so that (1) the number
3387  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
3388  * the number of component in the result array is same as that of each of given arrays.
3389  * Info on components is copied from the first of the given arrays. Number of components
3390  * in the given arrays must be  the same.
3391  *  \param [in] a1 - an array to include in the result array.
3392  *  \param [in] a2 - another array to include in the result array.
3393  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3394  *          The caller is to delete this result array using decrRef() as it is no more
3395  *          needed.
3396  *  \throw If both \a a1 and \a a2 are NULL.
3397  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
3398  */
3399 DataArrayDouble *DataArrayDouble::Aggregate(const DataArrayDouble *a1, const DataArrayDouble *a2)
3400 {
3401   std::vector<const DataArrayDouble *> tmp(2);
3402   tmp[0]=a1; tmp[1]=a2;
3403   return Aggregate(tmp);
3404 }
3405
3406 /*!
3407  * Returns a new DataArrayDouble by concatenating all given arrays, so that (1) the number
3408  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
3409  * the number of component in the result array is same as that of each of given arrays.
3410  * Info on components is copied from the first of the given arrays. Number of components
3411  * in the given arrays must be  the same.
3412  * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it
3413  * not the object itself.
3414  *  \param [in] arr - a sequence of arrays to include in the result array.
3415  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3416  *          The caller is to delete this result array using decrRef() as it is no more
3417  *          needed.
3418  *  \throw If all arrays within \a arr are NULL.
3419  *  \throw If getNumberOfComponents() of arrays within \a arr.
3420  */
3421 DataArrayDouble *DataArrayDouble::Aggregate(const std::vector<const DataArrayDouble *>& arr)
3422 {
3423   std::vector<const DataArrayDouble *> a;
3424   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
3425     if(*it4)
3426       a.push_back(*it4);
3427   if(a.empty())
3428     throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : input list must contain at least one NON EMPTY DataArrayDouble !");
3429   std::vector<const DataArrayDouble *>::const_iterator it=a.begin();
3430   int nbOfComp=(*it)->getNumberOfComponents();
3431   int nbt=(*it++)->getNumberOfTuples();
3432   for(int i=1;it!=a.end();it++,i++)
3433     {
3434       if((*it)->getNumberOfComponents()!=nbOfComp)
3435         throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : Nb of components mismatch for array aggregation !");
3436       nbt+=(*it)->getNumberOfTuples();
3437     }
3438   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
3439   ret->alloc(nbt,nbOfComp);
3440   double *pt=ret->getPointer();
3441   for(it=a.begin();it!=a.end();it++)
3442     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
3443   ret->copyStringInfoFrom(*(a[0]));
3444   return ret.retn();
3445 }
3446
3447 /*!
3448  * Returns a new DataArrayDouble by aggregating two given arrays, so that (1) the number
3449  * of components in the result array is a sum of the number of components of given arrays
3450  * and (2) the number of tuples in the result array is same as that of each of given
3451  * arrays. In other words the i-th tuple of result array includes all components of
3452  * i-th tuples of all given arrays.
3453  * Number of tuples in the given arrays must be  the same.
3454  *  \param [in] a1 - an array to include in the result array.
3455  *  \param [in] a2 - another array to include in the result array.
3456  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3457  *          The caller is to delete this result array using decrRef() as it is no more
3458  *          needed.
3459  *  \throw If both \a a1 and \a a2 are NULL.
3460  *  \throw If any given array is not allocated.
3461  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3462  */
3463 DataArrayDouble *DataArrayDouble::Meld(const DataArrayDouble *a1, const DataArrayDouble *a2)
3464 {
3465   std::vector<const DataArrayDouble *> arr(2);
3466   arr[0]=a1; arr[1]=a2;
3467   return Meld(arr);
3468 }
3469
3470 /*!
3471  * Returns a new DataArrayDouble by aggregating all given arrays, so that (1) the number
3472  * of components in the result array is a sum of the number of components of given arrays
3473  * and (2) the number of tuples in the result array is same as that of each of given
3474  * arrays. In other words the i-th tuple of result array includes all components of
3475  * i-th tuples of all given arrays.
3476  * Number of tuples in the given arrays must be  the same.
3477  *  \param [in] arr - a sequence of arrays to include in the result array.
3478  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3479  *          The caller is to delete this result array using decrRef() as it is no more
3480  *          needed.
3481  *  \throw If all arrays within \a arr are NULL.
3482  *  \throw If any given array is not allocated.
3483  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
3484  */
3485 DataArrayDouble *DataArrayDouble::Meld(const std::vector<const DataArrayDouble *>& arr)
3486 {
3487   std::vector<const DataArrayDouble *> a;
3488   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
3489     if(*it4)
3490       a.push_back(*it4);
3491   if(a.empty())
3492     throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : input list must contain at least one NON EMPTY DataArrayDouble !");
3493   std::vector<const DataArrayDouble *>::const_iterator it;
3494   for(it=a.begin();it!=a.end();it++)
3495     (*it)->checkAllocated();
3496   it=a.begin();
3497   int nbOfTuples=(*it)->getNumberOfTuples();
3498   std::vector<int> nbc(a.size());
3499   std::vector<const double *> pts(a.size());
3500   nbc[0]=(*it)->getNumberOfComponents();
3501   pts[0]=(*it++)->getConstPointer();
3502   for(int i=1;it!=a.end();it++,i++)
3503     {
3504       if(nbOfTuples!=(*it)->getNumberOfTuples())
3505         throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : mismatch of number of tuples !");
3506       nbc[i]=(*it)->getNumberOfComponents();
3507       pts[i]=(*it)->getConstPointer();
3508     }
3509   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
3510   DataArrayDouble *ret=DataArrayDouble::New();
3511   ret->alloc(nbOfTuples,totalNbOfComp);
3512   double *retPtr=ret->getPointer();
3513   for(int i=0;i<nbOfTuples;i++)
3514     for(int j=0;j<(int)a.size();j++)
3515       {
3516         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
3517         pts[j]+=nbc[j];
3518       }
3519   int k=0;
3520   for(int i=0;i<(int)a.size();i++)
3521     for(int j=0;j<nbc[i];j++,k++)
3522       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j));
3523   return ret;
3524 }
3525
3526 /*!
3527  * Returns a new DataArrayDouble containing a dot product of two given arrays, so that
3528  * the i-th tuple of the result array is a sum of products of j-th components of i-th
3529  * tuples of given arrays (\f$ a_i = \sum_{j=1}^n a1_j * a2_j \f$).
3530  * Info on components and name is copied from the first of the given arrays.
3531  * Number of tuples and components in the given arrays must be the same.
3532  *  \param [in] a1 - a given array.
3533  *  \param [in] a2 - another given array.
3534  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3535  *          The caller is to delete this result array using decrRef() as it is no more
3536  *          needed.
3537  *  \throw If either \a a1 or \a a2 is NULL.
3538  *  \throw If any given array is not allocated.
3539  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3540  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
3541  */
3542 DataArrayDouble *DataArrayDouble::Dot(const DataArrayDouble *a1, const DataArrayDouble *a2)
3543 {
3544   if(!a1 || !a2)
3545     throw INTERP_KERNEL::Exception("DataArrayDouble::Dot : input DataArrayDouble instance is NULL !");
3546   a1->checkAllocated();
3547   a2->checkAllocated();
3548   int nbOfComp=a1->getNumberOfComponents();
3549   if(nbOfComp!=a2->getNumberOfComponents())
3550     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Dot !");
3551   int nbOfTuple=a1->getNumberOfTuples();
3552   if(nbOfTuple!=a2->getNumberOfTuples())
3553     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Dot !");
3554   DataArrayDouble *ret=DataArrayDouble::New();
3555   ret->alloc(nbOfTuple,1);
3556   double *retPtr=ret->getPointer();
3557   const double *a1Ptr=a1->getConstPointer();
3558   const double *a2Ptr=a2->getConstPointer();
3559   for(int i=0;i<nbOfTuple;i++)
3560     {
3561       double sum=0.;
3562       for(int j=0;j<nbOfComp;j++)
3563         sum+=a1Ptr[i*nbOfComp+j]*a2Ptr[i*nbOfComp+j];
3564       retPtr[i]=sum;
3565     }
3566   ret->setInfoOnComponent(0,a1->getInfoOnComponent(0));
3567   ret->setName(a1->getName());
3568   return ret;
3569 }
3570
3571 /*!
3572  * Returns a new DataArrayDouble containing a cross product of two given arrays, so that
3573  * the i-th tuple of the result array contains 3 components of a vector which is a cross
3574  * product of two vectors defined by the i-th tuples of given arrays.
3575  * Info on components is copied from the first of the given arrays.
3576  * Number of tuples in the given arrays must be the same.
3577  * Number of components in the given arrays must be 3.
3578  *  \param [in] a1 - a given array.
3579  *  \param [in] a2 - another given array.
3580  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3581  *          The caller is to delete this result array using decrRef() as it is no more
3582  *          needed.
3583  *  \throw If either \a a1 or \a a2 is NULL.
3584  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3585  *  \throw If \a a1->getNumberOfComponents() != 3
3586  *  \throw If \a a2->getNumberOfComponents() != 3
3587  */
3588 DataArrayDouble *DataArrayDouble::CrossProduct(const DataArrayDouble *a1, const DataArrayDouble *a2)
3589 {
3590   if(!a1 || !a2)
3591     throw INTERP_KERNEL::Exception("DataArrayDouble::CrossProduct : input DataArrayDouble instance is NULL !");
3592   int nbOfComp=a1->getNumberOfComponents();
3593   if(nbOfComp!=a2->getNumberOfComponents())
3594     throw INTERP_KERNEL::Exception("Nb of components mismatch for array crossProduct !");
3595   if(nbOfComp!=3)
3596     throw INTERP_KERNEL::Exception("Nb of components must be equal to 3 for array crossProduct !");
3597   int nbOfTuple=a1->getNumberOfTuples();
3598   if(nbOfTuple!=a2->getNumberOfTuples())
3599     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array crossProduct !");
3600   DataArrayDouble *ret=DataArrayDouble::New();
3601   ret->alloc(nbOfTuple,3);
3602   double *retPtr=ret->getPointer();
3603   const double *a1Ptr=a1->getConstPointer();
3604   const double *a2Ptr=a2->getConstPointer();
3605   for(int i=0;i<nbOfTuple;i++)
3606     {
3607       retPtr[3*i]=a1Ptr[3*i+1]*a2Ptr[3*i+2]-a1Ptr[3*i+2]*a2Ptr[3*i+1];
3608       retPtr[3*i+1]=a1Ptr[3*i+2]*a2Ptr[3*i]-a1Ptr[3*i]*a2Ptr[3*i+2];
3609       retPtr[3*i+2]=a1Ptr[3*i]*a2Ptr[3*i+1]-a1Ptr[3*i+1]*a2Ptr[3*i];
3610     }
3611   ret->copyStringInfoFrom(*a1);
3612   return ret;
3613 }
3614
3615 /*!
3616  * Returns a new DataArrayDouble containing maximal values of two given arrays.
3617  * Info on components is copied from the first of the given arrays.
3618  * Number of tuples and components in the given arrays must be the same.
3619  *  \param [in] a1 - an array to compare values with another one.
3620  *  \param [in] a2 - another array to compare values with the first one.
3621  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3622  *          The caller is to delete this result array using decrRef() as it is no more
3623  *          needed.
3624  *  \throw If either \a a1 or \a a2 is NULL.
3625  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3626  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
3627  */
3628 DataArrayDouble *DataArrayDouble::Max(const DataArrayDouble *a1, const DataArrayDouble *a2)
3629 {
3630   if(!a1 || !a2)
3631     throw INTERP_KERNEL::Exception("DataArrayDouble::Max : input DataArrayDouble instance is NULL !");
3632   int nbOfComp=a1->getNumberOfComponents();
3633   if(nbOfComp!=a2->getNumberOfComponents())
3634     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Max !");
3635   int nbOfTuple=a1->getNumberOfTuples();
3636   if(nbOfTuple!=a2->getNumberOfTuples())
3637     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Max !");
3638   DataArrayDouble *ret=DataArrayDouble::New();
3639   ret->alloc(nbOfTuple,nbOfComp);
3640   double *retPtr=ret->getPointer();
3641   const double *a1Ptr=a1->getConstPointer();
3642   const double *a2Ptr=a2->getConstPointer();
3643   int nbElem=nbOfTuple*nbOfComp;
3644   for(int i=0;i<nbElem;i++)
3645     retPtr[i]=std::max(a1Ptr[i],a2Ptr[i]);
3646   ret->copyStringInfoFrom(*a1);
3647   return ret;
3648 }
3649
3650 /*!
3651  * Returns a new DataArrayDouble containing minimal values of two given arrays.
3652  * Info on components is copied from the first of the given arrays.
3653  * Number of tuples and components in the given arrays must be the same.
3654  *  \param [in] a1 - an array to compare values with another one.
3655  *  \param [in] a2 - another array to compare values with the first one.
3656  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3657  *          The caller is to delete this result array using decrRef() as it is no more
3658  *          needed.
3659  *  \throw If either \a a1 or \a a2 is NULL.
3660  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3661  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
3662  */
3663 DataArrayDouble *DataArrayDouble::Min(const DataArrayDouble *a1, const DataArrayDouble *a2)
3664 {
3665   if(!a1 || !a2)
3666     throw INTERP_KERNEL::Exception("DataArrayDouble::Min : input DataArrayDouble instance is NULL !");
3667   int nbOfComp=a1->getNumberOfComponents();
3668   if(nbOfComp!=a2->getNumberOfComponents())
3669     throw INTERP_KERNEL::Exception("Nb of components mismatch for array min !");
3670   int nbOfTuple=a1->getNumberOfTuples();
3671   if(nbOfTuple!=a2->getNumberOfTuples())
3672     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array min !");
3673   DataArrayDouble *ret=DataArrayDouble::New();
3674   ret->alloc(nbOfTuple,nbOfComp);
3675   double *retPtr=ret->getPointer();
3676   const double *a1Ptr=a1->getConstPointer();
3677   const double *a2Ptr=a2->getConstPointer();
3678   int nbElem=nbOfTuple*nbOfComp;
3679   for(int i=0;i<nbElem;i++)
3680     retPtr[i]=std::min(a1Ptr[i],a2Ptr[i]);
3681   ret->copyStringInfoFrom(*a1);
3682   return ret;
3683 }
3684
3685 /*!
3686  * Returns a new DataArrayDouble that is a sum of two given arrays. There are 3
3687  * valid cases.
3688  * 1.  The arrays have same number of tuples and components. Then each value of
3689  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
3690  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
3691  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
3692  *   component. Then
3693  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
3694  * 3.  The arrays have same number of components and one array, say _a2_, has one
3695  *   tuple. Then
3696  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
3697  *
3698  * Info on components is copied either from the first array (in the first case) or from
3699  * the array with maximal number of elements (getNbOfElems()).
3700  *  \param [in] a1 - an array to sum up.
3701  *  \param [in] a2 - another array to sum up.
3702  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3703  *          The caller is to delete this result array using decrRef() as it is no more
3704  *          needed.
3705  *  \throw If either \a a1 or \a a2 is NULL.
3706  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
3707  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
3708  *         none of them has number of tuples or components equal to 1.
3709  */
3710 DataArrayDouble *DataArrayDouble::Add(const DataArrayDouble *a1, const DataArrayDouble *a2)
3711 {
3712   if(!a1 || !a2)
3713     throw INTERP_KERNEL::Exception("DataArrayDouble::Add : input DataArrayDouble instance is NULL !");
3714   int nbOfTuple=a1->getNumberOfTuples();
3715   int nbOfTuple2=a2->getNumberOfTuples();
3716   int nbOfComp=a1->getNumberOfComponents();
3717   int nbOfComp2=a2->getNumberOfComponents();
3718   MCAuto<DataArrayDouble> ret=0;
3719   if(nbOfTuple==nbOfTuple2)
3720     {
3721       if(nbOfComp==nbOfComp2)
3722         {
3723           ret=DataArrayDouble::New();
3724           ret->alloc(nbOfTuple,nbOfComp);
3725           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<double>());
3726           ret->copyStringInfoFrom(*a1);
3727         }
3728       else
3729         {
3730           int nbOfCompMin,nbOfCompMax;
3731           const DataArrayDouble *aMin, *aMax;
3732           if(nbOfComp>nbOfComp2)
3733             {
3734               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
3735               aMin=a2; aMax=a1;
3736             }
3737           else
3738             {
3739               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
3740               aMin=a1; aMax=a2;
3741             }
3742           if(nbOfCompMin==1)
3743             {
3744               ret=DataArrayDouble::New();
3745               ret->alloc(nbOfTuple,nbOfCompMax);
3746               const double *aMinPtr=aMin->getConstPointer();
3747               const double *aMaxPtr=aMax->getConstPointer();
3748               double *res=ret->getPointer();
3749               for(int i=0;i<nbOfTuple;i++)
3750                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<double>(),aMinPtr[i]));
3751               ret->copyStringInfoFrom(*aMax);
3752             }
3753           else
3754             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
3755         }
3756     }
3757   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
3758     {
3759       if(nbOfComp==nbOfComp2)
3760         {
3761           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
3762           const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
3763           const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
3764           const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
3765           ret=DataArrayDouble::New();
3766           ret->alloc(nbOfTupleMax,nbOfComp);
3767           double *res=ret->getPointer();
3768           for(int i=0;i<nbOfTupleMax;i++)
3769             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<double>());
3770           ret->copyStringInfoFrom(*aMax);
3771         }
3772       else
3773         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
3774     }
3775   else
3776     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
3777   return ret.retn();
3778 }
3779
3780 /*!
3781  * Adds values of another DataArrayDouble to values of \a this one. There are 3
3782  * valid cases.
3783  * 1.  The arrays have same number of tuples and components. Then each value of
3784  *   \a other array is added to the corresponding value of \a this array, i.e.:
3785  *   _a_ [ i, j ] += _other_ [ i, j ].
3786  * 2.  The arrays have same number of tuples and \a other array has one component. Then
3787  *   _a_ [ i, j ] += _other_ [ i, 0 ].
3788  * 3.  The arrays have same number of components and \a other array has one tuple. Then
3789  *   _a_ [ i, j ] += _a2_ [ 0, j ].
3790  *
3791  *  \param [in] other - an array to add to \a this one.
3792  *  \throw If \a other is NULL.
3793  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
3794  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
3795  *         \a other has number of both tuples and components not equal to 1.
3796  */
3797 void DataArrayDouble::addEqual(const DataArrayDouble *other)
3798 {
3799   if(!other)
3800     throw INTERP_KERNEL::Exception("DataArrayDouble::addEqual : input DataArrayDouble instance is NULL !");
3801   const char *msg="Nb of tuples mismatch for DataArrayDouble::addEqual  !";
3802   checkAllocated();
3803   other->checkAllocated();
3804   int nbOfTuple=getNumberOfTuples();
3805   int nbOfTuple2=other->getNumberOfTuples();
3806   int nbOfComp=getNumberOfComponents();
3807   int nbOfComp2=other->getNumberOfComponents();
3808   if(nbOfTuple==nbOfTuple2)
3809     {
3810       if(nbOfComp==nbOfComp2)
3811         {
3812           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<double>());
3813         }
3814       else if(nbOfComp2==1)
3815         {
3816           double *ptr=getPointer();
3817           const double *ptrc=other->getConstPointer();
3818           for(int i=0;i<nbOfTuple;i++)
3819             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<double>(),*ptrc++));
3820         }
3821       else
3822         throw INTERP_KERNEL::Exception(msg);
3823     }
3824   else if(nbOfTuple2==1)
3825     {
3826       if(nbOfComp2==nbOfComp)
3827         {
3828           double *ptr=getPointer();
3829           const double *ptrc=other->getConstPointer();
3830           for(int i=0;i<nbOfTuple;i++)
3831             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<double>());
3832         }
3833       else
3834         throw INTERP_KERNEL::Exception(msg);
3835     }
3836   else
3837     throw INTERP_KERNEL::Exception(msg);
3838   declareAsNew();
3839 }
3840
3841 /*!
3842  * Returns a new DataArrayDouble that is a subtraction of two given arrays. There are 3
3843  * valid cases.
3844  * 1.  The arrays have same number of tuples and components. Then each value of
3845  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
3846  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
3847  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
3848  *   component. Then
3849  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
3850  * 3.  The arrays have same number of components and one array, say _a2_, has one
3851  *   tuple. Then
3852  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
3853  *
3854  * Info on components is copied either from the first array (in the first case) or from
3855  * the array with maximal number of elements (getNbOfElems()).
3856  *  \param [in] a1 - an array to subtract from.
3857  *  \param [in] a2 - an array to subtract.
3858  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3859  *          The caller is to delete this result array using decrRef() as it is no more
3860  *          needed.
3861  *  \throw If either \a a1 or \a a2 is NULL.
3862  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
3863  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
3864  *         none of them has number of tuples or components equal to 1.
3865  */
3866 DataArrayDouble *DataArrayDouble::Substract(const DataArrayDouble *a1, const DataArrayDouble *a2)
3867 {
3868   if(!a1 || !a2)
3869     throw INTERP_KERNEL::Exception("DataArrayDouble::Substract : input DataArrayDouble instance is NULL !");
3870   int nbOfTuple1=a1->getNumberOfTuples();
3871   int nbOfTuple2=a2->getNumberOfTuples();
3872   int nbOfComp1=a1->getNumberOfComponents();
3873   int nbOfComp2=a2->getNumberOfComponents();
3874   if(nbOfTuple2==nbOfTuple1)
3875     {
3876       if(nbOfComp1==nbOfComp2)
3877         {
3878           MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
3879           ret->alloc(nbOfTuple2,nbOfComp1);
3880           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<double>());
3881           ret->copyStringInfoFrom(*a1);
3882           return ret.retn();
3883         }
3884       else if(nbOfComp2==1)
3885         {
3886           MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
3887           ret->alloc(nbOfTuple1,nbOfComp1);
3888           const double *a2Ptr=a2->getConstPointer();
3889           const double *a1Ptr=a1->getConstPointer();
3890           double *res=ret->getPointer();
3891           for(int i=0;i<nbOfTuple1;i++)
3892             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<double>(),a2Ptr[i]));
3893           ret->copyStringInfoFrom(*a1);
3894           return ret.retn();
3895         }
3896       else
3897         {
3898           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
3899           return 0;
3900         }
3901     }
3902   else if(nbOfTuple2==1)
3903     {
3904       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
3905       MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
3906       ret->alloc(nbOfTuple1,nbOfComp1);
3907       const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
3908       double *pt=ret->getPointer();
3909       for(int i=0;i<nbOfTuple1;i++)
3910         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<double>());
3911       ret->copyStringInfoFrom(*a1);
3912       return ret.retn();
3913     }
3914   else
3915     {
3916       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
3917       return 0;
3918     }
3919 }
3920
3921 /*!
3922  * Subtract values of another DataArrayDouble from values of \a this one. There are 3
3923  * valid cases.
3924  * 1.  The arrays have same number of tuples and components. Then each value of
3925  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
3926  *   _a_ [ i, j ] -= _other_ [ i, j ].
3927  * 2.  The arrays have same number of tuples and \a other array has one component. Then
3928  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
3929  * 3.  The arrays have same number of components and \a other array has one tuple. Then
3930  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
3931  *
3932  *  \param [in] other - an array to subtract from \a this one.
3933  *  \throw If \a other is NULL.
3934  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
3935  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
3936  *         \a other has number of both tuples and components not equal to 1.
3937  */
3938 void DataArrayDouble::substractEqual(const DataArrayDouble *other)
3939 {
3940   if(!other)
3941     throw INTERP_KERNEL::Exception("DataArrayDouble::substractEqual : input DataArrayDouble instance is NULL !");
3942   const char *msg="Nb of tuples mismatch for DataArrayDouble::substractEqual  !";
3943   checkAllocated();
3944   other->checkAllocated();
3945   int nbOfTuple=getNumberOfTuples();
3946   int nbOfTuple2=other->getNumberOfTuples();
3947   int nbOfComp=getNumberOfComponents();
3948   int nbOfComp2=other->getNumberOfComponents();
3949   if(nbOfTuple==nbOfTuple2)
3950     {
3951       if(nbOfComp==nbOfComp2)
3952         {
3953           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<double>());
3954         }
3955       else if(nbOfComp2==1)
3956         {
3957           double *ptr=getPointer();
3958           const double *ptrc=other->getConstPointer();
3959           for(int i=0;i<nbOfTuple;i++)
3960             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<double>(),*ptrc++)); 
3961         }
3962       else
3963         throw INTERP_KERNEL::Exception(msg);
3964     }
3965   else if(nbOfTuple2==1)
3966     {
3967       if(nbOfComp2==nbOfComp)
3968         {
3969           double *ptr=getPointer();
3970           const double *ptrc=other->getConstPointer();
3971           for(int i=0;i<nbOfTuple;i++)
3972             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<double>());
3973         }
3974       else
3975         throw INTERP_KERNEL::Exception(msg);
3976     }
3977   else
3978     throw INTERP_KERNEL::Exception(msg);
3979   declareAsNew();
3980 }
3981
3982 /*!
3983  * Returns a new DataArrayDouble that is a product of two given arrays. There are 3
3984  * valid cases.
3985  * 1.  The arrays have same number of tuples and components. Then each value of
3986  *   the result array (_a_) is a product of the corresponding values of \a a1 and
3987  *   \a a2, i.e. _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
3988  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
3989  *   component. Then
3990  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
3991  * 3.  The arrays have same number of components and one array, say _a2_, has one
3992  *   tuple. Then
3993  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
3994  *
3995  * Info on components is copied either from the first array (in the first case) or from
3996  * the array with maximal number of elements (getNbOfElems()).
3997  *  \param [in] a1 - a factor array.
3998  *  \param [in] a2 - another factor array.
3999  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4000  *          The caller is to delete this result array using decrRef() as it is no more
4001  *          needed.
4002  *  \throw If either \a a1 or \a a2 is NULL.
4003  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
4004  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
4005  *         none of them has number of tuples or components equal to 1.
4006  */
4007 DataArrayDouble *DataArrayDouble::Multiply(const DataArrayDouble *a1, const DataArrayDouble *a2)
4008 {
4009   if(!a1 || !a2)
4010     throw INTERP_KERNEL::Exception("DataArrayDouble::Multiply : input DataArrayDouble instance is NULL !");
4011   int nbOfTuple=a1->getNumberOfTuples();
4012   int nbOfTuple2=a2->getNumberOfTuples();
4013   int nbOfComp=a1->getNumberOfComponents();
4014   int nbOfComp2=a2->getNumberOfComponents();
4015   MCAuto<DataArrayDouble> ret=0;
4016   if(nbOfTuple==nbOfTuple2)
4017     {
4018       if(nbOfComp==nbOfComp2)
4019         {
4020           ret=DataArrayDouble::New();
4021           ret->alloc(nbOfTuple,nbOfComp);
4022           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<double>());
4023           ret->copyStringInfoFrom(*a1);
4024         }
4025       else
4026         {
4027           int nbOfCompMin,nbOfCompMax;
4028           const DataArrayDouble *aMin, *aMax;
4029           if(nbOfComp>nbOfComp2)
4030             {
4031               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
4032               aMin=a2; aMax=a1;
4033             }
4034           else
4035             {
4036               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
4037               aMin=a1; aMax=a2;
4038             }
4039           if(nbOfCompMin==1)
4040             {
4041               ret=DataArrayDouble::New();
4042               ret->alloc(nbOfTuple,nbOfCompMax);
4043               const double *aMinPtr=aMin->getConstPointer();
4044               const double *aMaxPtr=aMax->getConstPointer();
4045               double *res=ret->getPointer();
4046               for(int i=0;i<nbOfTuple;i++)
4047                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<double>(),aMinPtr[i]));
4048               ret->copyStringInfoFrom(*aMax);
4049             }
4050           else
4051             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
4052         }
4053     }
4054   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
4055     {
4056       if(nbOfComp==nbOfComp2)
4057         {
4058           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
4059           const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
4060           const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
4061           const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
4062           ret=DataArrayDouble::New();
4063           ret->alloc(nbOfTupleMax,nbOfComp);
4064           double *res=ret->getPointer();
4065           for(int i=0;i<nbOfTupleMax;i++)
4066             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<double>());
4067           ret->copyStringInfoFrom(*aMax);
4068         }
4069       else
4070         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
4071     }
4072   else
4073     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
4074   return ret.retn();
4075 }
4076
4077 /*!
4078  * Multiply values of another DataArrayDouble to values of \a this one. There are 3
4079  * valid cases.
4080  * 1.  The arrays have same number of tuples and components. Then each value of
4081  *   \a other array is multiplied to the corresponding value of \a this array, i.e.
4082  *   _this_ [ i, j ] *= _other_ [ i, j ].
4083  * 2.  The arrays have same number of tuples and \a other array has one component. Then
4084  *   _this_ [ i, j ] *= _other_ [ i, 0 ].
4085  * 3.  The arrays have same number of components and \a other array has one tuple. Then
4086  *   _this_ [ i, j ] *= _a2_ [ 0, j ].
4087  *
4088  *  \param [in] other - an array to multiply to \a this one.
4089  *  \throw If \a other is NULL.
4090  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
4091  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
4092  *         \a other has number of both tuples and components not equal to 1.
4093  */
4094 void DataArrayDouble::multiplyEqual(const DataArrayDouble *other)
4095 {
4096   if(!other)
4097     throw INTERP_KERNEL::Exception("DataArrayDouble::multiplyEqual : input DataArrayDouble instance is NULL !");
4098   const char *msg="Nb of tuples mismatch for DataArrayDouble::multiplyEqual !";
4099   checkAllocated();
4100   other->checkAllocated();
4101   int nbOfTuple=getNumberOfTuples();
4102   int nbOfTuple2=other->getNumberOfTuples();
4103   int nbOfComp=getNumberOfComponents();
4104   int nbOfComp2=other->getNumberOfComponents();
4105   if(nbOfTuple==nbOfTuple2)
4106     {
4107       if(nbOfComp==nbOfComp2)
4108         {
4109           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<double>());
4110         }
4111       else if(nbOfComp2==1)
4112         {
4113           double *ptr=getPointer();
4114           const double *ptrc=other->getConstPointer();
4115           for(int i=0;i<nbOfTuple;i++)
4116             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<double>(),*ptrc++));
4117         }
4118       else
4119         throw INTERP_KERNEL::Exception(msg);
4120     }
4121   else if(nbOfTuple2==1)
4122     {
4123       if(nbOfComp2==nbOfComp)
4124         {
4125           double *ptr=getPointer();
4126           const double *ptrc=other->getConstPointer();
4127           for(int i=0;i<nbOfTuple;i++)
4128             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<double>());
4129         }
4130       else
4131         throw INTERP_KERNEL::Exception(msg);
4132     }
4133   else
4134     throw INTERP_KERNEL::Exception(msg);
4135   declareAsNew();
4136 }
4137
4138 /*!
4139  * Returns a new DataArrayDouble that is a division of two given arrays. There are 3
4140  * valid cases.
4141  * 1.  The arrays have same number of tuples and components. Then each value of
4142  *   the result array (_a_) is a division of the corresponding values of \a a1 and
4143  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
4144  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
4145  *   component. Then
4146  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
4147  * 3.  The arrays have same number of components and one array, say _a2_, has one
4148  *   tuple. Then
4149  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
4150  *
4151  * Info on components is copied either from the first array (in the first case) or from
4152  * the array with maximal number of elements (getNbOfElems()).
4153  *  \warning No check of division by zero is performed!
4154  *  \param [in] a1 - a numerator array.
4155  *  \param [in] a2 - a denominator array.
4156  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4157  *          The caller is to delete this result array using decrRef() as it is no more
4158  *          needed.
4159  *  \throw If either \a a1 or \a a2 is NULL.
4160  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
4161  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
4162  *         none of them has number of tuples or components equal to 1.
4163  */
4164 DataArrayDouble *DataArrayDouble::Divide(const DataArrayDouble *a1, const DataArrayDouble *a2)
4165 {
4166   if(!a1 || !a2)
4167     throw INTERP_KERNEL::Exception("DataArrayDouble::Divide : input DataArrayDouble instance is NULL !");
4168   int nbOfTuple1=a1->getNumberOfTuples();
4169   int nbOfTuple2=a2->getNumberOfTuples();
4170   int nbOfComp1=a1->getNumberOfComponents();
4171   int nbOfComp2=a2->getNumberOfComponents();
4172   if(nbOfTuple2==nbOfTuple1)
4173     {
4174       if(nbOfComp1==nbOfComp2)
4175         {
4176           MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
4177           ret->alloc(nbOfTuple2,nbOfComp1);
4178           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<double>());
4179           ret->copyStringInfoFrom(*a1);
4180           return ret.retn();
4181         }
4182       else if(nbOfComp2==1)
4183         {
4184           MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
4185           ret->alloc(nbOfTuple1,nbOfComp1);
4186           const double *a2Ptr=a2->getConstPointer();
4187           const double *a1Ptr=a1->getConstPointer();
4188           double *res=ret->getPointer();
4189           for(int i=0;i<nbOfTuple1;i++)
4190             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<double>(),a2Ptr[i]));
4191           ret->copyStringInfoFrom(*a1);
4192           return ret.retn();
4193         }
4194       else
4195         {
4196           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
4197           return 0;
4198         }
4199     }
4200   else if(nbOfTuple2==1)
4201     {
4202       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
4203       MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
4204       ret->alloc(nbOfTuple1,nbOfComp1);
4205       const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
4206       double *pt=ret->getPointer();
4207       for(int i=0;i<nbOfTuple1;i++)
4208         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<double>());
4209       ret->copyStringInfoFrom(*a1);
4210       return ret.retn();
4211     }
4212   else
4213     {
4214       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
4215       return 0;
4216     }
4217 }
4218
4219 /*!
4220  * Divide values of \a this array by values of another DataArrayDouble. There are 3
4221  * valid cases.
4222  * 1.  The arrays have same number of tuples and components. Then each value of
4223  *    \a this array is divided by the corresponding value of \a other one, i.e.:
4224  *   _a_ [ i, j ] /= _other_ [ i, j ].
4225  * 2.  The arrays have same number of tuples and \a other array has one component. Then
4226  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
4227  * 3.  The arrays have same number of components and \a other array has one tuple. Then
4228  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
4229  *
4230  *  \warning No check of division by zero is performed!
4231  *  \param [in] other - an array to divide \a this one by.
4232  *  \throw If \a other is NULL.
4233  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
4234  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
4235  *         \a other has number of both tuples and components not equal to 1.
4236  */
4237 void DataArrayDouble::divideEqual(const DataArrayDouble *other)
4238 {
4239   if(!other)
4240     throw INTERP_KERNEL::Exception("DataArrayDouble::divideEqual : input DataArrayDouble instance is NULL !");
4241   const char *msg="Nb of tuples mismatch for DataArrayDouble::divideEqual !";
4242   checkAllocated();
4243   other->checkAllocated();
4244   int nbOfTuple=getNumberOfTuples();
4245   int nbOfTuple2=other->getNumberOfTuples();
4246   int nbOfComp=getNumberOfComponents();
4247   int nbOfComp2=other->getNumberOfComponents();
4248   if(nbOfTuple==nbOfTuple2)
4249     {
4250       if(nbOfComp==nbOfComp2)
4251         {
4252           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<double>());
4253         }
4254       else if(nbOfComp2==1)
4255         {
4256           double *ptr=getPointer();
4257           const double *ptrc=other->getConstPointer();
4258           for(int i=0;i<nbOfTuple;i++)
4259             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<double>(),*ptrc++));
4260         }
4261       else
4262         throw INTERP_KERNEL::Exception(msg);
4263     }
4264   else if(nbOfTuple2==1)
4265     {
4266       if(nbOfComp2==nbOfComp)
4267         {
4268           double *ptr=getPointer();
4269           const double *ptrc=other->getConstPointer();
4270           for(int i=0;i<nbOfTuple;i++)
4271             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<double>());
4272         }
4273       else
4274         throw INTERP_KERNEL::Exception(msg);
4275     }
4276   else
4277     throw INTERP_KERNEL::Exception(msg);
4278   declareAsNew();
4279 }
4280
4281 /*!
4282  * Returns a new DataArrayDouble that is the result of pow of two given arrays. There are 3
4283  * valid cases.
4284  *
4285  *  \param [in] a1 - an array to pow up.
4286  *  \param [in] a2 - another array to sum up.
4287  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4288  *          The caller is to delete this result array using decrRef() as it is no more
4289  *          needed.
4290  *  \throw If either \a a1 or \a a2 is NULL.
4291  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4292  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
4293  *  \throw If there is a negative value in \a a1.
4294  */
4295 DataArrayDouble *DataArrayDouble::Pow(const DataArrayDouble *a1, const DataArrayDouble *a2)
4296 {
4297   if(!a1 || !a2)
4298     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : at least one of input instances is null !");
4299   int nbOfTuple=a1->getNumberOfTuples();
4300   int nbOfTuple2=a2->getNumberOfTuples();
4301   int nbOfComp=a1->getNumberOfComponents();
4302   int nbOfComp2=a2->getNumberOfComponents();
4303   if(nbOfTuple!=nbOfTuple2)
4304     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of tuples mismatches !");
4305   if(nbOfComp!=1 || nbOfComp2!=1)
4306     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of components of both arrays must be equal to 1 !");
4307   MCAuto<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbOfTuple,1);
4308   const double *ptr1(a1->begin()),*ptr2(a2->begin());
4309   double *ptr=ret->getPointer();
4310   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
4311     {
4312       if(*ptr1>=0)
4313         {
4314           *ptr=pow(*ptr1,*ptr2);
4315         }
4316       else
4317         {
4318           std::ostringstream oss; oss << "DataArrayDouble::Pow : on tuple #" << i << " of a1 value is < 0 (" << *ptr1 << ") !";
4319           throw INTERP_KERNEL::Exception(oss.str().c_str());
4320         }
4321     }
4322   return ret.retn();
4323 }
4324
4325 /*!
4326  * Apply pow on values of another DataArrayDouble to values of \a this one.
4327  *
4328  *  \param [in] other - an array to pow to \a this one.
4329  *  \throw If \a other is NULL.
4330  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
4331  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
4332  *  \throw If there is a negative value in \a this.
4333  */
4334 void DataArrayDouble::powEqual(const DataArrayDouble *other)
4335 {
4336   if(!other)
4337     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : input instance is null !");
4338   int nbOfTuple=getNumberOfTuples();
4339   int nbOfTuple2=other->getNumberOfTuples();
4340   int nbOfComp=getNumberOfComponents();
4341   int nbOfComp2=other->getNumberOfComponents();
4342   if(nbOfTuple!=nbOfTuple2)
4343     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of tuples mismatches !");
4344   if(nbOfComp!=1 || nbOfComp2!=1)
4345     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of components of both arrays must be equal to 1 !");
4346   double *ptr=getPointer();
4347   const double *ptrc=other->begin();
4348   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
4349     {
4350       if(*ptr>=0)
4351         *ptr=pow(*ptr,*ptrc);
4352       else
4353         {
4354           std::ostringstream oss; oss << "DataArrayDouble::powEqual : on tuple #" << i << " of this value is < 0 (" << *ptr << ") !";
4355           throw INTERP_KERNEL::Exception(oss.str().c_str());
4356         }
4357     }
4358   declareAsNew();
4359 }
4360
4361 /*!
4362  * This method is \b NOT wrapped into python because it can be useful only for performance reasons in C++ context.
4363  * All values in \a this must be 0. or 1. within eps error. 0 means false, 1 means true.
4364  * If an another value than 0 or 1 appear (within eps precision) an INTERP_KERNEL::Exception will be thrown.
4365  *
4366  * \throw if \a this is not allocated.
4367  * \throw if \a this has not exactly one component.
4368  */
4369 std::vector<bool> DataArrayDouble::toVectorOfBool(double eps) const
4370 {
4371   checkAllocated();
4372   if(getNumberOfComponents()!=1)
4373     throw INTERP_KERNEL::Exception("DataArrayDouble::toVectorOfBool : must be applied on single component array !");
4374   int nbt(getNumberOfTuples());
4375   std::vector<bool> ret(nbt);
4376   const double *pt(begin());
4377   for(int i=0;i<nbt;i++)
4378     {
4379       if(fabs(pt[i])<eps)
4380         ret[i]=false;
4381       else if(fabs(pt[i]-1.)<eps)
4382         ret[i]=true;
4383       else
4384         {
4385           std::ostringstream oss; oss << "DataArrayDouble::toVectorOfBool : the tuple #" << i << " has value " << pt[i] << " is invalid ! must be 0. or 1. !";
4386           throw INTERP_KERNEL::Exception(oss.str().c_str());
4387         }
4388     }
4389   return ret;
4390 }
4391
4392 /*!
4393  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
4394  * Server side.
4395  */
4396 void DataArrayDouble::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
4397 {
4398   tinyInfo.resize(2);
4399   if(isAllocated())
4400     {
4401       tinyInfo[0]=getNumberOfTuples();
4402       tinyInfo[1]=getNumberOfComponents();
4403     }
4404   else
4405     {
4406       tinyInfo[0]=-1;
4407       tinyInfo[1]=-1;
4408     }
4409 }
4410
4411 /*!
4412  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
4413  * Server side.
4414  */
4415 void DataArrayDouble::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
4416 {
4417   if(isAllocated())
4418     {
4419       int nbOfCompo=getNumberOfComponents();
4420       tinyInfo.resize(nbOfCompo+1);
4421       tinyInfo[0]=getName();
4422       for(int i=0;i<nbOfCompo;i++)
4423         tinyInfo[i+1]=getInfoOnComponent(i);
4424     }
4425   else
4426     {
4427       tinyInfo.resize(1);
4428       tinyInfo[0]=getName();
4429     }
4430 }
4431
4432 /*!
4433  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
4434  * This method returns if a feeding is needed.
4435  */
4436 bool DataArrayDouble::resizeForUnserialization(const std::vector<int>& tinyInfoI)
4437 {
4438   int nbOfTuple=tinyInfoI[0];
4439   int nbOfComp=tinyInfoI[1];
4440   if(nbOfTuple!=-1 || nbOfComp!=-1)
4441     {
4442       alloc(nbOfTuple,nbOfComp);
4443       return true;
4444     }
4445   return false;
4446 }
4447
4448 /*!
4449  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
4450  */
4451 void DataArrayDouble::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
4452 {
4453   setName(tinyInfoS[0]);
4454   if(isAllocated())
4455     {
4456       int nbOfCompo=getNumberOfComponents();
4457       for(int i=0;i<nbOfCompo;i++)
4458         setInfoOnComponent(i,tinyInfoS[i+1]);
4459     }
4460 }
4461
4462 /*!
4463  * Low static method that operates 3D rotation of 'nbNodes' 3D nodes whose coordinates are arranged in \a coordsIn
4464  * around an axe ( \a center, \a vect) and with angle \a angle.
4465  */
4466 void DataArrayDouble::Rotate3DAlg(const double *center, const double *vect, double angle, int nbNodes, const double *coordsIn, double *coordsOut)
4467 {
4468   if(!center || !vect)
4469     throw INTERP_KERNEL::Exception("DataArrayDouble::Rotate3DAlg : null vector in input !");
4470   double sina(sin(angle));
4471   double cosa(cos(angle));
4472   double vectorNorm[3];
4473   double matrix[9];
4474   double matrixTmp[9];
4475   double norm(sqrt(vect[0]*vect[0]+vect[1]*vect[1]+vect[2]*vect[2]));
4476   if(norm<std::numeric_limits<double>::min())
4477     throw INTERP_KERNEL::Exception("DataArrayDouble::Rotate3DAlg : magnitude of input vector is too close of 0. !");
4478   std::transform(vect,vect+3,vectorNorm,std::bind2nd(std::multiplies<double>(),1/norm));
4479   //rotation matrix computation
4480   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;
4481   matrixTmp[0]=vectorNorm[0]*vectorNorm[0]; matrixTmp[1]=vectorNorm[0]*vectorNorm[1]; matrixTmp[2]=vectorNorm[0]*vectorNorm[2];
4482   matrixTmp[3]=vectorNorm[1]*vectorNorm[0]; matrixTmp[4]=vectorNorm[1]*vectorNorm[1]; matrixTmp[5]=vectorNorm[1]*vectorNorm[2];
4483   matrixTmp[6]=vectorNorm[2]*vectorNorm[0]; matrixTmp[7]=vectorNorm[2]*vectorNorm[1]; matrixTmp[8]=vectorNorm[2]*vectorNorm[2];
4484   std::transform(matrixTmp,matrixTmp+9,matrixTmp,std::bind2nd(std::multiplies<double>(),1-cosa));
4485   std::transform(matrix,matrix+9,matrixTmp,matrix,std::plus<double>());
4486   matrixTmp[0]=0.; matrixTmp[1]=-vectorNorm[2]; matrixTmp[2]=vectorNorm[1];
4487   matrixTmp[3]=vectorNorm[2]; matrixTmp[4]=0.; matrixTmp[5]=-vectorNorm[0];
4488   matrixTmp[6]=-vectorNorm[1]; matrixTmp[7]=vectorNorm[0]; matrixTmp[8]=0.;
4489   std::transform(matrixTmp,matrixTmp+9,matrixTmp,std::bind2nd(std::multiplies<double>(),sina));
4490   std::transform(matrix,matrix+9,matrixTmp,matrix,std::plus<double>());
4491   //rotation matrix computed.
4492   double tmp[3];
4493   for(int i=0; i<nbNodes; i++)
4494     {
4495       std::transform(coordsIn+i*3,coordsIn+(i+1)*3,center,tmp,std::minus<double>());
4496       coordsOut[i*3]=matrix[0]*tmp[0]+matrix[1]*tmp[1]+matrix[2]*tmp[2]+center[0];
4497       coordsOut[i*3+1]=matrix[3]*tmp[0]+matrix[4]*tmp[1]+matrix[5]*tmp[2]+center[1];
4498       coordsOut[i*3+2]=matrix[6]*tmp[0]+matrix[7]*tmp[1]+matrix[8]*tmp[2]+center[2];
4499     }
4500 }
4501
4502 void DataArrayDouble::Symmetry3DPlane(const double point[3], const double normalVector[3], int nbNodes, const double *coordsIn, double *coordsOut)
4503 {
4504   double matrix[9],matrix2[9],matrix3[9];
4505   double vect[3],crossVect[3];
4506   INTERP_KERNEL::orthogonalVect3(normalVector,vect);
4507   crossVect[0]=normalVector[1]*vect[2]-normalVector[2]*vect[1];
4508   crossVect[1]=normalVector[2]*vect[0]-normalVector[0]*vect[2];
4509   crossVect[2]=normalVector[0]*vect[1]-normalVector[1]*vect[0];
4510   double nv(INTERP_KERNEL::norm<3>(vect)),ni(INTERP_KERNEL::norm<3>(normalVector)),nc(INTERP_KERNEL::norm<3>(crossVect));
4511   matrix[0]=vect[0]/nv; matrix[1]=crossVect[0]/nc; matrix[2]=-normalVector[0]/ni;
4512   matrix[3]=vect[1]/nv; matrix[4]=crossVect[1]/nc; matrix[5]=-normalVector[1]/ni;
4513   matrix[6]=vect[2]/nv; matrix[7]=crossVect[2]/nc; matrix[8]=-normalVector[2]/ni;
4514   matrix2[0]=vect[0]/nv; matrix2[1]=vect[1]/nv; matrix2[2]=vect[2]/nv;
4515   matrix2[3]=crossVect[0]/nc; matrix2[4]=crossVect[1]/nc; matrix2[5]=crossVect[2]/nc;
4516   matrix2[6]=normalVector[0]/ni; matrix2[7]=normalVector[1]/ni; matrix2[8]=normalVector[2]/ni;
4517   for(int i=0;i<3;i++)
4518     for(int j=0;j<3;j++)
4519       {
4520         double val(0.);
4521         for(int k=0;k<3;k++)
4522           val+=matrix[3*i+k]*matrix2[3*k+j];
4523         matrix3[3*i+j]=val;
4524       }
4525   //rotation matrix computed.
4526   double tmp[3];
4527   for(int i=0; i<nbNodes; i++)
4528     {
4529       std::transform(coordsIn+i*3,coordsIn+(i+1)*3,point,tmp,std::minus<double>());
4530       coordsOut[i*3]=matrix3[0]*tmp[0]+matrix3[1]*tmp[1]+matrix3[2]*tmp[2]+point[0];
4531       coordsOut[i*3+1]=matrix3[3]*tmp[0]+matrix3[4]*tmp[1]+matrix3[5]*tmp[2]+point[1];
4532       coordsOut[i*3+2]=matrix3[6]*tmp[0]+matrix3[7]*tmp[1]+matrix3[8]*tmp[2]+point[2];
4533     }
4534 }
4535
4536 void DataArrayDouble::GiveBaseForPlane(const double normalVector[3], double baseOfPlane[9])
4537 {
4538   double vect[3],crossVect[3];
4539   INTERP_KERNEL::orthogonalVect3(normalVector,vect);
4540   crossVect[0]=normalVector[1]*vect[2]-normalVector[2]*vect[1];
4541   crossVect[1]=normalVector[2]*vect[0]-normalVector[0]*vect[2];
4542   crossVect[2]=normalVector[0]*vect[1]-normalVector[1]*vect[0];
4543   double nv(INTERP_KERNEL::norm<3>(vect)),ni(INTERP_KERNEL::norm<3>(normalVector)),nc(INTERP_KERNEL::norm<3>(crossVect));
4544   baseOfPlane[0]=vect[0]/nv; baseOfPlane[1]=vect[1]/nv; baseOfPlane[2]=vect[2]/nv;
4545   baseOfPlane[3]=crossVect[0]/nc; baseOfPlane[4]=crossVect[1]/nc; baseOfPlane[5]=crossVect[2]/nc;
4546   baseOfPlane[6]=normalVector[0]/ni; baseOfPlane[7]=normalVector[1]/ni; baseOfPlane[8]=normalVector[2]/ni;
4547 }
4548
4549 /*!
4550  * Low static method that operates 3D rotation of \a nbNodes 3D nodes whose coordinates are arranged in \a coords
4551  * around the center point \a center and with angle \a angle.
4552  */
4553 void DataArrayDouble::Rotate2DAlg(const double *center, double angle, int nbNodes, const double *coordsIn, double *coordsOut)
4554 {
4555   double cosa=cos(angle);
4556   double sina=sin(angle);
4557   double matrix[4];
4558   matrix[0]=cosa; matrix[1]=-sina; matrix[2]=sina; matrix[3]=cosa;
4559   double tmp[2];
4560   for(int i=0; i<nbNodes; i++)
4561     {
4562       std::transform(coordsIn+i*2,coordsIn+(i+1)*2,center,tmp,std::minus<double>());
4563       coordsOut[i*2]=matrix[0]*tmp[0]+matrix[1]*tmp[1]+center[0];
4564       coordsOut[i*2+1]=matrix[2]*tmp[0]+matrix[3]*tmp[1]+center[1];
4565     }
4566 }
4567
4568 DataArrayDoubleIterator::DataArrayDoubleIterator(DataArrayDouble *da):DataArrayIterator<double>(da)
4569 {
4570 }
4571
4572 DataArrayDoubleTuple::DataArrayDoubleTuple(double *pt, int nbOfComp):DataArrayTuple<double>(pt,nbOfComp)
4573 {
4574 }
4575
4576
4577 std::string DataArrayDoubleTuple::repr() const
4578 {
4579   std::ostringstream oss; oss.precision(17); oss << "(";
4580   for(int i=0;i<_nb_of_compo-1;i++)
4581     oss << _pt[i] << ", ";
4582   oss << _pt[_nb_of_compo-1] << ")";
4583   return oss.str();
4584 }
4585
4586 double DataArrayDoubleTuple::doubleValue() const
4587 {
4588   if(_nb_of_compo==1)
4589     return *_pt;
4590   throw INTERP_KERNEL::Exception("DataArrayDoubleTuple::doubleValue : DataArrayDoubleTuple instance has not exactly 1 component -> Not possible to convert it into a double precision float !");
4591 }
4592
4593 /*!
4594  * This method returns a newly allocated instance the caller should dealed with by a MEDCoupling::DataArrayDouble::decrRef.
4595  * This method performs \b no copy of data. The content is only referenced using MEDCoupling::DataArrayDouble::useArray with ownership set to \b false.
4596  * 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
4597  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
4598  */
4599 DataArrayDouble *DataArrayDoubleTuple::buildDADouble(int nbOfTuples, int nbOfCompo) const
4600 {
4601   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
4602     {
4603       DataArrayDouble *ret=DataArrayDouble::New();
4604       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
4605       return ret;
4606     }
4607   else
4608     {
4609       std::ostringstream oss; oss << "DataArrayDoubleTuple::buildDADouble : unable to build a requested DataArrayDouble instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
4610       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
4611       throw INTERP_KERNEL::Exception(oss.str().c_str());
4612     }
4613 }
4614
4615 /*!
4616  * Returns a new instance of DataArrayInt. The caller is to delete this array
4617  * using decrRef() as it is no more needed. 
4618  */
4619 DataArrayInt *DataArrayInt::New()
4620 {
4621   return new DataArrayInt;
4622 }
4623
4624 /*!
4625  * Returns the only one value in \a this, if and only if number of elements
4626  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
4627  *  \return double - the sole value stored in \a this array.
4628  *  \throw If at least one of conditions stated above is not fulfilled.
4629  */
4630 int DataArrayInt::intValue() const
4631 {
4632   if(isAllocated())
4633     {
4634       if(getNbOfElems()==1)
4635         {
4636           return *getConstPointer();
4637         }
4638       else
4639         throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is allocated but number of elements is not equal to 1 !");
4640     }
4641   else
4642     throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is not allocated !");
4643 }
4644
4645 /*!
4646  * Returns an integer value characterizing \a this array, which is useful for a quick
4647  * comparison of many instances of DataArrayInt.
4648  *  \return int - the hash value.
4649  *  \throw If \a this is not allocated.
4650  */
4651 int DataArrayInt::getHashCode() const
4652 {
4653   checkAllocated();
4654   std::size_t nbOfElems=getNbOfElems();
4655   int ret=nbOfElems*65536;
4656   int delta=3;
4657   if(nbOfElems>48)
4658     delta=nbOfElems/8;
4659   int ret0=0;
4660   const int *pt=begin();
4661   for(std::size_t i=0;i<nbOfElems;i+=delta)
4662     ret0+=pt[i] & 0x1FFF;
4663   return ret+ret0;
4664 }
4665
4666 /*!
4667  * Returns a full copy of \a this. For more info on copying data arrays see
4668  * \ref MEDCouplingArrayBasicsCopyDeep.
4669  *  \return DataArrayInt * - a new instance of DataArrayInt.
4670  */
4671 DataArrayInt *DataArrayInt::deepCopy() const
4672 {
4673   return new DataArrayInt(*this);
4674 }
4675
4676 /*!
4677  * Returns either a \a deep or \a shallow copy of this array. For more info see
4678  * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
4679  *  \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
4680  *  \return DataArrayInt * - either a new instance of DataArrayInt (if \a dCpy
4681  *          == \a true) or \a this instance (if \a dCpy == \a false).
4682  */
4683 DataArrayInt *DataArrayInt::performCopyOrIncrRef(bool dCpy) const
4684 {
4685   return DataArrayTemplateClassic<int>::PerformCopyOrIncrRef(dCpy,*this);
4686 }
4687
4688 /*!
4689  * Assign zero to all values in \a this array. To know more on filling arrays see
4690  * \ref MEDCouplingArrayFill.
4691  * \throw If \a this is not allocated.
4692  */
4693 void DataArrayInt::fillWithZero()
4694 {
4695   fillWithValue(0);
4696 }
4697
4698 /*!
4699  * Set all values in \a this array so that the i-th element equals to \a init + i
4700  * (i starts from zero). To know more on filling arrays see \ref MEDCouplingArrayFill.
4701  *  \param [in] init - value to assign to the first element of array.
4702  *  \throw If \a this->getNumberOfComponents() != 1
4703  *  \throw If \a this is not allocated.
4704  */
4705 void DataArrayInt::iota(int init)
4706 {
4707   checkAllocated();
4708   if(getNumberOfComponents()!=1)
4709     throw INTERP_KERNEL::Exception("DataArrayInt::iota : works only for arrays with only one component, you can call 'rearrange' method before !");
4710   int *ptr=getPointer();
4711   int ntuples=getNumberOfTuples();
4712   for(int i=0;i<ntuples;i++)
4713     ptr[i]=init+i;
4714   declareAsNew();
4715 }
4716
4717 /*!
4718  * Returns a textual and human readable representation of \a this instance of
4719  * DataArrayInt. This text is shown when a DataArrayInt is printed in Python.
4720  * \return std::string - text describing \a this DataArrayInt.
4721  * 
4722  * \sa reprNotTooLong, reprZip
4723  */
4724 std::string DataArrayInt::repr() const
4725 {
4726   std::ostringstream ret;
4727   reprStream(ret);
4728   return ret.str();
4729 }
4730
4731 std::string DataArrayInt::reprZip() const
4732 {
4733   std::ostringstream ret;
4734   reprZipStream(ret);
4735   return ret.str();
4736 }
4737
4738 /*!
4739  * This method is close to repr method except that when \a this has more than 1000 tuples, all tuples are not
4740  * printed out to avoid to consume too much space in interpretor.
4741  * \sa repr
4742  */
4743 std::string DataArrayInt::reprNotTooLong() const
4744 {
4745   std::ostringstream ret;
4746   reprNotTooLongStream(ret);
4747   return ret.str();
4748 }
4749
4750 void DataArrayInt::writeVTK(std::ostream& ofs, int indent, const std::string& type, const std::string& nameInFile, DataArrayByte *byteArr) const
4751 {
4752   static const char SPACE[4]={' ',' ',' ',' '};
4753   checkAllocated();
4754   std::string idt(indent,' ');
4755   ofs << idt << "<DataArray type=\"" << type << "\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
4756   if(byteArr)
4757     {
4758       ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
4759       if(std::string(type)=="Int32")
4760         {
4761           const char *data(reinterpret_cast<const char *>(begin()));
4762           std::size_t sz(getNbOfElems()*sizeof(int));
4763           byteArr->insertAtTheEnd(data,data+sz);
4764           byteArr->insertAtTheEnd(SPACE,SPACE+4);
4765         }
4766       else if(std::string(type)=="Int8")
4767         {
4768           INTERP_KERNEL::AutoPtr<char> tmp(new char[getNbOfElems()]);
4769           std::copy(begin(),end(),(char *)tmp);
4770           byteArr->insertAtTheEnd((char *)tmp,(char *)tmp+getNbOfElems());
4771           byteArr->insertAtTheEnd(SPACE,SPACE+4);
4772         }
4773       else if(std::string(type)=="UInt8")
4774         {
4775           INTERP_KERNEL::AutoPtr<unsigned char> tmp(new unsigned char[getNbOfElems()]);
4776           std::copy(begin(),end(),(unsigned char *)tmp);
4777           byteArr->insertAtTheEnd((unsigned char *)tmp,(unsigned char *)tmp+getNbOfElems());
4778           byteArr->insertAtTheEnd(SPACE,SPACE+4);
4779         }
4780       else
4781         throw INTERP_KERNEL::Exception("DataArrayInt::writeVTK : Only Int32, Int8 and UInt8 supported !");
4782     }
4783   else
4784     {
4785       ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
4786       std::copy(begin(),end(),std::ostream_iterator<int>(ofs," "));
4787     }
4788   ofs << std::endl << idt << "</DataArray>\n";
4789 }
4790
4791 void DataArrayInt::reprStream(std::ostream& stream) const
4792 {
4793   stream << "Name of int array : \"" << _name << "\"\n";
4794   reprWithoutNameStream(stream);
4795 }
4796
4797 void DataArrayInt::reprZipStream(std::ostream& stream) const
4798 {
4799   stream << "Name of int array : \"" << _name << "\"\n";
4800   reprZipWithoutNameStream(stream);
4801 }
4802
4803 void DataArrayInt::reprNotTooLongStream(std::ostream& stream) const
4804 {
4805   stream << "Name of int array : \"" << _name << "\"\n";
4806   reprNotTooLongWithoutNameStream(stream);
4807 }
4808
4809 void DataArrayInt::reprWithoutNameStream(std::ostream& stream) const
4810 {
4811   DataArray::reprWithoutNameStream(stream);
4812   _mem.repr(getNumberOfComponents(),stream);
4813 }
4814
4815 void DataArrayInt::reprZipWithoutNameStream(std::ostream& stream) const
4816 {
4817   DataArray::reprWithoutNameStream(stream);
4818   _mem.reprZip(getNumberOfComponents(),stream);
4819 }
4820
4821 void DataArrayInt::reprNotTooLongWithoutNameStream(std::ostream& stream) const
4822 {
4823   DataArray::reprWithoutNameStream(stream);
4824   stream.precision(17);
4825   _mem.reprNotTooLong(getNumberOfComponents(),stream);
4826 }
4827
4828 void DataArrayInt::reprCppStream(const std::string& varName, std::ostream& stream) const
4829 {
4830   int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
4831   const int *data=getConstPointer();
4832   stream << "DataArrayInt *" << varName << "=DataArrayInt::New();" << std::endl;
4833   if(nbTuples*nbComp>=1)
4834     {
4835       stream << "const int " << varName << "Data[" << nbTuples*nbComp << "]={";
4836       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<int>(stream,","));
4837       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
4838       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
4839     }
4840   else
4841     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
4842   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
4843 }
4844
4845 /*!
4846  * Method that gives a quick overvien of \a this for python.
4847  */
4848 void DataArrayInt::reprQuickOverview(std::ostream& stream) const
4849 {
4850   static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
4851   stream << "DataArrayInt C++ instance at " << this << ". ";
4852   if(isAllocated())
4853     {
4854       int nbOfCompo=(int)_info_on_compo.size();
4855       if(nbOfCompo>=1)
4856         {
4857           int nbOfTuples=getNumberOfTuples();
4858           stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
4859           reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
4860         }
4861       else
4862         stream << "Number of components : 0.";
4863     }
4864   else
4865     stream << "*** No data allocated ****";
4866 }
4867
4868 void DataArrayInt::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
4869 {
4870   const int *data=begin();
4871   int nbOfTuples=getNumberOfTuples();
4872   int nbOfCompo=(int)_info_on_compo.size();
4873   std::ostringstream oss2; oss2 << "[";
4874   std::string oss2Str(oss2.str());
4875   bool isFinished=true;
4876   for(int i=0;i<nbOfTuples && isFinished;i++)
4877     {
4878       if(nbOfCompo>1)
4879         {
4880           oss2 << "(";
4881           for(int j=0;j<nbOfCompo;j++,data++)
4882             {
4883               oss2 << *data;
4884               if(j!=nbOfCompo-1) oss2 << ", ";
4885             }
4886           oss2 << ")";
4887         }
4888       else
4889         oss2 << *data++;
4890       if(i!=nbOfTuples-1) oss2 << ", ";
4891       std::string oss3Str(oss2.str());
4892       if(oss3Str.length()<maxNbOfByteInRepr)
4893         oss2Str=oss3Str;
4894       else
4895         isFinished=false;
4896     }
4897   stream << oss2Str;
4898   if(!isFinished)
4899     stream << "... ";
4900   stream << "]";
4901 }
4902
4903 /*!
4904  * Modifies in place \a this one-dimensional array so that each value \a v = \a indArrBg[ \a v ],
4905  * i.e. a current value is used as in index to get a new value from \a indArrBg.
4906  *  \param [in] indArrBg - pointer to the first element of array of new values to assign
4907  *         to \a this array.
4908  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
4909  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
4910  *  \throw If \a this->getNumberOfComponents() != 1
4911  *  \throw If any value of \a this can't be used as a valid index for 
4912  *         [\a indArrBg, \a indArrEnd).
4913  *
4914  *  \sa changeValue
4915  */
4916 void DataArrayInt::transformWithIndArr(const int *indArrBg, const int *indArrEnd)
4917 {
4918   checkAllocated();
4919   if(getNumberOfComponents()!=1)
4920     throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
4921   int nbElemsIn((int)std::distance(indArrBg,indArrEnd)),nbOfTuples(getNumberOfTuples()),*pt(getPointer());
4922   for(int i=0;i<nbOfTuples;i++,pt++)
4923     {
4924       if(*pt>=0 && *pt<nbElemsIn)
4925         *pt=indArrBg[*pt];
4926       else
4927         {
4928           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " of this value is " << *pt << ", should be in [0," << nbElemsIn << ") !";
4929           throw INTERP_KERNEL::Exception(oss.str().c_str());
4930         }
4931     }
4932   declareAsNew();
4933 }
4934
4935 /*!
4936  * Computes distribution of values of \a this one-dimensional array between given value
4937  * ranges (casts). This method is typically useful for entity number spliting by types,
4938  * for example. 
4939  *  \warning The values contained in \a arrBg should be sorted ascendently. No
4940  *           check of this is be done. If not, the result is not warranted. 
4941  *  \param [in] arrBg - the array of ascending values defining the value ranges. The i-th
4942  *         value of \a arrBg (\a arrBg[ i ]) gives the lowest value of the i-th range,
4943  *         and the greatest value of the i-th range equals to \a arrBg[ i+1 ] - 1. \a
4944  *         arrBg containing \a n values defines \a n-1 ranges. The last value of \a arrBg
4945  *         should be more than every value in \a this array.
4946  *  \param [in] arrEnd - specifies the end of the array \a arrBg, so that
4947  *              the last value of \a arrBg is \a arrEnd[ -1 ].
4948  *  \param [out] castArr - a new instance of DataArrayInt, of same size as \a this array
4949  *         (same number of tuples and components), the caller is to delete 
4950  *         using decrRef() as it is no more needed.
4951  *         This array contains indices of ranges for every value of \a this array. I.e.
4952  *         the i-th value of \a castArr gives the index of range the i-th value of \a this
4953  *         belongs to. Or, in other words, this parameter contains for each tuple in \a
4954  *         this in which cast it holds.
4955  *  \param [out] rankInsideCast - a new instance of DataArrayInt, of same size as \a this
4956  *         array, the caller is to delete using decrRef() as it is no more needed.
4957  *         This array contains ranks of values of \a this array within ranges
4958  *         they belongs to. I.e. the i-th value of \a rankInsideCast gives the rank of
4959  *         the i-th value of \a this array within the \a castArr[ i ]-th range, to which
4960  *         the i-th value of \a this belongs to. Or, in other words, this param contains 
4961  *         for each tuple its rank inside its cast. The rank is computed as difference
4962  *         between the value and the lowest value of range.
4963  *  \param [out] castsPresent - a new instance of DataArrayInt, containing indices of
4964  *         ranges (casts) to which at least one value of \a this array belongs.
4965  *         Or, in other words, this param contains the casts that \a this contains.
4966  *         The caller is to delete this array using decrRef() as it is no more needed.
4967  *
4968  * \b Example: If \a this contains [6,5,0,3,2,7,8,1,4] and \a arrBg contains [0,4,9] then
4969  *            the output of this method will be : 
4970  * - \a castArr       : [1,1,0,0,0,1,1,0,1]
4971  * - \a rankInsideCast: [2,1,0,3,2,3,4,1,0]
4972  * - \a castsPresent  : [0,1]
4973  *
4974  * I.e. values of \a this array belong to 2 ranges: #0 and #1. Value 6 belongs to the
4975  * range #1 and its rank within this range is 2; etc.
4976  *
4977  *  \throw If \a this->getNumberOfComponents() != 1.
4978  *  \throw If \a arrEnd - arrBg < 2.
4979  *  \throw If any value of \a this is not less than \a arrEnd[-1].
4980  */
4981 void DataArrayInt::splitByValueRange(const int *arrBg, const int *arrEnd,
4982                                      DataArrayInt *& castArr, DataArrayInt *& rankInsideCast, DataArrayInt *& castsPresent) const
4983 {
4984   checkAllocated();
4985   if(getNumberOfComponents()!=1)
4986     throw INTERP_KERNEL::Exception("Call splitByValueRange  method on DataArrayInt with only one component, you can call 'rearrange' method before !");
4987   int nbOfTuples=getNumberOfTuples();
4988   std::size_t nbOfCast=std::distance(arrBg,arrEnd);
4989   if(nbOfCast<2)
4990     throw INTERP_KERNEL::Exception("DataArrayInt::splitByValueRange : The input array giving the cast range values should be of size >=2 !");
4991   nbOfCast--;
4992   const int *work=getConstPointer();
4993   typedef std::reverse_iterator<const int *> rintstart;
4994   rintstart bg(arrEnd);//OK no problem because size of 'arr' is greater or equal 2
4995   rintstart end2(arrBg);
4996   MCAuto<DataArrayInt> ret1=DataArrayInt::New();
4997   MCAuto<DataArrayInt> ret2=DataArrayInt::New();
4998   MCAuto<DataArrayInt> ret3=DataArrayInt::New();
4999   ret1->alloc(nbOfTuples,1);
5000   ret2->alloc(nbOfTuples,1);
5001   int *ret1Ptr=ret1->getPointer();
5002   int *ret2Ptr=ret2->getPointer();
5003   std::set<std::size_t> castsDetected;
5004   for(int i=0;i<nbOfTuples;i++)
5005     {
5006       rintstart res=std::find_if(bg,end2,std::bind2nd(std::less_equal<int>(), work[i]));
5007       std::size_t pos=std::distance(bg,res);
5008       std::size_t pos2=nbOfCast-pos;
5009       if(pos2<nbOfCast)
5010         {
5011           ret1Ptr[i]=(int)pos2;
5012           ret2Ptr[i]=work[i]-arrBg[pos2];
5013           castsDetected.insert(pos2);
5014         }
5015       else
5016         {
5017           std::ostringstream oss; oss << "DataArrayInt::splitByValueRange : At rank #" << i << " the value is " << work[i] << " should be in [0," << *bg << ") !";
5018           throw INTERP_KERNEL::Exception(oss.str().c_str());
5019         }
5020     }
5021   ret3->alloc((int)castsDetected.size(),1);
5022   std::copy(castsDetected.begin(),castsDetected.end(),ret3->getPointer());
5023   castArr=ret1.retn();
5024   rankInsideCast=ret2.retn();
5025   castsPresent=ret3.retn();
5026 }
5027
5028 /*!
5029  * 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 ).
5030  * 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 ).
5031  * This method works only if \a this is allocated and single component. If not an exception will be thrown.
5032  *
5033  * \param [out] strt - the start of the range (included) if true is returned.
5034  * \param [out] sttoopp - the end of the range (not included) if true is returned.
5035  * \param [out] stteepp - the step of the range if true is returned.
5036  * \return the verdict of the check.
5037  *
5038  * \sa DataArray::GetNumberOfItemGivenBES
5039  */
5040 bool DataArrayInt::isRange(int& strt, int& sttoopp, int& stteepp) const
5041 {
5042   checkAllocated();
5043   if(getNumberOfComponents()!=1)
5044     throw INTERP_KERNEL::Exception("DataArrayInt::isRange : this must be single component array !");
5045   int nbTuples(getNumberOfTuples());
5046   if(nbTuples==0)
5047     { strt=0; sttoopp=0; stteepp=1; return true; }
5048   const int *pt(begin());
5049   strt=*pt; 
5050   if(nbTuples==1)
5051     { sttoopp=strt+1; stteepp=1; return true; }
5052   strt=*pt; sttoopp=pt[nbTuples-1];
5053   if(strt==sttoopp)
5054     return false;
5055   if(sttoopp>strt)
5056     {
5057       sttoopp++;
5058       int a(sttoopp-1-strt),tmp(strt);
5059       if(a%(nbTuples-1)!=0)
5060         return false;
5061       stteepp=a/(nbTuples-1);
5062       for(int i=0;i<nbTuples;i++,tmp+=stteepp)
5063         if(pt[i]!=tmp)
5064           return false;
5065       return true;
5066     }
5067   else
5068     {
5069       sttoopp--;
5070       int a(strt-sttoopp-1),tmp(strt);
5071       if(a%(nbTuples-1)!=0)
5072         return false;
5073       stteepp=-(a/(nbTuples-1));
5074       for(int i=0;i<nbTuples;i++,tmp+=stteepp)
5075         if(pt[i]!=tmp)
5076           return false;
5077       return true;
5078     }
5079 }
5080
5081 /*!
5082  * Creates a one-dimensional DataArrayInt (\a res) whose contents are computed from 
5083  * values of \a this (\a a) and the given (\a indArr) arrays as follows:
5084  * \a res[ \a indArr[ \a a[ i ]]] = i. I.e. for each value in place i \a v = \a a[ i ],
5085  * new value in place \a indArr[ \a v ] is i.
5086  *  \param [in] indArrBg - the array holding indices within the result array to assign
5087  *         indices of values of \a this array pointing to values of \a indArrBg.
5088  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
5089  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
5090  *  \return DataArrayInt * - the new instance of DataArrayInt.
5091  *          The caller is to delete this result array using decrRef() as it is no more
5092  *          needed.
5093  *  \throw If \a this->getNumberOfComponents() != 1.
5094  *  \throw If any value of \a this array is not a valid index for \a indArrBg array.
5095  *  \throw If any value of \a indArrBg is not a valid index for \a this array.
5096  */
5097 DataArrayInt *DataArrayInt::transformWithIndArrR(const int *indArrBg, const int *indArrEnd) const
5098 {
5099   checkAllocated();
5100   if(getNumberOfComponents()!=1)
5101     throw INTERP_KERNEL::Exception("Call transformWithIndArrR method on DataArrayInt with only one component, you can call 'rearrange' method before !");
5102   int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
5103   int nbOfTuples=getNumberOfTuples();
5104   const int *pt=getConstPointer();
5105   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5106   ret->alloc(nbOfTuples,1);
5107   ret->fillWithValue(-1);
5108   int *tmp=ret->getPointer();
5109   for(int i=0;i<nbOfTuples;i++,pt++)
5110     {
5111       if(*pt>=0 && *pt<nbElemsIn)
5112         {
5113           int pos=indArrBg[*pt];
5114           if(pos>=0 && pos<nbOfTuples)
5115             tmp[pos]=i;
5116           else
5117             {
5118               std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value of new pos is " << pos << " ( indArrBg[" << *pt << "]) ! Should be in [0," << nbOfTuples << ") !";
5119               throw INTERP_KERNEL::Exception(oss.str().c_str());
5120             }
5121         }
5122       else
5123         {
5124           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn << " !";
5125           throw INTERP_KERNEL::Exception(oss.str().c_str());
5126         }
5127     }
5128   return ret.retn();
5129 }
5130
5131 /*!
5132  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
5133  * from values of \a this array, which is supposed to contain a renumbering map in 
5134  * "Old to New" mode. The result array contains a renumbering map in "New to Old" mode.
5135  * To know how to use the renumbering maps see \ref numbering.
5136  *  \param [in] newNbOfElem - the number of tuples in the result array.
5137  *  \return DataArrayInt * - the new instance of DataArrayInt.
5138  *          The caller is to delete this result array using decrRef() as it is no more
5139  *          needed.
5140  * 
5141  *  \if ENABLE_EXAMPLES
5142  *  \ref cpp_mcdataarrayint_invertarrayo2n2n2o "Here is a C++ example".<br>
5143  *  \ref py_mcdataarrayint_invertarrayo2n2n2o  "Here is a Python example".
5144  *  \endif
5145  */
5146 DataArrayInt *DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const
5147 {
5148   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5149   ret->alloc(newNbOfElem,1);
5150   int nbOfOldNodes=getNumberOfTuples();
5151   const int *old2New=getConstPointer();
5152   int *pt=ret->getPointer();
5153   for(int i=0;i!=nbOfOldNodes;i++)
5154     {
5155       int newp(old2New[i]);
5156       if(newp!=-1)
5157         {
5158           if(newp>=0 && newp<newNbOfElem)
5159             pt[newp]=i;
5160           else
5161             {
5162               std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2O : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
5163               throw INTERP_KERNEL::Exception(oss.str().c_str());
5164             }
5165         }
5166     }
5167   return ret.retn();
5168 }
5169
5170 /*!
5171  * This method is similar to DataArrayInt::invertArrayO2N2N2O except that 
5172  * 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]
5173  */
5174 DataArrayInt *DataArrayInt::invertArrayO2N2N2OBis(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=nbOfOldNodes-1;i>=0;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::invertArrayO2N2N2OBis : 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  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
5200  * from values of \a this array, which is supposed to contain a renumbering map in 
5201  * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
5202  * To know how to use the renumbering maps see \ref numbering.
5203  *  \param [in] newNbOfElem - the number of tuples in the result array.
5204  *  \return DataArrayInt * - the new instance of DataArrayInt.
5205  *          The caller is to delete this result array using decrRef() as it is no more
5206  *          needed.
5207  * 
5208  *  \if ENABLE_EXAMPLES
5209  *  \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
5210  *
5211  *  \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
5212  *  \endif
5213  */
5214 DataArrayInt *DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const
5215 {
5216   checkAllocated();
5217   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5218   ret->alloc(oldNbOfElem,1);
5219   const int *new2Old=getConstPointer();
5220   int *pt=ret->getPointer();
5221   std::fill(pt,pt+oldNbOfElem,-1);
5222   int nbOfNewElems=getNumberOfTuples();
5223   for(int i=0;i<nbOfNewElems;i++)
5224     {
5225       int v(new2Old[i]);
5226       if(v>=0 && v<oldNbOfElem)
5227         pt[v]=i;
5228       else
5229         {
5230           std::ostringstream oss; oss << "DataArrayInt::invertArrayN2O2O2N : in new id #" << i << " old value is " << v << " expected to be in [0," << oldNbOfElem << ") !";
5231           throw INTERP_KERNEL::Exception(oss.str().c_str());
5232         }
5233     }
5234   return ret.retn();
5235 }
5236
5237 /*!
5238  * Equivalent to DataArrayInt::isEqual except that if false the reason of
5239  * mismatch is given.
5240  * 
5241  * \param [in] other the instance to be compared with \a this
5242  * \param [out] reason In case of inequality returns the reason.
5243  * \sa DataArrayInt::isEqual
5244  */
5245 bool DataArrayInt::isEqualIfNotWhy(const DataArrayInt& other, std::string& reason) const
5246 {
5247   if(!areInfoEqualsIfNotWhy(other,reason))
5248     return false;
5249   return _mem.isEqual(other._mem,0,reason);
5250 }
5251
5252 /*!
5253  * Checks if \a this and another DataArrayInt are fully equal. For more info see
5254  * \ref MEDCouplingArrayBasicsCompare.
5255  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
5256  *  \return bool - \a true if the two arrays are equal, \a false else.
5257  */
5258 bool DataArrayInt::isEqual(const DataArrayInt& other) const
5259 {
5260   std::string tmp;
5261   return isEqualIfNotWhy(other,tmp);
5262 }
5263
5264 /*!
5265  * Checks if values of \a this and another DataArrayInt are equal. For more info see
5266  * \ref MEDCouplingArrayBasicsCompare.
5267  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
5268  *  \return bool - \a true if the values of two arrays are equal, \a false else.
5269  */
5270 bool DataArrayInt::isEqualWithoutConsideringStr(const DataArrayInt& other) const
5271 {
5272   std::string tmp;
5273   return _mem.isEqual(other._mem,0,tmp);
5274 }
5275
5276 /*!
5277  * Checks if values of \a this and another DataArrayInt are equal. Comparison is
5278  * performed on sorted value sequences.
5279  * For more info see\ref MEDCouplingArrayBasicsCompare.
5280  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
5281  *  \return bool - \a true if the sorted values of two arrays are equal, \a false else.
5282  */
5283 bool DataArrayInt::isEqualWithoutConsideringStrAndOrder(const DataArrayInt& other) const
5284 {
5285   MCAuto<DataArrayInt> a=deepCopy();
5286   MCAuto<DataArrayInt> b=other.deepCopy();
5287   a->sort();
5288   b->sort();
5289   return a->isEqualWithoutConsideringStr(*b);
5290 }
5291
5292 /*!
5293  * This method compares content of input vector \a v and \a this.
5294  * 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.
5295  * For performance reasons \a this is expected to be sorted ascendingly. If not an exception will be thrown.
5296  *
5297  * \param [in] v - the vector of 'flags' to be compared with \a this.
5298  *
5299  * \throw If \a this is not sorted ascendingly.
5300  * \throw If \a this has not exactly one component.
5301  * \throw If \a this is not allocated.
5302  */
5303 bool DataArrayInt::isFittingWith(const std::vector<bool>& v) const
5304 {
5305   checkAllocated();
5306   if(getNumberOfComponents()!=1)
5307     throw INTERP_KERNEL::Exception("DataArrayInt::isFittingWith : number of components of this should be equal to one !");
5308   const int *w(begin()),*end2(end());
5309   int refVal=-std::numeric_limits<int>::max();
5310   int i=0;
5311   std::vector<bool>::const_iterator it(v.begin());
5312   for(;it!=v.end();it++,i++)
5313     {
5314       if(*it)
5315         {
5316           if(w!=end2)
5317             {
5318               if(*w++==i)
5319                 {
5320                   if(i>refVal)
5321                     refVal=i;
5322                   else
5323                     {
5324                       std::ostringstream oss; oss << "DataArrayInt::isFittingWith : At pos #" << std::distance(begin(),w-1) << " this is not sorted ascendingly !";
5325                       throw INTERP_KERNEL::Exception(oss.str().c_str());
5326                     }
5327                 }
5328               else
5329                 return false;
5330             }
5331           else
5332             return false;
5333         }
5334     }
5335   return w==end2;
5336 }
5337
5338 /*!
5339  * 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
5340  * put True to the corresponding entry in \a vec.
5341  * \a vec is expected to be with the same size than the number of tuples of \a this.
5342  *
5343  *  \sa DataArrayInt::switchOnTupleNotEqualTo.
5344  */
5345 void DataArrayInt::switchOnTupleEqualTo(int val, std::vector<bool>& vec) const
5346 {
5347   checkAllocated();
5348   if(getNumberOfComponents()!=1)
5349     throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleEqualTo : number of components of this should be equal to one !");
5350   int nbOfTuples(getNumberOfTuples());
5351   if(nbOfTuples!=(int)vec.size())
5352     throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleEqualTo : number of tuples of this should be equal to size of input vector of bool !");
5353   const int *pt(begin());
5354   for(int i=0;i<nbOfTuples;i++)
5355     if(pt[i]==val)
5356       vec[i]=true;
5357 }
5358
5359 /*!
5360  * 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
5361  * put True to the corresponding entry in \a vec.
5362  * \a vec is expected to be with the same size than the number of tuples of \a this.
5363  * 
5364  *  \sa DataArrayInt::switchOnTupleEqualTo.
5365  */
5366 void DataArrayInt::switchOnTupleNotEqualTo(int val, std::vector<bool>& vec) const
5367 {
5368   checkAllocated();
5369   if(getNumberOfComponents()!=1)
5370     throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleNotEqualTo : number of components of this should be equal to one !");
5371   int nbOfTuples(getNumberOfTuples());
5372   if(nbOfTuples!=(int)vec.size())
5373     throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleNotEqualTo : number of tuples of this should be equal to size of input vector of bool !");
5374   const int *pt(begin());
5375   for(int i=0;i<nbOfTuples;i++)
5376     if(pt[i]!=val)
5377       vec[i]=true;
5378 }
5379
5380 /*!
5381  * Computes for each tuple the sum of number of components values in the tuple and return it.
5382  * 
5383  * \return DataArrayInt * - the new instance of DataArrayInt containing the
5384  *          same number of tuples as \a this array and one component.
5385  *          The caller is to delete this result array using decrRef() as it is no more
5386  *          needed.
5387  *  \throw If \a this is not allocated.
5388  */
5389 DataArrayInt *DataArrayInt::sumPerTuple() const
5390 {
5391   checkAllocated();
5392   int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
5393   MCAuto<DataArrayInt> ret(DataArrayInt::New());
5394   ret->alloc(nbOfTuple,1);
5395   const int *src(getConstPointer());
5396   int *dest(ret->getPointer());
5397   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
5398     *dest=std::accumulate(src,src+nbOfComp,0);
5399   return ret.retn();
5400 }
5401
5402 /*!
5403  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
5404  * If not an exception is thrown.
5405  *  \param [in] increasing - if \a true, the array values should be increasing.
5406  *  \throw If sequence of values is not strictly monotonic in agreement with \a
5407  *         increasing arg.
5408  *  \throw If \a this->getNumberOfComponents() != 1.
5409  *  \throw If \a this is not allocated.
5410  */
5411 void DataArrayInt::checkMonotonic(bool increasing) const
5412 {
5413   if(!isMonotonic(increasing))
5414     {
5415       if (increasing)
5416         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not INCREASING monotonic !");
5417       else
5418         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not DECREASING monotonic !");
5419     }
5420 }
5421
5422 /*!
5423  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
5424  *  \param [in] increasing - if \a true, array values should be increasing.
5425  *  \return bool - \a true if values change in accordance with \a increasing arg.
5426  *  \throw If \a this->getNumberOfComponents() != 1.
5427  *  \throw If \a this is not allocated.
5428  */
5429 bool DataArrayInt::isMonotonic(bool increasing) const
5430 {
5431   checkAllocated();
5432   if(getNumberOfComponents()!=1)
5433     throw INTERP_KERNEL::Exception("DataArrayInt::isMonotonic : only supported with 'this' array with ONE component !");
5434   int nbOfElements=getNumberOfTuples();
5435   const int *ptr=getConstPointer();
5436   if(nbOfElements==0)
5437     return true;
5438   int ref=ptr[0];
5439   if(increasing)
5440     {
5441       for(int i=1;i<nbOfElements;i++)
5442         {
5443           if(ptr[i]>=ref)
5444             ref=ptr[i];
5445           else
5446             return false;
5447         }
5448     }
5449   else
5450     {
5451       for(int i=1;i<nbOfElements;i++)
5452         {
5453           if(ptr[i]<=ref)
5454             ref=ptr[i];
5455           else
5456             return false;
5457         }
5458     }
5459   return true;
5460 }
5461
5462 /*!
5463  * This method check that array consistently INCREASING or DECREASING in value.
5464  */
5465 bool DataArrayInt::isStrictlyMonotonic(bool increasing) const
5466 {
5467   checkAllocated();
5468   if(getNumberOfComponents()!=1)
5469     throw INTERP_KERNEL::Exception("DataArrayInt::isStrictlyMonotonic : only supported with 'this' array with ONE component !");
5470   int nbOfElements=getNumberOfTuples();
5471   const int *ptr=getConstPointer();
5472   if(nbOfElements==0)
5473     return true;
5474   int ref=ptr[0];
5475   if(increasing)
5476     {
5477       for(int i=1;i<nbOfElements;i++)
5478         {
5479           if(ptr[i]>ref)
5480             ref=ptr[i];
5481           else
5482             return false;
5483         }
5484     }
5485   else
5486     {
5487       for(int i=1;i<nbOfElements;i++)
5488         {
5489           if(ptr[i]<ref)
5490             ref=ptr[i];
5491           else
5492             return false;
5493         }
5494     }
5495   return true;
5496 }
5497
5498 /*!
5499  * This method check that array consistently INCREASING or DECREASING in value.
5500  */
5501 void DataArrayInt::checkStrictlyMonotonic(bool increasing) const
5502 {
5503   if(!isStrictlyMonotonic(increasing))
5504     {
5505       if (increasing)
5506         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly INCREASING monotonic !");
5507       else
5508         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly DECREASING monotonic !");
5509     }
5510 }
5511
5512 /*!
5513  * Creates a new one-dimensional DataArrayInt of the same size as \a this and a given
5514  * one-dimensional arrays that must be of the same length. The result array describes
5515  * correspondence between \a this and \a other arrays, so that 
5516  * <em> other.getIJ(i,0) == this->getIJ(ret->getIJ(i),0)</em>. If such a permutation is
5517  * not possible because some element in \a other is not in \a this, an exception is thrown.
5518  *  \param [in] other - an array to compute permutation to.
5519  *  \return DataArrayInt * - a new instance of DataArrayInt, which is a permutation array
5520  * from \a this to \a other. The caller is to delete this array using decrRef() as it is
5521  * no more needed.
5522  *  \throw If \a this->getNumberOfComponents() != 1.
5523  *  \throw If \a other->getNumberOfComponents() != 1.
5524  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples().
5525  *  \throw If \a other includes a value which is not in \a this array.
5526  * 
5527  *  \if ENABLE_EXAMPLES
5528  *  \ref cpp_mcdataarrayint_buildpermutationarr "Here is a C++ example".
5529  *
5530  *  \ref py_mcdataarrayint_buildpermutationarr "Here is a Python example".
5531  *  \endif
5532  */
5533 DataArrayInt *DataArrayInt::buildPermutationArr(const DataArrayInt& other) const
5534 {
5535   checkAllocated();
5536   if(getNumberOfComponents()!=1 || other.getNumberOfComponents()!=1)
5537     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' have to have exactly ONE component !");
5538   int nbTuple=getNumberOfTuples();
5539   other.checkAllocated();
5540   if(nbTuple!=other.getNumberOfTuples())
5541     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' must have the same number of tuple !");
5542   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5543   ret->alloc(nbTuple,1);
5544   ret->fillWithValue(-1);
5545   const int *pt=getConstPointer();
5546   std::map<int,int> mm;
5547   for(int i=0;i<nbTuple;i++)
5548     mm[pt[i]]=i;
5549   pt=other.getConstPointer();
5550   int *retToFill=ret->getPointer();
5551   for(int i=0;i<nbTuple;i++)
5552     {
5553       std::map<int,int>::const_iterator it=mm.find(pt[i]);
5554       if(it==mm.end())
5555         {
5556           std::ostringstream oss; oss << "DataArrayInt::buildPermutationArr : Arrays mismatch : element (" << pt[i] << ") in 'other' not findable in 'this' !";
5557           throw INTERP_KERNEL::Exception(oss.str().c_str());
5558         }
5559       retToFill[i]=(*it).second;
5560     }
5561   return ret.retn();
5562 }
5563
5564 /*!
5565  * Elements of \a partOfThis are expected to be included in \a this.
5566  * The returned array \a ret is so that this[ret]==partOfThis
5567  *
5568  * 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]
5569  * the return array will contain [3,2,5,7].
5570  *
5571  * \a this is expected to be a 1 compo allocated array.
5572  * \param [in] partOfThis - A 1 compo allocated array
5573  * \return - A newly allocated array to be dealed by caller having the same number of tuples than \a partOfThis.
5574  * \throw if two same element is present twice in \a this
5575  * \throw if an element in \a partOfThis is \b NOT in \a this.
5576  */
5577 DataArrayInt *DataArrayInt::indicesOfSubPart(const DataArrayInt& partOfThis) const
5578 {
5579   if(getNumberOfComponents()!=1 || partOfThis.getNumberOfComponents()!=1)
5580     throw INTERP_KERNEL::Exception("DataArrayInt::indicesOfSubPart : this and input array must be one component array !");
5581   checkAllocated(); partOfThis.checkAllocated();
5582   int thisNbTuples(getNumberOfTuples()),nbTuples(partOfThis.getNumberOfTuples());
5583   const int *thisPt(begin()),*pt(partOfThis.begin());
5584   MCAuto<DataArrayInt> ret(DataArrayInt::New());
5585   ret->alloc(nbTuples,1);
5586   int *retPt(ret->getPointer());
5587   std::map<int,int> m;
5588   for(int i=0;i<thisNbTuples;i++,thisPt++)
5589     m[*thisPt]=i;
5590   if(m.size()!=thisNbTuples)
5591     throw INTERP_KERNEL::Exception("DataArrayInt::indicesOfSubPart : some elements appears more than once !");
5592   for(int i=0;i<nbTuples;i++,retPt++,pt++)
5593     {
5594       std::map<int,int>::const_iterator it(m.find(*pt));
5595       if(it!=m.end())
5596         *retPt=(*it).second;
5597       else
5598         {
5599           std::ostringstream oss; oss << "DataArrayInt::indicesOfSubPart : At pos #" << i << " of input array value is " << *pt << " not in this !";
5600           throw INTERP_KERNEL::Exception(oss.str());
5601         }
5602     }
5603   return ret.retn();
5604 }
5605
5606 void DataArrayInt::aggregate(const DataArrayInt *other)
5607 {
5608   if(!other)
5609     throw INTERP_KERNEL::Exception("DataArrayInt::aggregate : null pointer !");
5610   if(getNumberOfComponents()!=other->getNumberOfComponents())
5611     throw INTERP_KERNEL::Exception("DataArrayInt::aggregate : mismatch number of components !");
5612   _mem.insertAtTheEnd(other->begin(),other->end());
5613 }
5614
5615 /*!
5616  * Returns a new DataArrayInt holding the same values as \a this array but differently
5617  * arranged in memory. If \a this array holds 2 components of 3 values:
5618  * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
5619  * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
5620  *  \warning Do not confuse this method with transpose()!
5621  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
5622  *          is to delete using decrRef() as it is no more needed.
5623  *  \throw If \a this is not allocated.
5624  */
5625 DataArrayInt *DataArrayInt::fromNoInterlace() const
5626 {
5627   checkAllocated();
5628   if(_mem.isNull())
5629     throw INTERP_KERNEL::Exception("DataArrayInt::fromNoInterlace : Not defined array !");
5630   int *tab=_mem.fromNoInterlace(getNumberOfComponents());
5631   DataArrayInt *ret=DataArrayInt::New();
5632   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
5633   return ret;
5634 }
5635
5636 /*!
5637  * Returns a new DataArrayInt holding the same values as \a this array but differently
5638  * arranged in memory. If \a this array holds 2 components of 3 values:
5639  * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
5640  * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
5641  *  \warning Do not confuse this method with transpose()!
5642  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
5643  *          is to delete using decrRef() as it is no more needed.
5644  *  \throw If \a this is not allocated.
5645  */
5646 DataArrayInt *DataArrayInt::toNoInterlace() const
5647 {
5648   checkAllocated();
5649   if(_mem.isNull())
5650     throw INTERP_KERNEL::Exception("DataArrayInt::toNoInterlace : Not defined array !");
5651   int *tab=_mem.toNoInterlace(getNumberOfComponents());
5652   DataArrayInt *ret=DataArrayInt::New();
5653   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
5654   return ret;
5655 }
5656
5657 /*!
5658  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode.
5659  * This map, if applied to \a this array, would make it sorted. For example, if
5660  * \a this array contents are [9,10,0,6,4,11,3,7] then the contents of the result array
5661  * are [5,6,0,3,2,7,1,4]; if this result array (\a res) is used as an argument in call
5662  * \a this->renumber(\a res) then the returned array contains [0,3,4,6,7,9,10,11].
5663  * This method is useful for renumbering (in MED file for example). For more info
5664  * on renumbering see \ref numbering.
5665  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5666  *          array using decrRef() as it is no more needed.
5667  *  \throw If \a this is not allocated.
5668  *  \throw If \a this->getNumberOfComponents() != 1.
5669  *  \throw If there are equal values in \a this array.
5670  */
5671 DataArrayInt *DataArrayInt::checkAndPreparePermutation() const
5672 {
5673   checkAllocated();
5674   if(getNumberOfComponents()!=1)
5675     throw INTERP_KERNEL::Exception("DataArrayInt::checkAndPreparePermutation : number of components must == 1 !");
5676   int nbTuples=getNumberOfTuples();
5677   const int *pt=getConstPointer();
5678   int *pt2=CheckAndPreparePermutation(pt,pt+nbTuples);
5679   DataArrayInt *ret=DataArrayInt::New();
5680   ret->useArray(pt2,true,C_DEALLOC,nbTuples,1);
5681   return ret;
5682 }
5683
5684 /*!
5685  * 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
5686  * input array \a ids2.
5687  * \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.
5688  * 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
5689  * inversely.
5690  * In case of success (no throw) : \c ids1->renumber(ret)->isEqual(ids2) where \a ret is the return of this method.
5691  *
5692  * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5693  *          array using decrRef() as it is no more needed.
5694  * \throw If either ids1 or ids2 is null not allocated or not with one components.
5695  * 
5696  */
5697 DataArrayInt *DataArrayInt::FindPermutationFromFirstToSecond(const DataArrayInt *ids1, const DataArrayInt *ids2)
5698 {
5699   if(!ids1 || !ids2)
5700     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be not null !");
5701   if(!ids1->isAllocated() || !ids2->isAllocated())
5702     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be allocated !");
5703   if(ids1->getNumberOfComponents()!=1 || ids2->getNumberOfComponents()!=1)
5704     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays have exactly one component !");
5705   if(ids1->getNumberOfTuples()!=ids2->getNumberOfTuples())
5706     {
5707       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 !";
5708       throw INTERP_KERNEL::Exception(oss.str().c_str());
5709     }
5710   MCAuto<DataArrayInt> p1(ids1->deepCopy());
5711   MCAuto<DataArrayInt> p2(ids2->deepCopy());
5712   p1->sort(true); p2->sort(true);
5713   if(!p1->isEqualWithoutConsideringStr(*p2))
5714     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two arrays are not lying on same ids ! Impossible to find a permutation between the 2 arrays !");
5715   p1=ids1->checkAndPreparePermutation();
5716   p2=ids2->checkAndPreparePermutation();
5717   p2=p2->invertArrayO2N2N2O(p2->getNumberOfTuples());
5718   p2=p2->selectByTupleIdSafe(p1->begin(),p1->end());
5719   return p2.retn();
5720 }
5721
5722 /*!
5723  * Returns two arrays describing a surjective mapping from \a this set of values (\a A)
5724  * onto a set of values of size \a targetNb (\a B). The surjective function is 
5725  * \a B[ \a A[ i ]] = i. That is to say that for each \a id in [0,\a targetNb), where \a
5726  * targetNb < \a this->getNumberOfTuples(), there exists at least one tupleId (\a tid) so
5727  * that <em> this->getIJ( tid, 0 ) == id</em>. <br>
5728  * The first of out arrays returns indices of elements of \a this array, grouped by their
5729  * place in the set \a B. The second out array is the index of the first one; it shows how
5730  * many elements of \a A are mapped into each element of \a B. <br>
5731  * For more info on
5732  * mapping and its usage in renumbering see \ref numbering. <br>
5733  * \b Example:
5734  * - \a this: [0,3,2,3,2,2,1,2]
5735  * - \a targetNb: 4
5736  * - \a arr:  [0,  6,  2,4,5,7,  1,3]
5737  * - \a arrI: [0,1,2,6,8]
5738  *
5739  * This result means: <br>
5740  * the element of \a B 0 encounters within \a A once (\a arrI[ 0+1 ] - \a arrI[ 0 ]) and
5741  * its index within \a A is 0 ( \a arr[ 0:1 ] == \a arr[ \a arrI[ 0 ] : \a arrI[ 0+1 ]]);<br>
5742  * the element of \a B 2 encounters within \a A 4 times (\a arrI[ 2+1 ] - \a arrI[ 2 ]) and
5743  * its indices within \a A are [2,4,5,7] ( \a arr[ 2:6 ] == \a arr[ \a arrI[ 2 ] : 
5744  * \a arrI[ 2+1 ]]); <br> etc.
5745  *  \param [in] targetNb - the size of the set \a B. \a targetNb must be equal or more
5746  *         than the maximal value of \a A.
5747  *  \param [out] arr - a new instance of DataArrayInt returning indices of
5748  *         elements of \a this, grouped by their place in the set \a B. The caller is to delete
5749  *         this array using decrRef() as it is no more needed.
5750  *  \param [out] arrI - a new instance of DataArrayInt returning size of groups of equal
5751  *         elements of \a this. The caller is to delete this array using decrRef() as it
5752  *         is no more needed.
5753  *  \throw If \a this is not allocated.
5754  *  \throw If \a this->getNumberOfComponents() != 1.
5755  *  \throw If any value in \a this is more or equal to \a targetNb.
5756  */
5757 void DataArrayInt::changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, DataArrayInt *&arrI) const
5758 {
5759   checkAllocated();
5760   if(getNumberOfComponents()!=1)
5761     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : number of components must == 1 !");
5762   int nbOfTuples=getNumberOfTuples();
5763   MCAuto<DataArrayInt> ret(DataArrayInt::New());
5764   MCAuto<DataArrayInt> retI(DataArrayInt::New());
5765   retI->alloc(targetNb+1,1);
5766   const int *input=getConstPointer();
5767   std::vector< std::vector<int> > tmp(targetNb);
5768   for(int i=0;i<nbOfTuples;i++)
5769     {
5770       int tmp2=input[i];
5771       if(tmp2>=0 && tmp2<targetNb)
5772         tmp[tmp2].push_back(i);
5773       else
5774         {
5775           std::ostringstream oss; oss << "DataArrayInt::changeSurjectiveFormat : At pos " << i << " presence of element " << tmp2 << " ! should be in [0," << targetNb << ") !";
5776           throw INTERP_KERNEL::Exception(oss.str().c_str());
5777         }
5778     }
5779   int *retIPtr=retI->getPointer();
5780   *retIPtr=0;
5781   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++,retIPtr++)
5782     retIPtr[1]=retIPtr[0]+(int)((*it1).size());
5783   if(nbOfTuples!=retI->getIJ(targetNb,0))
5784     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : big problem should never happen !");
5785   ret->alloc(nbOfTuples,1);
5786   int *retPtr=ret->getPointer();
5787   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++)
5788     retPtr=std::copy((*it1).begin(),(*it1).end(),retPtr);
5789   arr=ret.retn();
5790   arrI=retI.retn();
5791 }
5792
5793
5794 /*!
5795  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode computed
5796  * from a zip representation of a surjective format (returned e.g. by
5797  * \ref MEDCoupling::DataArrayDouble::findCommonTuples() "DataArrayDouble::findCommonTuples()"
5798  * for example). The result array minimizes the permutation. <br>
5799  * For more info on renumbering see \ref numbering. <br>
5800  * \b Example: <br>
5801  * - \a nbOfOldTuples: 10 
5802  * - \a arr          : [0,3, 5,7,9]
5803  * - \a arrIBg       : [0,2,5]
5804  * - \a newNbOfTuples: 7
5805  * - result array    : [0,1,2,0,3,4,5,4,6,4]
5806  *
5807  *  \param [in] nbOfOldTuples - number of tuples in the initial array \a arr.
5808  *  \param [in] arr - the array of tuple indices grouped by \a arrIBg array.
5809  *  \param [in] arrIBg - the array dividing all indices stored in \a arr into groups of
5810  *         (indices of) equal values. Its every element (except the last one) points to
5811  *         the first element of a group of equal values.
5812  *  \param [in] arrIEnd - specifies the end of \a arrIBg, so that the last element of \a
5813  *          arrIBg is \a arrIEnd[ -1 ].
5814  *  \param [out] newNbOfTuples - number of tuples after surjection application.
5815  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5816  *          array using decrRef() as it is no more needed.
5817  *  \throw If any value of \a arr breaks condition ( 0 <= \a arr[ i ] < \a nbOfOldTuples ).
5818  */
5819 DataArrayInt *DataArrayInt::ConvertIndexArrayToO2N(int nbOfOldTuples, const int *arr, const int *arrIBg, const int *arrIEnd, int &newNbOfTuples)
5820 {
5821   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5822   ret->alloc(nbOfOldTuples,1);
5823   int *pt=ret->getPointer();
5824   std::fill(pt,pt+nbOfOldTuples,-1);
5825   int nbOfGrps=((int)std::distance(arrIBg,arrIEnd))-1;
5826   const int *cIPtr=arrIBg;
5827   for(int i=0;i<nbOfGrps;i++)
5828     pt[arr[cIPtr[i]]]=-(i+2);
5829   int newNb=0;
5830   for(int iNode=0;iNode<nbOfOldTuples;iNode++)
5831     {
5832       if(pt[iNode]<0)
5833         {
5834           if(pt[iNode]==-1)
5835             pt[iNode]=newNb++;
5836           else
5837             {
5838               int grpId=-(pt[iNode]+2);
5839               for(int j=cIPtr[grpId];j<cIPtr[grpId+1];j++)
5840                 {
5841                   if(arr[j]>=0 && arr[j]<nbOfOldTuples)
5842                     pt[arr[j]]=newNb;
5843                   else
5844                     {
5845                       std::ostringstream oss; oss << "DataArrayInt::ConvertIndexArrayToO2N : With element #" << j << " value is " << arr[j] << " should be in [0," << nbOfOldTuples << ") !";
5846                       throw INTERP_KERNEL::Exception(oss.str().c_str());
5847                     }
5848                 }
5849               newNb++;
5850             }
5851         }
5852     }
5853   newNbOfTuples=newNb;
5854   return ret.retn();
5855 }
5856
5857 /*!
5858  * Returns a new DataArrayInt containing a renumbering map in "New to Old" mode,
5859  * which if applied to \a this array would make it sorted ascendingly.
5860  * For more info on renumbering see \ref numbering. <br>
5861  * \b Example: <br>
5862  * - \a this: [2,0,1,1,0,1,2,0,1,1,0,0]
5863  * - result: [10,0,5,6,1,7,11,2,8,9,3,4]
5864  * - after applying result to \a this: [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2] 
5865  *
5866  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5867  *          array using decrRef() as it is no more needed.
5868  *  \throw If \a this is not allocated.
5869  *  \throw If \a this->getNumberOfComponents() != 1.
5870  */
5871 DataArrayInt *DataArrayInt::buildPermArrPerLevel() const
5872 {
5873   checkAllocated();
5874   if(getNumberOfComponents()!=1)
5875     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermArrPerLevel : number of components must == 1 !");
5876   int nbOfTuples=getNumberOfTuples();
5877   const int *pt=getConstPointer();
5878   std::map<int,int> m;
5879   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5880   ret->alloc(nbOfTuples,1);
5881   int *opt=ret->getPointer();
5882   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
5883     {
5884       int val=*pt;
5885       std::map<int,int>::iterator it=m.find(val);
5886       if(it!=m.end())
5887         {
5888           *opt=(*it).second;
5889           (*it).second++;
5890         }
5891       else
5892         {
5893           *opt=0;
5894           m.insert(std::pair<int,int>(val,1));
5895         }
5896     }
5897   int sum=0;
5898   for(std::map<int,int>::iterator it=m.begin();it!=m.end();it++)
5899     {
5900       int vt=(*it).second;
5901       (*it).second=sum;
5902       sum+=vt;
5903     }
5904   pt=getConstPointer();
5905   opt=ret->getPointer();
5906   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
5907     *opt+=m[*pt];
5908   //
5909   return ret.retn();
5910 }
5911
5912 /*!
5913  * Checks if \a this array has the given size, and if its contents is equal to an array filled with
5914  * iota(). This method is particularly useful for DataArrayInt instances that represent
5915  * a renumbering array, to check if there is a real need in renumbering.
5916  * This method checks than \a this can be considered as an identity mapping
5917  * of a set having \a sizeExpected elements into itself.
5918  *
5919  *  \param [in] sizeExpected - The number of elements expected.
5920  *  \return bool - \a true if \a this array contents == \a range( \a this->getNumberOfTuples())
5921  *  \throw If \a this is not allocated.
5922  *  \throw If \a this->getNumberOfComponents() != 1.
5923  */
5924 bool DataArrayInt::isIota(int sizeExpected) const
5925 {
5926   checkAllocated();
5927   if(getNumberOfComponents()!=1)
5928     return false;
5929   int nbOfTuples(getNumberOfTuples());
5930   if(nbOfTuples!=sizeExpected)
5931     return false;
5932   const int *pt=getConstPointer();
5933   for(int i=0;i<nbOfTuples;i++,pt++)
5934     if(*pt!=i)
5935       return false;
5936   return true;
5937 }
5938
5939 /*!
5940  * Checks if all values in \a this array are equal to \a val.
5941  *  \param [in] val - value to check equality of array values to.
5942  *  \return bool - \a true if all values are \a val.
5943  *  \throw If \a this is not allocated.
5944  *  \throw If \a this->getNumberOfComponents() != 1
5945  */
5946 bool DataArrayInt::isUniform(int val) const
5947 {
5948   checkAllocated();
5949   if(getNumberOfComponents()!=1)
5950     throw INTERP_KERNEL::Exception("DataArrayInt::isUniform : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
5951   int nbOfTuples=getNumberOfTuples();
5952   const int *w=getConstPointer();
5953   const int *end2=w+nbOfTuples;
5954   for(;w!=end2;w++)
5955     if(*w!=val)
5956       return false;
5957   return true;
5958 }
5959
5960 /*!
5961  * Checks if all values in \a this array are unique.
5962  *  \return bool - \a true if condition above is true
5963  *  \throw If \a this is not allocated.
5964  *  \throw If \a this->getNumberOfComponents() != 1
5965  */
5966 bool DataArrayInt::hasUniqueValues() const
5967 {
5968   checkAllocated();
5969   if(getNumberOfComponents()!=1)
5970     throw INTERP_KERNEL::Exception("DataArrayInt::hasOnlyUniqueValues: must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
5971   int nbOfTuples(getNumberOfTuples());
5972   std::set<int> s(begin(),end());  // in C++11, should use unordered_set (O(1) complexity)
5973   if (s.size() != nbOfTuples)
5974     return false;
5975   return true;
5976 }
5977
5978 /*!
5979  * Appends components of another array to components of \a this one, tuple by tuple.
5980  * So that the number of tuples of \a this array remains the same and the number of 
5981  * components increases.
5982  *  \param [in] other - the DataArrayInt to append to \a this one.
5983  *  \throw If \a this is not allocated.
5984  *  \throw If \a this and \a other arrays have different number of tuples.
5985  *
5986  *  \if ENABLE_EXAMPLES
5987  *  \ref cpp_mcdataarrayint_meldwith "Here is a C++ example".
5988  *
5989  *  \ref py_mcdataarrayint_meldwith "Here is a Python example".
5990  *  \endif
5991  */
5992 void DataArrayInt::meldWith(const DataArrayInt *other)
5993 {
5994   if(!other)
5995     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : DataArrayInt pointer in input is NULL !");
5996   checkAllocated();
5997   other->checkAllocated();
5998   int nbOfTuples=getNumberOfTuples();
5999   if(nbOfTuples!=other->getNumberOfTuples())
6000     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : mismatch of number of tuples !");
6001   int nbOfComp1=getNumberOfComponents();
6002   int nbOfComp2=other->getNumberOfComponents();
6003   int *newArr=(int *)malloc(nbOfTuples*(nbOfComp1+nbOfComp2)*sizeof(int));
6004   int *w=newArr;
6005   const int *inp1=getConstPointer();
6006   const int *inp2=other->getConstPointer();
6007   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
6008     {
6009       w=std::copy(inp1,inp1+nbOfComp1,w);
6010       w=std::copy(inp2,inp2+nbOfComp2,w);
6011     }
6012   useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
6013   std::vector<int> compIds(nbOfComp2);
6014   for(int i=0;i<nbOfComp2;i++)
6015     compIds[i]=nbOfComp1+i;
6016   copyPartOfStringInfoFrom2(compIds,*other);
6017 }
6018
6019 /*!
6020  * Copy all components in a specified order from another DataArrayInt.
6021  * The specified components become the first ones in \a this array.
6022  * Both numerical and textual data is copied. The number of tuples in \a this and
6023  * the other array can be different.
6024  *  \param [in] a - the array to copy data from.
6025  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
6026  *              to be copied.
6027  *  \throw If \a a is NULL.
6028  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
6029  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
6030  *
6031  *  \if ENABLE_EXAMPLES
6032  *  \ref py_mcdataarrayint_setselectedcomponents "Here is a Python example".
6033  *  \endif
6034  */
6035 void DataArrayInt::setSelectedComponents(const DataArrayInt *a, const std::vector<int>& compoIds)
6036 {
6037   if(!a)
6038     throw INTERP_KERNEL::Exception("DataArrayInt::setSelectedComponents : input DataArrayInt is NULL !");
6039   checkAllocated();
6040   a->checkAllocated();
6041   copyPartOfStringInfoFrom2(compoIds,*a);
6042   std::size_t partOfCompoSz=compoIds.size();
6043   int nbOfCompo=getNumberOfComponents();
6044   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
6045   const int *ac=a->getConstPointer();
6046   int *nc=getPointer();
6047   for(int i=0;i<nbOfTuples;i++)
6048     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
6049       nc[nbOfCompo*i+compoIds[j]]=*ac;
6050 }
6051
6052 /*!
6053  * Assign pointer to one array to a pointer to another appay. Reference counter of
6054  * \a arrayToSet is incremented / decremented.
6055  *  \param [in] newArray - the pointer to array to assign to \a arrayToSet.
6056  *  \param [in,out] arrayToSet - the pointer to array to assign to.
6057  */
6058 void DataArrayInt::SetArrayIn(DataArrayInt *newArray, DataArrayInt* &arrayToSet)
6059 {
6060   if(newArray!=arrayToSet)
6061     {
6062       if(arrayToSet)
6063         arrayToSet->decrRef();
6064       arrayToSet=newArray;
6065       if(arrayToSet)
6066         arrayToSet->incrRef();
6067     }
6068 }
6069
6070 DataArrayIntIterator *DataArrayInt::iterator()
6071 {
6072   return new DataArrayIntIterator(this);
6073 }
6074
6075 /*!
6076  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to a
6077  * given one. The ids are sorted in the ascending order.
6078  *  \param [in] val - the value to find within \a this.
6079  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6080  *          array using decrRef() as it is no more needed.
6081  *  \throw If \a this is not allocated.
6082  *  \throw If \a this->getNumberOfComponents() != 1.
6083  *  \sa DataArrayInt::findIdsEqualTuple
6084  */
6085 DataArrayInt *DataArrayInt::findIdsEqual(int val) const
6086 {
6087   checkAllocated();
6088   if(getNumberOfComponents()!=1)
6089     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqual : the array must have only one component, you can call 'rearrange' method before !");
6090   const int *cptr(getConstPointer());
6091   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6092   int nbOfTuples=getNumberOfTuples();
6093   for(int i=0;i<nbOfTuples;i++,cptr++)
6094     if(*cptr==val)
6095       ret->pushBackSilent(i);
6096   return ret.retn();
6097 }
6098
6099 /*!
6100  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value \b not
6101  * equal to a given one. 
6102  *  \param [in] val - the value to ignore within \a this.
6103  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6104  *          array using decrRef() as it is no more needed.
6105  *  \throw If \a this is not allocated.
6106  *  \throw If \a this->getNumberOfComponents() != 1.
6107  */
6108 DataArrayInt *DataArrayInt::findIdsNotEqual(int val) const
6109 {
6110   checkAllocated();
6111   if(getNumberOfComponents()!=1)
6112     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotEqual : the array must have only one component, you can call 'rearrange' method before !");
6113   const int *cptr(getConstPointer());
6114   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6115   int nbOfTuples=getNumberOfTuples();
6116   for(int i=0;i<nbOfTuples;i++,cptr++)
6117     if(*cptr!=val)
6118       ret->pushBackSilent(i);
6119   return ret.retn();
6120 }
6121
6122 /*!
6123  * Creates a new DataArrayInt containing IDs (indices) of tuples holding tuple equal to those defined by [ \a tupleBg , \a tupleEnd )
6124  * This method is an extension of  DataArrayInt::findIdsEqual method.
6125  *
6126  *  \param [in] tupleBg - the begin (included) of the input tuple to find within \a this.
6127  *  \param [in] tupleEnd - the end (excluded) of the input tuple to find within \a this.
6128  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6129  *          array using decrRef() as it is no more needed.
6130  *  \throw If \a this is not allocated.
6131  *  \throw If \a this->getNumberOfComponents() != std::distance(tupleBg,tupleEnd).
6132  * \throw If \a this->getNumberOfComponents() is equal to 0.
6133  * \sa DataArrayInt::findIdsEqual
6134  */
6135 DataArrayInt *DataArrayInt::findIdsEqualTuple(const int *tupleBg, const int *tupleEnd) const
6136 {
6137   std::size_t nbOfCompoExp(std::distance(tupleBg,tupleEnd));
6138   checkAllocated();
6139   if(getNumberOfComponents()!=(int)nbOfCompoExp)
6140     {
6141       std::ostringstream oss; oss << "DataArrayInt::findIdsEqualTuple : mismatch of number of components. Input tuple has " << nbOfCompoExp << " whereas this array has " << getNumberOfComponents() << " components !";
6142       throw INTERP_KERNEL::Exception(oss.str().c_str());
6143     }
6144   if(nbOfCompoExp==0)
6145     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqualTuple : number of components should be > 0 !");
6146   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6147   const int *bg(begin()),*end2(end()),*work(begin());
6148   while(work!=end2)
6149     {
6150       work=std::search(work,end2,tupleBg,tupleEnd);
6151       if(work!=end2)
6152         {
6153           std::size_t pos(std::distance(bg,work));
6154           if(pos%nbOfCompoExp==0)
6155             ret->pushBackSilent(pos/nbOfCompoExp);
6156           work++;
6157         }
6158     }
6159   return ret.retn();
6160 }
6161
6162 /*!
6163  * Assigns \a newValue to all elements holding \a oldValue within \a this
6164  * one-dimensional array.
6165  *  \param [in] oldValue - the value to replace.
6166  *  \param [in] newValue - the value to assign.
6167  *  \return int - number of replacements performed.
6168  *  \throw If \a this is not allocated.
6169  *  \throw If \a this->getNumberOfComponents() != 1.
6170  */
6171 int DataArrayInt::changeValue(int oldValue, int newValue)
6172 {
6173   checkAllocated();
6174   if(getNumberOfComponents()!=1)
6175     throw INTERP_KERNEL::Exception("DataArrayInt::changeValue : the array must have only one component, you can call 'rearrange' method before !");
6176   if(oldValue==newValue)
6177     return 0;
6178   int *start(getPointer()),*end2(start+getNbOfElems());
6179   int ret(0);
6180   for(int *val=start;val!=end2;val++)
6181     {
6182       if(*val==oldValue)
6183         {
6184           *val=newValue;
6185           ret++;
6186         }
6187     }
6188   if(ret>0)
6189     declareAsNew();
6190   return ret;
6191 }
6192
6193 /*!
6194  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to
6195  * one of given values.
6196  *  \param [in] valsBg - an array of values to find within \a this array.
6197  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
6198  *              the last value of \a valsBg is \a valsEnd[ -1 ].
6199  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6200  *          array using decrRef() as it is no more needed.
6201  *  \throw If \a this->getNumberOfComponents() != 1.
6202  */
6203 DataArrayInt *DataArrayInt::findIdsEqualList(const int *valsBg, const int *valsEnd) const
6204 {
6205   if(getNumberOfComponents()!=1)
6206     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqualList : the array must have only one component, you can call 'rearrange' method before !");
6207   std::set<int> vals2(valsBg,valsEnd);
6208   const int *cptr(getConstPointer());
6209   std::vector<int> res;
6210   int nbOfTuples(getNumberOfTuples());
6211   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6212   for(int i=0;i<nbOfTuples;i++,cptr++)
6213     if(vals2.find(*cptr)!=vals2.end())
6214       ret->pushBackSilent(i);
6215   return ret.retn();
6216 }
6217
6218 /*!
6219  * Creates a new DataArrayInt containing IDs (indices) of tuples holding values \b not
6220  * equal to any of given values.
6221  *  \param [in] valsBg - an array of values to ignore within \a this array.
6222  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
6223  *              the last value of \a valsBg is \a valsEnd[ -1 ].
6224  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6225  *          array using decrRef() as it is no more needed.
6226  *  \throw If \a this->getNumberOfComponents() != 1.
6227  */
6228 DataArrayInt *DataArrayInt::findIdsNotEqualList(const int *valsBg, const int *valsEnd) const
6229 {
6230   if(getNumberOfComponents()!=1)
6231     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotEqualList : the array must have only one component, you can call 'rearrange' method before !");
6232   std::set<int> vals2(valsBg,valsEnd);
6233   const int *cptr=getConstPointer();
6234   std::vector<int> res;
6235   int nbOfTuples=getNumberOfTuples();
6236   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6237   for(int i=0;i<nbOfTuples;i++,cptr++)
6238     if(vals2.find(*cptr)==vals2.end())
6239       ret->pushBackSilent(i);
6240   return ret.retn();
6241 }
6242
6243 /*!
6244  * This method is an extension of DataArrayInt::findIdFirstEqual method because this method works for DataArrayInt with
6245  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
6246  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
6247  * If any the tuple id is returned. If not -1 is returned.
6248  * 
6249  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
6250  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
6251  *
6252  * \return tuple id where \b tupl is. -1 if no such tuple exists in \b this.
6253  * \sa DataArrayInt::findIdSequence, DataArrayInt::presenceOfTuple.
6254  */
6255 int DataArrayInt::findIdFirstEqualTuple(const std::vector<int>& tupl) const
6256 {
6257   checkAllocated();
6258   int nbOfCompo=getNumberOfComponents();
6259   if(nbOfCompo==0)
6260     throw INTERP_KERNEL::Exception("DataArrayInt::findIdFirstEqualTuple : 0 components in 'this' !");
6261   if(nbOfCompo!=(int)tupl.size())
6262     {
6263       std::ostringstream oss; oss << "DataArrayInt::findIdFirstEqualTuple : 'this' contains " << nbOfCompo << " components and searching for a tuple of length " << tupl.size() << " !";
6264       throw INTERP_KERNEL::Exception(oss.str().c_str());
6265     }
6266   const int *cptr=getConstPointer();
6267   std::size_t nbOfVals=getNbOfElems();
6268   for(const int *work=cptr;work!=cptr+nbOfVals;)
6269     {
6270       work=std::search(work,cptr+nbOfVals,tupl.begin(),tupl.end());
6271       if(work!=cptr+nbOfVals)
6272         {
6273           if(std::distance(cptr,work)%nbOfCompo!=0)
6274             work++;
6275           else
6276             return std::distance(cptr,work)/nbOfCompo;
6277         }
6278     }
6279   return -1;
6280 }
6281
6282 /*!
6283  * This method searches the sequence specified in input parameter \b vals in \b this.
6284  * This works only for DataArrayInt having number of components equal to one (if not an INTERP_KERNEL::Exception will be thrown).
6285  * This method differs from DataArrayInt::findIdFirstEqualTuple in that the position is internal raw data is not considered here contrary to DataArrayInt::findIdFirstEqualTuple.
6286  * \sa DataArrayInt::findIdFirstEqualTuple
6287  */
6288 int DataArrayInt::findIdSequence(const std::vector<int>& vals) const
6289 {
6290   checkAllocated();
6291   int nbOfCompo=getNumberOfComponents();
6292   if(nbOfCompo!=1)
6293     throw INTERP_KERNEL::Exception("DataArrayInt::findIdSequence : works only for DataArrayInt instance with one component !");
6294   const int *cptr=getConstPointer();
6295   std::size_t nbOfVals=getNbOfElems();
6296   const int *loc=std::search(cptr,cptr+nbOfVals,vals.begin(),vals.end());
6297   if(loc!=cptr+nbOfVals)
6298     return std::distance(cptr,loc);
6299   return -1;
6300 }
6301
6302 /*!
6303  * This method expects to be called when number of components of this is equal to one.
6304  * This method returns the tuple id, if it exists, of the first tuple equal to \b value.
6305  * If not any tuple contains \b value -1 is returned.
6306  * \sa DataArrayInt::presenceOfValue
6307  */
6308 int DataArrayInt::findIdFirstEqual(int value) const
6309 {
6310   checkAllocated();
6311   if(getNumberOfComponents()!=1)
6312     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
6313   const int *cptr=getConstPointer();
6314   int nbOfTuples=getNumberOfTuples();
6315   const int *ret=std::find(cptr,cptr+nbOfTuples,value);
6316   if(ret!=cptr+nbOfTuples)
6317     return std::distance(cptr,ret);
6318   return -1;
6319 }
6320
6321 /*!
6322  * This method expects to be called when number of components of this is equal to one.
6323  * This method returns the tuple id, if it exists, of the first tuple so that the value is contained in \b vals.
6324  * If not any tuple contains one of the values contained in 'vals' -1 is returned.
6325  * \sa DataArrayInt::presenceOfValue
6326  */
6327 int DataArrayInt::findIdFirstEqual(const std::vector<int>& vals) const
6328 {
6329   checkAllocated();
6330   if(getNumberOfComponents()!=1)
6331     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
6332   std::set<int> vals2(vals.begin(),vals.end());
6333   const int *cptr=getConstPointer();
6334   int nbOfTuples=getNumberOfTuples();
6335   for(const int *w=cptr;w!=cptr+nbOfTuples;w++)
6336     if(vals2.find(*w)!=vals2.end())
6337       return std::distance(cptr,w);
6338   return -1;
6339 }
6340
6341 /*!
6342  * This method returns the number of values in \a this that are equals to input parameter \a value.
6343  * This method only works for single component array.
6344  *
6345  * \return a value in [ 0, \c this->getNumberOfTuples() )
6346  *
6347  * \throw If \a this is not allocated
6348  *
6349  */
6350 int DataArrayInt::count(int value) const
6351 {
6352   int ret=0;
6353   checkAllocated();
6354   if(getNumberOfComponents()!=1)
6355     throw INTERP_KERNEL::Exception("DataArrayInt::count : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
6356   const int *vals=begin();
6357   int nbOfTuples=getNumberOfTuples();
6358   for(int i=0;i<nbOfTuples;i++,vals++)
6359     if(*vals==value)
6360       ret++;
6361   return ret;
6362 }
6363
6364 /*!
6365  * This method is an extension of DataArrayInt::presenceOfValue method because this method works for DataArrayInt with
6366  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
6367  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
6368  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
6369  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
6370  * \sa DataArrayInt::findIdFirstEqualTuple
6371  */
6372 bool DataArrayInt::presenceOfTuple(const std::vector<int>& tupl) const
6373 {
6374   return findIdFirstEqualTuple(tupl)!=-1;
6375 }
6376
6377
6378 /*!
6379  * Returns \a true if a given value is present within \a this one-dimensional array.
6380  *  \param [in] value - the value to find within \a this array.
6381  *  \return bool - \a true in case if \a value is present within \a this array.
6382  *  \throw If \a this is not allocated.
6383  *  \throw If \a this->getNumberOfComponents() != 1.
6384  *  \sa findIdFirstEqual()
6385  */
6386 bool DataArrayInt::presenceOfValue(int value) const
6387 {
6388   return findIdFirstEqual(value)!=-1;
6389 }
6390
6391 /*!
6392  * This method expects to be called when number of components of this is equal to one.
6393  * This method returns true if it exists a tuple so that the value is contained in \b vals.
6394  * If not any tuple contains one of the values contained in 'vals' false is returned.
6395  * \sa DataArrayInt::findIdFirstEqual
6396  */
6397 bool DataArrayInt::presenceOfValue(const std::vector<int>& vals) const
6398 {
6399   return findIdFirstEqual(vals)!=-1;
6400 }
6401
6402 /*!
6403  * Accumulates values of each component of \a this array.
6404  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
6405  *         by the caller, that is filled by this method with sum value for each
6406  *         component.
6407  *  \throw If \a this is not allocated.
6408  */
6409 void DataArrayInt::accumulate(int *res) const
6410 {
6411   checkAllocated();
6412   const int *ptr=getConstPointer();
6413   int nbTuple=getNumberOfTuples();
6414   int nbComps=getNumberOfComponents();
6415   std::fill(res,res+nbComps,0);
6416   for(int i=0;i<nbTuple;i++)
6417     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<int>());
6418 }
6419
6420 int DataArrayInt::accumulate(int compId) const
6421 {
6422   checkAllocated();
6423   const int *ptr=getConstPointer();
6424   int nbTuple=getNumberOfTuples();
6425   int nbComps=getNumberOfComponents();
6426   if(compId<0 || compId>=nbComps)
6427     throw INTERP_KERNEL::Exception("DataArrayInt::accumulate : Invalid compId specified : No such nb of components !");
6428   int ret=0;
6429   for(int i=0;i<nbTuple;i++)
6430     ret+=ptr[i*nbComps+compId];
6431   return ret;
6432 }
6433
6434 /*!
6435  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
6436  * The returned array will have same number of components than \a this and number of tuples equal to
6437  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
6438  *
6439  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
6440  *
6441  * \param [in] bgOfIndex - begin (included) of the input index array.
6442  * \param [in] endOfIndex - end (excluded) of the input index array.
6443  * \return DataArrayInt * - the new instance having the same number of components than \a this.
6444  * 
6445  * \throw If bgOfIndex or end is NULL.
6446  * \throw If input index array is not ascendingly sorted.
6447  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
6448  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
6449  */
6450 DataArrayInt *DataArrayInt::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
6451 {
6452   if(!bgOfIndex || !endOfIndex)
6453     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : input pointer NULL !");
6454   checkAllocated();
6455   int nbCompo=getNumberOfComponents();
6456   int nbOfTuples=getNumberOfTuples();
6457   int sz=(int)std::distance(bgOfIndex,endOfIndex);
6458   if(sz<1)
6459     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : invalid size of input index array !");
6460   sz--;
6461   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(sz,nbCompo);
6462   const int *w=bgOfIndex;
6463   if(*w<0 || *w>=nbOfTuples)
6464     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
6465   const int *srcPt=begin()+(*w)*nbCompo;
6466   int *tmp=ret->getPointer();
6467   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
6468     {
6469       std::fill(tmp,tmp+nbCompo,0);
6470       if(w[1]>=w[0])
6471         {
6472           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
6473             {
6474               if(j>=0 && j<nbOfTuples)
6475                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<int>());
6476               else
6477                 {
6478                   std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
6479                   throw INTERP_KERNEL::Exception(oss.str().c_str());
6480                 }
6481             }
6482         }
6483       else
6484         {
6485           std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
6486           throw INTERP_KERNEL::Exception(oss.str().c_str());
6487         }
6488     }
6489   ret->copyStringInfoFrom(*this);
6490   return ret.retn();
6491 }
6492
6493 /*!
6494  * Returns a new DataArrayInt by concatenating two given arrays, so that (1) the number
6495  * of tuples in the result array is <em> a1->getNumberOfTuples() + a2->getNumberOfTuples() -
6496  * offsetA2</em> and (2)
6497  * the number of component in the result array is same as that of each of given arrays.
6498  * First \a offsetA2 tuples of \a a2 are skipped and thus are missing from the result array.
6499  * Info on components is copied from the first of the given arrays. Number of components
6500  * in the given arrays must be the same.
6501  *  \param [in] a1 - an array to include in the result array.
6502  *  \param [in] a2 - another array to include in the result array.
6503  *  \param [in] offsetA2 - number of tuples of \a a2 to skip.
6504  *  \return DataArrayInt * - the new instance of DataArrayInt.
6505  *          The caller is to delete this result array using decrRef() as it is no more
6506  *          needed.
6507  *  \throw If either \a a1 or \a a2 is NULL.
6508  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
6509  */
6510 DataArrayInt *DataArrayInt::Aggregate(const DataArrayInt *a1, const DataArrayInt *a2, int offsetA2)
6511 {
6512   if(!a1 || !a2)
6513     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input DataArrayInt instance is NULL !");
6514   int nbOfComp=a1->getNumberOfComponents();
6515   if(nbOfComp!=a2->getNumberOfComponents())
6516     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Aggregation !");
6517   int nbOfTuple1=a1->getNumberOfTuples();
6518   int nbOfTuple2=a2->getNumberOfTuples();
6519   DataArrayInt *ret=DataArrayInt::New();
6520   ret->alloc(nbOfTuple1+nbOfTuple2-offsetA2,nbOfComp);
6521   int *pt=std::copy(a1->getConstPointer(),a1->getConstPointer()+nbOfTuple1*nbOfComp,ret->getPointer());
6522   std::copy(a2->getConstPointer()+offsetA2*nbOfComp,a2->getConstPointer()+nbOfTuple2*nbOfComp,pt);
6523   ret->copyStringInfoFrom(*a1);
6524   return ret;
6525 }
6526
6527 /*!
6528  * Returns a new DataArrayInt by concatenating all given arrays, so that (1) the number
6529  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
6530  * the number of component in the result array is same as that of each of given arrays.
6531  * Info on components is copied from the first of the given arrays. Number of components
6532  * in the given arrays must be  the same.
6533  * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it
6534  * not the object itself.
6535  *  \param [in] arr - a sequence of arrays to include in the result array.
6536  *  \return DataArrayInt * - the new instance of DataArrayInt.
6537  *          The caller is to delete this result array using decrRef() as it is no more
6538  *          needed.
6539  *  \throw If all arrays within \a arr are NULL.
6540  *  \throw If getNumberOfComponents() of arrays within \a arr.
6541  */
6542 DataArrayInt *DataArrayInt::Aggregate(const std::vector<const DataArrayInt *>& arr)
6543 {
6544   std::vector<const DataArrayInt *> a;
6545   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
6546     if(*it4)
6547       a.push_back(*it4);
6548   if(a.empty())
6549     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input list must be NON EMPTY !");
6550   std::vector<const DataArrayInt *>::const_iterator it=a.begin();
6551   int nbOfComp=(*it)->getNumberOfComponents();
6552   int nbt=(*it++)->getNumberOfTuples();
6553   for(int i=1;it!=a.end();it++,i++)
6554     {
6555       if((*it)->getNumberOfComponents()!=nbOfComp)
6556         throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : Nb of components mismatch for array aggregation !");
6557       nbt+=(*it)->getNumberOfTuples();
6558     }
6559   MCAuto<DataArrayInt> ret=DataArrayInt::New();
6560   ret->alloc(nbt,nbOfComp);
6561   int *pt=ret->getPointer();
6562   for(it=a.begin();it!=a.end();it++)
6563     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
6564   ret->copyStringInfoFrom(*(a[0]));
6565   return ret.retn();
6566 }
6567
6568 /*!
6569  * This method takes as input a list of DataArrayInt instances \a arrs that represent each a packed index arrays.
6570  * A packed index array is an allocated array with one component, and at least one tuple. The first element
6571  * of each array in \a arrs must be 0. Each array in \a arrs is expected to be increasingly monotonic.
6572  * 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.
6573  * 
6574  * \return DataArrayInt * - a new object to be managed by the caller.
6575  */
6576 DataArrayInt *DataArrayInt::AggregateIndexes(const std::vector<const DataArrayInt *>& arrs)
6577 {
6578   int retSz=1;
6579   for(std::vector<const DataArrayInt *>::const_iterator it4=arrs.begin();it4!=arrs.end();it4++)
6580     {
6581       if(*it4)
6582         {
6583           (*it4)->checkAllocated();
6584           if((*it4)->getNumberOfComponents()!=1)
6585             {
6586               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of compo != 1 at pos " << std::distance(arrs.begin(),it4) << " !";
6587               throw INTERP_KERNEL::Exception(oss.str().c_str());
6588             }
6589           int nbTupl=(*it4)->getNumberOfTuples();
6590           if(nbTupl<1)
6591             {
6592               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of tuples < 1 at pos " << std::distance(arrs.begin(),it4) << " !";
6593               throw INTERP_KERNEL::Exception(oss.str().c_str());
6594             }
6595           if((*it4)->front()!=0)
6596             {
6597               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with front value != 0 at pos " << std::distance(arrs.begin(),it4) << " !";
6598               throw INTERP_KERNEL::Exception(oss.str().c_str());
6599             }
6600           retSz+=nbTupl-1;
6601         }
6602       else
6603         {
6604           std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a null instance at pos " << std::distance(arrs.begin(),it4) << " !";
6605           throw INTERP_KERNEL::Exception(oss.str().c_str());
6606         }
6607     }
6608   if(arrs.empty())
6609     throw INTERP_KERNEL::Exception("DataArrayInt::AggregateIndexes : input list must be NON EMPTY !");
6610   MCAuto<DataArrayInt> ret=DataArrayInt::New();
6611   ret->alloc(retSz,1);
6612   int *pt=ret->getPointer(); *pt++=0;
6613   for(std::vector<const DataArrayInt *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
6614     pt=std::transform((*it)->begin()+1,(*it)->end(),pt,std::bind2nd(std::plus<int>(),pt[-1]));
6615   ret->copyStringInfoFrom(*(arrs[0]));
6616   return ret.retn();
6617 }
6618
6619 /*!
6620  * Returns in a single walk in \a this the min value and the max value in \a this.
6621  * \a this is expected to be single component array.
6622  *
6623  * \param [out] minValue - the min value in \a this.
6624  * \param [out] maxValue - the max value in \a this.
6625  *
6626  * \sa getMinValueInArray, getMinValue, getMaxValueInArray, getMaxValue
6627  */
6628 void DataArrayInt::getMinMaxValues(int& minValue, int& maxValue) const
6629 {
6630   checkAllocated();
6631   if(getNumberOfComponents()!=1)
6632     throw INTERP_KERNEL::Exception("DataArrayInt::getMinMaxValues : must be applied on DataArrayInt with only one component !");
6633   int nbTuples(getNumberOfTuples());
6634   const int *pt(begin());
6635   minValue=std::numeric_limits<int>::max(); maxValue=-std::numeric_limits<int>::max();
6636   for(int i=0;i<nbTuples;i++,pt++)
6637     {
6638       if(*pt<minValue)
6639         minValue=*pt;
6640       if(*pt>maxValue)
6641         maxValue=*pt;
6642     }
6643 }
6644
6645 /*!
6646  * Converts every value of \a this array to its absolute value.
6647  * \b WARNING this method is non const. If a new DataArrayInt instance should be built containing the result of abs DataArrayInt::computeAbs
6648  * should be called instead.
6649  *
6650  * \throw If \a this is not allocated.
6651  * \sa DataArrayInt::computeAbs
6652  */
6653 void DataArrayInt::abs()
6654 {
6655   checkAllocated();
6656   int *ptr(getPointer());
6657   std::size_t nbOfElems(getNbOfElems());
6658   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<int,int>(std::abs));
6659   declareAsNew();
6660 }
6661
6662 /*!
6663  * This method builds a new instance of \a this object containing the result of std::abs applied of all elements in \a this.
6664  * This method is a const method (that do not change any values in \a this) contrary to  DataArrayInt::abs method.
6665  *
6666  * \return DataArrayInt * - the new instance of DataArrayInt containing the
6667  *         same number of tuples and component as \a this array.
6668  *         The caller is to delete this result array using decrRef() as it is no more
6669  *         needed.
6670  * \throw If \a this is not allocated.
6671  * \sa DataArrayInt::abs
6672  */
6673 DataArrayInt *DataArrayInt::computeAbs() const
6674 {
6675   checkAllocated();
6676   DataArrayInt *newArr(DataArrayInt::New());
6677   int nbOfTuples(getNumberOfTuples());
6678   int nbOfComp(getNumberOfComponents());
6679   newArr->alloc(nbOfTuples,nbOfComp);
6680   std::transform(begin(),end(),newArr->getPointer(),std::ptr_fun<int,int>(std::abs));
6681   newArr->copyStringInfoFrom(*this);
6682   return newArr;
6683 }
6684
6685 /*!
6686  * Apply a liner function to a given component of \a this array, so that
6687  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
6688  *  \param [in] a - the first coefficient of the function.
6689  *  \param [in] b - the second coefficient of the function.
6690  *  \param [in] compoId - the index of component to modify.
6691  *  \throw If \a this is not allocated.
6692  */
6693 void DataArrayInt::applyLin(int a, int b, int compoId)
6694 {
6695   checkAllocated();
6696   int *ptr=getPointer()+compoId;
6697   int nbOfComp=getNumberOfComponents();
6698   int nbOfTuple=getNumberOfTuples();
6699   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
6700     *ptr=a*(*ptr)+b;
6701   declareAsNew();
6702 }
6703
6704 /*!
6705  * Apply a liner function to all elements of \a this array, so that
6706  * an element _x_ becomes \f$ a * x + b \f$.
6707  *  \param [in] a - the first coefficient of the function.
6708  *  \param [in] b - the second coefficient of the function.
6709  *  \throw If \a this is not allocated.
6710  */
6711 void DataArrayInt::applyLin(int a, int b)
6712 {
6713   checkAllocated();
6714   int *ptr=getPointer();
6715   std::size_t nbOfElems=getNbOfElems();
6716   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
6717     *ptr=a*(*ptr)+b;
6718   declareAsNew();
6719 }
6720
6721 /*!
6722  * Returns a full copy of \a this array except that sign of all elements is reversed.
6723  *  \return DataArrayInt * - the new instance of DataArrayInt containing the
6724  *          same number of tuples and component as \a this array.
6725  *          The caller is to delete this result array using decrRef() as it is no more
6726  *          needed.
6727  *  \throw If \a this is not allocated.
6728  */
6729 DataArrayInt *DataArrayInt::negate() const
6730 {
6731   checkAllocated();
6732   DataArrayInt *newArr=DataArrayInt::New();
6733   int nbOfTuples=getNumberOfTuples();
6734   int nbOfComp=getNumberOfComponents();
6735   newArr->alloc(nbOfTuples,nbOfComp);
6736   const int *cptr=getConstPointer();
6737   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<int>());
6738   newArr->copyStringInfoFrom(*this);
6739   return newArr;
6740 }
6741
6742 /*!
6743  * Modify all elements of \a this array, so that
6744  * an element _x_ becomes \f$ numerator / x \f$.
6745  *  \warning If an exception is thrown because of presence of 0 element in \a this 
6746  *           array, all elements processed before detection of the zero element remain
6747  *           modified.
6748  *  \param [in] numerator - the numerator used to modify array elements.
6749  *  \throw If \a this is not allocated.
6750  *  \throw If there is an element equal to 0 in \a this array.
6751  */
6752 void DataArrayInt::applyInv(int numerator)
6753 {
6754   checkAllocated();
6755   int *ptr=getPointer();
6756   std::size_t nbOfElems=getNbOfElems();
6757   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
6758     {
6759       if(*ptr!=0)
6760         {
6761           *ptr=numerator/(*ptr);
6762         }
6763       else
6764         {
6765           std::ostringstream oss; oss << "DataArrayInt::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
6766           oss << " !";
6767           throw INTERP_KERNEL::Exception(oss.str().c_str());
6768         }
6769     }
6770   declareAsNew();
6771 }
6772
6773 /*!
6774  * Modify all elements of \a this array, so that
6775  * an element _x_ becomes \f$ x / val \f$.
6776  *  \param [in] val - the denominator used to modify array elements.
6777  *  \throw If \a this is not allocated.
6778  *  \throw If \a val == 0.
6779  */
6780 void DataArrayInt::applyDivideBy(int val)
6781 {
6782   if(val==0)
6783     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to divide by 0 !");
6784   checkAllocated();
6785   int *ptr=getPointer();
6786   std::size_t nbOfElems=getNbOfElems();
6787   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::divides<int>(),val));
6788   declareAsNew();
6789 }
6790
6791 /*!
6792  * Modify all elements of \a this array, so that
6793  * an element _x_ becomes  <em> x % val </em>.
6794  *  \param [in] val - the divisor used to modify array elements.
6795  *  \throw If \a this is not allocated.
6796  *  \throw If \a val <= 0.
6797  */
6798 void DataArrayInt::applyModulus(int val)
6799 {
6800   if(val<=0)
6801     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to operate modulus on value <= 0 !");
6802   checkAllocated();
6803   int *ptr=getPointer();
6804   std::size_t nbOfElems=getNbOfElems();
6805   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::modulus<int>(),val));
6806   declareAsNew();
6807 }
6808
6809 struct GreatEqual
6810 {
6811   GreatEqual(int v):_v(v) { }
6812   bool operator()(int v) const { return v>=_v; }
6813   int _v;
6814 };
6815
6816 struct GreaterThan
6817 {
6818   GreaterThan(int v):_v(v) { }
6819   bool operator()(int v) const { return v>_v; }
6820   int _v;
6821 };
6822
6823 struct LowerEqual
6824 {
6825   LowerEqual(int v):_v(v) { }
6826   bool operator()(int v) const { return v<=_v; }
6827   int _v;
6828 };
6829
6830 struct LowerThan
6831 {
6832   LowerThan(int v):_v(v) { }
6833   bool operator()(int v) const { return v<_v; }
6834   int _v;
6835 };
6836
6837 struct InRange
6838 {
6839   InRange(int a, int b):_a(a),_b(b) { }
6840   bool operator()(int v) const { return v>=_a && v<_b; }
6841   int _a,_b;
6842 };
6843
6844 /*!
6845  * This method works only on data array with one component.
6846  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
6847  * this[*id] in [\b vmin,\b vmax)
6848  * 
6849  * \param [in] vmin begin of range. This value is included in range (included).
6850  * \param [in] vmax end of range. This value is \b not included in range (excluded).
6851  * \return a newly allocated data array that the caller should deal with.
6852  *
6853  * \sa DataArrayInt::findIdsNotInRange , DataArrayInt::findIdsStricltyNegative
6854  */
6855 DataArrayInt *DataArrayInt::findIdsInRange(int vmin, int vmax) const
6856 {
6857   InRange ir(vmin,vmax);
6858   MCAuto<DataArrayInt> ret(findIdsAdv(ir));
6859   return ret.retn();
6860 }
6861
6862 struct NotInRange
6863 {
6864   NotInRange(int a, int b):_a(a),_b(b) { }
6865   bool operator()(int v) const { return v<_a || v>=_b; }
6866   int _a,_b;
6867 };
6868
6869 /*!
6870  * This method works only on data array with one component.
6871  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
6872  * this[*id] \b not in [\b vmin,\b vmax)
6873  * 
6874  * \param [in] vmin begin of range. This value is \b not included in range (excluded).
6875  * \param [in] vmax end of range. This value is included in range (included).
6876  * \return a newly allocated data array that the caller should deal with.
6877  * 
6878  * \sa DataArrayInt::findIdsInRange , DataArrayInt::findIdsStricltyNegative
6879  */
6880 DataArrayInt *DataArrayInt::findIdsNotInRange(int vmin, int vmax) const
6881 {
6882   NotInRange nir(vmin,vmax);
6883   MCAuto<DataArrayInt> ret(findIdsAdv(nir));
6884   return ret.retn();
6885 }
6886
6887 /*!
6888  * 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.
6889  *
6890  * \return a newly allocated data array that the caller should deal with.
6891  * \sa DataArrayInt::findIdsInRange
6892  */
6893 DataArrayInt *DataArrayInt::findIdsStricltyNegative() const
6894 {
6895   LowerThan lt(0);
6896   MCAuto<DataArrayInt> ret(findIdsAdv(lt));
6897   return ret.retn();
6898 }
6899
6900 MCAuto<DataArrayInt> DataArrayInt::findIdsGreaterOrEqualTo(int val) const
6901 {
6902   GreatEqual ge(val);
6903   return findIdsAdv(ge);
6904 }
6905
6906 MCAuto<DataArrayInt> DataArrayInt::findIdsGreaterThan(int val) const
6907 {
6908   GreaterThan gt(val);
6909   return findIdsAdv(gt);
6910 }
6911
6912 MCAuto<DataArrayInt> DataArrayInt::findIdsLowerOrEqualTo(int val) const
6913 {
6914   LowerEqual le(val);
6915   return findIdsAdv(le);
6916 }
6917
6918 MCAuto<DataArrayInt> DataArrayInt::findIdsLowerThan(int val) const
6919 {
6920   LowerThan lt(val);
6921   return findIdsAdv(lt);
6922 }
6923
6924 /*!
6925  * This method works only on data array with one component.
6926  * 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.
6927  * 
6928  * \param [in] vmin begin of range. This value is included in range (included).
6929  * \param [in] vmax end of range. This value is \b not included in range (excluded).
6930  * \return if all ids in \a this are so that (*this)[i]==i for all i in [ 0, \c this->getNumberOfTuples() ). */
6931 bool DataArrayInt::checkAllIdsInRange(int vmin, int vmax) const
6932 {
6933   checkAllocated();
6934   if(getNumberOfComponents()!=1)
6935     throw INTERP_KERNEL::Exception("DataArrayInt::checkAllIdsInRange : this must have exactly one component !");
6936   int nbOfTuples=getNumberOfTuples();
6937   bool ret=true;
6938   const int *cptr=getConstPointer();
6939   for(int i=0;i<nbOfTuples;i++,cptr++)
6940     {
6941       if(*cptr>=vmin && *cptr<vmax)
6942         { ret=ret && *cptr==i; }
6943       else
6944         {
6945           std::ostringstream oss; oss << "DataArrayInt::checkAllIdsInRange : tuple #" << i << " has value " << *cptr << " should be in [" << vmin << "," << vmax << ") !";
6946           throw INTERP_KERNEL::Exception(oss.str().c_str());
6947         }
6948     }
6949   return ret;
6950 }
6951
6952 /*!
6953  * Modify all elements of \a this array, so that
6954  * an element _x_ becomes <em> val % x </em>.
6955  *  \warning If an exception is thrown because of presence of an element <= 0 in \a this 
6956  *           array, all elements processed before detection of the zero element remain
6957  *           modified.
6958  *  \param [in] val - the divident used to modify array elements.
6959  *  \throw If \a this is not allocated.
6960  *  \throw If there is an element equal to or less than 0 in \a this array.
6961  */
6962 void DataArrayInt::applyRModulus(int val)
6963 {
6964   checkAllocated();
6965   int *ptr=getPointer();
6966   std::size_t nbOfElems=getNbOfElems();
6967   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
6968     {
6969       if(*ptr>0)
6970         {
6971           *ptr=val%(*ptr);
6972         }
6973       else
6974         {
6975           std::ostringstream oss; oss << "DataArrayInt::applyRModulus : presence of value <=0 in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
6976           oss << " !";
6977           throw INTERP_KERNEL::Exception(oss.str().c_str());
6978         }
6979     }
6980   declareAsNew();
6981 }
6982
6983 /*!
6984  * Modify all elements of \a this array, so that
6985  * an element _x_ becomes <em> val ^ x </em>.
6986  *  \param [in] val - the value used to apply pow on all array elements.
6987  *  \throw If \a this is not allocated.
6988  *  \throw If \a val < 0.
6989  */
6990 void DataArrayInt::applyPow(int val)
6991 {
6992   checkAllocated();
6993   if(val<0)
6994     throw INTERP_KERNEL::Exception("DataArrayInt::applyPow : input pow in < 0 !");
6995   int *ptr=getPointer();
6996   std::size_t nbOfElems=getNbOfElems();
6997   if(val==0)
6998     {
6999       std::fill(ptr,ptr+nbOfElems,1);
7000       return ;
7001     }
7002   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
7003     {
7004       int tmp=1;
7005       for(int j=0;j<val;j++)
7006         tmp*=*ptr;
7007       *ptr=tmp;
7008     }
7009   declareAsNew();
7010 }
7011
7012 /*!
7013  * Modify all elements of \a this array, so that
7014  * an element _x_ becomes \f$ val ^ x \f$.
7015  *  \param [in] val - the value used to apply pow on all array elements.
7016  *  \throw If \a this is not allocated.
7017  *  \throw If there is an element < 0 in \a this array.
7018  *  \warning If an exception is thrown because of presence of 0 element in \a this 
7019  *           array, all elements processed before detection of the zero element remain
7020  *           modified.
7021  */
7022 void DataArrayInt::applyRPow(int val)
7023 {
7024   checkAllocated();
7025   int *ptr=getPointer();
7026   std::size_t nbOfElems=getNbOfElems();
7027   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
7028     {
7029       if(*ptr>=0)
7030         {
7031           int tmp=1;
7032           for(int j=0;j<*ptr;j++)
7033             tmp*=val;
7034           *ptr=tmp;
7035         }
7036       else
7037         {
7038           std::ostringstream oss; oss << "DataArrayInt::applyRPow : presence of negative value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
7039           oss << " !";
7040           throw INTERP_KERNEL::Exception(oss.str().c_str());
7041         }
7042     }
7043   declareAsNew();
7044 }
7045
7046 /*!
7047  * Returns a new DataArrayInt by aggregating two given arrays, so that (1) the number
7048  * of components in the result array is a sum of the number of components of given arrays
7049  * and (2) the number of tuples in the result array is same as that of each of given
7050  * arrays. In other words the i-th tuple of result array includes all components of
7051  * i-th tuples of all given arrays.
7052  * Number of tuples in the given arrays must be the same.
7053  *  \param [in] a1 - an array to include in the result array.
7054  *  \param [in] a2 - another array to include in the result array.
7055  *  \return DataArrayInt * - the new instance of DataArrayInt.
7056  *          The caller is to delete this result array using decrRef() as it is no more
7057  *          needed.
7058  *  \throw If both \a a1 and \a a2 are NULL.
7059  *  \throw If any given array is not allocated.
7060  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
7061  */
7062 DataArrayInt *DataArrayInt::Meld(const DataArrayInt *a1, const DataArrayInt *a2)
7063 {
7064   std::vector<const DataArrayInt *> arr(2);
7065   arr[0]=a1; arr[1]=a2;
7066   return Meld(arr);
7067 }
7068
7069 /*!
7070  * Returns a new DataArrayInt by aggregating all given arrays, so that (1) the number
7071  * of components in the result array is a sum of the number of components of given arrays
7072  * and (2) the number of tuples in the result array is same as that of each of given
7073  * arrays. In other words the i-th tuple of result array includes all components of
7074  * i-th tuples of all given arrays.
7075  * Number of tuples in the given arrays must be  the same.
7076  *  \param [in] arr - a sequence of arrays to include in the result array.
7077  *  \return DataArrayInt * - the new instance of DataArrayInt.
7078  *          The caller is to delete this result array using decrRef() as it is no more
7079  *          needed.
7080  *  \throw If all arrays within \a arr are NULL.
7081  *  \throw If any given array is not allocated.
7082  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
7083  */
7084 DataArrayInt *DataArrayInt::Meld(const std::vector<const DataArrayInt *>& arr)
7085 {
7086   std::vector<const DataArrayInt *> a;
7087   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
7088     if(*it4)
7089       a.push_back(*it4);
7090   if(a.empty())
7091     throw INTERP_KERNEL::Exception("DataArrayInt::Meld : array must be NON empty !");
7092   std::vector<const DataArrayInt *>::const_iterator it;
7093   for(it=a.begin();it!=a.end();it++)
7094     (*it)->checkAllocated();
7095   it=a.begin();
7096   int nbOfTuples=(*it)->getNumberOfTuples();
7097   std::vector<int> nbc(a.size());
7098   std::vector<const int *> pts(a.size());
7099   nbc[0]=(*it)->getNumberOfComponents();
7100   pts[0]=(*it++)->getConstPointer();
7101   for(int i=1;it!=a.end();it++,i++)
7102     {
7103       if(nbOfTuples!=(*it)->getNumberOfTuples())
7104         throw INTERP_KERNEL::Exception("DataArrayInt::meld : mismatch of number of tuples !");
7105       nbc[i]=(*it)->getNumberOfComponents();
7106       pts[i]=(*it)->getConstPointer();
7107     }
7108   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
7109   DataArrayInt *ret=DataArrayInt::New();
7110   ret->alloc(nbOfTuples,totalNbOfComp);
7111   int *retPtr=ret->getPointer();
7112   for(int i=0;i<nbOfTuples;i++)
7113     for(int j=0;j<(int)a.size();j++)
7114       {
7115         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
7116         pts[j]+=nbc[j];
7117       }
7118   int k=0;
7119   for(int i=0;i<(int)a.size();i++)
7120     for(int j=0;j<nbc[i];j++,k++)
7121       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j));
7122   return ret;
7123 }
7124
7125 /*!
7126  * Returns a new DataArrayInt which is a minimal partition of elements of \a groups.
7127  * The i-th item of the result array is an ID of a set of elements belonging to a
7128  * unique set of groups, which the i-th element is a part of. This set of elements
7129  * belonging to a unique set of groups is called \a family, so the result array contains
7130  * IDs of families each element belongs to.
7131  *
7132  * \b Example: if we have two groups of elements: \a group1 [0,4] and \a group2 [ 0,1,2 ],
7133  * then there are 3 families:
7134  * - \a family1 (with ID 1) contains element [0] belonging to ( \a group1 + \a group2 ),
7135  * - \a family2 (with ID 2) contains elements [4] belonging to ( \a group1 ),
7136  * - \a family3 (with ID 3) contains element [1,2] belonging to ( \a group2 ), <br>
7137  * and the result array contains IDs of families [ 1,3,3,0,2 ]. <br> Note a family ID 0 which
7138  * stands for the element #3 which is in none of groups.
7139  *
7140  *  \param [in] groups - sequence of groups of element IDs.
7141  *  \param [in] newNb - total number of elements; it must be more than max ID of element
7142  *         in \a groups.
7143  *  \param [out] fidsOfGroups - IDs of families the elements of each group belong to.
7144  *  \return DataArrayInt * - a new instance of DataArrayInt containing IDs of families
7145  *         each element with ID from range [0, \a newNb ) belongs to. The caller is to
7146  *         delete this array using decrRef() as it is no more needed.
7147  *  \throw If any element ID in \a groups violates condition ( 0 <= ID < \a newNb ).
7148  */
7149 DataArrayInt *DataArrayInt::MakePartition(const std::vector<const DataArrayInt *>& groups, int newNb, std::vector< std::vector<int> >& fidsOfGroups)
7150 {
7151   std::vector<const DataArrayInt *> groups2;
7152   for(std::vector<const DataArrayInt *>::const_iterator it4=groups.begin();it4!=groups.end();it4++)
7153     if(*it4)
7154       groups2.push_back(*it4);
7155   MCAuto<DataArrayInt> ret=DataArrayInt::New();
7156   ret->alloc(newNb,1);
7157   int *retPtr=ret->getPointer();
7158   std::fill(retPtr,retPtr+newNb,0);
7159   int fid=1;
7160   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++)
7161     {
7162       const int *ptr=(*iter)->getConstPointer();
7163       std::size_t nbOfElem=(*iter)->getNbOfElems();
7164       int sfid=fid;
7165       for(int j=0;j<sfid;j++)
7166         {
7167           bool found=false;
7168           for(std::size_t i=0;i<nbOfElem;i++)
7169             {
7170               if(ptr[i]>=0 && ptr[i]<newNb)
7171                 {
7172                   if(retPtr[ptr[i]]==j)
7173                     {
7174                       retPtr[ptr[i]]=fid;
7175                       found=true;
7176                     }
7177                 }
7178               else
7179                 {
7180                   std::ostringstream oss; oss << "DataArrayInt::MakePartition : In group \"" << (*iter)->getName() << "\" in tuple #" << i << " value = " << ptr[i] << " ! Should be in [0," << newNb;
7181                   oss << ") !";
7182                   throw INTERP_KERNEL::Exception(oss.str().c_str());
7183                 }
7184             }
7185           if(found)
7186             fid++;
7187         }
7188     }
7189   fidsOfGroups.clear();
7190   fidsOfGroups.resize(groups2.size());
7191   int grId=0;
7192   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++,grId++)
7193     {
7194       std::set<int> tmp;
7195       const int *ptr=(*iter)->getConstPointer();
7196       std::size_t nbOfElem=(*iter)->getNbOfElems();
7197       for(const int *p=ptr;p!=ptr+nbOfElem;p++)
7198         tmp.insert(retPtr[*p]);
7199       fidsOfGroups[grId].insert(fidsOfGroups[grId].end(),tmp.begin(),tmp.end());
7200     }
7201   return ret.retn();
7202 }
7203
7204 /*!
7205  * Returns a new DataArrayInt which contains all elements of given one-dimensional
7206  * arrays. The result array does not contain any duplicates and its values
7207  * are sorted in ascending order.
7208  *  \param [in] arr - sequence of DataArrayInt's to unite.
7209  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7210  *         array using decrRef() as it is no more needed.
7211  *  \throw If any \a arr[i] is not allocated.
7212  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
7213  */
7214 DataArrayInt *DataArrayInt::BuildUnion(const std::vector<const DataArrayInt *>& arr)
7215 {
7216   std::vector<const DataArrayInt *> a;
7217   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
7218     if(*it4)
7219       a.push_back(*it4);
7220   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
7221     {
7222       (*it)->checkAllocated();
7223       if((*it)->getNumberOfComponents()!=1)
7224         throw INTERP_KERNEL::Exception("DataArrayInt::BuildUnion : only single component allowed !");
7225     }
7226   //
7227   std::set<int> r;
7228   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
7229     {
7230       const int *pt=(*it)->getConstPointer();
7231       int nbOfTuples=(*it)->getNumberOfTuples();
7232       r.insert(pt,pt+nbOfTuples);
7233     }
7234   DataArrayInt *ret=DataArrayInt::New();
7235   ret->alloc((int)r.size(),1);
7236   std::copy(r.begin(),r.end(),ret->getPointer());
7237   return ret;
7238 }
7239
7240 /*!
7241  * Returns a new DataArrayInt which contains elements present in each of given one-dimensional
7242  * arrays. The result array does not contain any duplicates and its values
7243  * are sorted in ascending order.
7244  *  \param [in] arr - sequence of DataArrayInt's to intersect.
7245  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7246  *         array using decrRef() as it is no more needed.
7247  *  \throw If any \a arr[i] is not allocated.
7248  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
7249  */
7250 DataArrayInt *DataArrayInt::BuildIntersection(const std::vector<const DataArrayInt *>& arr)
7251 {
7252   std::vector<const DataArrayInt *> a;
7253   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
7254     if(*it4)
7255       a.push_back(*it4);
7256   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
7257     {
7258       (*it)->checkAllocated();
7259       if((*it)->getNumberOfComponents()!=1)
7260         throw INTERP_KERNEL::Exception("DataArrayInt::BuildIntersection : only single component allowed !");
7261     }
7262   //
7263   std::set<int> r;
7264   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
7265     {
7266       const int *pt=(*it)->getConstPointer();
7267       int nbOfTuples=(*it)->getNumberOfTuples();
7268       std::set<int> s1(pt,pt+nbOfTuples);
7269       if(it!=a.begin())
7270         {
7271           std::set<int> r2;
7272           std::set_intersection(r.begin(),r.end(),s1.begin(),s1.end(),inserter(r2,r2.end()));
7273           r=r2;
7274         }
7275       else
7276         r=s1;
7277     }
7278   DataArrayInt *ret(DataArrayInt::New());
7279   ret->alloc((int)r.size(),1);
7280   std::copy(r.begin(),r.end(),ret->getPointer());
7281   return ret;
7282 }
7283
7284 /// @cond INTERNAL
7285 namespace MEDCouplingImpl
7286 {
7287   class OpSwitchedOn
7288   {
7289   public:
7290     OpSwitchedOn(int *pt):_pt(pt),_cnt(0) { }
7291     void operator()(const bool& b) { if(b) *_pt++=_cnt; _cnt++; }
7292   private:
7293     int *_pt;
7294     int _cnt;
7295   };
7296
7297   class OpSwitchedOff
7298   {
7299   public:
7300     OpSwitchedOff(int *pt):_pt(pt),_cnt(0) { }
7301     void operator()(const bool& b) { if(!b) *_pt++=_cnt; _cnt++; }
7302   private:
7303     int *_pt;
7304     int _cnt;
7305   };
7306 }
7307 /// @endcond
7308
7309 /*!
7310  * This method returns the list of ids in ascending mode so that v[id]==true.
7311  */
7312 DataArrayInt *DataArrayInt::BuildListOfSwitchedOn(const std::vector<bool>& v)
7313 {
7314   int sz((int)std::count(v.begin(),v.end(),true));
7315   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
7316   std::for_each(v.begin(),v.end(),MEDCouplingImpl::OpSwitchedOn(ret->getPointer()));
7317   return ret.retn();
7318 }
7319
7320 /*!
7321  * This method returns the list of ids in ascending mode so that v[id]==false.
7322  */
7323 DataArrayInt *DataArrayInt::BuildListOfSwitchedOff(const std::vector<bool>& v)
7324 {
7325   int sz((int)std::count(v.begin(),v.end(),false));
7326   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
7327   std::for_each(v.begin(),v.end(),MEDCouplingImpl::OpSwitchedOff(ret->getPointer()));
7328   return ret.retn();
7329 }
7330
7331 /*!
7332  * This method allows to put a vector of vector of integer into a more compact data stucture (skyline). 
7333  * This method is not available into python because no available optimized data structure available to map std::vector< std::vector<int> >.
7334  *
7335  * \param [in] v the input data structure to be translate into skyline format.
7336  * \param [out] data the first element of the skyline format. The user is expected to deal with newly allocated array.
7337  * \param [out] dataIndex the second element of the skyline format.
7338  */
7339 void DataArrayInt::PutIntoToSkylineFrmt(const std::vector< std::vector<int> >& v, DataArrayInt *& data, DataArrayInt *& dataIndex)
7340 {
7341   int sz((int)v.size());
7342   MCAuto<DataArrayInt> ret0(DataArrayInt::New()),ret1(DataArrayInt::New());
7343   ret1->alloc(sz+1,1);
7344   int *pt(ret1->getPointer()); *pt=0;
7345   for(int i=0;i<sz;i++,pt++)
7346     pt[1]=pt[0]+(int)v[i].size();
7347   ret0->alloc(ret1->back(),1);
7348   pt=ret0->getPointer();
7349   for(int i=0;i<sz;i++)
7350     pt=std::copy(v[i].begin(),v[i].end(),pt);
7351   data=ret0.retn(); dataIndex=ret1.retn();
7352 }
7353
7354 /*!
7355  * Returns a new DataArrayInt which contains a complement of elements of \a this
7356  * one-dimensional array. I.e. the result array contains all elements from the range [0,
7357  * \a nbOfElement) not present in \a this array.
7358  *  \param [in] nbOfElement - maximal size of the result array.
7359  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7360  *         array using decrRef() as it is no more needed.
7361  *  \throw If \a this is not allocated.
7362  *  \throw If \a this->getNumberOfComponents() != 1.
7363  *  \throw If any element \a x of \a this array violates condition ( 0 <= \a x < \a
7364  *         nbOfElement ).
7365  */
7366 DataArrayInt *DataArrayInt::buildComplement(int nbOfElement) const
7367 {
7368   checkAllocated();
7369   if(getNumberOfComponents()!=1)
7370     throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : only single component allowed !");
7371   std::vector<bool> tmp(nbOfElement);
7372   const int *pt=getConstPointer();
7373   int nbOfTuples=getNumberOfTuples();
7374   for(const int *w=pt;w!=pt+nbOfTuples;w++)
7375     if(*w>=0 && *w<nbOfElement)
7376       tmp[*w]=true;
7377     else
7378       throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : an element is not in valid range : [0,nbOfElement) !");
7379   int nbOfRetVal=(int)std::count(tmp.begin(),tmp.end(),false);
7380   DataArrayInt *ret=DataArrayInt::New();
7381   ret->alloc(nbOfRetVal,1);
7382   int j=0;
7383   int *retPtr=ret->getPointer();
7384   for(int i=0;i<nbOfElement;i++)
7385     if(!tmp[i])
7386       retPtr[j++]=i;
7387   return ret;
7388 }
7389
7390 /*!
7391  * Returns a new DataArrayInt containing elements of \a this one-dimensional missing
7392  * from an \a other one-dimensional array.
7393  *  \param [in] other - a DataArrayInt containing elements not to include in the result array.
7394  *  \return DataArrayInt * - a new instance of DataArrayInt with one component. The
7395  *         caller is to delete this array using decrRef() as it is no more needed.
7396  *  \throw If \a other is NULL.
7397  *  \throw If \a other is not allocated.
7398  *  \throw If \a other->getNumberOfComponents() != 1.
7399  *  \throw If \a this is not allocated.
7400  *  \throw If \a this->getNumberOfComponents() != 1.
7401  *  \sa DataArrayInt::buildSubstractionOptimized()
7402  */
7403 DataArrayInt *DataArrayInt::buildSubstraction(const DataArrayInt *other) const
7404 {
7405   if(!other)
7406     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : DataArrayInt pointer in input is NULL !");
7407   checkAllocated();
7408   other->checkAllocated();
7409   if(getNumberOfComponents()!=1)
7410     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed !");
7411   if(other->getNumberOfComponents()!=1)
7412     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed for other type !");
7413   const int *pt=getConstPointer();
7414   int nbOfTuples=getNumberOfTuples();
7415   std::set<int> s1(pt,pt+nbOfTuples);
7416   pt=other->getConstPointer();
7417   nbOfTuples=other->getNumberOfTuples();
7418   std::set<int> s2(pt,pt+nbOfTuples);
7419   std::vector<int> r;
7420   std::set_difference(s1.begin(),s1.end(),s2.begin(),s2.end(),std::back_insert_iterator< std::vector<int> >(r));
7421   DataArrayInt *ret=DataArrayInt::New();
7422   ret->alloc((int)r.size(),1);
7423   std::copy(r.begin(),r.end(),ret->getPointer());
7424   return ret;
7425 }
7426
7427 /*!
7428  * \a this is expected to have one component and to be sorted ascendingly (as for \a other).
7429  * \a other is expected to be a part of \a this. If not DataArrayInt::buildSubstraction should be called instead.
7430  * 
7431  * \param [in] other an array with one component and expected to be sorted ascendingly.
7432  * \ret list of ids in \a this but not in \a other.
7433  * \sa DataArrayInt::buildSubstraction
7434  */
7435 DataArrayInt *DataArrayInt::buildSubstractionOptimized(const DataArrayInt *other) const
7436 {
7437   static const char *MSG="DataArrayInt::buildSubstractionOptimized : only single component allowed !";
7438   if(!other) throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstractionOptimized : NULL input array !");
7439   checkAllocated(); other->checkAllocated();
7440   if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
7441   if(other->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
7442   const int *pt1Bg(begin()),*pt1End(end()),*pt2Bg(other->begin()),*pt2End(other->end());
7443   const int *work1(pt1Bg),*work2(pt2Bg);
7444   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
7445   for(;work1!=pt1End;work1++)
7446     {
7447       if(work2!=pt2End && *work1==*work2)
7448         work2++;
7449       else
7450         ret->pushBackSilent(*work1);
7451     }
7452   return ret.retn();
7453 }
7454
7455
7456 /*!
7457  * Returns a new DataArrayInt which contains all elements of \a this and a given
7458  * one-dimensional arrays. The result array does not contain any duplicates
7459  * and its values are sorted in ascending order.
7460  *  \param [in] other - an array to unite with \a this one.
7461  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7462  *         array using decrRef() as it is no more needed.
7463  *  \throw If \a this or \a other is not allocated.
7464  *  \throw If \a this->getNumberOfComponents() != 1.
7465  *  \throw If \a other->getNumberOfComponents() != 1.
7466  */
7467 DataArrayInt *DataArrayInt::buildUnion(const DataArrayInt *other) const
7468 {
7469   std::vector<const DataArrayInt *>arrs(2);
7470   arrs[0]=this; arrs[1]=other;
7471   return BuildUnion(arrs);
7472 }
7473
7474
7475 /*!
7476  * Returns a new DataArrayInt which contains elements present in both \a this and a given
7477  * one-dimensional arrays. The result array does not contain any duplicates
7478  * and its values are sorted in ascending order.
7479  *  \param [in] other - an array to intersect with \a this one.
7480  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7481  *         array using decrRef() as it is no more needed.
7482  *  \throw If \a this or \a other is not allocated.
7483  *  \throw If \a this->getNumberOfComponents() != 1.
7484  *  \throw If \a other->getNumberOfComponents() != 1.
7485  */
7486 DataArrayInt *DataArrayInt::buildIntersection(const DataArrayInt *other) const
7487 {
7488   std::vector<const DataArrayInt *>arrs(2);
7489   arrs[0]=this; arrs[1]=other;
7490   return BuildIntersection(arrs);
7491 }
7492
7493 /*!
7494  * This method can be applied on allocated with one component DataArrayInt instance.
7495  * This method is typically relevant for sorted arrays. All consecutive duplicated items in \a this will appear only once in returned DataArrayInt instance.
7496  * 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]
7497  * 
7498  * \return a newly allocated array that contain the result of the unique operation applied on \a this.
7499  * \throw if \a this is not allocated or if \a this has not exactly one component.
7500  * \sa DataArrayInt::buildUniqueNotSorted
7501  */
7502 DataArrayInt *DataArrayInt::buildUnique() const
7503 {
7504   checkAllocated();
7505   if(getNumberOfComponents()!=1)
7506     throw INTERP_KERNEL::Exception("DataArrayInt::buildUnique : only single component allowed !");
7507   int nbOfTuples=getNumberOfTuples();
7508   MCAuto<DataArrayInt> tmp=deepCopy();
7509   int *data=tmp->getPointer();
7510   int *last=std::unique(data,data+nbOfTuples);
7511   MCAuto<DataArrayInt> ret=DataArrayInt::New();
7512   ret->alloc(std::distance(data,last),1);
7513   std::copy(data,last,ret->getPointer());
7514   return ret.retn();
7515 }
7516
7517 /*!
7518  * This method can be applied on allocated with one component DataArrayInt instance.
7519  * This method keep elements only once by keeping the same order in \a this that is not expected to be sorted.
7520  *
7521  * \return a newly allocated array that contain the result of the unique operation applied on \a this.
7522  *
7523  * \throw if \a this is not allocated or if \a this has not exactly one component.
7524  *
7525  * \sa DataArrayInt::buildUnique
7526  */
7527 DataArrayInt *DataArrayInt::buildUniqueNotSorted() const
7528 {
7529   checkAllocated();
7530     if(getNumberOfComponents()!=1)
7531       throw INTERP_KERNEL::Exception("DataArrayInt::buildUniqueNotSorted : only single component allowed !");
7532   int minVal,maxVal;
7533   getMinMaxValues(minVal,maxVal);
7534   std::vector<bool> b(maxVal-minVal+1,false);
7535   const int *ptBg(begin()),*endBg(end());
7536   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
7537   for(const int *pt=ptBg;pt!=endBg;pt++)
7538     {
7539       if(!b[*pt-minVal])
7540         {
7541           ret->pushBackSilent(*pt);
7542           b[*pt-minVal]=true;
7543         }
7544     }
7545   ret->copyStringInfoFrom(*this);
7546   return ret.retn();
7547 }
7548
7549 /*!
7550  * Returns a new DataArrayInt which contains size of every of groups described by \a this
7551  * "index" array. Such "index" array is returned for example by 
7552  * \ref MEDCoupling::MEDCouplingUMesh::buildDescendingConnectivity
7553  * "MEDCouplingUMesh::buildDescendingConnectivity" and
7554  * \ref MEDCoupling::MEDCouplingUMesh::getNodalConnectivityIndex
7555  * "MEDCouplingUMesh::getNodalConnectivityIndex" etc.
7556  * This method preforms the reverse operation of DataArrayInt::computeOffsetsFull.
7557  *  \return DataArrayInt * - a new instance of DataArrayInt, whose number of tuples
7558  *          equals to \a this->getNumberOfComponents() - 1, and number of components is 1.
7559  *          The caller is to delete this array using decrRef() as it is no more needed. 
7560  *  \throw If \a this is not allocated.
7561  *  \throw If \a this->getNumberOfComponents() != 1.
7562  *  \throw If \a this->getNumberOfTuples() < 2.
7563  *
7564  *  \b Example: <br> 
7565  *         - this contains [1,3,6,7,7,9,15]
7566  *         - result array contains [2,3,1,0,2,6],
7567  *          where 2 = 3 - 1, 3 = 6 - 3, 1 = 7 - 6 etc.
7568  *
7569  * \sa DataArrayInt::computeOffsetsFull
7570  */
7571 DataArrayInt *DataArrayInt::deltaShiftIndex() const
7572 {
7573   checkAllocated();
7574   if(getNumberOfComponents()!=1)
7575     throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : only single component allowed !");
7576   int nbOfTuples=getNumberOfTuples();
7577   if(nbOfTuples<2)
7578     throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : 1 tuple at least must be present in 'this' !");
7579   const int *ptr=getConstPointer();
7580   DataArrayInt *ret=DataArrayInt::New();
7581   ret->alloc(nbOfTuples-1,1);
7582   int *out=ret->getPointer();
7583   std::transform(ptr+1,ptr+nbOfTuples,ptr,out,std::minus<int>());
7584   return ret;
7585 }
7586
7587 /*!
7588  * Modifies \a this one-dimensional array so that value of each element \a x
7589  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
7590  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number of tuples
7591  * and components remains the same.<br>
7592  * This method is useful for allToAllV in MPI with contiguous policy. This method
7593  * differs from computeOffsetsFull() in that the number of tuples is \b not changed by
7594  * this one.
7595  *  \throw If \a this is not allocated.
7596  *  \throw If \a this->getNumberOfComponents() != 1.
7597  *
7598  *  \b Example: <br>
7599  *          - Before \a this contains [3,5,1,2,0,8]
7600  *          - After \a this contains  [0,3,8,9,11,11]<br>
7601  *          Note that the last element 19 = 11 + 8 is missing because size of \a this
7602  *          array is retained and thus there is no space to store the last element.
7603  */
7604 void DataArrayInt::computeOffsets()
7605 {
7606   checkAllocated();
7607   if(getNumberOfComponents()!=1)
7608     throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets : only single component allowed !");
7609   int nbOfTuples=getNumberOfTuples();
7610   if(nbOfTuples==0)
7611     return ;
7612   int *work=getPointer();
7613   int tmp=work[0];
7614   work[0]=0;
7615   for(int i=1;i<nbOfTuples;i++)
7616     {
7617       int tmp2=work[i];
7618       work[i]=work[i-1]+tmp;
7619       tmp=tmp2;
7620     }
7621   declareAsNew();
7622 }
7623
7624
7625 /*!
7626  * Modifies \a this one-dimensional array so that value of each element \a x
7627  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
7628  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number
7629  * components remains the same and number of tuples is inceamented by one.<br>
7630  * This method is useful for allToAllV in MPI with contiguous policy. This method
7631  * differs from computeOffsets() in that the number of tuples is changed by this one.
7632  * This method preforms the reverse operation of DataArrayInt::deltaShiftIndex.
7633  *  \throw If \a this is not allocated.
7634  *  \throw If \a this->getNumberOfComponents() != 1.
7635  *
7636  *  \b Example: <br>
7637  *          - Before \a this contains [3,5,1,2,0,8]
7638  *          - After \a this contains  [0,3,8,9,11,11,19]<br>
7639  * \sa DataArrayInt::deltaShiftIndex
7640  */
7641 void DataArrayInt::computeOffsetsFull()
7642 {
7643   checkAllocated();
7644   if(getNumberOfComponents()!=1)
7645     throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsetsFull : only single component allowed !");
7646   int nbOfTuples=getNumberOfTuples();
7647   int *ret=(int *)malloc((nbOfTuples+1)*sizeof(int));
7648   const int *work=getConstPointer();
7649   ret[0]=0;
7650   for(int i=0;i<nbOfTuples;i++)
7651     ret[i+1]=work[i]+ret[i];
7652   useArray(ret,true,C_DEALLOC,nbOfTuples+1,1);
7653   declareAsNew();
7654 }
7655
7656 /*!
7657  * Returns two new DataArrayInt instances whose contents is computed from that of \a this and \a listOfIds arrays as follows.
7658  * \a this is expected to be an offset format ( as returned by DataArrayInt::computeOffsetsFull ) that is to say with one component
7659  * and ** sorted strictly increasingly **. \a listOfIds is expected to be sorted ascendingly (not strictly needed for \a listOfIds).
7660  * This methods searches in \a this, considered as a set of contiguous \c this->getNumberOfComponents() ranges, all ids in \a listOfIds
7661  * filling completely one of the ranges in \a this.
7662  *
7663  * \param [in] listOfIds a list of ids that has to be sorted ascendingly.
7664  * \param [out] rangeIdsFetched the range ids fetched
7665  * \param [out] idsInInputListThatFetch contains the list of ids in \a listOfIds that are \b fully included in a range in \a this. So
7666  *              \a idsInInputListThatFetch is a part of input \a listOfIds.
7667  *
7668  * \sa DataArrayInt::computeOffsetsFull
7669  *
7670  *  \b Example: <br>
7671  *          - \a this : [0,3,7,9,15,18]
7672  *          - \a listOfIds contains  [0,1,2,3,7,8,15,16,17]
7673  *          - \a rangeIdsFetched result array: [0,2,4]
7674  *          - \a idsInInputListThatFetch result array: [0,1,2,7,8,15,16,17]
7675  * In this example id 3 in input \a listOfIds is alone so it do not appear in output \a idsInInputListThatFetch.
7676  * <br>
7677  */
7678 void DataArrayInt::findIdsRangesInListOfIds(const DataArrayInt *listOfIds, DataArrayInt *& rangeIdsFetched, DataArrayInt *& idsInInputListThatFetch) const
7679 {
7680   if(!listOfIds)
7681     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : input list of ids is null !");
7682   listOfIds->checkAllocated(); checkAllocated();
7683   if(listOfIds->getNumberOfComponents()!=1)
7684     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : input list of ids must have exactly one component !");
7685   if(getNumberOfComponents()!=1)
7686     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : this must have exactly one component !");
7687   MCAuto<DataArrayInt> ret0=DataArrayInt::New(); ret0->alloc(0,1);
7688   MCAuto<DataArrayInt> ret1=DataArrayInt::New(); ret1->alloc(0,1);
7689   const int *tupEnd(listOfIds->end()),*offBg(begin()),*offEnd(end()-1);
7690   const int *tupPtr(listOfIds->begin()),*offPtr(offBg);
7691   while(tupPtr!=tupEnd && offPtr!=offEnd)
7692     {
7693       if(*tupPtr==*offPtr)
7694         {
7695           int i=offPtr[0];
7696           while(i<offPtr[1] && *tupPtr==i && tupPtr!=tupEnd) { i++; tupPtr++; }
7697           if(i==offPtr[1])
7698             {
7699               ret0->pushBackSilent((int)std::distance(offBg,offPtr));
7700               ret1->pushBackValsSilent(tupPtr-(offPtr[1]-offPtr[0]),tupPtr);
7701               offPtr++;
7702             }
7703         }
7704       else
7705         { if(*tupPtr<*offPtr) tupPtr++; else offPtr++; }
7706     }
7707   rangeIdsFetched=ret0.retn();
7708   idsInInputListThatFetch=ret1.retn();
7709 }
7710
7711 /*!
7712  * Returns a new DataArrayInt whose contents is computed from that of \a this and \a
7713  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
7714  * "index" array of a "iota" array, thus, whose each element gives an index of a group
7715  * beginning within the "iota" array. And \a this is a one-dimensional array
7716  * considered as a selector of groups described by \a offsets to include into the result array.
7717  *  \throw If \a offsets is NULL.
7718  *  \throw If \a offsets is not allocated.
7719  *  \throw If \a offsets->getNumberOfComponents() != 1.
7720  *  \throw If \a offsets is not monotonically increasing.
7721  *  \throw If \a this is not allocated.
7722  *  \throw If \a this->getNumberOfComponents() != 1.
7723  *  \throw If any element of \a this is not a valid index for \a offsets array.
7724  *
7725  *  \b Example: <br>
7726  *          - \a this: [0,2,3]
7727  *          - \a offsets: [0,3,6,10,14,20]
7728  *          - result array: [0,1,2,6,7,8,9,10,11,12,13] == <br>
7729  *            \c range(0,3) + \c range(6,10) + \c range(10,14) ==<br>
7730  *            \c range( \a offsets[ \a this[0] ], offsets[ \a this[0]+1 ]) + 
7731  *            \c range( \a offsets[ \a this[1] ], offsets[ \a this[1]+1 ]) + 
7732  *            \c range( \a offsets[ \a this[2] ], offsets[ \a this[2]+1 ])
7733  */
7734 DataArrayInt *DataArrayInt::buildExplicitArrByRanges(const DataArrayInt *offsets) const
7735 {
7736   if(!offsets)
7737     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : DataArrayInt pointer in input is NULL !");
7738   checkAllocated();
7739   if(getNumberOfComponents()!=1)
7740     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : only single component allowed !");
7741   offsets->checkAllocated();
7742   if(offsets->getNumberOfComponents()!=1)
7743     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : input array should have only single component !");
7744   int othNbTuples=offsets->getNumberOfTuples()-1;
7745   int nbOfTuples=getNumberOfTuples();
7746   int retNbOftuples=0;
7747   const int *work=getConstPointer();
7748   const int *offPtr=offsets->getConstPointer();
7749   for(int i=0;i<nbOfTuples;i++)
7750     {
7751       int val=work[i];
7752       if(val>=0 && val<othNbTuples)
7753         {
7754           int delta=offPtr[val+1]-offPtr[val];
7755           if(delta>=0)
7756             retNbOftuples+=delta;
7757           else
7758             {
7759               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << val << " of offset array has a delta < 0 !";
7760               throw INTERP_KERNEL::Exception(oss.str().c_str());
7761             }
7762         }
7763       else
7764         {
7765           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << i << " in this contains " << val;
7766           oss << " whereas offsets array is of size " << othNbTuples+1 << " !";
7767           throw INTERP_KERNEL::Exception(oss.str().c_str());
7768         }
7769     }
7770   MCAuto<DataArrayInt> ret=DataArrayInt::New();
7771   ret->alloc(retNbOftuples,1);
7772   int *retPtr=ret->getPointer();
7773   for(int i=0;i<nbOfTuples;i++)
7774     {
7775       int val=work[i];
7776       int start=offPtr[val];
7777       int off=offPtr[val+1]-start;
7778       for(int j=0;j<off;j++,retPtr++)
7779         *retPtr=start+j;
7780     }
7781   return ret.retn();
7782 }
7783
7784 /*!
7785  * Returns a new DataArrayInt whose contents is computed using \a this that must be a 
7786  * scaled array (monotonically increasing).
7787 from that of \a this and \a
7788  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
7789  * "index" array of a "iota" array, thus, whose each element gives an index of a group
7790  * beginning within the "iota" array. And \a this is a one-dimensional array
7791  * considered as a selector of groups described by \a offsets to include into the result array.
7792  *  \throw If \a  is NULL.
7793  *  \throw If \a this is not allocated.
7794  *  \throw If \a this->getNumberOfComponents() != 1.
7795  *  \throw If \a this->getNumberOfTuples() == 0.
7796  *  \throw If \a this is not monotonically increasing.
7797  *  \throw If any element of ids in ( \a bg \a stop \a step ) points outside the scale in \a this.
7798  *
7799  *  \b Example: <br>
7800  *          - \a bg , \a stop and \a step : (0,5,2)
7801  *          - \a this: [0,3,6,10,14,20]
7802  *          - result array: [0,0,0, 2,2,2,2, 4,4,4,4,4,4] == <br>
7803  */
7804 DataArrayInt *DataArrayInt::buildExplicitArrOfSliceOnScaledArr(int bg, int stop, int step) const
7805 {
7806   if(!isAllocated())
7807     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : not allocated array !");
7808   if(getNumberOfComponents()!=1)
7809     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of components is expected to be equal to one !");
7810   int nbOfTuples(getNumberOfTuples());
7811   if(nbOfTuples==0)
7812     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of tuples must be != 0 !");
7813   const int *ids(begin());
7814   int nbOfEltsInSlc(GetNumberOfItemGivenBESRelative(bg,stop,step,"DataArrayInt::buildExplicitArrOfSliceOnScaledArr")),sz(0),pos(bg);
7815   for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
7816     {
7817       if(pos>=0 && pos<nbOfTuples-1)
7818         {
7819           int delta(ids[pos+1]-ids[pos]);
7820           sz+=delta;
7821           if(delta<0)
7822             {
7823               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " and at this pos this is not monotonically increasing !";
7824               throw INTERP_KERNEL::Exception(oss.str().c_str());
7825             }          
7826         }
7827       else
7828         {
7829           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " should be in [0," << nbOfTuples-1 << ") !";  
7830           throw INTERP_KERNEL::Exception(oss.str().c_str());
7831         }
7832     }
7833   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
7834   int *retPtr(ret->getPointer());
7835   pos=bg;
7836   for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
7837     {
7838       int delta(ids[pos+1]-ids[pos]);
7839       for(int j=0;j<delta;j++,retPtr++)
7840         *retPtr=pos;
7841     }
7842   return ret.retn();
7843 }
7844
7845 /*!
7846  * 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.
7847  * 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
7848  * in tuple **i** of returned DataArrayInt.
7849  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the first range.
7850  *
7851  * 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)]
7852  * The return DataArrayInt will contain : **[0,4,1,2,2,3]**
7853  * 
7854  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
7855  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
7856  * \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
7857  *        is thrown if no ranges in \a ranges contains value in \a this.
7858  * 
7859  * \sa DataArrayInt::findIdInRangeForEachTuple
7860  */
7861 DataArrayInt *DataArrayInt::findRangeIdForEachTuple(const DataArrayInt *ranges) const
7862 {
7863   if(!ranges)
7864     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : null input pointer !");
7865   if(ranges->getNumberOfComponents()!=2)
7866     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : input DataArrayInt instance should have 2 components !");
7867   checkAllocated();
7868   if(getNumberOfComponents()!=1)
7869     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : this should have only one component !");
7870   int nbTuples=getNumberOfTuples();
7871   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
7872   int nbOfRanges=ranges->getNumberOfTuples();
7873   const int *rangesPtr=ranges->getConstPointer();
7874   int *retPtr=ret->getPointer();
7875   const int *inPtr=getConstPointer();
7876   for(int i=0;i<nbTuples;i++,retPtr++)
7877     {
7878       int val=inPtr[i];
7879       bool found=false;
7880       for(int j=0;j<nbOfRanges && !found;j++)
7881         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
7882           { *retPtr=j; found=true; }
7883       if(found)
7884         continue;
7885       else
7886         {
7887           std::ostringstream oss; oss << "DataArrayInt::findRangeIdForEachTuple : tuple #" << i << " not found by any ranges !";
7888           throw INTERP_KERNEL::Exception(oss.str().c_str());
7889         }
7890     }
7891   return ret.retn();
7892 }
7893
7894 /*!
7895  * 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.
7896  * 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
7897  * in tuple **i** of returned DataArrayInt.
7898  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the sub position of the first range.
7899  *
7900  * 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)]
7901  * The return DataArrayInt will contain : **[1,2,4,0,2,2]**
7902  * This method is often called in pair with DataArrayInt::findRangeIdForEachTuple method.
7903  * 
7904  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
7905  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
7906  * \throw If offsets is a null pointer or does not have 2 components or if \a this is not allocated or \a this do not have exactly one component. To finish an exception
7907  *        is thrown if no ranges in \a ranges contains value in \a this.
7908  * \sa DataArrayInt::findRangeIdForEachTuple
7909  */
7910 DataArrayInt *DataArrayInt::findIdInRangeForEachTuple(const DataArrayInt *ranges) const
7911 {
7912   if(!ranges)
7913     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : null input pointer !");
7914   if(ranges->getNumberOfComponents()!=2)
7915     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : input DataArrayInt instance should have 2 components !");
7916   checkAllocated();
7917   if(getNumberOfComponents()!=1)
7918     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : this should have only one component !");
7919   int nbTuples=getNumberOfTuples();
7920   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
7921   int nbOfRanges=ranges->getNumberOfTuples();
7922   const int *rangesPtr=ranges->getConstPointer();
7923   int *retPtr=ret->getPointer();
7924   const int *inPtr=getConstPointer();
7925   for(int i=0;i<nbTuples;i++,retPtr++)
7926     {
7927       int val=inPtr[i];
7928       bool found=false;
7929       for(int j=0;j<nbOfRanges && !found;j++)
7930         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
7931           { *retPtr=val-rangesPtr[2*j]; found=true; }
7932       if(found)
7933         continue;
7934       else
7935         {
7936           std::ostringstream oss; oss << "DataArrayInt::findIdInRangeForEachTuple : tuple #" << i << " not found by any ranges !";
7937           throw INTERP_KERNEL::Exception(oss.str().c_str());
7938         }
7939     }
7940   return ret.retn();
7941 }
7942
7943 /*!
7944  * \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).
7945  * 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).
7946  * 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 !
7947  * If this method has correctly worked, \a this will be able to be considered as a linked list.
7948  * This method does nothing if number of tuples is lower of equal to 1.
7949  *
7950  * This method is useful for users having an unstructured mesh having only SEG2 to rearrange internaly the connectibity without any coordinates consideration.
7951  *
7952  * \sa MEDCouplingUMesh::orderConsecutiveCells1D, DataArrayInt::fromLinkedListOfPairToList
7953  */
7954 void DataArrayInt::sortEachPairToMakeALinkedList()
7955 {
7956   checkAllocated();
7957   if(getNumberOfComponents()!=2)
7958     throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : Only works on DataArrayInt instance with nb of components equal to 2 !");
7959   int nbOfTuples(getNumberOfTuples());
7960   if(nbOfTuples<=1)
7961     return ;
7962   int *conn(getPointer());
7963   for(int i=1;i<nbOfTuples;i++,conn+=2)
7964     {
7965       if(i>1)
7966         {
7967           if(conn[2]==conn[3])
7968             {
7969               std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " presence of a pair filled with same ids !";
7970               throw INTERP_KERNEL::Exception(oss.str().c_str());
7971             }
7972           if(conn[2]!=conn[1] && conn[3]==conn[1] && conn[2]!=conn[0])
7973             std::swap(conn[2],conn[3]);
7974           //not(conn[2]==conn[1] && conn[3]!=conn[1] && conn[3]!=conn[0])
7975           if(conn[2]!=conn[1] || conn[3]==conn[1] || conn[3]==conn[0])
7976             {
7977               std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " something is invalid !";
7978               throw INTERP_KERNEL::Exception(oss.str().c_str());
7979             }
7980         }
7981       else
7982         {
7983           if(conn[0]==conn[1] || conn[2]==conn[3])
7984             throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : In the 2 first tuples presence of a pair filled with same ids !");
7985           int tmp[4];
7986           std::set<int> s;
7987           s.insert(conn,conn+4);
7988           if(s.size()!=3)
7989             throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : This can't be considered as a linked list regarding 2 first tuples !");
7990           if(std::count(conn,conn+4,conn[0])==2)
7991             {
7992               tmp[0]=conn[1];
7993               tmp[1]=conn[0];
7994               tmp[2]=conn[0];
7995               if(conn[2]==conn[0])
7996                 { tmp[3]=conn[3]; }
7997               else
7998                 { tmp[3]=conn[2];}
7999               std::copy(tmp,tmp+4,conn);
8000             }
8001           else
8002             {//here we are sure to have (std::count(conn,conn+4,conn[1])==2)
8003               if(conn[1]==conn[3])
8004                 std::swap(conn[2],conn[3]);
8005             }
8006         }
8007     }
8008 }
8009
8010 /*!
8011  * \a this is expected to be a correctly linked list of pairs.
8012  * 
8013  * \sa DataArrayInt::sortEachPairToMakeALinkedList
8014  */
8015 MCAuto<DataArrayInt> DataArrayInt::fromLinkedListOfPairToList() const
8016 {
8017   checkAllocated();
8018   checkNbOfComps(2,"DataArrayInt::fromLinkedListOfPairToList : this is expected to have 2 components");
8019   int nbTuples(getNumberOfTuples());
8020   if(nbTuples<1)
8021     throw INTERP_KERNEL::Exception("DataArrayInt::fromLinkedListOfPairToList : no tuples in this ! Not a linked list !");
8022   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbTuples+1,1);
8023   const int *thisPtr(begin());
8024   int *retPtr(ret->getPointer());
8025   retPtr[0]=thisPtr[0];
8026   for(int i=0;i<nbTuples;i++)
8027     {
8028       retPtr[i+1]=thisPtr[2*i+1];
8029       if(i<nbTuples-1)
8030         if(thisPtr[2*i+1]!=thisPtr[2*(i+1)+0])
8031           {
8032             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 ?";
8033             throw INTERP_KERNEL::Exception(oss.str());
8034           }
8035     }
8036   return ret;
8037 }
8038
8039 /*!
8040  * 
8041  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayInt instance.
8042  *             \a nbTimes  should be at least equal to 1.
8043  * \return a newly allocated DataArrayInt having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
8044  * \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.
8045  */
8046 DataArrayInt *DataArrayInt::duplicateEachTupleNTimes(int nbTimes) const
8047 {
8048   checkAllocated();
8049   if(getNumberOfComponents()!=1)
8050     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : this should have only one component !");
8051   if(nbTimes<1)
8052     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : nb times should be >= 1 !");
8053   int nbTuples=getNumberOfTuples();
8054   const int *inPtr=getConstPointer();
8055   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTimes*nbTuples,1);
8056   int *retPtr=ret->getPointer();
8057   for(int i=0;i<nbTuples;i++,inPtr++)
8058     {
8059       int val=*inPtr;
8060       for(int j=0;j<nbTimes;j++,retPtr++)
8061         *retPtr=val;
8062     }
8063   ret->copyStringInfoFrom(*this);
8064   return ret.retn();
8065 }
8066
8067 /*!
8068  * This method returns all different values found in \a this. This method throws if \a this has not been allocated.
8069  * But the number of components can be different from one.
8070  * \return a newly allocated array (that should be dealt by the caller) containing different values in \a this.
8071  */
8072 DataArrayInt *DataArrayInt::getDifferentValues() const
8073 {
8074   checkAllocated();
8075   std::set<int> ret;
8076   ret.insert(begin(),end());
8077   MCAuto<DataArrayInt> ret2=DataArrayInt::New(); ret2->alloc((int)ret.size(),1);
8078   std::copy(ret.begin(),ret.end(),ret2->getPointer());
8079   return ret2.retn();
8080 }
8081
8082 /*!
8083  * This method is a refinement of DataArrayInt::getDifferentValues because it returns not only different values in \a this but also, for each of
8084  * them it tells which tuple id have this id.
8085  * This method works only on arrays with one component (if it is not the case call DataArrayInt::rearrange(1) ).
8086  * This method returns two arrays having same size.
8087  * 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.
8088  * 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]]
8089  */
8090 std::vector<DataArrayInt *> DataArrayInt::partitionByDifferentValues(std::vector<int>& differentIds) const
8091 {
8092   checkAllocated();
8093   if(getNumberOfComponents()!=1)
8094     throw INTERP_KERNEL::Exception("DataArrayInt::partitionByDifferentValues : this should have only one component !");
8095   int id=0;
8096   std::map<int,int> m,m2,m3;
8097   for(const int *w=begin();w!=end();w++)
8098     m[*w]++;
8099   differentIds.resize(m.size());
8100   std::vector<DataArrayInt *> ret(m.size());
8101   std::vector<int *> retPtr(m.size());
8102   for(std::map<int,int>::const_iterator it=m.begin();it!=m.end();it++,id++)
8103     {
8104       m2[(*it).first]=id;
8105       ret[id]=DataArrayInt::New();
8106       ret[id]->alloc((*it).second,1);
8107       retPtr[id]=ret[id]->getPointer();
8108       differentIds[id]=(*it).first;
8109     }
8110   id=0;
8111   for(const int *w=begin();w!=end();w++,id++)
8112     {
8113       retPtr[m2[*w]][m3[*w]++]=id;
8114     }
8115   return ret;
8116 }
8117
8118 /*!
8119  * This method split ids in [0, \c this->getNumberOfTuples() ) using \a this array as a field of weight (>=0 each).
8120  * The aim of this method is to return a set of \a nbOfSlices chunk of contiguous ids as balanced as possible.
8121  *
8122  * \param [in] nbOfSlices - number of slices expected.
8123  * \return - a vector having a size equal to \a nbOfSlices giving the start (included) and the stop (excluded) of each chunks.
8124  * 
8125  * \sa DataArray::GetSlice
8126  * \throw If \a this is not allocated or not with exactly one component.
8127  * \throw If an element in \a this if < 0.
8128  */
8129 std::vector< std::pair<int,int> > DataArrayInt::splitInBalancedSlices(int nbOfSlices) const
8130 {
8131   if(!isAllocated() || getNumberOfComponents()!=1)
8132     throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : this array should have number of components equal to one and must be allocated !");
8133   if(nbOfSlices<=0)
8134     throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : number of slices must be >= 1 !");
8135   int sum(accumulate(0)),nbOfTuples(getNumberOfTuples());
8136   int sumPerSlc(sum/nbOfSlices),pos(0);
8137   const int *w(begin());
8138   std::vector< std::pair<int,int> > ret(nbOfSlices);
8139   for(int i=0;i<nbOfSlices;i++)
8140     {
8141       std::pair<int,int> p(pos,-1);
8142       int locSum(0);
8143       while(locSum<sumPerSlc && pos<nbOfTuples) { pos++; locSum+=*w++; }
8144       if(i!=nbOfSlices-1)
8145         p.second=pos;
8146       else
8147         p.second=nbOfTuples;
8148       ret[i]=p;
8149     }
8150   return ret;
8151 }
8152
8153 /*!
8154  * Returns a new DataArrayInt that is a sum of two given arrays. There are 3
8155  * valid cases.
8156  * 1.  The arrays have same number of tuples and components. Then each value of
8157  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
8158  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
8159  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
8160  *   component. Then
8161  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
8162  * 3.  The arrays have same number of components and one array, say _a2_, has one
8163  *   tuple. Then
8164  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
8165  *
8166  * Info on components is copied either from the first array (in the first case) or from
8167  * the array with maximal number of elements (getNbOfElems()).
8168  *  \param [in] a1 - an array to sum up.
8169  *  \param [in] a2 - another array to sum up.
8170  *  \return DataArrayInt * - the new instance of DataArrayInt.
8171  *          The caller is to delete this result array using decrRef() as it is no more
8172  *          needed.
8173  *  \throw If either \a a1 or \a a2 is NULL.
8174  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
8175  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
8176  *         none of them has number of tuples or components equal to 1.
8177  */
8178 DataArrayInt *DataArrayInt::Add(const DataArrayInt *a1, const DataArrayInt *a2)
8179 {
8180   if(!a1 || !a2)
8181     throw INTERP_KERNEL::Exception("DataArrayInt::Add : input DataArrayInt instance is NULL !");
8182   int nbOfTuple=a1->getNumberOfTuples();
8183   int nbOfTuple2=a2->getNumberOfTuples();
8184   int nbOfComp=a1->getNumberOfComponents();
8185   int nbOfComp2=a2->getNumberOfComponents();
8186   MCAuto<DataArrayInt> ret=0;
8187   if(nbOfTuple==nbOfTuple2)
8188     {
8189       if(nbOfComp==nbOfComp2)
8190         {
8191           ret=DataArrayInt::New();
8192           ret->alloc(nbOfTuple,nbOfComp);
8193           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<int>());
8194           ret->copyStringInfoFrom(*a1);
8195         }
8196       else
8197         {
8198           int nbOfCompMin,nbOfCompMax;
8199           const DataArrayInt *aMin, *aMax;
8200           if(nbOfComp>nbOfComp2)
8201             {
8202               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
8203               aMin=a2; aMax=a1;
8204             }
8205           else
8206             {
8207               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
8208               aMin=a1; aMax=a2;
8209             }
8210           if(nbOfCompMin==1)
8211             {
8212               ret=DataArrayInt::New();
8213               ret->alloc(nbOfTuple,nbOfCompMax);
8214               const int *aMinPtr=aMin->getConstPointer();
8215               const int *aMaxPtr=aMax->getConstPointer();
8216               int *res=ret->getPointer();
8217               for(int i=0;i<nbOfTuple;i++)
8218                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<int>(),aMinPtr[i]));
8219               ret->copyStringInfoFrom(*aMax);
8220             }
8221           else
8222             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
8223         }
8224     }
8225   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
8226     {
8227       if(nbOfComp==nbOfComp2)
8228         {
8229           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
8230           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
8231           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
8232           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
8233           ret=DataArrayInt::New();
8234           ret->alloc(nbOfTupleMax,nbOfComp);
8235           int *res=ret->getPointer();
8236           for(int i=0;i<nbOfTupleMax;i++)
8237             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<int>());
8238           ret->copyStringInfoFrom(*aMax);
8239         }
8240       else
8241         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
8242     }
8243   else
8244     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
8245   return ret.retn();
8246 }
8247
8248 /*!
8249  * Adds values of another DataArrayInt to values of \a this one. There are 3
8250  * valid cases.
8251  * 1.  The arrays have same number of tuples and components. Then each value of
8252  *   \a other array is added to the corresponding value of \a this array, i.e.:
8253  *   _a_ [ i, j ] += _other_ [ i, j ].
8254  * 2.  The arrays have same number of tuples and \a other array has one component. Then
8255  *   _a_ [ i, j ] += _other_ [ i, 0 ].
8256  * 3.  The arrays have same number of components and \a other array has one tuple. Then
8257  *   _a_ [ i, j ] += _a2_ [ 0, j ].
8258  *
8259  *  \param [in] other - an array to add to \a this one.
8260  *  \throw If \a other is NULL.
8261  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
8262  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
8263  *         \a other has number of both tuples and components not equal to 1.
8264  */
8265 void DataArrayInt::addEqual(const DataArrayInt *other)
8266 {
8267   if(!other)
8268     throw INTERP_KERNEL::Exception("DataArrayInt::addEqual : input DataArrayInt instance is NULL !");
8269   const char *msg="Nb of tuples mismatch for DataArrayInt::addEqual  !";
8270   checkAllocated(); other->checkAllocated();
8271   int nbOfTuple=getNumberOfTuples();
8272   int nbOfTuple2=other->getNumberOfTuples();
8273   int nbOfComp=getNumberOfComponents();
8274   int nbOfComp2=other->getNumberOfComponents();
8275   if(nbOfTuple==nbOfTuple2)
8276     {
8277       if(nbOfComp==nbOfComp2)
8278         {
8279           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<int>());
8280         }
8281       else if(nbOfComp2==1)
8282         {
8283           int *ptr=getPointer();
8284           const int *ptrc=other->getConstPointer();
8285           for(int i=0;i<nbOfTuple;i++)
8286             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<int>(),*ptrc++));
8287         }
8288       else
8289         throw INTERP_KERNEL::Exception(msg);
8290     }
8291   else if(nbOfTuple2==1)
8292     {
8293       if(nbOfComp2==nbOfComp)
8294         {
8295           int *ptr=getPointer();
8296           const int *ptrc=other->getConstPointer();
8297           for(int i=0;i<nbOfTuple;i++)
8298             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<int>());
8299         }
8300       else
8301         throw INTERP_KERNEL::Exception(msg);
8302     }
8303   else
8304     throw INTERP_KERNEL::Exception(msg);
8305   declareAsNew();
8306 }
8307
8308 /*!
8309  * Returns a new DataArrayInt that is a subtraction of two given arrays. There are 3
8310  * valid cases.
8311  * 1.  The arrays have same number of tuples and components. Then each value of
8312  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
8313  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
8314  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
8315  *   component. Then
8316  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
8317  * 3.  The arrays have same number of components and one array, say _a2_, has one
8318  *   tuple. Then
8319  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
8320  *
8321  * Info on components is copied either from the first array (in the first case) or from
8322  * the array with maximal number of elements (getNbOfElems()).
8323  *  \param [in] a1 - an array to subtract from.
8324  *  \param [in] a2 - an array to subtract.
8325  *  \return DataArrayInt * - the new instance of DataArrayInt.
8326  *          The caller is to delete this result array using decrRef() as it is no more
8327  *          needed.
8328  *  \throw If either \a a1 or \a a2 is NULL.
8329  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
8330  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
8331  *         none of them has number of tuples or components equal to 1.
8332  */
8333 DataArrayInt *DataArrayInt::Substract(const DataArrayInt *a1, const DataArrayInt *a2)
8334 {
8335   if(!a1 || !a2)
8336     throw INTERP_KERNEL::Exception("DataArrayInt::Substract : input DataArrayInt instance is NULL !");
8337   int nbOfTuple1=a1->getNumberOfTuples();
8338   int nbOfTuple2=a2->getNumberOfTuples();
8339   int nbOfComp1=a1->getNumberOfComponents();
8340   int nbOfComp2=a2->getNumberOfComponents();
8341   if(nbOfTuple2==nbOfTuple1)
8342     {
8343       if(nbOfComp1==nbOfComp2)
8344         {
8345           MCAuto<DataArrayInt> ret=DataArrayInt::New();
8346           ret->alloc(nbOfTuple2,nbOfComp1);
8347           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<int>());
8348           ret->copyStringInfoFrom(*a1);
8349           return ret.retn();
8350         }
8351       else if(nbOfComp2==1)
8352         {
8353           MCAuto<DataArrayInt> ret=DataArrayInt::New();
8354           ret->alloc(nbOfTuple1,nbOfComp1);
8355           const int *a2Ptr=a2->getConstPointer();
8356           const int *a1Ptr=a1->getConstPointer();
8357           int *res=ret->getPointer();
8358           for(int i=0;i<nbOfTuple1;i++)
8359             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<int>(),a2Ptr[i]));
8360           ret->copyStringInfoFrom(*a1);
8361           return ret.retn();
8362         }
8363       else
8364         {
8365           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
8366           return 0;
8367         }
8368     }
8369   else if(nbOfTuple2==1)
8370     {
8371       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
8372       MCAuto<DataArrayInt> ret=DataArrayInt::New();
8373       ret->alloc(nbOfTuple1,nbOfComp1);
8374       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
8375       int *pt=ret->getPointer();
8376       for(int i=0;i<nbOfTuple1;i++)
8377         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<int>());
8378       ret->copyStringInfoFrom(*a1);
8379       return ret.retn();
8380     }
8381   else
8382     {
8383       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
8384       return 0;
8385     }
8386 }
8387
8388 /*!
8389  * Subtract values of another DataArrayInt from values of \a this one. There are 3
8390  * valid cases.
8391  * 1.  The arrays have same number of tuples and components. Then each value of
8392  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
8393  *   _a_ [ i, j ] -= _other_ [ i, j ].
8394  * 2.  The arrays have same number of tuples and \a other array has one component. Then
8395  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
8396  * 3.  The arrays have same number of components and \a other array has one tuple. Then
8397  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
8398  *
8399  *  \param [in] other - an array to subtract from \a this one.
8400  *  \throw If \a other is NULL.
8401  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
8402  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
8403  *         \a other has number of both tuples and components not equal to 1.
8404  */
8405 void DataArrayInt::substractEqual(const DataArrayInt *other)
8406 {
8407   if(!other)
8408     throw INTERP_KERNEL::Exception("DataArrayInt::substractEqual : input DataArrayInt instance is NULL !");
8409   const char *msg="Nb of tuples mismatch for DataArrayInt::substractEqual  !";
8410   checkAllocated(); other->checkAllocated();
8411   int nbOfTuple=getNumberOfTuples();
8412   int nbOfTuple2=other->getNumberOfTuples();
8413   int nbOfComp=getNumberOfComponents();
8414   int nbOfComp2=other->getNumberOfComponents();
8415   if(nbOfTuple==nbOfTuple2)
8416     {
8417       if(nbOfComp==nbOfComp2)
8418         {
8419           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<int>());
8420         }
8421       else if(nbOfComp2==1)
8422         {
8423           int *ptr=getPointer();
8424           const int *ptrc=other->getConstPointer();
8425           for(int i=0;i<nbOfTuple;i++)
8426             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<int>(),*ptrc++));
8427         }
8428       else
8429         throw INTERP_KERNEL::Exception(msg);
8430     }
8431   else if(nbOfTuple2==1)
8432     {
8433       int *ptr=getPointer();
8434       const int *ptrc=other->getConstPointer();
8435       for(int i=0;i<nbOfTuple;i++)
8436         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<int>());
8437     }
8438   else
8439     throw INTERP_KERNEL::Exception(msg);
8440   declareAsNew();
8441 }
8442
8443 /*!
8444  * Returns a new DataArrayInt that is a product of two given arrays. There are 3
8445  * valid cases.
8446  * 1.  The arrays have same number of tuples and components. Then each value of
8447  *   the result array (_a_) is a product of the corresponding values of \a a1 and
8448  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
8449  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
8450  *   component. Then
8451  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
8452  * 3.  The arrays have same number of components and one array, say _a2_, has one
8453  *   tuple. Then
8454  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
8455  *
8456  * Info on components is copied either from the first array (in the first case) or from
8457  * the array with maximal number of elements (getNbOfElems()).
8458  *  \param [in] a1 - a factor array.
8459  *  \param [in] a2 - another factor array.
8460  *  \return DataArrayInt * - the new instance of DataArrayInt.
8461  *          The caller is to delete this result array using decrRef() as it is no more
8462  *          needed.
8463  *  \throw If either \a a1 or \a a2 is NULL.
8464  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
8465  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
8466  *         none of them has number of tuples or components equal to 1.
8467  */
8468 DataArrayInt *DataArrayInt::Multiply(const DataArrayInt *a1, const DataArrayInt *a2)
8469 {
8470   if(!a1 || !a2)
8471     throw INTERP_KERNEL::Exception("DataArrayInt::Multiply : input DataArrayInt instance is NULL !");
8472   int nbOfTuple=a1->getNumberOfTuples();
8473   int nbOfTuple2=a2->getNumberOfTuples();
8474   int nbOfComp=a1->getNumberOfComponents();
8475   int nbOfComp2=a2->getNumberOfComponents();
8476   MCAuto<DataArrayInt> ret=0;
8477   if(nbOfTuple==nbOfTuple2)
8478     {
8479       if(nbOfComp==nbOfComp2)
8480         {
8481           ret=DataArrayInt::New();
8482           ret->alloc(nbOfTuple,nbOfComp);
8483           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<int>());
8484           ret->copyStringInfoFrom(*a1);
8485         }
8486       else
8487         {
8488           int nbOfCompMin,nbOfCompMax;
8489           const DataArrayInt *aMin, *aMax;
8490           if(nbOfComp>nbOfComp2)
8491             {
8492               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
8493               aMin=a2; aMax=a1;
8494             }
8495           else
8496             {
8497               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
8498               aMin=a1; aMax=a2;
8499             }
8500           if(nbOfCompMin==1)
8501             {
8502               ret=DataArrayInt::New();
8503               ret->alloc(nbOfTuple,nbOfCompMax);
8504               const int *aMinPtr=aMin->getConstPointer();
8505               const int *aMaxPtr=aMax->getConstPointer();
8506               int *res=ret->getPointer();
8507               for(int i=0;i<nbOfTuple;i++)
8508                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<int>(),aMinPtr[i]));
8509               ret->copyStringInfoFrom(*aMax);
8510             }
8511           else
8512             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
8513         }
8514     }
8515   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
8516     {
8517       if(nbOfComp==nbOfComp2)
8518         {
8519           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
8520           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
8521           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
8522           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
8523           ret=DataArrayInt::New();
8524           ret->alloc(nbOfTupleMax,nbOfComp);
8525           int *res=ret->getPointer();
8526           for(int i=0;i<nbOfTupleMax;i++)
8527             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<int>());
8528           ret->copyStringInfoFrom(*aMax);
8529         }
8530       else
8531         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
8532     }
8533   else
8534     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
8535   return ret.retn();
8536 }
8537
8538
8539 /*!
8540  * Multiply values of another DataArrayInt to values of \a this one. There are 3
8541  * valid cases.
8542  * 1.  The arrays have same number of tuples and components. Then each value of
8543  *   \a other array is multiplied to the corresponding value of \a this array, i.e.:
8544  *   _a_ [ i, j ] *= _other_ [ i, j ].
8545  * 2.  The arrays have same number of tuples and \a other array has one component. Then
8546  *   _a_ [ i, j ] *= _other_ [ i, 0 ].
8547  * 3.  The arrays have same number of components and \a other array has one tuple. Then
8548  *   _a_ [ i, j ] *= _a2_ [ 0, j ].
8549  *
8550  *  \param [in] other - an array to multiply to \a this one.
8551  *  \throw If \a other is NULL.
8552  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
8553  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
8554  *         \a other has number of both tuples and components not equal to 1.
8555  */
8556 void DataArrayInt::multiplyEqual(const DataArrayInt *other)
8557 {
8558   if(!other)
8559     throw INTERP_KERNEL::Exception("DataArrayInt::multiplyEqual : input DataArrayInt instance is NULL !");
8560   const char *msg="Nb of tuples mismatch for DataArrayInt::multiplyEqual !";
8561   checkAllocated(); other->checkAllocated();
8562   int nbOfTuple=getNumberOfTuples();
8563   int nbOfTuple2=other->getNumberOfTuples();
8564   int nbOfComp=getNumberOfComponents();
8565   int nbOfComp2=other->getNumberOfComponents();
8566   if(nbOfTuple==nbOfTuple2)
8567     {
8568       if(nbOfComp==nbOfComp2)
8569         {
8570           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<int>());
8571         }
8572       else if(nbOfComp2==1)
8573         {
8574           int *ptr=getPointer();
8575           const int *ptrc=other->getConstPointer();
8576           for(int i=0;i<nbOfTuple;i++)
8577             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<int>(),*ptrc++));    
8578         }
8579       else
8580         throw INTERP_KERNEL::Exception(msg);
8581     }
8582   else if(nbOfTuple2==1)
8583     {
8584       if(nbOfComp2==nbOfComp)
8585         {
8586           int *ptr=getPointer();
8587           const int *ptrc=other->getConstPointer();
8588           for(int i=0;i<nbOfTuple;i++)
8589             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<int>());
8590         }
8591       else
8592         throw INTERP_KERNEL::Exception(msg);
8593     }
8594   else
8595     throw INTERP_KERNEL::Exception(msg);
8596   declareAsNew();
8597 }
8598
8599
8600 /*!
8601  * Returns a new DataArrayInt that is a division of two given arrays. There are 3
8602  * valid cases.
8603  * 1.  The arrays have same number of tuples and components. Then each value of
8604  *   the result array (_a_) is a division of the corresponding values of \a a1 and
8605  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
8606  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
8607  *   component. Then
8608  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
8609  * 3.  The arrays have same number of components and one array, say _a2_, has one
8610  *   tuple. Then
8611  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
8612  *
8613  * Info on components is copied either from the first array (in the first case) or from
8614  * the array with maximal number of elements (getNbOfElems()).
8615  *  \warning No check of division by zero is performed!
8616  *  \param [in] a1 - a numerator array.
8617  *  \param [in] a2 - a denominator array.
8618  *  \return DataArrayInt * - the new instance of DataArrayInt.
8619  *          The caller is to delete this result array using decrRef() as it is no more
8620  *          needed.
8621  *  \throw If either \a a1 or \a a2 is NULL.
8622  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
8623  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
8624  *         none of them has number of tuples or components equal to 1.
8625  */
8626 DataArrayInt *DataArrayInt::Divide(const DataArrayInt *a1, const DataArrayInt *a2)
8627 {
8628   if(!a1 || !a2)
8629     throw INTERP_KERNEL::Exception("DataArrayInt::Divide : input DataArrayInt instance is NULL !");
8630   int nbOfTuple1=a1->getNumberOfTuples();
8631   int nbOfTuple2=a2->getNumberOfTuples();
8632   int nbOfComp1=a1->getNumberOfComponents();
8633   int nbOfComp2=a2->getNumberOfComponents();
8634   if(nbOfTuple2==nbOfTuple1)
8635     {
8636       if(nbOfComp1==nbOfComp2)
8637         {
8638           MCAuto<DataArrayInt> ret=DataArrayInt::New();
8639           ret->alloc(nbOfTuple2,nbOfComp1);
8640           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<int>());
8641           ret->copyStringInfoFrom(*a1);
8642           return ret.retn();
8643         }
8644       else if(nbOfComp2==1)
8645         {
8646           MCAuto<DataArrayInt> ret=DataArrayInt::New();
8647           ret->alloc(nbOfTuple1,nbOfComp1);
8648           const int *a2Ptr=a2->getConstPointer();
8649           const int *a1Ptr=a1->getConstPointer();
8650           int *res=ret->getPointer();
8651           for(int i=0;i<nbOfTuple1;i++)
8652             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<int>(),a2Ptr[i]));
8653           ret->copyStringInfoFrom(*a1);
8654           return ret.retn();
8655         }
8656       else
8657         {
8658           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
8659           return 0;
8660         }
8661     }
8662   else if(nbOfTuple2==1)
8663     {
8664       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
8665       MCAuto<DataArrayInt> ret=DataArrayInt::New();
8666       ret->alloc(nbOfTuple1,nbOfComp1);
8667       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
8668       int *pt=ret->getPointer();
8669       for(int i=0;i<nbOfTuple1;i++)
8670         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<int>());
8671       ret->copyStringInfoFrom(*a1);
8672       return ret.retn();
8673     }
8674   else
8675     {
8676       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
8677       return 0;
8678     }
8679 }
8680
8681 /*!
8682  * Divide values of \a this array by values of another DataArrayInt. There are 3
8683  * valid cases.
8684  * 1.  The arrays have same number of tuples and components. Then each value of
8685  *    \a this array is divided by the corresponding value of \a other one, i.e.:
8686  *   _a_ [ i, j ] /= _other_ [ i, j ].
8687  * 2.  The arrays have same number of tuples and \a other array has one component. Then
8688  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
8689  * 3.  The arrays have same number of components and \a other array has one tuple. Then
8690  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
8691  *
8692  *  \warning No check of division by zero is performed!
8693  *  \param [in] other - an array to divide \a this one by.
8694  *  \throw If \a other is NULL.
8695  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
8696  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
8697  *         \a other has number of both tuples and components not equal to 1.
8698  */
8699 void DataArrayInt::divideEqual(const DataArrayInt *other)
8700 {
8701   if(!other)
8702     throw INTERP_KERNEL::Exception("DataArrayInt::divideEqual : input DataArrayInt instance is NULL !");
8703   const char *msg="Nb of tuples mismatch for DataArrayInt::divideEqual !";
8704   checkAllocated(); other->checkAllocated();
8705   int nbOfTuple=getNumberOfTuples();
8706   int nbOfTuple2=other->getNumberOfTuples();
8707   int nbOfComp=getNumberOfComponents();
8708   int nbOfComp2=other->getNumberOfComponents();
8709   if(nbOfTuple==nbOfTuple2)
8710     {
8711       if(nbOfComp==nbOfComp2)
8712         {
8713           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<int>());
8714         }
8715       else if(nbOfComp2==1)
8716         {
8717           int *ptr=getPointer();
8718           const int *ptrc=other->getConstPointer();
8719           for(int i=0;i<nbOfTuple;i++)
8720             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<int>(),*ptrc++));
8721         }
8722       else
8723         throw INTERP_KERNEL::Exception(msg);
8724     }
8725   else if(nbOfTuple2==1)
8726     {
8727       if(nbOfComp2==nbOfComp)
8728         {
8729           int *ptr=getPointer();
8730           const int *ptrc=other->getConstPointer();
8731           for(int i=0;i<nbOfTuple;i++)
8732             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<int>());
8733         }
8734       else
8735         throw INTERP_KERNEL::Exception(msg);
8736     }
8737   else
8738     throw INTERP_KERNEL::Exception(msg);
8739   declareAsNew();
8740 }
8741
8742
8743 /*!
8744  * Returns a new DataArrayInt that is a modulus of two given arrays. There are 3
8745  * valid cases.
8746  * 1.  The arrays have same number of tuples and components. Then each value of
8747  *   the result array (_a_) is a division of the corresponding values of \a a1 and
8748  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, j ].
8749  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
8750  *   component. Then
8751  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, 0 ].
8752  * 3.  The arrays have same number of components and one array, say _a2_, has one
8753  *   tuple. Then
8754  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ 0, j ].
8755  *
8756  * Info on components is copied either from the first array (in the first case) or from
8757  * the array with maximal number of elements (getNbOfElems()).
8758  *  \warning No check of division by zero is performed!
8759  *  \param [in] a1 - a dividend array.
8760  *  \param [in] a2 - a divisor array.
8761  *  \return DataArrayInt * - the new instance of DataArrayInt.
8762  *          The caller is to delete this result array using decrRef() as it is no more
8763  *          needed.
8764  *  \throw If either \a a1 or \a a2 is NULL.
8765  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
8766  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
8767  *         none of them has number of tuples or components equal to 1.
8768  */
8769 DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt *a2)
8770 {
8771   if(!a1 || !a2)
8772     throw INTERP_KERNEL::Exception("DataArrayInt::Modulus : input DataArrayInt instance is NULL !");
8773   int nbOfTuple1=a1->getNumberOfTuples();
8774   int nbOfTuple2=a2->getNumberOfTuples();
8775   int nbOfComp1=a1->getNumberOfComponents();
8776   int nbOfComp2=a2->getNumberOfComponents();
8777   if(nbOfTuple2==nbOfTuple1)
8778     {
8779       if(nbOfComp1==nbOfComp2)
8780         {
8781           MCAuto<DataArrayInt> ret=DataArrayInt::New();
8782           ret->alloc(nbOfTuple2,nbOfComp1);
8783           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::modulus<int>());
8784           ret->copyStringInfoFrom(*a1);
8785           return ret.retn();
8786         }
8787       else if(nbOfComp2==1)
8788         {
8789           MCAuto<DataArrayInt> ret=DataArrayInt::New();
8790           ret->alloc(nbOfTuple1,nbOfComp1);
8791           const int *a2Ptr=a2->getConstPointer();
8792           const int *a1Ptr=a1->getConstPointer();
8793           int *res=ret->getPointer();
8794           for(int i=0;i<nbOfTuple1;i++)
8795             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::modulus<int>(),a2Ptr[i]));
8796           ret->copyStringInfoFrom(*a1);
8797           return ret.retn();
8798         }
8799       else
8800         {
8801           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
8802           return 0;
8803         }
8804     }
8805   else if(nbOfTuple2==1)
8806     {
8807       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
8808       MCAuto<DataArrayInt> ret=DataArrayInt::New();
8809       ret->alloc(nbOfTuple1,nbOfComp1);
8810       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
8811       int *pt=ret->getPointer();
8812       for(int i=0;i<nbOfTuple1;i++)
8813         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::modulus<int>());
8814       ret->copyStringInfoFrom(*a1);
8815       return ret.retn();
8816     }
8817   else
8818     {
8819       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Modulus !");//will always throw an exception
8820       return 0;
8821     }
8822 }
8823
8824 /*!
8825  * Modify \a this array so that each value becomes a modulus of division of this value by
8826  * a value of another DataArrayInt. There are 3 valid cases.
8827  * 1.  The arrays have same number of tuples and components. Then each value of
8828  *    \a this array is divided by the corresponding value of \a other one, i.e.:
8829  *   _a_ [ i, j ] %= _other_ [ i, j ].
8830  * 2.  The arrays have same number of tuples and \a other array has one component. Then
8831  *   _a_ [ i, j ] %= _other_ [ i, 0 ].
8832  * 3.  The arrays have same number of components and \a other array has one tuple. Then
8833  *   _a_ [ i, j ] %= _a2_ [ 0, j ].
8834  *
8835  *  \warning No check of division by zero is performed!
8836  *  \param [in] other - a divisor array.
8837  *  \throw If \a other is NULL.
8838  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
8839  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
8840  *         \a other has number of both tuples and components not equal to 1.
8841  */
8842 void DataArrayInt::modulusEqual(const DataArrayInt *other)
8843 {
8844   if(!other)
8845     throw INTERP_KERNEL::Exception("DataArrayInt::modulusEqual : input DataArrayInt instance is NULL !");
8846   const char *msg="Nb of tuples mismatch for DataArrayInt::modulusEqual !";
8847   checkAllocated(); other->checkAllocated();
8848   int nbOfTuple=getNumberOfTuples();
8849   int nbOfTuple2=other->getNumberOfTuples();
8850   int nbOfComp=getNumberOfComponents();
8851   int nbOfComp2=other->getNumberOfComponents();
8852   if(nbOfTuple==nbOfTuple2)
8853     {
8854       if(nbOfComp==nbOfComp2)
8855         {
8856           std::transform(begin(),end(),other->begin(),getPointer(),std::modulus<int>());
8857         }
8858       else if(nbOfComp2==1)
8859         {
8860           if(nbOfComp2==nbOfComp)
8861             {
8862               int *ptr=getPointer();
8863               const int *ptrc=other->getConstPointer();
8864               for(int i=0;i<nbOfTuple;i++)
8865                 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::modulus<int>(),*ptrc++));
8866             }
8867           else
8868             throw INTERP_KERNEL::Exception(msg);
8869         }
8870       else
8871         throw INTERP_KERNEL::Exception(msg);
8872     }
8873   else if(nbOfTuple2==1)
8874     {
8875       int *ptr=getPointer();
8876       const int *ptrc=other->getConstPointer();
8877       for(int i=0;i<nbOfTuple;i++)
8878         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::modulus<int>());
8879     }
8880   else
8881     throw INTERP_KERNEL::Exception(msg);
8882   declareAsNew();
8883 }
8884
8885 /*!
8886  * Returns a new DataArrayInt that is the result of pow of two given arrays. There are 3
8887  * valid cases.
8888  *
8889  *  \param [in] a1 - an array to pow up.
8890  *  \param [in] a2 - another array to sum up.
8891  *  \return DataArrayInt * - the new instance of DataArrayInt.
8892  *          The caller is to delete this result array using decrRef() as it is no more
8893  *          needed.
8894  *  \throw If either \a a1 or \a a2 is NULL.
8895  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
8896  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
8897  *  \throw If there is a negative value in \a a2.
8898  */
8899 DataArrayInt *DataArrayInt::Pow(const DataArrayInt *a1, const DataArrayInt *a2)
8900 {
8901   if(!a1 || !a2)
8902     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : at least one of input instances is null !");
8903   int nbOfTuple=a1->getNumberOfTuples();
8904   int nbOfTuple2=a2->getNumberOfTuples();
8905   int nbOfComp=a1->getNumberOfComponents();
8906   int nbOfComp2=a2->getNumberOfComponents();
8907   if(nbOfTuple!=nbOfTuple2)
8908     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of tuples mismatches !");
8909   if(nbOfComp!=1 || nbOfComp2!=1)
8910     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of components of both arrays must be equal to 1 !");
8911   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuple,1);
8912   const int *ptr1(a1->begin()),*ptr2(a2->begin());
8913   int *ptr=ret->getPointer();
8914   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
8915     {
8916       if(*ptr2>=0)
8917         {
8918           int tmp=1;
8919           for(int j=0;j<*ptr2;j++)
8920             tmp*=*ptr1;
8921           *ptr=tmp;
8922         }
8923       else
8924         {
8925           std::ostringstream oss; oss << "DataArrayInt::Pow : on tuple #" << i << " of a2 value is < 0 (" << *ptr2 << ") !";
8926           throw INTERP_KERNEL::Exception(oss.str().c_str());
8927         }
8928     }
8929   return ret.retn();
8930 }
8931
8932 /*!
8933  * Apply pow on values of another DataArrayInt to values of \a this one.
8934  *
8935  *  \param [in] other - an array to pow to \a this one.
8936  *  \throw If \a other is NULL.
8937  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
8938  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
8939  *  \throw If there is a negative value in \a other.
8940  */
8941 void DataArrayInt::powEqual(const DataArrayInt *other)
8942 {
8943   if(!other)
8944     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : input instance is null !");
8945   int nbOfTuple=getNumberOfTuples();
8946   int nbOfTuple2=other->getNumberOfTuples();
8947   int nbOfComp=getNumberOfComponents();
8948   int nbOfComp2=other->getNumberOfComponents();
8949   if(nbOfTuple!=nbOfTuple2)
8950     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of tuples mismatches !");
8951   if(nbOfComp!=1 || nbOfComp2!=1)
8952     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of components of both arrays must be equal to 1 !");
8953   int *ptr=getPointer();
8954   const int *ptrc=other->begin();
8955   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
8956     {
8957       if(*ptrc>=0)
8958         {
8959           int tmp=1;
8960           for(int j=0;j<*ptrc;j++)
8961             tmp*=*ptr;
8962           *ptr=tmp;
8963         }
8964       else
8965         {
8966           std::ostringstream oss; oss << "DataArrayInt::powEqual : on tuple #" << i << " of other value is < 0 (" << *ptrc << ") !";
8967           throw INTERP_KERNEL::Exception(oss.str().c_str());
8968         }
8969     }
8970   declareAsNew();
8971 }
8972
8973 /*!
8974  * Returns a C array which is a renumbering map in "Old to New" mode for the input array.
8975  * This map, if applied to \a start array, would make it sorted. For example, if
8976  * \a start array contents are [9,10,0,6,4,11,3,7] then the contents of the result array is
8977  * [5,6,0,3,2,7,1,4].
8978  *  \param [in] start - pointer to the first element of the array for which the
8979  *         permutation map is computed.
8980  *  \param [in] end - pointer specifying the end of the array \a start, so that
8981  *         the last value of \a start is \a end[ -1 ].
8982  *  \return int * - the result permutation array that the caller is to delete as it is no
8983  *         more needed.
8984  *  \throw If there are equal values in the input array.
8985  */
8986 int *DataArrayInt::CheckAndPreparePermutation(const int *start, const int *end)
8987 {
8988   std::size_t sz=std::distance(start,end);
8989   int *ret=(int *)malloc(sz*sizeof(int));
8990   int *work=new int[sz];
8991   std::copy(start,end,work);
8992   std::sort(work,work+sz);
8993   if(std::unique(work,work+sz)!=work+sz)
8994     {
8995       delete [] work;
8996       free(ret);
8997       throw INTERP_KERNEL::Exception("Some elements are equals in the specified array !");
8998     }
8999   std::map<int,int> m;
9000   for(int *workPt=work;workPt!=work+sz;workPt++)
9001     m[*workPt]=(int)std::distance(work,workPt);
9002   int *iter2=ret;
9003   for(const int *iter=start;iter!=end;iter++,iter2++)
9004     *iter2=m[*iter];
9005   delete [] work;
9006   return ret;
9007 }
9008
9009 /*!
9010  * Returns a new DataArrayInt containing an arithmetic progression
9011  * that is equal to the sequence returned by Python \c range(\a begin,\a  end,\a  step )
9012  * function.
9013  *  \param [in] begin - the start value of the result sequence.
9014  *  \param [in] end - limiting value, so that every value of the result array is less than
9015  *              \a end.
9016  *  \param [in] step - specifies the increment or decrement.
9017  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9018  *          array using decrRef() as it is no more needed.
9019  *  \throw If \a step == 0.
9020  *  \throw If \a end < \a begin && \a step > 0.
9021  *  \throw If \a end > \a begin && \a step < 0.
9022  */
9023 DataArrayInt *DataArrayInt::Range(int begin, int end, int step)
9024 {
9025   int nbOfTuples=GetNumberOfItemGivenBESRelative(begin,end,step,"DataArrayInt::Range");
9026   MCAuto<DataArrayInt> ret=DataArrayInt::New();
9027   ret->alloc(nbOfTuples,1);
9028   int *ptr=ret->getPointer();
9029   if(step>0)
9030     {
9031       for(int i=begin;i<end;i+=step,ptr++)
9032         *ptr=i;
9033     }
9034   else
9035     {
9036       for(int i=begin;i>end;i+=step,ptr++)
9037         *ptr=i;
9038     }
9039   return ret.retn();
9040 }
9041
9042 /*!
9043  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
9044  * Server side.
9045  */
9046 void DataArrayInt::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
9047 {
9048   tinyInfo.resize(2);
9049   if(isAllocated())
9050     {
9051       tinyInfo[0]=getNumberOfTuples();
9052       tinyInfo[1]=getNumberOfComponents();
9053     }
9054   else
9055     {
9056       tinyInfo[0]=-1;
9057       tinyInfo[1]=-1;
9058     }
9059 }
9060
9061 /*!
9062  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
9063  * Server side.
9064  */
9065 void DataArrayInt::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
9066 {
9067   if(isAllocated())
9068     {
9069       int nbOfCompo=getNumberOfComponents();
9070       tinyInfo.resize(nbOfCompo+1);
9071       tinyInfo[0]=getName();
9072       for(int i=0;i<nbOfCompo;i++)
9073         tinyInfo[i+1]=getInfoOnComponent(i);
9074     }
9075   else
9076     {
9077       tinyInfo.resize(1);
9078       tinyInfo[0]=getName();
9079     }
9080 }
9081
9082 /*!
9083  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
9084  * This method returns if a feeding is needed.
9085  */
9086 bool DataArrayInt::resizeForUnserialization(const std::vector<int>& tinyInfoI)
9087 {
9088   int nbOfTuple=tinyInfoI[0];
9089   int nbOfComp=tinyInfoI[1];
9090   if(nbOfTuple!=-1 || nbOfComp!=-1)
9091     {
9092       alloc(nbOfTuple,nbOfComp);
9093       return true;
9094     }
9095   return false;
9096 }
9097
9098 /*!
9099  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
9100  * This method returns if a feeding is needed.
9101  */
9102 void DataArrayInt::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
9103 {
9104   setName(tinyInfoS[0]);
9105   if(isAllocated())
9106     {
9107       int nbOfCompo=tinyInfoI[1];
9108       for(int i=0;i<nbOfCompo;i++)
9109         setInfoOnComponent(i,tinyInfoS[i+1]);
9110     }
9111 }
9112
9113 DataArrayIntIterator::DataArrayIntIterator(DataArrayInt *da):DataArrayIterator<int>(da)
9114 {
9115 }
9116
9117 DataArrayIntTuple::DataArrayIntTuple(int *pt, int nbOfComp):DataArrayTuple<int>(pt,nbOfComp)
9118 {
9119 }
9120
9121 std::string DataArrayIntTuple::repr() const
9122 {
9123   std::ostringstream oss; oss << "(";
9124   for(int i=0;i<_nb_of_compo-1;i++)
9125     oss << _pt[i] << ", ";
9126   oss << _pt[_nb_of_compo-1] << ")";
9127   return oss.str();
9128 }
9129
9130 int DataArrayIntTuple::intValue() const
9131 {
9132   if(_nb_of_compo==1)
9133     return *_pt;
9134   throw INTERP_KERNEL::Exception("DataArrayIntTuple::intValue : DataArrayIntTuple instance has not exactly 1 component -> Not possible to convert it into an integer !");
9135 }
9136
9137 /*!
9138  * This method returns a newly allocated instance the caller should dealed with by a MEDCoupling::DataArrayInt::decrRef.
9139  * This method performs \b no copy of data. The content is only referenced using MEDCoupling::DataArrayInt::useArray with ownership set to \b false.
9140  * 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
9141  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
9142  */
9143 DataArrayInt *DataArrayIntTuple::buildDAInt(int nbOfTuples, int nbOfCompo) const
9144 {
9145   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
9146     {
9147       DataArrayInt *ret=DataArrayInt::New();
9148       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
9149       return ret;
9150     }
9151   else
9152     {
9153       std::ostringstream oss; oss << "DataArrayIntTuple::buildDAInt : unable to build a requested DataArrayInt instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
9154       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
9155       throw INTERP_KERNEL::Exception(oss.str().c_str());
9156     }
9157 }