Salome HOME
a6e0f23e7e4e51bc4f79ce1163b93e5b908bdf25
[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 template class MEDCoupling::DataArrayIterator<int>;
48
49 template<int SPACEDIM>
50 void DataArrayDouble::findCommonTuplesAlg(const double *bbox, int nbNodes, int limitNodeId, double prec, DataArrayInt *c, DataArrayInt *cI) const
51 {
52   const double *coordsPtr=getConstPointer();
53   BBTreePts<SPACEDIM,int> myTree(bbox,0,0,nbNodes,prec);
54   std::vector<bool> isDone(nbNodes);
55   for(int i=0;i<nbNodes;i++)
56     {
57       if(!isDone[i])
58         {
59           std::vector<int> intersectingElems;
60           myTree.getElementsAroundPoint(coordsPtr+i*SPACEDIM,intersectingElems);
61           if(intersectingElems.size()>1)
62             {
63               std::vector<int> commonNodes;
64               for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
65                 if(*it!=i)
66                   if(*it>=limitNodeId)
67                     {
68                       commonNodes.push_back(*it);
69                       isDone[*it]=true;
70                     }
71               if(!commonNodes.empty())
72                 {
73                   cI->pushBackSilent(cI->back()+(int)commonNodes.size()+1);
74                   c->pushBackSilent(i);
75                   c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
76                 }
77             }
78         }
79     }
80 }
81
82 template<int SPACEDIM>
83 void DataArrayDouble::FindTupleIdsNearTuplesAlg(const BBTreePts<SPACEDIM,int>& myTree, const double *pos, int nbOfTuples, double eps,
84                                                 DataArrayInt *c, DataArrayInt *cI)
85 {
86   for(int i=0;i<nbOfTuples;i++)
87     {
88       std::vector<int> intersectingElems;
89       myTree.getElementsAroundPoint(pos+i*SPACEDIM,intersectingElems);
90       std::vector<int> commonNodes;
91       for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
92         commonNodes.push_back(*it);
93       cI->pushBackSilent(cI->back()+(int)commonNodes.size());
94       c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
95     }
96 }
97
98 template<int SPACEDIM>
99 void DataArrayDouble::FindClosestTupleIdAlg(const BBTreePts<SPACEDIM,int>& myTree, double dist, const double *pos, int nbOfTuples, const double *thisPt, int thisNbOfTuples, int *res)
100 {
101   double distOpt(dist);
102   const double *p(pos);
103   int *r(res);
104   for(int i=0;i<nbOfTuples;i++,p+=SPACEDIM,r++)
105     {
106       while(true)
107         {
108           int elem=-1;
109           double ret=myTree.getElementsAroundPoint2(p,distOpt,elem);
110           if(ret!=std::numeric_limits<double>::max())
111             {
112               distOpt=std::max(ret,1e-4);
113               *r=elem;
114               break;
115             }
116           else
117             { distOpt=2*distOpt; continue; }
118         }
119     }
120 }
121
122 int DataArray::EffectiveCircPerm(int nbOfShift, int nbOfTuples)
123 {
124   if(nbOfTuples<=0)
125     throw INTERP_KERNEL::Exception("DataArray::EffectiveCircPerm : number of tuples is expected to be > 0 !");
126   if(nbOfShift>=0)
127     {
128       return nbOfShift%nbOfTuples;
129     }
130   else
131     {
132       int tmp(-nbOfShift);
133       tmp=tmp%nbOfTuples;
134       return nbOfTuples-tmp;
135     }
136 }
137
138 std::size_t DataArray::getHeapMemorySizeWithoutChildren() const
139 {
140   std::size_t sz1=_name.capacity();
141   std::size_t sz2=_info_on_compo.capacity();
142   std::size_t sz3=0;
143   for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
144     sz3+=(*it).capacity();
145   return sz1+sz2+sz3;
146 }
147
148 std::vector<const BigMemoryObject *> DataArray::getDirectChildrenWithNull() const
149 {
150   return std::vector<const BigMemoryObject *>();
151 }
152
153 /*!
154  * Sets the attribute \a _name of \a this array.
155  * See \ref MEDCouplingArrayBasicsName "DataArrays infos" for more information.
156  *  \param [in] name - new array name
157  */
158 void DataArray::setName(const std::string& name)
159 {
160   _name=name;
161 }
162
163 /*!
164  * Copies textual data from an \a other DataArray. The copied data are
165  * - the name attribute,
166  * - the information of components.
167  *
168  * For more information on these data see \ref MEDCouplingArrayBasicsName "DataArrays infos".
169  *
170  *  \param [in] other - another instance of DataArray to copy the textual data from.
171  *  \throw If number of components of \a this array differs from that of the \a other.
172  */
173 void DataArray::copyStringInfoFrom(const DataArray& other)
174 {
175   if(_info_on_compo.size()!=other._info_on_compo.size())
176     throw INTERP_KERNEL::Exception("Size of arrays mismatches on copyStringInfoFrom !");
177   _name=other._name;
178   _info_on_compo=other._info_on_compo;
179 }
180
181 void DataArray::copyPartOfStringInfoFrom(const DataArray& other, const std::vector<int>& compoIds)
182 {
183   int nbOfCompoOth=other.getNumberOfComponents();
184   std::size_t newNbOfCompo=compoIds.size();
185   for(std::size_t i=0;i<newNbOfCompo;i++)
186     if(compoIds[i]>=nbOfCompoOth || compoIds[i]<0)
187       {
188         std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompoOth << ")";
189         throw INTERP_KERNEL::Exception(oss.str().c_str());
190       }
191   for(std::size_t i=0;i<newNbOfCompo;i++)
192     setInfoOnComponent((int)i,other.getInfoOnComponent(compoIds[i]));
193 }
194
195 void DataArray::copyPartOfStringInfoFrom2(const std::vector<int>& compoIds, const DataArray& other)
196 {
197   int nbOfCompo=getNumberOfComponents();
198   std::size_t partOfCompoToSet=compoIds.size();
199   if((int)partOfCompoToSet!=other.getNumberOfComponents())
200     throw INTERP_KERNEL::Exception("Given compoIds has not the same size as number of components of given array !");
201   for(std::size_t i=0;i<partOfCompoToSet;i++)
202     if(compoIds[i]>=nbOfCompo || compoIds[i]<0)
203       {
204         std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompo << ")";
205         throw INTERP_KERNEL::Exception(oss.str().c_str());
206       }
207   for(std::size_t i=0;i<partOfCompoToSet;i++)
208     setInfoOnComponent(compoIds[i],other.getInfoOnComponent((int)i));
209 }
210
211 bool DataArray::areInfoEqualsIfNotWhy(const DataArray& other, std::string& reason) const
212 {
213   std::ostringstream oss;
214   if(_name!=other._name)
215     {
216       oss << "Names DataArray mismatch : this name=\"" << _name << " other name=\"" << other._name << "\" !";
217       reason=oss.str();
218       return false;
219     }
220   if(_info_on_compo!=other._info_on_compo)
221     {
222       oss << "Components DataArray mismatch : \nThis components=";
223       for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
224         oss << "\"" << *it << "\",";
225       oss << "\nOther components=";
226       for(std::vector<std::string>::const_iterator it=other._info_on_compo.begin();it!=other._info_on_compo.end();it++)
227         oss << "\"" << *it << "\",";
228       reason=oss.str();
229       return false;
230     }
231   return true;
232 }
233
234 /*!
235  * Compares textual information of \a this DataArray with that of an \a other one.
236  * The compared data are
237  * - the name attribute,
238  * - the information of components.
239  *
240  * For more information on these data see \ref MEDCouplingArrayBasicsName "DataArrays infos".
241  *  \param [in] other - another instance of DataArray to compare the textual data of.
242  *  \return bool - \a true if the textual information is same, \a false else.
243  */
244 bool DataArray::areInfoEquals(const DataArray& other) const
245 {
246   std::string tmp;
247   return areInfoEqualsIfNotWhy(other,tmp);
248 }
249
250 void DataArray::reprWithoutNameStream(std::ostream& stream) const
251 {
252   stream << "Number of components : "<< getNumberOfComponents() << "\n";
253   stream << "Info of these components : ";
254   for(std::vector<std::string>::const_iterator iter=_info_on_compo.begin();iter!=_info_on_compo.end();iter++)
255     stream << "\"" << *iter << "\"   ";
256   stream << "\n";
257 }
258
259 std::string DataArray::cppRepr(const std::string& varName) const
260 {
261   std::ostringstream ret;
262   reprCppStream(varName,ret);
263   return ret.str();
264 }
265
266 /*!
267  * Sets information on all components. To know more on format of this information
268  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
269  *  \param [in] info - a vector of strings.
270  *  \throw If size of \a info differs from the number of components of \a this.
271  */
272 void DataArray::setInfoOnComponents(const std::vector<std::string>& info)
273 {
274   if(getNumberOfComponents()!=(int)info.size())
275     {
276       std::ostringstream oss; oss << "DataArray::setInfoOnComponents : input is of size " << info.size() << " whereas number of components is equal to " << getNumberOfComponents() << " !";
277       throw INTERP_KERNEL::Exception(oss.str().c_str());
278     }
279   _info_on_compo=info;
280 }
281
282 /*!
283  * This method is only a dispatcher towards DataArrayDouble::setPartOfValues3, DataArrayInt::setPartOfValues3, DataArrayChar::setPartOfValues3 depending on the true
284  * type of \a this and \a aBase.
285  *
286  * \throw If \a aBase and \a this do not have the same type.
287  *
288  * \sa DataArrayDouble::setPartOfValues3, DataArrayInt::setPartOfValues3, DataArrayChar::setPartOfValues3.
289  */
290 void DataArray::setPartOfValuesBase3(const DataArray *aBase, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
291 {
292   if(!aBase)
293     throw INTERP_KERNEL::Exception("DataArray::setPartOfValuesBase3 : input aBase object is NULL !");
294   DataArrayDouble *this1(dynamic_cast<DataArrayDouble *>(this));
295   DataArrayInt *this2(dynamic_cast<DataArrayInt *>(this));
296   DataArrayChar *this3(dynamic_cast<DataArrayChar *>(this));
297   const DataArrayDouble *a1(dynamic_cast<const DataArrayDouble *>(aBase));
298   const DataArrayInt *a2(dynamic_cast<const DataArrayInt *>(aBase));
299   const DataArrayChar *a3(dynamic_cast<const DataArrayChar *>(aBase));
300   if(this1 && a1)
301     {
302       this1->setPartOfValues3(a1,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
303       return ;
304     }
305   if(this2 && a2)
306     {
307       this2->setPartOfValues3(a2,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
308       return ;
309     }
310   if(this3 && a3)
311     {
312       this3->setPartOfValues3(a3,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
313       return ;
314     }
315   throw INTERP_KERNEL::Exception("DataArray::setPartOfValuesBase3 : input aBase object and this do not have the same type !");
316 }
317
318 std::vector<std::string> DataArray::getVarsOnComponent() const
319 {
320   int nbOfCompo=(int)_info_on_compo.size();
321   std::vector<std::string> ret(nbOfCompo);
322   for(int i=0;i<nbOfCompo;i++)
323     ret[i]=getVarOnComponent(i);
324   return ret;
325 }
326
327 std::vector<std::string> DataArray::getUnitsOnComponent() const
328 {
329   int nbOfCompo=(int)_info_on_compo.size();
330   std::vector<std::string> ret(nbOfCompo);
331   for(int i=0;i<nbOfCompo;i++)
332     ret[i]=getUnitOnComponent(i);
333   return ret;
334 }
335
336 /*!
337  * Returns information on a component specified by an index.
338  * To know more on format of this information
339  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
340  *  \param [in] i - the index (zero based) of the component of interest.
341  *  \return std::string - a string containing the information on \a i-th component.
342  *  \throw If \a i is not a valid component index.
343  */
344 std::string DataArray::getInfoOnComponent(int i) const
345 {
346   if(i<(int)_info_on_compo.size() && i>=0)
347     return _info_on_compo[i];
348   else
349     {
350       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();
351       throw INTERP_KERNEL::Exception(oss.str().c_str());
352     }
353 }
354
355 /*!
356  * Returns the var part of the full information of the \a i-th component.
357  * For example, if \c getInfoOnComponent(0) returns "SIGXY [N/m^2]", then
358  * \c getVarOnComponent(0) returns "SIGXY".
359  * If a unit part of information is not detected by presence of
360  * two square brackets, then the full information is returned.
361  * To read more about the component information format, see
362  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
363  *  \param [in] i - the index (zero based) of the component of interest.
364  *  \return std::string - a string containing the var information, or the full info.
365  *  \throw If \a i is not a valid component index.
366  */
367 std::string DataArray::getVarOnComponent(int i) const
368 {
369   if(i<(int)_info_on_compo.size() && i>=0)
370     {
371       return GetVarNameFromInfo(_info_on_compo[i]);
372     }
373   else
374     {
375       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();
376       throw INTERP_KERNEL::Exception(oss.str().c_str());
377     }
378 }
379
380 /*!
381  * Returns the unit part of the full information of the \a i-th component.
382  * For example, if \c getInfoOnComponent(0) returns "SIGXY [ N/m^2]", then
383  * \c getUnitOnComponent(0) returns " N/m^2".
384  * If a unit part of information is not detected by presence of
385  * two square brackets, then an empty string is returned.
386  * To read more about the component information format, see
387  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
388  *  \param [in] i - the index (zero based) of the component of interest.
389  *  \return std::string - a string containing the unit information, if any, or "".
390  *  \throw If \a i is not a valid component index.
391  */
392 std::string DataArray::getUnitOnComponent(int i) const
393 {
394   if(i<(int)_info_on_compo.size() && i>=0)
395     {
396       return GetUnitFromInfo(_info_on_compo[i]);
397     }
398   else
399     {
400       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();
401       throw INTERP_KERNEL::Exception(oss.str().c_str());
402     }
403 }
404
405 /*!
406  * Returns the var part of the full component information.
407  * For example, if \a info == "SIGXY [N/m^2]", then this method returns "SIGXY".
408  * If a unit part of information is not detected by presence of
409  * two square brackets, then the whole \a info is returned.
410  * To read more about the component information format, see
411  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
412  *  \param [in] info - the full component information.
413  *  \return std::string - a string containing only var information, or the \a info.
414  */
415 std::string DataArray::GetVarNameFromInfo(const std::string& info)
416 {
417   std::size_t p1=info.find_last_of('[');
418   std::size_t p2=info.find_last_of(']');
419   if(p1==std::string::npos || p2==std::string::npos)
420     return info;
421   if(p1>p2)
422     return info;
423   if(p1==0)
424     return std::string();
425   std::size_t p3=info.find_last_not_of(' ',p1-1);
426   return info.substr(0,p3+1);
427 }
428
429 /*!
430  * Returns the unit part of the full component information.
431  * For example, if \a info == "SIGXY [ N/m^2]", then this method returns " N/m^2".
432  * If a unit part of information is not detected by presence of
433  * two square brackets, then an empty string is returned.
434  * To read more about the component information format, see
435  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
436  *  \param [in] info - the full component information.
437  *  \return std::string - a string containing only unit information, if any, or "".
438  */
439 std::string DataArray::GetUnitFromInfo(const std::string& info)
440 {
441   std::size_t p1=info.find_last_of('[');
442   std::size_t p2=info.find_last_of(']');
443   if(p1==std::string::npos || p2==std::string::npos)
444     return std::string();
445   if(p1>p2)
446     return std::string();
447   return info.substr(p1+1,p2-p1-1);
448 }
449
450 /*!
451  * This method put in info format the result of the merge of \a var and \a unit.
452  * The standard format for that is "var [unit]".
453  * Inversely you can retrieve the var part or the unit part of info string using resp. GetVarNameFromInfo and GetUnitFromInfo.
454  */
455 std::string DataArray::BuildInfoFromVarAndUnit(const std::string& var, const std::string& unit)
456 {
457   std::ostringstream oss;
458   oss << var << " [" << unit << "]";
459   return oss.str();
460 }
461
462 std::string DataArray::GetAxisTypeRepr(MEDCouplingAxisType at)
463 {
464   switch(at)
465     {
466     case AX_CART:
467       return std::string("AX_CART");
468     case AX_CYL:
469       return std::string("AX_CYL");
470     case AX_SPHER:
471       return std::string("AX_SPHER");
472     default:
473       throw INTERP_KERNEL::Exception("DataArray::GetAxisTypeRepr : unrecognized axis type enum !");
474     }
475 }
476
477 /*!
478  * Returns a new DataArray by concatenating all given arrays, so that (1) the number
479  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
480  * the number of component in the result array is same as that of each of given arrays.
481  * Info on components is copied from the first of the given arrays. Number of components
482  * in the given arrays must be  the same.
483  *  \param [in] arrs - a sequence of arrays to include in the result array. All arrays must have the same type.
484  *  \return DataArray * - the new instance of DataArray (that can be either DataArrayInt, DataArrayDouble, DataArrayChar).
485  *          The caller is to delete this result array using decrRef() as it is no more
486  *          needed.
487  *  \throw If all arrays within \a arrs are NULL.
488  *  \throw If all not null arrays in \a arrs have not the same type.
489  *  \throw If getNumberOfComponents() of arrays within \a arrs.
490  */
491 DataArray *DataArray::Aggregate(const std::vector<const DataArray *>& arrs)
492 {
493   std::vector<const DataArray *> arr2;
494   for(std::vector<const DataArray *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
495     if(*it)
496       arr2.push_back(*it);
497   if(arr2.empty())
498     throw INTERP_KERNEL::Exception("DataArray::Aggregate : only null instance in input vector !");
499   std::vector<const DataArrayDouble *> arrd;
500   std::vector<const DataArrayInt *> arri;
501   std::vector<const DataArrayChar *> arrc;
502   for(std::vector<const DataArray *>::const_iterator it=arr2.begin();it!=arr2.end();it++)
503     {
504       const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(*it);
505       if(a)
506         { arrd.push_back(a); continue; }
507       const DataArrayInt *b=dynamic_cast<const DataArrayInt *>(*it);
508       if(b)
509         { arri.push_back(b); continue; }
510       const DataArrayChar *c=dynamic_cast<const DataArrayChar *>(*it);
511       if(c)
512         { arrc.push_back(c); continue; }
513       throw INTERP_KERNEL::Exception("DataArray::Aggregate : presence of not null instance in inuput that is not in [DataArrayDouble, DataArrayInt, DataArrayChar] !");
514     }
515   if(arr2.size()==arrd.size())
516     return DataArrayDouble::Aggregate(arrd);
517   if(arr2.size()==arri.size())
518     return DataArrayInt::Aggregate(arri);
519   if(arr2.size()==arrc.size())
520     return DataArrayChar::Aggregate(arrc);
521   throw INTERP_KERNEL::Exception("DataArray::Aggregate : all input arrays must have the same type !");
522 }
523
524 /*!
525  * Sets information on a component specified by an index.
526  * To know more on format of this information
527  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
528  *  \warning Don't pass NULL as \a info!
529  *  \param [in] i - the index (zero based) of the component of interest.
530  *  \param [in] info - the string containing the information.
531  *  \throw If \a i is not a valid component index.
532  */
533 void DataArray::setInfoOnComponent(int i, const std::string& info)
534 {
535   if(i<(int)_info_on_compo.size() && i>=0)
536     _info_on_compo[i]=info;
537   else
538     {
539       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();
540       throw INTERP_KERNEL::Exception(oss.str().c_str());
541     }
542 }
543
544 /*!
545  * Sets information on all components. This method can change number of components
546  * at certain conditions; if the conditions are not respected, an exception is thrown.
547  * The number of components can be changed in \a this only if \a this is not allocated.
548  * The condition of number of components must not be changed.
549  *
550  * To know more on format of the component information see
551  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
552  *  \param [in] info - a vector of component infos.
553  *  \throw If \a this->getNumberOfComponents() != \a info.size() && \a this->isAllocated()
554  */
555 void DataArray::setInfoAndChangeNbOfCompo(const std::vector<std::string>& info)
556 {
557   if(getNumberOfComponents()!=(int)info.size())
558     {
559       if(!isAllocated())
560         _info_on_compo=info;
561       else
562         {
563           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 !";
564           throw INTERP_KERNEL::Exception(oss.str().c_str());
565         }
566     }
567   else
568     _info_on_compo=info;
569 }
570
571 void DataArray::checkNbOfTuples(int nbOfTuples, const std::string& msg) const
572 {
573   if(getNumberOfTuples()!=nbOfTuples)
574     {
575       std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " <<  nbOfTuples << " having " << getNumberOfTuples() << " !";
576       throw INTERP_KERNEL::Exception(oss.str().c_str());
577     }
578 }
579
580 void DataArray::checkNbOfComps(int nbOfCompo, const std::string& msg) const
581 {
582   if(getNumberOfComponents()!=nbOfCompo)
583     {
584       std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << nbOfCompo << " having " << getNumberOfComponents() << " !";
585       throw INTERP_KERNEL::Exception(oss.str().c_str());
586     }
587 }
588
589 void DataArray::checkNbOfElems(std::size_t nbOfElems, const std::string& msg) const
590 {
591   if(getNbOfElems()!=nbOfElems)
592     {
593       std::ostringstream oss; oss << msg << " : mismatch number of elems : Expected " << nbOfElems << " having " << getNbOfElems() << " !";
594       throw INTERP_KERNEL::Exception(oss.str().c_str());
595     }
596 }
597
598 void DataArray::checkNbOfTuplesAndComp(const DataArray& other, const std::string& msg) const
599 {
600   if(getNumberOfTuples()!=other.getNumberOfTuples())
601     {
602       std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " <<  other.getNumberOfTuples() << " having " << getNumberOfTuples() << " !";
603       throw INTERP_KERNEL::Exception(oss.str().c_str());
604     }
605   if(getNumberOfComponents()!=other.getNumberOfComponents())
606     {
607       std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << other.getNumberOfComponents() << " having " << getNumberOfComponents() << " !";
608       throw INTERP_KERNEL::Exception(oss.str().c_str());
609     }
610 }
611
612 void DataArray::checkNbOfTuplesAndComp(int nbOfTuples, int nbOfCompo, const std::string& msg) const
613 {
614   checkNbOfTuples(nbOfTuples,msg);
615   checkNbOfComps(nbOfCompo,msg);
616 }
617
618 /*!
619  * Simply this method checks that \b value is in [0,\b ref).
620  */
621 void DataArray::CheckValueInRange(int ref, int value, const std::string& msg)
622 {
623   if(value<0 || value>=ref)
624     {
625       std::ostringstream oss; oss << "DataArray::CheckValueInRange : " << msg  << " ! Expected in range [0," << ref << "[ having " << value << " !";
626       throw INTERP_KERNEL::Exception(oss.str().c_str());
627     }
628 }
629
630 /*!
631  * This method checks that [\b start, \b end) is compliant with ref length \b value.
632  * typicaly start in [0,\b value) and end in [0,\b value). If value==start and start==end, it is supported.
633  */
634 void DataArray::CheckValueInRangeEx(int value, int start, int end, const std::string& msg)
635 {
636   if(start<0 || start>=value)
637     {
638       if(value!=start || end!=start)
639         {
640           std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg  << " ! Expected start " << start << " of input range, in [0," << value << "[ !";
641           throw INTERP_KERNEL::Exception(oss.str().c_str());
642         }
643     }
644   if(end<0 || end>value)
645     {
646       std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg  << " ! Expected end " << end << " of input range, in [0," << value << "] !";
647       throw INTERP_KERNEL::Exception(oss.str().c_str());
648     }
649 }
650
651 void DataArray::CheckClosingParInRange(int ref, int value, const std::string& msg)
652 {
653   if(value<0 || value>ref)
654     {
655       std::ostringstream oss; oss << "DataArray::CheckClosingParInRange : " << msg  << " ! Expected input range in [0," << ref << "] having closing open parenthesis " << value << " !";
656       throw INTERP_KERNEL::Exception(oss.str().c_str());
657     }
658 }
659
660 /*!
661  * 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, 
662  * typically it is a whole slice of tuples of DataArray or cells, nodes of a mesh...
663  *
664  * The input \a sliceId should be an id in [0, \a nbOfSlices) that specifies the slice of work.
665  *
666  * \param [in] start - the start of the input slice of the whole work to perform splitted into slices.
667  * \param [in] stop - the stop of the input slice of the whole work to perform splitted into slices.
668  * \param [in] step - the step (that can be <0) of the input slice of the whole work to perform splitted into slices.
669  * \param [in] sliceId - the slice id considered
670  * \param [in] nbOfSlices - the number of slices (typically the number of cores on which the work is expected to be sliced)
671  * \param [out] startSlice - the start of the slice considered
672  * \param [out] stopSlice - the stop of the slice consided
673  * 
674  * \throw If \a step == 0
675  * \throw If \a nbOfSlices not > 0
676  * \throw If \a sliceId not in [0,nbOfSlices)
677  */
678 void DataArray::GetSlice(int start, int stop, int step, int sliceId, int nbOfSlices, int& startSlice, int& stopSlice)
679 {
680   if(nbOfSlices<=0)
681     {
682       std::ostringstream oss; oss << "DataArray::GetSlice : nbOfSlices (" << nbOfSlices << ") must be > 0 !";
683       throw INTERP_KERNEL::Exception(oss.str().c_str());
684     }
685   if(sliceId<0 || sliceId>=nbOfSlices)
686     {
687       std::ostringstream oss; oss << "DataArray::GetSlice : sliceId (" << nbOfSlices << ") must be in [0 , nbOfSlices (" << nbOfSlices << ") ) !";
688       throw INTERP_KERNEL::Exception(oss.str().c_str());
689     }
690   int nbElems=GetNumberOfItemGivenBESRelative(start,stop,step,"DataArray::GetSlice");
691   int minNbOfElemsPerSlice=nbElems/nbOfSlices;
692   startSlice=start+minNbOfElemsPerSlice*step*sliceId;
693   if(sliceId<nbOfSlices-1)
694     stopSlice=start+minNbOfElemsPerSlice*step*(sliceId+1);
695   else
696     stopSlice=stop;
697 }
698
699 int DataArray::GetNumberOfItemGivenBES(int begin, int end, int step, const std::string& msg)
700 {
701   if(end<begin)
702     {
703       std::ostringstream oss; oss << msg << " : end before begin !";
704       throw INTERP_KERNEL::Exception(oss.str().c_str());
705     }
706   if(end==begin)
707     return 0;
708   if(step<=0)
709     {
710       std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
711       throw INTERP_KERNEL::Exception(oss.str().c_str());
712     }
713   return (end-1-begin)/step+1;
714 }
715
716 int DataArray::GetNumberOfItemGivenBESRelative(int begin, int end, int step, const std::string& msg)
717 {
718   if(step==0)
719     throw INTERP_KERNEL::Exception("DataArray::GetNumberOfItemGivenBES : step=0 is not allowed !");
720   if(end<begin && step>0)
721     {
722       std::ostringstream oss; oss << msg << " : end before begin whereas step is positive !";
723       throw INTERP_KERNEL::Exception(oss.str().c_str());
724     }
725   if(begin<end && step<0)
726     {
727       std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
728       throw INTERP_KERNEL::Exception(oss.str().c_str());
729     }
730   if(begin!=end)
731     return (std::max(begin,end)-1-std::min(begin,end))/std::abs(step)+1;
732   else
733     return 0;
734 }
735
736 int DataArray::GetPosOfItemGivenBESRelativeNoThrow(int value, int begin, int end, int step)
737 {
738   if(step!=0)
739     {
740       if(step>0)
741         {
742           if(begin<=value && value<end)
743             {
744               if((value-begin)%step==0)
745                 return (value-begin)/step;
746               else
747                 return -1;
748             }
749           else
750             return -1;
751         }
752       else
753         {
754           if(begin>=value && value>end)
755             {
756               if((begin-value)%(-step)==0)
757                 return (begin-value)/(-step);
758               else
759                 return -1;
760             }
761           else
762             return -1;
763         }
764     }
765   else
766     return -1;
767 }
768
769 /*!
770  * Returns a new instance of DataArrayDouble. The caller is to delete this array
771  * using decrRef() as it is no more needed. 
772  */
773 DataArrayDouble *DataArrayDouble::New()
774 {
775   return new DataArrayDouble;
776 }
777
778 /*!
779  * Returns the only one value in \a this, if and only if number of elements
780  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
781  *  \return double - the sole value stored in \a this array.
782  *  \throw If at least one of conditions stated above is not fulfilled.
783  */
784 double DataArrayDouble::doubleValue() const
785 {
786   if(isAllocated())
787     {
788       if(getNbOfElems()==1)
789         {
790           return *getConstPointer();
791         }
792       else
793         throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is allocated but number of elements is not equal to 1 !");
794     }
795   else
796     throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is not allocated !");
797 }
798
799 /*!
800  * Returns a full copy of \a this. For more info on copying data arrays see
801  * \ref MEDCouplingArrayBasicsCopyDeep.
802  *  \return DataArrayDouble * - a new instance of DataArrayDouble. The caller is to
803  *          delete this array using decrRef() as it is no more needed. 
804  */
805 DataArrayDouble *DataArrayDouble::deepCopy() const
806 {
807   return new DataArrayDouble(*this);
808 }
809
810 /*!
811  * Returns either a \a deep or \a shallow copy of this array. For more info see
812  * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
813  *  \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
814  *  \return DataArrayDouble * - either a new instance of DataArrayDouble (if \a dCpy
815  *          == \a true) or \a this instance (if \a dCpy == \a false).
816  */
817 DataArrayDouble *DataArrayDouble::performCopyOrIncrRef(bool dCpy) const
818 {
819   return DataArrayTemplateClassic<double>::PerformCopyOrIncrRef(dCpy,*this);
820 }
821
822 /*!
823  * Assign zero to all values in \a this array. To know more on filling arrays see
824  * \ref MEDCouplingArrayFill.
825  * \throw If \a this is not allocated.
826  */
827 void DataArrayDouble::fillWithZero()
828 {
829   fillWithValue(0.);
830 }
831
832 /*!
833  * Checks that \a this array is consistently **increasing** or **decreasing** in value,
834  * with at least absolute difference value of |\a eps| at each step.
835  * If not an exception is thrown.
836  *  \param [in] increasing - if \a true, the array values should be increasing.
837  *  \param [in] eps - minimal absolute difference between the neighbor values at which 
838  *                    the values are considered different.
839  *  \throw If sequence of values is not strictly monotonic in agreement with \a
840  *         increasing arg.
841  *  \throw If \a this->getNumberOfComponents() != 1.
842  *  \throw If \a this is not allocated.
843  */
844 void DataArrayDouble::checkMonotonic(bool increasing, double eps) const
845 {
846   if(!isMonotonic(increasing,eps))
847     {
848       if (increasing)
849         throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not INCREASING monotonic !");
850       else
851         throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not DECREASING monotonic !");
852     }
853 }
854
855 /*!
856  * Checks that \a this array is consistently **increasing** or **decreasing** in value,
857  * with at least absolute difference value of |\a eps| at each step.
858  *  \param [in] increasing - if \a true, array values should be increasing.
859  *  \param [in] eps - minimal absolute difference between the neighbor values at which 
860  *                    the values are considered different.
861  *  \return bool - \a true if values change in accordance with \a increasing arg.
862  *  \throw If \a this->getNumberOfComponents() != 1.
863  *  \throw If \a this is not allocated.
864  */
865 bool DataArrayDouble::isMonotonic(bool increasing, double eps) const
866 {
867   checkAllocated();
868   if(getNumberOfComponents()!=1)
869     throw INTERP_KERNEL::Exception("DataArrayDouble::isMonotonic : only supported with 'this' array with ONE component !");
870   int nbOfElements=getNumberOfTuples();
871   const double *ptr=getConstPointer();
872   if(nbOfElements==0)
873     return true;
874   double ref=ptr[0];
875   double absEps=fabs(eps);
876   if(increasing)
877     {
878       for(int i=1;i<nbOfElements;i++)
879         {
880           if(ptr[i]<(ref+absEps))
881             return false;
882           ref=ptr[i];
883         }
884       return true;
885     }
886   else
887     {
888       for(int i=1;i<nbOfElements;i++)
889         {
890           if(ptr[i]>(ref-absEps))
891             return false;
892           ref=ptr[i];
893         }
894       return true;
895     }
896 }
897
898 /*!
899  * Returns a textual and human readable representation of \a this instance of
900  * DataArrayDouble. This text is shown when a DataArrayDouble is printed in Python.
901  * \return std::string - text describing \a this DataArrayDouble.
902  *
903  * \sa reprNotTooLong, reprZip
904  */
905 std::string DataArrayDouble::repr() const
906 {
907   std::ostringstream ret;
908   reprStream(ret);
909   return ret.str();
910 }
911
912 std::string DataArrayDouble::reprZip() const
913 {
914   std::ostringstream ret;
915   reprZipStream(ret);
916   return ret.str();
917 }
918
919 /*!
920  * This method is close to repr method except that when \a this has more than 1000 tuples, all tuples are not
921  * printed out to avoid to consume too much space in interpretor.
922  * \sa repr
923  */
924 std::string DataArrayDouble::reprNotTooLong() const
925 {
926   std::ostringstream ret;
927   reprNotTooLongStream(ret);
928   return ret.str();
929 }
930
931 void DataArrayDouble::writeVTK(std::ostream& ofs, int indent, const std::string& nameInFile, DataArrayByte *byteArr) const
932 {
933   static const char SPACE[4]={' ',' ',' ',' '};
934   checkAllocated();
935   std::string idt(indent,' ');
936   ofs.precision(17);
937   ofs << idt << "<DataArray type=\"Float32\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
938   //
939   bool areAllEmpty(true);
940   for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
941     if(!(*it).empty())
942       areAllEmpty=false;
943   if(!areAllEmpty)
944     for(std::size_t i=0;i<_info_on_compo.size();i++)
945       ofs << " ComponentName" << i << "=\"" << _info_on_compo[i] << "\"";
946   //
947   if(byteArr)
948     {
949       ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
950       INTERP_KERNEL::AutoPtr<float> tmp(new float[getNbOfElems()]);
951       float *pt(tmp);
952       // to make Visual C++ happy : instead of std::copy(begin(),end(),(float *)tmp);
953       for(const double *src=begin();src!=end();src++,pt++)
954         *pt=float(*src);
955       const char *data(reinterpret_cast<const char *>((float *)tmp));
956       std::size_t sz(getNbOfElems()*sizeof(float));
957       byteArr->insertAtTheEnd(data,data+sz);
958       byteArr->insertAtTheEnd(SPACE,SPACE+4);
959     }
960   else
961     {
962       ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
963       std::copy(begin(),end(),std::ostream_iterator<double>(ofs," "));
964     }
965   ofs << std::endl << idt << "</DataArray>\n";
966 }
967
968 void DataArrayDouble::reprStream(std::ostream& stream) const
969 {
970   stream << "Name of double array : \"" << _name << "\"\n";
971   reprWithoutNameStream(stream);
972 }
973
974 void DataArrayDouble::reprZipStream(std::ostream& stream) const
975 {
976   stream << "Name of double array : \"" << _name << "\"\n";
977   reprZipWithoutNameStream(stream);
978 }
979
980 void DataArrayDouble::reprNotTooLongStream(std::ostream& stream) const
981 {
982   stream << "Name of double array : \"" << _name << "\"\n";
983   reprNotTooLongWithoutNameStream(stream);
984 }
985
986 void DataArrayDouble::reprWithoutNameStream(std::ostream& stream) const
987 {
988   DataArray::reprWithoutNameStream(stream);
989   stream.precision(17);
990   _mem.repr(getNumberOfComponents(),stream);
991 }
992
993 void DataArrayDouble::reprZipWithoutNameStream(std::ostream& stream) const
994 {
995   DataArray::reprWithoutNameStream(stream);
996   stream.precision(17);
997   _mem.reprZip(getNumberOfComponents(),stream);
998 }
999
1000 void DataArrayDouble::reprNotTooLongWithoutNameStream(std::ostream& stream) const
1001 {
1002   DataArray::reprWithoutNameStream(stream);
1003   stream.precision(17);
1004   _mem.reprNotTooLong(getNumberOfComponents(),stream);
1005 }
1006
1007 void DataArrayDouble::reprCppStream(const std::string& varName, std::ostream& stream) const
1008 {
1009   int nbTuples(getNumberOfTuples()),nbComp(getNumberOfComponents());
1010   const double *data(getConstPointer());
1011   stream.precision(17);
1012   stream << "DataArrayDouble *" << varName << "=DataArrayDouble::New();" << std::endl;
1013   if(nbTuples*nbComp>=1)
1014     {
1015       stream << "const double " << varName << "Data[" << nbTuples*nbComp << "]={";
1016       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<double>(stream,","));
1017       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
1018       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
1019     }
1020   else
1021     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
1022   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
1023 }
1024
1025 /*!
1026  * Method that gives a quick overvien of \a this for python.
1027  */
1028 void DataArrayDouble::reprQuickOverview(std::ostream& stream) const
1029 {
1030   static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
1031   stream << "DataArrayDouble C++ instance at " << this << ". ";
1032   if(isAllocated())
1033     {
1034       int nbOfCompo=(int)_info_on_compo.size();
1035       if(nbOfCompo>=1)
1036         {
1037           int nbOfTuples=getNumberOfTuples();
1038           stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
1039           reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
1040         }
1041       else
1042         stream << "Number of components : 0.";
1043     }
1044   else
1045     stream << "*** No data allocated ****";
1046 }
1047
1048 void DataArrayDouble::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
1049 {
1050   const double *data=begin();
1051   int nbOfTuples=getNumberOfTuples();
1052   int nbOfCompo=(int)_info_on_compo.size();
1053   std::ostringstream oss2; oss2 << "[";
1054   oss2.precision(17);
1055   std::string oss2Str(oss2.str());
1056   bool isFinished=true;
1057   for(int i=0;i<nbOfTuples && isFinished;i++)
1058     {
1059       if(nbOfCompo>1)
1060         {
1061           oss2 << "(";
1062           for(int j=0;j<nbOfCompo;j++,data++)
1063             {
1064               oss2 << *data;
1065               if(j!=nbOfCompo-1) oss2 << ", ";
1066             }
1067           oss2 << ")";
1068         }
1069       else
1070         oss2 << *data++;
1071       if(i!=nbOfTuples-1) oss2 << ", ";
1072       std::string oss3Str(oss2.str());
1073       if(oss3Str.length()<maxNbOfByteInRepr)
1074         oss2Str=oss3Str;
1075       else
1076         isFinished=false;
1077     }
1078   stream << oss2Str;
1079   if(!isFinished)
1080     stream << "... ";
1081   stream << "]";
1082 }
1083
1084 /*!
1085  * Equivalent to DataArrayDouble::isEqual except that if false the reason of
1086  * mismatch is given.
1087  * 
1088  * \param [in] other the instance to be compared with \a this
1089  * \param [in] prec the precision to compare numeric data of the arrays.
1090  * \param [out] reason In case of inequality returns the reason.
1091  * \sa DataArrayDouble::isEqual
1092  */
1093 bool DataArrayDouble::isEqualIfNotWhy(const DataArrayDouble& other, double prec, std::string& reason) const
1094 {
1095   if(!areInfoEqualsIfNotWhy(other,reason))
1096     return false;
1097   return _mem.isEqual(other._mem,prec,reason);
1098 }
1099
1100 /*!
1101  * Checks if \a this and another DataArrayDouble are fully equal. For more info see
1102  * \ref MEDCouplingArrayBasicsCompare.
1103  *  \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1104  *  \param [in] prec - precision value to compare numeric data of the arrays.
1105  *  \return bool - \a true if the two arrays are equal, \a false else.
1106  */
1107 bool DataArrayDouble::isEqual(const DataArrayDouble& other, double prec) const
1108 {
1109   std::string tmp;
1110   return isEqualIfNotWhy(other,prec,tmp);
1111 }
1112
1113 /*!
1114  * Checks if values of \a this and another DataArrayDouble are equal. For more info see
1115  * \ref MEDCouplingArrayBasicsCompare.
1116  *  \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1117  *  \param [in] prec - precision value to compare numeric data of the arrays.
1118  *  \return bool - \a true if the values of two arrays are equal, \a false else.
1119  */
1120 bool DataArrayDouble::isEqualWithoutConsideringStr(const DataArrayDouble& other, double prec) const
1121 {
1122   std::string tmp;
1123   return _mem.isEqual(other._mem,prec,tmp);
1124 }
1125
1126 /*!
1127  * This method checks that all tuples in \a other are in \a this.
1128  * If true, the output param \a tupleIds contains the tuples ids of \a this that correspond to tupes in \a this.
1129  * 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.
1130  *
1131  * \param [in] other - the array having the same number of components than \a this.
1132  * \param [out] tupleIds - the tuple ids containing the same number of tuples than \a other has.
1133  * \sa DataArrayDouble::findCommonTuples
1134  */
1135 bool DataArrayDouble::areIncludedInMe(const DataArrayDouble *other, double prec, DataArrayInt *&tupleIds) const
1136 {
1137   if(!other)
1138     throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : input array is NULL !");
1139   checkAllocated(); other->checkAllocated();
1140   if(getNumberOfComponents()!=other->getNumberOfComponents())
1141     throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : the number of components does not match !");
1142   MCAuto<DataArrayDouble> a=DataArrayDouble::Aggregate(this,other);
1143   DataArrayInt *c=0,*ci=0;
1144   a->findCommonTuples(prec,getNumberOfTuples(),c,ci);
1145   MCAuto<DataArrayInt> cSafe(c),ciSafe(ci);
1146   int newNbOfTuples=-1;
1147   MCAuto<DataArrayInt> ids=DataArrayInt::ConvertIndexArrayToO2N(a->getNumberOfTuples(),c->begin(),ci->begin(),ci->end(),newNbOfTuples);
1148   MCAuto<DataArrayInt> ret1=ids->selectByTupleIdSafeSlice(getNumberOfTuples(),a->getNumberOfTuples(),1);
1149   tupleIds=ret1.retn();
1150   return newNbOfTuples==getNumberOfTuples();
1151 }
1152
1153 /*!
1154  * Searches for tuples coincident within \a prec tolerance. Each tuple is considered
1155  * as coordinates of a point in getNumberOfComponents()-dimensional space. The
1156  * distance separating two points is computed with the infinite norm.
1157  *
1158  * Indices of coincident tuples are stored in output arrays.
1159  * A pair of arrays (\a comm, \a commIndex) is called "Surjective Format 2".
1160  *
1161  * This method is typically used by MEDCouplingPointSet::findCommonNodes() and
1162  * MEDCouplingUMesh::mergeNodes().
1163  *  \param [in] prec - minimal absolute distance between two tuples (infinite norm) at which they are
1164  *              considered not coincident.
1165  *  \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
1166  *              tuples have id strictly lower than \a limitTupleId then they are not returned.
1167  *  \param [out] comm - the array holding ids (== indices) of coincident tuples. 
1168  *               \a comm->getNumberOfComponents() == 1. 
1169  *               \a comm->getNumberOfTuples() == \a commIndex->back().
1170  *  \param [out] commIndex - the array dividing all indices stored in \a comm into
1171  *               groups of (indices of) coincident tuples. Its every value is a tuple
1172  *               index where a next group of tuples begins. For example the second
1173  *               group of tuples in \a comm is described by following range of indices:
1174  *               [ \a commIndex[1], \a commIndex[2] ). \a commIndex->getNumberOfTuples()-1
1175  *               gives the number of groups of coincident tuples.
1176  *  \throw If \a this is not allocated.
1177  *  \throw If the number of components is not in [1,2,3,4].
1178  *
1179  *  \if ENABLE_EXAMPLES
1180  *  \ref cpp_mcdataarraydouble_findcommontuples "Here is a C++ example".
1181  *
1182  *  \ref py_mcdataarraydouble_findcommontuples  "Here is a Python example".
1183  *  \endif
1184  *  \sa DataArrayInt::ConvertIndexArrayToO2N(), DataArrayDouble::areIncludedInMe
1185  */
1186 void DataArrayDouble::findCommonTuples(double prec, int limitTupleId, DataArrayInt *&comm, DataArrayInt *&commIndex) const
1187 {
1188   checkAllocated();
1189   int nbOfCompo=getNumberOfComponents();
1190   if ((nbOfCompo<1) || (nbOfCompo>4)) //test before work
1191     throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : Unexpected spacedim of coords. Must be 1, 2, 3 or 4.");
1192
1193   int nbOfTuples=getNumberOfTuples();
1194   //
1195   MCAuto<DataArrayInt> c(DataArrayInt::New()),cI(DataArrayInt::New()); c->alloc(0,1); cI->pushBackSilent(0);
1196   switch(nbOfCompo)
1197   {
1198     case 4:
1199       findCommonTuplesAlg<4>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1200       break;
1201     case 3:
1202       findCommonTuplesAlg<3>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1203       break;
1204     case 2:
1205       findCommonTuplesAlg<2>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1206       break;
1207     case 1:
1208       findCommonTuplesAlg<1>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1209       break;
1210     default:
1211       throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : nb of components managed are 1,2,3 and 4 ! not implemented for other number of components !");
1212   }
1213   comm=c.retn();
1214   commIndex=cI.retn();
1215 }
1216
1217 /*!
1218  * This methods returns the minimal distance between the two set of points \a this and \a other.
1219  * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
1220  * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
1221  *
1222  * \param [out] thisTupleId the tuple id in \a this corresponding to the returned minimal distance
1223  * \param [out] otherTupleId the tuple id in \a other corresponding to the returned minimal distance
1224  * \return the minimal distance between the two set of points \a this and \a other.
1225  * \sa DataArrayDouble::findClosestTupleId
1226  */
1227 double DataArrayDouble::minimalDistanceTo(const DataArrayDouble *other, int& thisTupleId, int& otherTupleId) const
1228 {
1229   MCAuto<DataArrayInt> part1=findClosestTupleId(other);
1230   int nbOfCompo(getNumberOfComponents());
1231   int otherNbTuples(other->getNumberOfTuples());
1232   const double *thisPt(begin()),*otherPt(other->begin());
1233   const int *part1Pt(part1->begin());
1234   double ret=std::numeric_limits<double>::max();
1235   for(int i=0;i<otherNbTuples;i++,part1Pt++,otherPt+=nbOfCompo)
1236     {
1237       double tmp(0.);
1238       for(int j=0;j<nbOfCompo;j++)
1239         tmp+=(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j])*(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j]);
1240       if(tmp<ret)
1241         { ret=tmp; thisTupleId=*part1Pt; otherTupleId=i; }
1242     }
1243   return sqrt(ret);
1244 }
1245
1246 /*!
1247  * This methods returns for each tuple in \a other which tuple in \a this is the closest.
1248  * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
1249  * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
1250  *
1251  * \return a newly allocated (new object to be dealt by the caller) DataArrayInt having \c other->getNumberOfTuples() tuples and one components.
1252  * \sa DataArrayDouble::minimalDistanceTo
1253  */
1254 DataArrayInt *DataArrayDouble::findClosestTupleId(const DataArrayDouble *other) const
1255 {
1256   if(!other)
1257     throw INTERP_KERNEL::Exception("DataArrayDouble::findClosestTupleId : other instance is NULL !");
1258   checkAllocated(); other->checkAllocated();
1259   int nbOfCompo=getNumberOfComponents();
1260   if(nbOfCompo!=other->getNumberOfComponents())
1261     {
1262       std::ostringstream oss; oss << "DataArrayDouble::findClosestTupleId : number of components in this is " << nbOfCompo;
1263       oss << ", whereas number of components in other is " << other->getNumberOfComponents() << "! Should be equal !";
1264       throw INTERP_KERNEL::Exception(oss.str().c_str());
1265     }
1266   int nbOfTuples=other->getNumberOfTuples();
1267   int thisNbOfTuples=getNumberOfTuples();
1268   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuples,1);
1269   double bounds[6];
1270   getMinMaxPerComponent(bounds);
1271   switch(nbOfCompo)
1272   {
1273     case 3:
1274       {
1275         double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2])),zDelta(fabs(bounds[5]-bounds[4]));
1276         double delta=std::max(xDelta,yDelta); delta=std::max(delta,zDelta);
1277         double characSize=pow((delta*delta*delta)/((double)thisNbOfTuples),1./3.);
1278         BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1279         FindClosestTupleIdAlg<3>(myTree,3.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1280         break;
1281       }
1282     case 2:
1283       {
1284         double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2]));
1285         double delta=std::max(xDelta,yDelta);
1286         double characSize=sqrt(delta/(double)thisNbOfTuples);
1287         BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1288         FindClosestTupleIdAlg<2>(myTree,2.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1289         break;
1290       }
1291     case 1:
1292       {
1293         double characSize=fabs(bounds[1]-bounds[0])/thisNbOfTuples;
1294         BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1295         FindClosestTupleIdAlg<1>(myTree,1.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1296         break;
1297       }
1298     default:
1299       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for findClosestTupleId. Must be 1, 2 or 3.");
1300   }
1301   return ret.retn();
1302 }
1303
1304 /*!
1305  * This method expects that \a this and \a otherBBoxFrmt arrays are bounding box arrays ( as the output of MEDCouplingPointSet::getBoundingBoxForBBTree method ).
1306  * 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
1307  * how many bounding boxes in \a otherBBoxFrmt.
1308  * So, this method expects that \a this and \a otherBBoxFrmt have the same number of components.
1309  *
1310  * \param [in] otherBBoxFrmt - It is an array .
1311  * \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.
1312  * \sa MEDCouplingPointSet::getBoundingBoxForBBTree
1313  * \throw If \a this and \a otherBBoxFrmt have not the same number of components.
1314  * \throw If \a this and \a otherBBoxFrmt number of components is not even (BBox format).
1315  */
1316 DataArrayInt *DataArrayDouble::computeNbOfInteractionsWith(const DataArrayDouble *otherBBoxFrmt, double eps) const
1317 {
1318   if(!otherBBoxFrmt)
1319     throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : input array is NULL !");
1320   if(!isAllocated() || !otherBBoxFrmt->isAllocated())
1321     throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : this and input array must be allocated !");
1322   int nbOfComp(getNumberOfComponents()),nbOfTuples(getNumberOfTuples());
1323   if(nbOfComp!=otherBBoxFrmt->getNumberOfComponents())
1324     {
1325       std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : this number of components (" << nbOfComp << ") must be equal to the number of components of input array (" << otherBBoxFrmt->getNumberOfComponents() << ") !";
1326       throw INTERP_KERNEL::Exception(oss.str().c_str());
1327     }
1328   if(nbOfComp%2!=0)
1329     {
1330       std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : Number of components (" << nbOfComp << ") is not even ! It should be to be compatible with bbox format !";
1331       throw INTERP_KERNEL::Exception(oss.str().c_str());
1332     }
1333   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbOfTuples,1);
1334   const double *thisBBPtr(begin());
1335   int *retPtr(ret->getPointer());
1336   switch(nbOfComp/2)
1337   {
1338     case 3:
1339       {
1340         BBTree<3,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
1341         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
1342           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
1343         break;
1344       }
1345     case 2:
1346       {
1347         BBTree<2,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
1348         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
1349           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
1350         break;
1351       }
1352     case 1:
1353       {
1354         BBTree<1,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
1355         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
1356           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
1357         break;
1358       }
1359     default:
1360       throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : space dimension supported are [1,2,3] !");
1361   }
1362
1363   return ret.retn();
1364 }
1365
1366 /*!
1367  * Returns a copy of \a this array by excluding coincident tuples. Each tuple is
1368  * considered as coordinates of a point in getNumberOfComponents()-dimensional
1369  * space. The distance between tuples is computed using norm2. If several tuples are
1370  * not far each from other than \a prec, only one of them remains in the result
1371  * array. The order of tuples in the result array is same as in \a this one except
1372  * that coincident tuples are excluded.
1373  *  \param [in] prec - minimal absolute distance between two tuples at which they are
1374  *              considered not coincident.
1375  *  \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
1376  *              tuples have id strictly lower than \a limitTupleId then they are not excluded.
1377  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1378  *          is to delete using decrRef() as it is no more needed.
1379  *  \throw If \a this is not allocated.
1380  *  \throw If the number of components is not in [1,2,3,4].
1381  *
1382  *  \if ENABLE_EXAMPLES
1383  *  \ref py_mcdataarraydouble_getdifferentvalues "Here is a Python example".
1384  *  \endif
1385  */
1386 DataArrayDouble *DataArrayDouble::getDifferentValues(double prec, int limitTupleId) const
1387 {
1388   checkAllocated();
1389   DataArrayInt *c0=0,*cI0=0;
1390   findCommonTuples(prec,limitTupleId,c0,cI0);
1391   MCAuto<DataArrayInt> c(c0),cI(cI0);
1392   int newNbOfTuples=-1;
1393   MCAuto<DataArrayInt> o2n=DataArrayInt::ConvertIndexArrayToO2N(getNumberOfTuples(),c0->begin(),cI0->begin(),cI0->end(),newNbOfTuples);
1394   return renumberAndReduce(o2n->getConstPointer(),newNbOfTuples);
1395 }
1396
1397 /*!
1398  * Copy all components in a specified order from another DataArrayDouble.
1399  * Both numerical and textual data is copied. The number of tuples in \a this and
1400  * the other array can be different.
1401  *  \param [in] a - the array to copy data from.
1402  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
1403  *              to be copied.
1404  *  \throw If \a a is NULL.
1405  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
1406  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
1407  *
1408  *  \if ENABLE_EXAMPLES
1409  *  \ref py_mcdataarraydouble_setselectedcomponents "Here is a Python example".
1410  *  \endif
1411  */
1412 void DataArrayDouble::setSelectedComponents(const DataArrayDouble *a, const std::vector<int>& compoIds)
1413 {
1414   if(!a)
1415     throw INTERP_KERNEL::Exception("DataArrayDouble::setSelectedComponents : input DataArrayDouble is NULL !");
1416   checkAllocated();
1417   copyPartOfStringInfoFrom2(compoIds,*a);
1418   std::size_t partOfCompoSz=compoIds.size();
1419   int nbOfCompo=getNumberOfComponents();
1420   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
1421   const double *ac=a->getConstPointer();
1422   double *nc=getPointer();
1423   for(int i=0;i<nbOfTuples;i++)
1424     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
1425       nc[nbOfCompo*i+compoIds[j]]=*ac;
1426 }
1427
1428 /*!
1429  * Checks if 0.0 value is present in \a this array. If it is the case, an exception
1430  * is thrown.
1431  * \throw If zero is found in \a this array.
1432  */
1433 void DataArrayDouble::checkNoNullValues() const
1434 {
1435   const double *tmp=getConstPointer();
1436   std::size_t nbOfElems=getNbOfElems();
1437   const double *where=std::find(tmp,tmp+nbOfElems,0.);
1438   if(where!=tmp+nbOfElems)
1439     throw INTERP_KERNEL::Exception("A value 0.0 have been detected !");
1440 }
1441
1442 /*!
1443  * Computes minimal and maximal value in each component. An output array is filled
1444  * with \c 2 * \a this->getNumberOfComponents() values, so the caller is to allocate
1445  * enough memory before calling this method.
1446  *  \param [out] bounds - array of size at least 2 *\a this->getNumberOfComponents().
1447  *               It is filled as follows:<br>
1448  *               \a bounds[0] = \c min_of_component_0 <br>
1449  *               \a bounds[1] = \c max_of_component_0 <br>
1450  *               \a bounds[2] = \c min_of_component_1 <br>
1451  *               \a bounds[3] = \c max_of_component_1 <br>
1452  *               ...
1453  */
1454 void DataArrayDouble::getMinMaxPerComponent(double *bounds) const
1455 {
1456   checkAllocated();
1457   int dim=getNumberOfComponents();
1458   for (int idim=0; idim<dim; idim++)
1459     {
1460       bounds[idim*2]=std::numeric_limits<double>::max();
1461       bounds[idim*2+1]=-std::numeric_limits<double>::max();
1462     } 
1463   const double *ptr=getConstPointer();
1464   int nbOfTuples=getNumberOfTuples();
1465   for(int i=0;i<nbOfTuples;i++)
1466     {
1467       for(int idim=0;idim<dim;idim++)
1468         {
1469           if(bounds[idim*2]>ptr[i*dim+idim])
1470             {
1471               bounds[idim*2]=ptr[i*dim+idim];
1472             }
1473           if(bounds[idim*2+1]<ptr[i*dim+idim])
1474             {
1475               bounds[idim*2+1]=ptr[i*dim+idim];
1476             }
1477         }
1478     }
1479 }
1480
1481 /*!
1482  * This method retrieves a newly allocated DataArrayDouble instance having same number of tuples than \a this and twice number of components than \a this
1483  * to store both the min and max per component of each tuples. 
1484  * \param [in] epsilon the width of the bbox (identical in each direction) - 0.0 by default
1485  *
1486  * \return a newly created DataArrayDouble instance having \c this->getNumberOfTuples() tuples and 2 * \c this->getNumberOfComponent() components
1487  *
1488  * \throw If \a this is not allocated yet.
1489  */
1490 DataArrayDouble *DataArrayDouble::computeBBoxPerTuple(double epsilon) const
1491 {
1492   checkAllocated();
1493   const double *dataPtr=getConstPointer();
1494   int nbOfCompo=getNumberOfComponents();
1495   int nbTuples=getNumberOfTuples();
1496   MCAuto<DataArrayDouble> bbox=DataArrayDouble::New();
1497   bbox->alloc(nbTuples,2*nbOfCompo);
1498   double *bboxPtr=bbox->getPointer();
1499   for(int i=0;i<nbTuples;i++)
1500     {
1501       for(int j=0;j<nbOfCompo;j++)
1502         {
1503           bboxPtr[2*nbOfCompo*i+2*j]=dataPtr[nbOfCompo*i+j]-epsilon;
1504           bboxPtr[2*nbOfCompo*i+2*j+1]=dataPtr[nbOfCompo*i+j]+epsilon;
1505         }
1506     }
1507   return bbox.retn();
1508 }
1509
1510 /*!
1511  * For each tuples **t** in \a other, this method retrieves tuples in \a this that are equal to **t**.
1512  * Two tuples are considered equal if the euclidian distance between the two tuples is lower than \a eps.
1513  * 
1514  * \param [in] other a DataArrayDouble having same number of components than \a this.
1515  * \param [in] eps absolute precision representing distance (using infinite norm) between 2 tuples behind which 2 tuples are considered equal.
1516  * \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.
1517  *             \a cI allows to extract information in \a c.
1518  * \param [out] cI is an indirection array that allows to extract the data contained in \a c.
1519  *
1520  * \throw In case of:
1521  *  - \a this is not allocated
1522  *  - \a other is not allocated or null
1523  *  - \a this and \a other do not have the same number of components
1524  *  - if number of components of \a this is not in [1,2,3]
1525  *
1526  * \sa MEDCouplingPointSet::getNodeIdsNearPoints, DataArrayDouble::getDifferentValues
1527  */
1528 void DataArrayDouble::computeTupleIdsNearTuples(const DataArrayDouble *other, double eps, DataArrayInt *& c, DataArrayInt *& cI) const
1529 {
1530   if(!other)
1531     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : input pointer other is null !");
1532   checkAllocated();
1533   other->checkAllocated();
1534   int nbOfCompo=getNumberOfComponents();
1535   int otherNbOfCompo=other->getNumberOfComponents();
1536   if(nbOfCompo!=otherNbOfCompo)
1537     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : number of components should be equal between this and other !");
1538   int nbOfTuplesOther=other->getNumberOfTuples();
1539   MCAuto<DataArrayInt> cArr(DataArrayInt::New()),cIArr(DataArrayInt::New()); cArr->alloc(0,1); cIArr->pushBackSilent(0);
1540   switch(nbOfCompo)
1541   {
1542     case 3:
1543       {
1544         BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
1545         FindTupleIdsNearTuplesAlg<3>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
1546         break;
1547       }
1548     case 2:
1549       {
1550         BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
1551         FindTupleIdsNearTuplesAlg<2>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
1552         break;
1553       }
1554     case 1:
1555       {
1556         BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
1557         FindTupleIdsNearTuplesAlg<1>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
1558         break;
1559       }
1560     default:
1561       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for computeTupleIdsNearTuples. Must be 1, 2 or 3.");
1562   }
1563   c=cArr.retn(); cI=cIArr.retn();
1564 }
1565
1566 /*!
1567  * 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
1568  * around origin of 'radius' 1.
1569  * 
1570  * \param [in] eps absolute epsilon. under that value of delta between max and min no scale is performed.
1571  */
1572 void DataArrayDouble::recenterForMaxPrecision(double eps)
1573 {
1574   checkAllocated();
1575   int dim=getNumberOfComponents();
1576   std::vector<double> bounds(2*dim);
1577   getMinMaxPerComponent(&bounds[0]);
1578   for(int i=0;i<dim;i++)
1579     {
1580       double delta=bounds[2*i+1]-bounds[2*i];
1581       double offset=(bounds[2*i]+bounds[2*i+1])/2.;
1582       if(delta>eps)
1583         applyLin(1./delta,-offset/delta,i);
1584       else
1585         applyLin(1.,-offset,i);
1586     }
1587 }
1588
1589 /*!
1590  * Returns the maximal value and all its locations within \a this one-dimensional array.
1591  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
1592  *               tuples holding the maximal value. The caller is to delete it using
1593  *               decrRef() as it is no more needed.
1594  *  \return double - the maximal value among all values of \a this array.
1595  *  \throw If \a this->getNumberOfComponents() != 1
1596  *  \throw If \a this->getNumberOfTuples() < 1
1597  */
1598 double DataArrayDouble::getMaxValue2(DataArrayInt*& tupleIds) const
1599 {
1600   int tmp;
1601   tupleIds=0;
1602   double ret=getMaxValue(tmp);
1603   tupleIds=findIdsInRange(ret,ret);
1604   return ret;
1605 }
1606
1607 /*!
1608  * Returns the minimal value and all its locations within \a this one-dimensional array.
1609  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
1610  *               tuples holding the minimal value. The caller is to delete it using
1611  *               decrRef() as it is no more needed.
1612  *  \return double - the minimal value among all values of \a this array.
1613  *  \throw If \a this->getNumberOfComponents() != 1
1614  *  \throw If \a this->getNumberOfTuples() < 1
1615  */
1616 double DataArrayDouble::getMinValue2(DataArrayInt*& tupleIds) const
1617 {
1618   int tmp;
1619   tupleIds=0;
1620   double ret=getMinValue(tmp);
1621   tupleIds=findIdsInRange(ret,ret);
1622   return ret;
1623 }
1624
1625 /*!
1626  * 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.
1627  * This method only works for single component array.
1628  *
1629  * \return a value in [ 0, \c this->getNumberOfTuples() )
1630  *
1631  * \throw If \a this is not allocated
1632  *
1633  */
1634 int DataArrayDouble::count(double value, double eps) const
1635 {
1636   int ret=0;
1637   checkAllocated();
1638   if(getNumberOfComponents()!=1)
1639     throw INTERP_KERNEL::Exception("DataArrayDouble::count : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
1640   const double *vals=begin();
1641   int nbOfTuples=getNumberOfTuples();
1642   for(int i=0;i<nbOfTuples;i++,vals++)
1643     if(fabs(*vals-value)<=eps)
1644       ret++;
1645   return ret;
1646 }
1647
1648 /*!
1649  * Returns the average value of \a this one-dimensional array.
1650  *  \return double - the average value over all values of \a this array.
1651  *  \throw If \a this->getNumberOfComponents() != 1
1652  *  \throw If \a this->getNumberOfTuples() < 1
1653  */
1654 double DataArrayDouble::getAverageValue() const
1655 {
1656   if(getNumberOfComponents()!=1)
1657     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
1658   int nbOfTuples=getNumberOfTuples();
1659   if(nbOfTuples<=0)
1660     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : array exists but number of tuples must be > 0 !");
1661   const double *vals=getConstPointer();
1662   double ret=std::accumulate(vals,vals+nbOfTuples,0.);
1663   return ret/nbOfTuples;
1664 }
1665
1666 /*!
1667  * Returns the Euclidean norm of the vector defined by \a this array.
1668  *  \return double - the value of the Euclidean norm, i.e.
1669  *          the square root of the inner product of vector.
1670  *  \throw If \a this is not allocated.
1671  */
1672 double DataArrayDouble::norm2() const
1673 {
1674   checkAllocated();
1675   double ret=0.;
1676   std::size_t nbOfElems=getNbOfElems();
1677   const double *pt=getConstPointer();
1678   for(std::size_t i=0;i<nbOfElems;i++,pt++)
1679     ret+=(*pt)*(*pt);
1680   return sqrt(ret);
1681 }
1682
1683 /*!
1684  * Returns the maximum norm of the vector defined by \a this array.
1685  * This method works even if the number of components is diferent from one.
1686  * If the number of elements in \a this is 0, -1. is returned.
1687  *  \return double - the value of the maximum norm, i.e.
1688  *          the maximal absolute value among values of \a this array (whatever its number of components).
1689  *  \throw If \a this is not allocated.
1690  */
1691 double DataArrayDouble::normMax() const
1692 {
1693   checkAllocated();
1694   double ret(-1.);
1695   std::size_t nbOfElems(getNbOfElems());
1696   const double *pt(getConstPointer());
1697   for(std::size_t i=0;i<nbOfElems;i++,pt++)
1698     {
1699       double val(std::abs(*pt));
1700       if(val>ret)
1701         ret=val;
1702     }
1703   return ret;
1704 }
1705
1706 /*!
1707  * Returns the minimum norm (absolute value) of the vector defined by \a this array.
1708  * This method works even if the number of components is diferent from one.
1709  * If the number of elements in \a this is 0, std::numeric_limits<double>::max() is returned.
1710  *  \return double - the value of the minimum norm, i.e.
1711  *          the minimal absolute value among values of \a this array (whatever its number of components).
1712  *  \throw If \a this is not allocated.
1713  */
1714 double DataArrayDouble::normMin() const
1715 {
1716   checkAllocated();
1717   double ret(std::numeric_limits<double>::max());
1718   std::size_t nbOfElems(getNbOfElems());
1719   const double *pt(getConstPointer());
1720   for(std::size_t i=0;i<nbOfElems;i++,pt++)
1721     {
1722       double val(std::abs(*pt));
1723       if(val<ret)
1724         ret=val;
1725     }
1726   return ret;
1727 }
1728
1729 /*!
1730  * Accumulates values of each component of \a this array.
1731  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
1732  *         by the caller, that is filled by this method with sum value for each
1733  *         component.
1734  *  \throw If \a this is not allocated.
1735  */
1736 void DataArrayDouble::accumulate(double *res) const
1737 {
1738   checkAllocated();
1739   const double *ptr=getConstPointer();
1740   int nbTuple=getNumberOfTuples();
1741   int nbComps=getNumberOfComponents();
1742   std::fill(res,res+nbComps,0.);
1743   for(int i=0;i<nbTuple;i++)
1744     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<double>());
1745 }
1746
1747 /*!
1748  * This method returns the min distance from an external tuple defined by [ \a tupleBg , \a tupleEnd ) to \a this and
1749  * the first tuple in \a this that matches the returned distance. If there is no tuples in \a this an exception will be thrown.
1750  *
1751  *
1752  * \a this is expected to be allocated and expected to have a number of components equal to the distance from \a tupleBg to
1753  * \a tupleEnd. If not an exception will be thrown.
1754  *
1755  * \param [in] tupleBg start pointer (included) of input external tuple
1756  * \param [in] tupleEnd end pointer (not included) of input external tuple
1757  * \param [out] tupleId the tuple id in \a this that matches the min of distance between \a this and input external tuple
1758  * \return the min distance.
1759  * \sa MEDCouplingUMesh::distanceToPoint
1760  */
1761 double DataArrayDouble::distanceToTuple(const double *tupleBg, const double *tupleEnd, int& tupleId) const
1762 {
1763   checkAllocated();
1764   int nbTuple=getNumberOfTuples();
1765   int nbComps=getNumberOfComponents();
1766   if(nbComps!=(int)std::distance(tupleBg,tupleEnd))
1767     { 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()); }
1768   if(nbTuple==0)
1769     throw INTERP_KERNEL::Exception("DataArrayDouble::distanceToTuple : no tuple in this ! No distance to compute !");
1770   double ret0=std::numeric_limits<double>::max();
1771   tupleId=-1;
1772   const double *work=getConstPointer();
1773   for(int i=0;i<nbTuple;i++)
1774     {
1775       double val=0.;
1776       for(int j=0;j<nbComps;j++,work++) 
1777         val+=(*work-tupleBg[j])*((*work-tupleBg[j]));
1778       if(val>=ret0)
1779         continue;
1780       else
1781         { ret0=val; tupleId=i; }
1782     }
1783   return sqrt(ret0);
1784 }
1785
1786 /*!
1787  * Accumulate values of the given component of \a this array.
1788  *  \param [in] compId - the index of the component of interest.
1789  *  \return double - a sum value of \a compId-th component.
1790  *  \throw If \a this is not allocated.
1791  *  \throw If \a the condition ( 0 <= \a compId < \a this->getNumberOfComponents() ) is
1792  *         not respected.
1793  */
1794 double DataArrayDouble::accumulate(int compId) const
1795 {
1796   checkAllocated();
1797   const double *ptr=getConstPointer();
1798   int nbTuple=getNumberOfTuples();
1799   int nbComps=getNumberOfComponents();
1800   if(compId<0 || compId>=nbComps)
1801     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulate : Invalid compId specified : No such nb of components !");
1802   double ret=0.;
1803   for(int i=0;i<nbTuple;i++)
1804     ret+=ptr[i*nbComps+compId];
1805   return ret;
1806 }
1807
1808 /*!
1809  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
1810  * The returned array will have same number of components than \a this and number of tuples equal to
1811  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
1812  *
1813  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
1814  * 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.
1815  *
1816  * \param [in] bgOfIndex - begin (included) of the input index array.
1817  * \param [in] endOfIndex - end (excluded) of the input index array.
1818  * \return DataArrayDouble * - the new instance having the same number of components than \a this.
1819  * 
1820  * \throw If bgOfIndex or end is NULL.
1821  * \throw If input index array is not ascendingly sorted.
1822  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
1823  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
1824  */
1825 DataArrayDouble *DataArrayDouble::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
1826 {
1827   if(!bgOfIndex || !endOfIndex)
1828     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : input pointer NULL !");
1829   checkAllocated();
1830   int nbCompo=getNumberOfComponents();
1831   int nbOfTuples=getNumberOfTuples();
1832   int sz=(int)std::distance(bgOfIndex,endOfIndex);
1833   if(sz<1)
1834     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : invalid size of input index array !");
1835   sz--;
1836   MCAuto<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(sz,nbCompo);
1837   const int *w=bgOfIndex;
1838   if(*w<0 || *w>=nbOfTuples)
1839     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
1840   const double *srcPt=begin()+(*w)*nbCompo;
1841   double *tmp=ret->getPointer();
1842   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
1843     {
1844       std::fill(tmp,tmp+nbCompo,0.);
1845       if(w[1]>=w[0])
1846         {
1847           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
1848             {
1849               if(j>=0 && j<nbOfTuples)
1850                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<double>());
1851               else
1852                 {
1853                   std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
1854                   throw INTERP_KERNEL::Exception(oss.str().c_str());
1855                 }
1856             }
1857         }
1858       else
1859         {
1860           std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
1861           throw INTERP_KERNEL::Exception(oss.str().c_str());
1862         }
1863     }
1864   ret->copyStringInfoFrom(*this);
1865   return ret.retn();
1866 }
1867
1868 /*!
1869  * 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.
1870  * This method expects that \a this as only one component. The returned array will have \a this->getNumberOfTuples()+1 tuple with also one component.
1871  * The ith element of returned array is equal to the sum of elements in \a this with rank strictly lower than i.
1872  *
1873  * \return DataArrayDouble - A newly built array containing cum sum of \a this.
1874  */
1875 MCAuto<DataArrayDouble> DataArrayDouble::cumSum() const
1876 {
1877   checkAllocated();
1878   checkNbOfComps(1,"DataArrayDouble::cumSum : this is expected to be single component");
1879   int nbOfTuple(getNumberOfTuples());
1880   MCAuto<DataArrayDouble> ret(DataArrayDouble::New()); ret->alloc(nbOfTuple+1,1);
1881   double *ptr(ret->getPointer());
1882   ptr[0]=0.;
1883   const double *thisPtr(begin());
1884   for(int i=0;i<nbOfTuple;i++)
1885     ptr[i+1]=ptr[i]+thisPtr[i];
1886   return ret;
1887 }
1888
1889 /*!
1890  * Converts each 2D point defined by the tuple of \a this array from the Polar to the
1891  * Cartesian coordinate system. The two components of the tuple of \a this array are 
1892  * considered to contain (1) radius and (2) angle of the point in the Polar CS.
1893  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
1894  *          contains X and Y coordinates of the point in the Cartesian CS. The caller
1895  *          is to delete this array using decrRef() as it is no more needed. The array
1896  *          does not contain any textual info on components.
1897  *  \throw If \a this->getNumberOfComponents() != 2.
1898  * \sa fromCartToPolar
1899  */
1900 DataArrayDouble *DataArrayDouble::fromPolarToCart() const
1901 {
1902   checkAllocated();
1903   int nbOfComp(getNumberOfComponents());
1904   if(nbOfComp!=2)
1905     throw INTERP_KERNEL::Exception("DataArrayDouble::fromPolarToCart : must be an array with exactly 2 components !");
1906   int nbOfTuple(getNumberOfTuples());
1907   DataArrayDouble *ret(DataArrayDouble::New());
1908   ret->alloc(nbOfTuple,2);
1909   double *w(ret->getPointer());
1910   const double *wIn(getConstPointer());
1911   for(int i=0;i<nbOfTuple;i++,w+=2,wIn+=2)
1912     {
1913       w[0]=wIn[0]*cos(wIn[1]);
1914       w[1]=wIn[0]*sin(wIn[1]);
1915     }
1916   return ret;
1917 }
1918
1919 /*!
1920  * Converts each 3D point defined by the tuple of \a this array from the Cylindrical to
1921  * the Cartesian coordinate system. The three components of the tuple of \a this array 
1922  * are considered to contain (1) radius, (2) azimuth and (3) altitude of the point in
1923  * the Cylindrical CS.
1924  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
1925  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
1926  *          on the third component is copied from \a this array. The caller
1927  *          is to delete this array using decrRef() as it is no more needed. 
1928  *  \throw If \a this->getNumberOfComponents() != 3.
1929  * \sa fromCartToCyl
1930  */
1931 DataArrayDouble *DataArrayDouble::fromCylToCart() const
1932 {
1933   checkAllocated();
1934   int nbOfComp(getNumberOfComponents());
1935   if(nbOfComp!=3)
1936     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCylToCart : must be an array with exactly 3 components !");
1937   int nbOfTuple(getNumberOfTuples());
1938   DataArrayDouble *ret(DataArrayDouble::New());
1939   ret->alloc(getNumberOfTuples(),3);
1940   double *w(ret->getPointer());
1941   const double *wIn(getConstPointer());
1942   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
1943     {
1944       w[0]=wIn[0]*cos(wIn[1]);
1945       w[1]=wIn[0]*sin(wIn[1]);
1946       w[2]=wIn[2];
1947     }
1948   ret->setInfoOnComponent(2,getInfoOnComponent(2));
1949   return ret;
1950 }
1951
1952 /*!
1953  * Converts each 3D point defined by the tuple of \a this array from the Spherical to
1954  * the Cartesian coordinate system. The three components of the tuple of \a this array 
1955  * are considered to contain (1) radius, (2) polar angle and (3) azimuthal angle of the
1956  * point in the Cylindrical CS.
1957  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
1958  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
1959  *          on the third component is copied from \a this array. The caller
1960  *          is to delete this array using decrRef() as it is no more needed.
1961  *  \throw If \a this->getNumberOfComponents() != 3.
1962  * \sa fromCartToSpher
1963  */
1964 DataArrayDouble *DataArrayDouble::fromSpherToCart() const
1965 {
1966   checkAllocated();
1967   int nbOfComp(getNumberOfComponents());
1968   if(nbOfComp!=3)
1969     throw INTERP_KERNEL::Exception("DataArrayDouble::fromSpherToCart : must be an array with exactly 3 components !");
1970   int nbOfTuple(getNumberOfTuples());
1971   DataArrayDouble *ret(DataArrayDouble::New());
1972   ret->alloc(getNumberOfTuples(),3);
1973   double *w(ret->getPointer());
1974   const double *wIn(getConstPointer());
1975   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
1976     {
1977       w[0]=wIn[0]*cos(wIn[2])*sin(wIn[1]);
1978       w[1]=wIn[0]*sin(wIn[2])*sin(wIn[1]);
1979       w[2]=wIn[0]*cos(wIn[1]);
1980     }
1981   return ret;
1982 }
1983
1984 /*!
1985  * 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.
1986  * 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.
1987  * If \a at equals to AX_CYL the returned array will be the result of operation cylindric to cartesian of \a this...
1988  *
1989  * \param [in] atOfThis - The axis type of \a this.
1990  * \return DataArrayDouble * - the new instance of DataArrayDouble (that must be dealed by caller) containing the result of the cartesianizification of \a this.
1991  */
1992 DataArrayDouble *DataArrayDouble::cartesianize(MEDCouplingAxisType atOfThis) const
1993 {
1994   checkAllocated();
1995   int nbOfComp(getNumberOfComponents());
1996   MCAuto<DataArrayDouble> ret;
1997   switch(atOfThis)
1998     {
1999     case AX_CART:
2000       ret=deepCopy();
2001     case AX_CYL:
2002       if(nbOfComp==3)
2003         {
2004           ret=fromCylToCart();
2005           break;
2006         }
2007       if(nbOfComp==2)
2008         {
2009           ret=fromPolarToCart();
2010           break;
2011         }
2012       else
2013         throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : For AX_CYL, number of components must be in [2,3] !");
2014     case AX_SPHER:
2015       if(nbOfComp==3)
2016         {
2017           ret=fromSpherToCart();
2018           break;
2019         }
2020       if(nbOfComp==2)
2021         {
2022           ret=fromPolarToCart();
2023           break;
2024         }
2025       else
2026         throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : For AX_CYL, number of components must be in [2,3] !");
2027     default:
2028       throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : not recognized axis type ! Only AX_CART, AX_CYL and AX_SPHER supported !");
2029     }
2030   ret->copyStringInfoFrom(*this);
2031   return ret.retn();
2032 }
2033
2034 /*!
2035  * This method returns a newly created array to be deallocated that contains the result of conversion from cartesian to polar.
2036  * This method expects that \a this has exactly 2 components.
2037  * \sa fromPolarToCart
2038  */
2039 DataArrayDouble *DataArrayDouble::fromCartToPolar() const
2040 {
2041   MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2042   checkAllocated();
2043   int nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2044   if(nbOfComp!=2)
2045     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToPolar : must be an array with exactly 2 components !");
2046   ret->alloc(nbTuples,2);
2047   double *retPtr(ret->getPointer());
2048   const double *ptr(begin());
2049   for(int i=0;i<nbTuples;i++,ptr+=2,retPtr+=2)
2050     {
2051       retPtr[0]=sqrt(ptr[0]*ptr[0]+ptr[1]*ptr[1]);
2052       retPtr[1]=atan2(ptr[1],ptr[0]);
2053     }
2054   return ret.retn();
2055 }
2056
2057 /*!
2058  * This method returns a newly created array to be deallocated that contains the result of conversion from cartesian to cylindrical.
2059  * This method expects that \a this has exactly 3 components.
2060  * \sa fromCylToCart
2061  */
2062 DataArrayDouble *DataArrayDouble::fromCartToCyl() const
2063 {
2064   MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2065   checkAllocated();
2066   int nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2067   if(nbOfComp!=3)
2068     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCyl : must be an array with exactly 3 components !");
2069   ret->alloc(nbTuples,3);
2070   double *retPtr(ret->getPointer());
2071   const double *ptr(begin());
2072   for(int i=0;i<nbTuples;i++,ptr+=3,retPtr+=3)
2073     {
2074       retPtr[0]=sqrt(ptr[0]*ptr[0]+ptr[1]*ptr[1]);
2075       retPtr[1]=atan2(ptr[1],ptr[0]);
2076       retPtr[2]=ptr[2];
2077     }
2078   return ret.retn();
2079 }
2080
2081 /*!
2082  * This method returns a newly created array to be deallocated that contains the result of conversion from cartesian to spherical coordinates.
2083  * \sa fromSpherToCart
2084  */
2085 DataArrayDouble *DataArrayDouble::fromCartToSpher() const
2086 {
2087   MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2088   checkAllocated();
2089   int nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2090   if(nbOfComp!=3)
2091     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToSpher : must be an array with exactly 3 components !");
2092   ret->alloc(nbTuples,3);
2093   double *retPtr(ret->getPointer());
2094   const double *ptr(begin());
2095   for(int i=0;i<nbTuples;i++,ptr+=3,retPtr+=3)
2096     {
2097       retPtr[0]=sqrt(ptr[0]*ptr[0]+ptr[1]*ptr[1]+ptr[2]*ptr[2]);
2098       retPtr[1]=acos(ptr[2]/retPtr[0]);
2099       retPtr[2]=atan2(ptr[1],ptr[0]);
2100     }
2101   return ret.retn();
2102 }
2103
2104 /*!
2105  * 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.
2106  * This method expects that \a this has exactly 3 components.
2107  * \sa MEDCouplingFieldDouble::computeVectorFieldCyl
2108  */
2109 DataArrayDouble *DataArrayDouble::fromCartToCylGiven(const DataArrayDouble *coords, const double center[3], const double vect[3]) const
2110 {
2111   if(!coords)
2112     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : input coords are NULL !");
2113   MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2114   checkAllocated(); coords->checkAllocated();
2115   int nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2116   if(nbOfComp!=3)
2117     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : must be an array with exactly 3 components !");
2118   if(coords->getNumberOfComponents()!=3)
2119     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : coords array must have exactly 3 components !");
2120   if(coords->getNumberOfTuples()!=nbTuples)
2121     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : coords array must have the same number of tuples !");
2122   ret->alloc(nbTuples,nbOfComp);
2123   double magOfVect(sqrt(vect[0]*vect[0]+vect[1]*vect[1]+vect[2]*vect[2]));
2124   if(magOfVect<1e-12)
2125     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : magnitude of vect is too low !");
2126   double Ur[3],Uteta[3],Uz[3],*retPtr(ret->getPointer());
2127   const double *coo(coords->begin()),*vectField(begin());
2128   std::transform(vect,vect+3,Uz,std::bind2nd(std::multiplies<double>(),1./magOfVect));
2129   for(int i=0;i<nbTuples;i++,vectField+=3,retPtr+=3,coo+=3)
2130     {
2131       std::transform(coo,coo+3,center,Ur,std::minus<double>());
2132       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];
2133       double magOfTeta(sqrt(Uteta[0]*Uteta[0]+Uteta[1]*Uteta[1]+Uteta[2]*Uteta[2]));
2134       std::transform(Uteta,Uteta+3,Uteta,std::bind2nd(std::multiplies<double>(),1./magOfTeta));
2135       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];
2136       retPtr[0]=Ur[0]*vectField[0]+Ur[1]*vectField[1]+Ur[2]*vectField[2];
2137       retPtr[1]=Uteta[0]*vectField[0]+Uteta[1]*vectField[1]+Uteta[2]*vectField[2];
2138       retPtr[2]=Uz[0]*vectField[0]+Uz[1]*vectField[1]+Uz[2]*vectField[2];
2139     }
2140   ret->copyStringInfoFrom(*this);
2141   return ret.retn();
2142 }
2143
2144 /*!
2145  * Computes the doubly contracted product of every tensor defined by the tuple of \a this
2146  * array contating 6 components.
2147  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
2148  *          is calculated from the tuple <em>(t)</em> of \a this array as follows:
2149  *          \f$ t[0]^2+t[1]^2+t[2]^2+2*t[3]^2+2*t[4]^2+2*t[5]^2\f$.
2150  *         The caller is to delete this result array using decrRef() as it is no more needed. 
2151  *  \throw If \a this->getNumberOfComponents() != 6.
2152  */
2153 DataArrayDouble *DataArrayDouble::doublyContractedProduct() const
2154 {
2155   checkAllocated();
2156   int nbOfComp(getNumberOfComponents());
2157   if(nbOfComp!=6)
2158     throw INTERP_KERNEL::Exception("DataArrayDouble::doublyContractedProduct : must be an array with exactly 6 components !");
2159   DataArrayDouble *ret=DataArrayDouble::New();
2160   int nbOfTuple=getNumberOfTuples();
2161   ret->alloc(nbOfTuple,1);
2162   const double *src=getConstPointer();
2163   double *dest=ret->getPointer();
2164   for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
2165     *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];
2166   return ret;
2167 }
2168
2169 /*!
2170  * Computes the determinant of every square matrix defined by the tuple of \a this
2171  * array, which contains either 4, 6 or 9 components. The case of 6 components
2172  * corresponds to that of the upper triangular matrix.
2173  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
2174  *          is the determinant of matrix of the corresponding tuple of \a this array.
2175  *          The caller is to delete this result array using decrRef() as it is no more
2176  *          needed. 
2177  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2178  */
2179 DataArrayDouble *DataArrayDouble::determinant() const
2180 {
2181   checkAllocated();
2182   DataArrayDouble *ret=DataArrayDouble::New();
2183   int nbOfTuple=getNumberOfTuples();
2184   ret->alloc(nbOfTuple,1);
2185   const double *src=getConstPointer();
2186   double *dest=ret->getPointer();
2187   switch(getNumberOfComponents())
2188   {
2189     case 6:
2190       for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
2191         *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];
2192       return ret;
2193     case 4:
2194       for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
2195         *dest=src[0]*src[3]-src[1]*src[2];
2196       return ret;
2197     case 9:
2198       for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
2199         *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];
2200       return ret;
2201     default:
2202       ret->decrRef();
2203       throw INTERP_KERNEL::Exception("DataArrayDouble::determinant : Invalid number of components ! must be in 4,6,9 !");
2204   }
2205 }
2206
2207 /*!
2208  * Computes 3 eigenvalues of every upper triangular matrix defined by the tuple of
2209  * \a this array, which contains 6 components.
2210  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 3
2211  *          components, whose each tuple contains the eigenvalues of the matrix of
2212  *          corresponding tuple of \a this array. 
2213  *          The caller is to delete this result array using decrRef() as it is no more
2214  *          needed. 
2215  *  \throw If \a this->getNumberOfComponents() != 6.
2216  */
2217 DataArrayDouble *DataArrayDouble::eigenValues() const
2218 {
2219   checkAllocated();
2220   int nbOfComp=getNumberOfComponents();
2221   if(nbOfComp!=6)
2222     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenValues : must be an array with exactly 6 components !");
2223   DataArrayDouble *ret=DataArrayDouble::New();
2224   int nbOfTuple=getNumberOfTuples();
2225   ret->alloc(nbOfTuple,3);
2226   const double *src=getConstPointer();
2227   double *dest=ret->getPointer();
2228   for(int i=0;i<nbOfTuple;i++,dest+=3,src+=6)
2229     INTERP_KERNEL::computeEigenValues6(src,dest);
2230   return ret;
2231 }
2232
2233 /*!
2234  * Computes 3 eigenvectors of every upper triangular matrix defined by the tuple of
2235  * \a this array, which contains 6 components.
2236  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 9
2237  *          components, whose each tuple contains 3 eigenvectors of the matrix of
2238  *          corresponding tuple of \a this array.
2239  *          The caller is to delete this result array using decrRef() as it is no more
2240  *          needed.
2241  *  \throw If \a this->getNumberOfComponents() != 6.
2242  */
2243 DataArrayDouble *DataArrayDouble::eigenVectors() const
2244 {
2245   checkAllocated();
2246   int nbOfComp=getNumberOfComponents();
2247   if(nbOfComp!=6)
2248     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenVectors : must be an array with exactly 6 components !");
2249   DataArrayDouble *ret=DataArrayDouble::New();
2250   int nbOfTuple=getNumberOfTuples();
2251   ret->alloc(nbOfTuple,9);
2252   const double *src=getConstPointer();
2253   double *dest=ret->getPointer();
2254   for(int i=0;i<nbOfTuple;i++,src+=6)
2255     {
2256       double tmp[3];
2257       INTERP_KERNEL::computeEigenValues6(src,tmp);
2258       for(int j=0;j<3;j++,dest+=3)
2259         INTERP_KERNEL::computeEigenVectorForEigenValue6(src,tmp[j],1e-12,dest);
2260     }
2261   return ret;
2262 }
2263
2264 /*!
2265  * Computes the inverse matrix of every matrix defined by the tuple of \a this
2266  * array, which contains either 4, 6 or 9 components. The case of 6 components
2267  * corresponds to that of the upper triangular matrix.
2268  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2269  *          same number of components as \a this one, whose each tuple is the inverse
2270  *          matrix of the matrix of corresponding tuple of \a this array. 
2271  *          The caller is to delete this result array using decrRef() as it is no more
2272  *          needed. 
2273  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2274  */
2275 DataArrayDouble *DataArrayDouble::inverse() const
2276 {
2277   checkAllocated();
2278   int nbOfComp=getNumberOfComponents();
2279   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
2280     throw INTERP_KERNEL::Exception("DataArrayDouble::inversion : must be an array with 4,6 or 9 components !");
2281   DataArrayDouble *ret=DataArrayDouble::New();
2282   int nbOfTuple=getNumberOfTuples();
2283   ret->alloc(nbOfTuple,nbOfComp);
2284   const double *src=getConstPointer();
2285   double *dest=ret->getPointer();
2286   if(nbOfComp==6)
2287     for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
2288       {
2289         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];
2290         dest[0]=(src[1]*src[2]-src[4]*src[4])/det;
2291         dest[1]=(src[0]*src[2]-src[5]*src[5])/det;
2292         dest[2]=(src[0]*src[1]-src[3]*src[3])/det;
2293         dest[3]=(src[5]*src[4]-src[3]*src[2])/det;
2294         dest[4]=(src[5]*src[3]-src[0]*src[4])/det;
2295         dest[5]=(src[3]*src[4]-src[1]*src[5])/det;
2296       }
2297   else if(nbOfComp==4)
2298     for(int i=0;i<nbOfTuple;i++,dest+=4,src+=4)
2299       {
2300         double det=src[0]*src[3]-src[1]*src[2];
2301         dest[0]=src[3]/det;
2302         dest[1]=-src[1]/det;
2303         dest[2]=-src[2]/det;
2304         dest[3]=src[0]/det;
2305       }
2306   else
2307     for(int i=0;i<nbOfTuple;i++,dest+=9,src+=9)
2308       {
2309         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];
2310         dest[0]=(src[4]*src[8]-src[7]*src[5])/det;
2311         dest[1]=(src[7]*src[2]-src[1]*src[8])/det;
2312         dest[2]=(src[1]*src[5]-src[4]*src[2])/det;
2313         dest[3]=(src[6]*src[5]-src[3]*src[8])/det;
2314         dest[4]=(src[0]*src[8]-src[6]*src[2])/det;
2315         dest[5]=(src[2]*src[3]-src[0]*src[5])/det;
2316         dest[6]=(src[3]*src[7]-src[6]*src[4])/det;
2317         dest[7]=(src[6]*src[1]-src[0]*src[7])/det;
2318         dest[8]=(src[0]*src[4]-src[1]*src[3])/det;
2319       }
2320   return ret;
2321 }
2322
2323 /*!
2324  * Computes the trace of every matrix defined by the tuple of \a this
2325  * array, which contains either 4, 6 or 9 components. The case of 6 components
2326  * corresponds to that of the upper triangular matrix.
2327  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 
2328  *          1 component, whose each tuple is the trace of
2329  *          the matrix of corresponding tuple of \a this array. 
2330  *          The caller is to delete this result array using decrRef() as it is no more
2331  *          needed. 
2332  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2333  */
2334 DataArrayDouble *DataArrayDouble::trace() const
2335 {
2336   checkAllocated();
2337   int nbOfComp=getNumberOfComponents();
2338   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
2339     throw INTERP_KERNEL::Exception("DataArrayDouble::trace : must be an array with 4,6 or 9 components !");
2340   DataArrayDouble *ret=DataArrayDouble::New();
2341   int nbOfTuple=getNumberOfTuples();
2342   ret->alloc(nbOfTuple,1);
2343   const double *src=getConstPointer();
2344   double *dest=ret->getPointer();
2345   if(nbOfComp==6)
2346     for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
2347       *dest=src[0]+src[1]+src[2];
2348   else if(nbOfComp==4)
2349     for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
2350       *dest=src[0]+src[3];
2351   else
2352     for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
2353       *dest=src[0]+src[4]+src[8];
2354   return ret;
2355 }
2356
2357 /*!
2358  * Computes the stress deviator tensor of every stress tensor defined by the tuple of
2359  * \a this array, which contains 6 components.
2360  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2361  *          same number of components and tuples as \a this array.
2362  *          The caller is to delete this result array using decrRef() as it is no more
2363  *          needed.
2364  *  \throw If \a this->getNumberOfComponents() != 6.
2365  */
2366 DataArrayDouble *DataArrayDouble::deviator() const
2367 {
2368   checkAllocated();
2369   int nbOfComp=getNumberOfComponents();
2370   if(nbOfComp!=6)
2371     throw INTERP_KERNEL::Exception("DataArrayDouble::deviator : must be an array with exactly 6 components !");
2372   DataArrayDouble *ret=DataArrayDouble::New();
2373   int nbOfTuple=getNumberOfTuples();
2374   ret->alloc(nbOfTuple,6);
2375   const double *src=getConstPointer();
2376   double *dest=ret->getPointer();
2377   for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
2378     {
2379       double tr=(src[0]+src[1]+src[2])/3.;
2380       dest[0]=src[0]-tr;
2381       dest[1]=src[1]-tr;
2382       dest[2]=src[2]-tr;
2383       dest[3]=src[3];
2384       dest[4]=src[4];
2385       dest[5]=src[5];
2386     }
2387   return ret;
2388 }
2389
2390 /*!
2391  * Computes the magnitude of every vector defined by the tuple of
2392  * \a this array.
2393  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2394  *          same number of tuples as \a this array and one component.
2395  *          The caller is to delete this result array using decrRef() as it is no more
2396  *          needed.
2397  *  \throw If \a this is not allocated.
2398  */
2399 DataArrayDouble *DataArrayDouble::magnitude() const
2400 {
2401   checkAllocated();
2402   int nbOfComp=getNumberOfComponents();
2403   DataArrayDouble *ret=DataArrayDouble::New();
2404   int nbOfTuple=getNumberOfTuples();
2405   ret->alloc(nbOfTuple,1);
2406   const double *src=getConstPointer();
2407   double *dest=ret->getPointer();
2408   for(int i=0;i<nbOfTuple;i++,dest++)
2409     {
2410       double sum=0.;
2411       for(int j=0;j<nbOfComp;j++,src++)
2412         sum+=(*src)*(*src);
2413       *dest=sqrt(sum);
2414     }
2415   return ret;
2416 }
2417
2418 /*!
2419  * Computes for each tuple the sum of number of components values in the tuple and return it.
2420  * 
2421  * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2422  *          same number of tuples as \a this array and one component.
2423  *          The caller is to delete this result array using decrRef() as it is no more
2424  *          needed.
2425  *  \throw If \a this is not allocated.
2426  */
2427 DataArrayDouble *DataArrayDouble::sumPerTuple() const
2428 {
2429   checkAllocated();
2430   int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
2431   MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2432   ret->alloc(nbOfTuple,1);
2433   const double *src(getConstPointer());
2434   double *dest(ret->getPointer());
2435   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
2436     *dest=std::accumulate(src,src+nbOfComp,0.);
2437   return ret.retn();
2438 }
2439
2440 /*!
2441  * Computes the maximal value within every tuple of \a this array.
2442  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2443  *          same number of tuples as \a this array and one component.
2444  *          The caller is to delete this result array using decrRef() as it is no more
2445  *          needed.
2446  *  \throw If \a this is not allocated.
2447  *  \sa DataArrayDouble::maxPerTupleWithCompoId
2448  */
2449 DataArrayDouble *DataArrayDouble::maxPerTuple() const
2450 {
2451   checkAllocated();
2452   int nbOfComp=getNumberOfComponents();
2453   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
2454   int nbOfTuple=getNumberOfTuples();
2455   ret->alloc(nbOfTuple,1);
2456   const double *src=getConstPointer();
2457   double *dest=ret->getPointer();
2458   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
2459     *dest=*std::max_element(src,src+nbOfComp);
2460   return ret.retn();
2461 }
2462
2463 /*!
2464  * Computes the maximal value within every tuple of \a this array and it returns the first component
2465  * id for each tuple that corresponds to the maximal value within the tuple.
2466  * 
2467  *  \param [out] compoIdOfMaxPerTuple - the new new instance of DataArrayInt containing the
2468  *          same number of tuples and only one component.
2469  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2470  *          same number of tuples as \a this array and one component.
2471  *          The caller is to delete this result array using decrRef() as it is no more
2472  *          needed.
2473  *  \throw If \a this is not allocated.
2474  *  \sa DataArrayDouble::maxPerTuple
2475  */
2476 DataArrayDouble *DataArrayDouble::maxPerTupleWithCompoId(DataArrayInt* &compoIdOfMaxPerTuple) const
2477 {
2478   checkAllocated();
2479   int nbOfComp=getNumberOfComponents();
2480   MCAuto<DataArrayDouble> ret0=DataArrayDouble::New();
2481   MCAuto<DataArrayInt> ret1=DataArrayInt::New();
2482   int nbOfTuple=getNumberOfTuples();
2483   ret0->alloc(nbOfTuple,1); ret1->alloc(nbOfTuple,1);
2484   const double *src=getConstPointer();
2485   double *dest=ret0->getPointer(); int *dest1=ret1->getPointer();
2486   for(int i=0;i<nbOfTuple;i++,dest++,dest1++,src+=nbOfComp)
2487     {
2488       const double *loc=std::max_element(src,src+nbOfComp);
2489       *dest=*loc;
2490       *dest1=(int)std::distance(src,loc);
2491     }
2492   compoIdOfMaxPerTuple=ret1.retn();
2493   return ret0.retn();
2494 }
2495
2496 /*!
2497  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c this->getNumberOfTuples() tuples.
2498  * \n This returned array contains the euclidian distance for each tuple in \a this. 
2499  * \n So the returned array can be seen as a dense symmetrical matrix whose diagonal elements are equal to 0.
2500  * \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)
2501  *
2502  * \warning use this method with care because it can leads to big amount of consumed memory !
2503  * 
2504  * \return A newly allocated (huge) MEDCoupling::DataArrayDouble instance that the caller should deal with.
2505  *
2506  * \throw If \a this is not allocated.
2507  *
2508  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrixWith
2509  */
2510 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrix() const
2511 {
2512   checkAllocated();
2513   int nbOfComp=getNumberOfComponents();
2514   int nbOfTuples=getNumberOfTuples();
2515   const double *inData=getConstPointer();
2516   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
2517   ret->alloc(nbOfTuples*nbOfTuples,1);
2518   double *outData=ret->getPointer();
2519   for(int i=0;i<nbOfTuples;i++)
2520     {
2521       outData[i*nbOfTuples+i]=0.;
2522       for(int j=i+1;j<nbOfTuples;j++)
2523         {
2524           double dist=0.;
2525           for(int k=0;k<nbOfComp;k++)
2526             { double delta=inData[i*nbOfComp+k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
2527           dist=sqrt(dist);
2528           outData[i*nbOfTuples+j]=dist;
2529           outData[j*nbOfTuples+i]=dist;
2530         }
2531     }
2532   return ret.retn();
2533 }
2534
2535 /*!
2536  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c other->getNumberOfTuples() tuples.
2537  * \n This returned array contains the euclidian distance for each tuple in \a other with each tuple in \a this. 
2538  * \n So the returned array can be seen as a dense rectangular matrix with \c other->getNumberOfTuples() rows and \c this->getNumberOfTuples() columns.
2539  * \n Output rectangular matrix is sorted along rows.
2540  * \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)
2541  *
2542  * \warning use this method with care because it can leads to big amount of consumed memory !
2543  * 
2544  * \param [in] other DataArrayDouble instance having same number of components than \a this.
2545  * \return A newly allocated (huge) MEDCoupling::DataArrayDouble instance that the caller should deal with.
2546  *
2547  * \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.
2548  *
2549  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrix
2550  */
2551 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrixWith(const DataArrayDouble *other) const
2552 {
2553   if(!other)
2554     throw INTERP_KERNEL::Exception("DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : input parameter is null !");
2555   checkAllocated();
2556   other->checkAllocated();
2557   int nbOfComp=getNumberOfComponents();
2558   int otherNbOfComp=other->getNumberOfComponents();
2559   if(nbOfComp!=otherNbOfComp)
2560     {
2561       std::ostringstream oss; oss << "DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : this nb of compo=" << nbOfComp << " and other nb of compo=" << otherNbOfComp << ". It should match !";
2562       throw INTERP_KERNEL::Exception(oss.str().c_str());
2563     }
2564   int nbOfTuples=getNumberOfTuples();
2565   int otherNbOfTuples=other->getNumberOfTuples();
2566   const double *inData=getConstPointer();
2567   const double *inDataOther=other->getConstPointer();
2568   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
2569   ret->alloc(otherNbOfTuples*nbOfTuples,1);
2570   double *outData=ret->getPointer();
2571   for(int i=0;i<otherNbOfTuples;i++,inDataOther+=nbOfComp)
2572     {
2573       for(int j=0;j<nbOfTuples;j++)
2574         {
2575           double dist=0.;
2576           for(int k=0;k<nbOfComp;k++)
2577             { double delta=inDataOther[k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
2578           dist=sqrt(dist);
2579           outData[i*nbOfTuples+j]=dist;
2580         }
2581     }
2582   return ret.retn();
2583 }
2584
2585 /*!
2586  * Sorts value within every tuple of \a this array.
2587  *  \param [in] asc - if \a true, the values are sorted in ascending order, else,
2588  *              in descending order.
2589  *  \throw If \a this is not allocated.
2590  */
2591 void DataArrayDouble::sortPerTuple(bool asc)
2592 {
2593   checkAllocated();
2594   double *pt=getPointer();
2595   int nbOfTuple=getNumberOfTuples();
2596   int nbOfComp=getNumberOfComponents();
2597   if(asc)
2598     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
2599       std::sort(pt,pt+nbOfComp);
2600   else
2601     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
2602       std::sort(pt,pt+nbOfComp,std::greater<double>());
2603   declareAsNew();
2604 }
2605
2606 /*!
2607  * Converts every value of \a this array to its absolute value.
2608  * \b WARNING this method is non const. If a new DataArrayDouble instance should be built containing the result of abs DataArrayDouble::computeAbs
2609  * should be called instead.
2610  *
2611  * \throw If \a this is not allocated.
2612  * \sa DataArrayDouble::computeAbs
2613  */
2614 void DataArrayDouble::abs()
2615 {
2616   checkAllocated();
2617   double *ptr(getPointer());
2618   std::size_t nbOfElems(getNbOfElems());
2619   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<double,double>(fabs));
2620   declareAsNew();
2621 }
2622
2623 /*!
2624  * This method builds a new instance of \a this object containing the result of std::abs applied of all elements in \a this.
2625  * This method is a const method (that do not change any values in \a this) contrary to  DataArrayDouble::abs method.
2626  *
2627  * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2628  *         same number of tuples and component as \a this array.
2629  *         The caller is to delete this result array using decrRef() as it is no more
2630  *         needed.
2631  * \throw If \a this is not allocated.
2632  * \sa DataArrayDouble::abs
2633  */
2634 DataArrayDouble *DataArrayDouble::computeAbs() const
2635 {
2636   checkAllocated();
2637   DataArrayDouble *newArr(DataArrayDouble::New());
2638   int nbOfTuples(getNumberOfTuples());
2639   int nbOfComp(getNumberOfComponents());
2640   newArr->alloc(nbOfTuples,nbOfComp);
2641   std::transform(begin(),end(),newArr->getPointer(),std::ptr_fun<double,double>(fabs));
2642   newArr->copyStringInfoFrom(*this);
2643   return newArr;
2644 }
2645
2646 /*!
2647  * Modify all elements of \a this array, so that
2648  * an element _x_ becomes \f$ numerator / x \f$.
2649  *  \warning If an exception is thrown because of presence of 0.0 element in \a this 
2650  *           array, all elements processed before detection of the zero element remain
2651  *           modified.
2652  *  \param [in] numerator - the numerator used to modify array elements.
2653  *  \throw If \a this is not allocated.
2654  *  \throw If there is an element equal to 0.0 in \a this array.
2655  */
2656 void DataArrayDouble::applyInv(double numerator)
2657 {
2658   checkAllocated();
2659   double *ptr=getPointer();
2660   std::size_t nbOfElems=getNbOfElems();
2661   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2662     {
2663       if(std::abs(*ptr)>std::numeric_limits<double>::min())
2664         {
2665           *ptr=numerator/(*ptr);
2666         }
2667       else
2668         {
2669           std::ostringstream oss; oss << "DataArrayDouble::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
2670           oss << " !";
2671           throw INTERP_KERNEL::Exception(oss.str().c_str());
2672         }
2673     }
2674   declareAsNew();
2675 }
2676
2677 /*!
2678  * Modify all elements of \a this array, so that
2679  * an element _x_ becomes <em> val ^ x </em>. Contrary to DataArrayInt::applyPow
2680  * all values in \a this have to be >= 0 if val is \b not integer.
2681  *  \param [in] val - the value used to apply pow on all array elements.
2682  *  \throw If \a this is not allocated.
2683  *  \warning If an exception is thrown because of presence of 0 element in \a this 
2684  *           array and \a val is \b not integer, all elements processed before detection of the zero element remain
2685  *           modified.
2686  */
2687 void DataArrayDouble::applyPow(double val)
2688 {
2689   checkAllocated();
2690   double *ptr=getPointer();
2691   std::size_t nbOfElems=getNbOfElems();
2692   int val2=(int)val;
2693   bool isInt=((double)val2)==val;
2694   if(!isInt)
2695     {
2696       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2697         {
2698           if(*ptr>=0)
2699             *ptr=pow(*ptr,val);
2700           else
2701             {
2702               std::ostringstream oss; oss << "DataArrayDouble::applyPow (double) : At elem # " << i << " value is " << *ptr << " ! must be >=0. !";
2703               throw INTERP_KERNEL::Exception(oss.str().c_str());
2704             }
2705         }
2706     }
2707   else
2708     {
2709       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2710         *ptr=pow(*ptr,val2);
2711     }
2712   declareAsNew();
2713 }
2714
2715 /*!
2716  * Modify all elements of \a this array, so that
2717  * an element _x_ becomes \f$ val ^ x \f$.
2718  *  \param [in] val - the value used to apply pow on all array elements.
2719  *  \throw If \a this is not allocated.
2720  *  \throw If \a val < 0.
2721  *  \warning If an exception is thrown because of presence of 0 element in \a this 
2722  *           array, all elements processed before detection of the zero element remain
2723  *           modified.
2724  */
2725 void DataArrayDouble::applyRPow(double val)
2726 {
2727   checkAllocated();
2728   if(val<0.)
2729     throw INTERP_KERNEL::Exception("DataArrayDouble::applyRPow : the input value has to be >= 0 !");
2730   double *ptr=getPointer();
2731   std::size_t nbOfElems=getNbOfElems();
2732   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2733     *ptr=pow(val,*ptr);
2734   declareAsNew();
2735 }
2736
2737 /*!
2738  * Returns a new DataArrayDouble created from \a this one by applying \a
2739  * FunctionToEvaluate to every tuple of \a this array. Textual data is not copied.
2740  * For more info see \ref MEDCouplingArrayApplyFunc
2741  *  \param [in] nbOfComp - number of components in the result array.
2742  *  \param [in] func - the \a FunctionToEvaluate declared as 
2743  *              \c bool (*\a func)(\c const \c double *\a pos, \c double *\a res), 
2744  *              where \a pos points to the first component of a tuple of \a this array
2745  *              and \a res points to the first component of a tuple of the result array.
2746  *              Note that length (number of components) of \a pos can differ from
2747  *              that of \a res.
2748  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2749  *          same number of tuples as \a this array.
2750  *          The caller is to delete this result array using decrRef() as it is no more
2751  *          needed.
2752  *  \throw If \a this is not allocated.
2753  *  \throw If \a func returns \a false.
2754  */
2755 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, FunctionToEvaluate func) const
2756 {
2757   checkAllocated();
2758   DataArrayDouble *newArr=DataArrayDouble::New();
2759   int nbOfTuples=getNumberOfTuples();
2760   int oldNbOfComp=getNumberOfComponents();
2761   newArr->alloc(nbOfTuples,nbOfComp);
2762   const double *ptr=getConstPointer();
2763   double *ptrToFill=newArr->getPointer();
2764   for(int i=0;i<nbOfTuples;i++)
2765     {
2766       if(!func(ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp))
2767         {
2768           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
2769           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
2770           oss << ") : Evaluation of function failed !";
2771           newArr->decrRef();
2772           throw INTERP_KERNEL::Exception(oss.str().c_str());
2773         }
2774     }
2775   return newArr;
2776 }
2777
2778 /*!
2779  * Returns a new DataArrayDouble created from \a this one by applying a function to every
2780  * tuple of \a this array. Textual data is not copied.
2781  * For more info see \ref MEDCouplingArrayApplyFunc1.
2782  *  \param [in] nbOfComp - number of components in the result array.
2783  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
2784  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
2785  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
2786  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
2787  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2788  *          same number of tuples as \a this array and \a nbOfComp components.
2789  *          The caller is to delete this result array using decrRef() as it is no more
2790  *          needed.
2791  *  \throw If \a this is not allocated.
2792  *  \throw If computing \a func fails.
2793  */
2794 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, const std::string& func, bool isSafe) const
2795 {
2796   INTERP_KERNEL::ExprParser expr(func);
2797   expr.parse();
2798   std::set<std::string> vars;
2799   expr.getTrueSetOfVars(vars);
2800   std::vector<std::string> varsV(vars.begin(),vars.end());
2801   return applyFuncNamedCompo(nbOfComp,varsV,func,isSafe);
2802 }
2803
2804 /*!
2805  * Returns a new DataArrayDouble created from \a this one by applying a function to every
2806  * tuple of \a this array. Textual data is not copied. This method works by tuples (whatever its size).
2807  * If \a this is a one component array, call applyFuncOnThis instead that performs the same work faster.
2808  *
2809  * For more info see \ref MEDCouplingArrayApplyFunc0.
2810  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
2811  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
2812  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
2813  *                       If false the computation is carried on without any notification. When false the evaluation is a little faster.
2814  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2815  *          same number of tuples and components as \a this array.
2816  *          The caller is to delete this result array using decrRef() as it is no more
2817  *          needed.
2818  *  \sa applyFuncOnThis
2819  *  \throw If \a this is not allocated.
2820  *  \throw If computing \a func fails.
2821  */
2822 DataArrayDouble *DataArrayDouble::applyFunc(const std::string& func, bool isSafe) const
2823 {
2824   int nbOfComp(getNumberOfComponents());
2825   if(nbOfComp<=0)
2826     throw INTERP_KERNEL::Exception("DataArrayDouble::applyFunc : output number of component must be > 0 !");
2827   checkAllocated();
2828   int nbOfTuples(getNumberOfTuples());
2829   MCAuto<DataArrayDouble> newArr(DataArrayDouble::New());
2830   newArr->alloc(nbOfTuples,nbOfComp);
2831   INTERP_KERNEL::ExprParser expr(func);
2832   expr.parse();
2833   std::set<std::string> vars;
2834   expr.getTrueSetOfVars(vars);
2835   if((int)vars.size()>1)
2836     {
2837       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 : ";
2838       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
2839       throw INTERP_KERNEL::Exception(oss.str().c_str());
2840     }
2841   if(vars.empty())
2842     {
2843       expr.prepareFastEvaluator();
2844       newArr->rearrange(1);
2845       newArr->fillWithValue(expr.evaluateDouble());
2846       newArr->rearrange(nbOfComp);
2847       return newArr.retn();
2848     }
2849   std::vector<std::string> vars2(vars.begin(),vars.end());
2850   double buff,*ptrToFill(newArr->getPointer());
2851   const double *ptr(begin());
2852   std::vector<double> stck;
2853   expr.prepareExprEvaluationDouble(vars2,1,1,0,&buff,&buff+1);
2854   expr.prepareFastEvaluator();
2855   if(!isSafe)
2856     {
2857       for(int i=0;i<nbOfTuples;i++)
2858         {
2859           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
2860             {
2861               buff=*ptr;
2862               expr.evaluateDoubleInternal(stck);
2863               *ptrToFill=stck.back();
2864               stck.pop_back();
2865             }
2866         }
2867     }
2868   else
2869     {
2870       for(int i=0;i<nbOfTuples;i++)
2871         {
2872           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
2873             {
2874               buff=*ptr;
2875               try
2876               {
2877                   expr.evaluateDoubleInternalSafe(stck);
2878               }
2879               catch(INTERP_KERNEL::Exception& e)
2880               {
2881                   std::ostringstream oss; oss << "For tuple # " << i << " component # " << iComp << " with value (";
2882                   oss << buff;
2883                   oss << ") : Evaluation of function failed !" << e.what();
2884                   throw INTERP_KERNEL::Exception(oss.str().c_str());
2885               }
2886               *ptrToFill=stck.back();
2887               stck.pop_back();
2888             }
2889         }
2890     }
2891   return newArr.retn();
2892 }
2893
2894 /*!
2895  * This method is a non const method that modify the array in \a this.
2896  * This method only works on one component array. It means that function \a func must
2897  * contain at most one variable.
2898  * This method is a specialization of applyFunc method with one parameter on one component array.
2899  *
2900  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
2901  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
2902  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
2903  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
2904  *
2905  * \sa applyFunc
2906  */
2907 void DataArrayDouble::applyFuncOnThis(const std::string& func, bool isSafe)
2908 {
2909   int nbOfComp(getNumberOfComponents());
2910   if(nbOfComp<=0)
2911     throw INTERP_KERNEL::Exception("DataArrayDouble::applyFuncOnThis : output number of component must be > 0 !");
2912   checkAllocated();
2913   int nbOfTuples(getNumberOfTuples());
2914   INTERP_KERNEL::ExprParser expr(func);
2915   expr.parse();
2916   std::set<std::string> vars;
2917   expr.getTrueSetOfVars(vars);
2918   if((int)vars.size()>1)
2919     {
2920       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 : ";
2921       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
2922       throw INTERP_KERNEL::Exception(oss.str().c_str());
2923     }
2924   if(vars.empty())
2925     {
2926       expr.prepareFastEvaluator();
2927       std::vector<std::string> compInfo(getInfoOnComponents());
2928       rearrange(1);
2929       fillWithValue(expr.evaluateDouble());
2930       rearrange(nbOfComp);
2931       setInfoOnComponents(compInfo);
2932       return ;
2933     }
2934   std::vector<std::string> vars2(vars.begin(),vars.end());
2935   double buff,*ptrToFill(getPointer());
2936   const double *ptr(begin());
2937   std::vector<double> stck;
2938   expr.prepareExprEvaluationDouble(vars2,1,1,0,&buff,&buff+1);
2939   expr.prepareFastEvaluator();
2940   if(!isSafe)
2941     {
2942       for(int i=0;i<nbOfTuples;i++)
2943         {
2944           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
2945             {
2946               buff=*ptr;
2947               expr.evaluateDoubleInternal(stck);
2948               *ptrToFill=stck.back();
2949               stck.pop_back();
2950             }
2951         }
2952     }
2953   else
2954     {
2955       for(int i=0;i<nbOfTuples;i++)
2956         {
2957           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
2958             {
2959               buff=*ptr;
2960               try
2961               {
2962                   expr.evaluateDoubleInternalSafe(stck);
2963               }
2964               catch(INTERP_KERNEL::Exception& e)
2965               {
2966                   std::ostringstream oss; oss << "For tuple # " << i << " component # " << iComp << " with value (";
2967                   oss << buff;
2968                   oss << ") : Evaluation of function failed !" << e.what();
2969                   throw INTERP_KERNEL::Exception(oss.str().c_str());
2970               }
2971               *ptrToFill=stck.back();
2972               stck.pop_back();
2973             }
2974         }
2975     }
2976 }
2977
2978 /*!
2979  * Returns a new DataArrayDouble created from \a this one by applying a function to every
2980  * tuple of \a this array. Textual data is not copied.
2981  * For more info see \ref MEDCouplingArrayApplyFunc2.
2982  *  \param [in] nbOfComp - number of components in the result array.
2983  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
2984  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
2985  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
2986  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
2987  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2988  *          same number of tuples as \a this array.
2989  *          The caller is to delete this result array using decrRef() as it is no more
2990  *          needed.
2991  *  \throw If \a this is not allocated.
2992  *  \throw If \a func contains vars that are not in \a this->getInfoOnComponent().
2993  *  \throw If computing \a func fails.
2994  */
2995 DataArrayDouble *DataArrayDouble::applyFuncCompo(int nbOfComp, const std::string& func, bool isSafe) const
2996 {
2997   return applyFuncNamedCompo(nbOfComp,getVarsOnComponent(),func,isSafe);
2998 }
2999
3000 /*!
3001  * Returns a new DataArrayDouble created from \a this one by applying a function to every
3002  * tuple of \a this array. Textual data is not copied.
3003  * For more info see \ref MEDCouplingArrayApplyFunc3.
3004  *  \param [in] nbOfComp - number of components in the result array.
3005  *  \param [in] varsOrder - sequence of vars defining their order.
3006  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
3007  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
3008  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
3009  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
3010  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3011  *          same number of tuples as \a this array.
3012  *          The caller is to delete this result array using decrRef() as it is no more
3013  *          needed.
3014  *  \throw If \a this is not allocated.
3015  *  \throw If \a func contains vars not in \a varsOrder.
3016  *  \throw If computing \a func fails.
3017  */
3018 DataArrayDouble *DataArrayDouble::applyFuncNamedCompo(int nbOfComp, const std::vector<std::string>& varsOrder, const std::string& func, bool isSafe) const
3019 {
3020   if(nbOfComp<=0)
3021     throw INTERP_KERNEL::Exception("DataArrayDouble::applyFuncNamedCompo : output number of component must be > 0 !");
3022   std::vector<std::string> varsOrder2(varsOrder);
3023   int oldNbOfComp(getNumberOfComponents());
3024   for(int i=(int)varsOrder.size();i<oldNbOfComp;i++)
3025     varsOrder2.push_back(std::string());
3026   checkAllocated();
3027   int nbOfTuples(getNumberOfTuples());
3028   INTERP_KERNEL::ExprParser expr(func);
3029   expr.parse();
3030   std::set<std::string> vars;
3031   expr.getTrueSetOfVars(vars);
3032   if((int)vars.size()>oldNbOfComp)
3033     {
3034       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
3035       oss << vars.size() << " variables : ";
3036       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
3037       throw INTERP_KERNEL::Exception(oss.str().c_str());
3038     }
3039   MCAuto<DataArrayDouble> newArr(DataArrayDouble::New());
3040   newArr->alloc(nbOfTuples,nbOfComp);
3041   INTERP_KERNEL::AutoPtr<double> buff(new double[oldNbOfComp]);
3042   double *buffPtr(buff),*ptrToFill;
3043   std::vector<double> stck;
3044   for(int iComp=0;iComp<nbOfComp;iComp++)
3045     {
3046       expr.prepareExprEvaluationDouble(varsOrder2,oldNbOfComp,nbOfComp,iComp,buffPtr,buffPtr+oldNbOfComp);
3047       expr.prepareFastEvaluator();
3048       const double *ptr(getConstPointer());
3049       ptrToFill=newArr->getPointer()+iComp;
3050       if(!isSafe)
3051         {
3052           for(int i=0;i<nbOfTuples;i++,ptrToFill+=nbOfComp,ptr+=oldNbOfComp)
3053             {
3054               std::copy(ptr,ptr+oldNbOfComp,buffPtr);
3055               expr.evaluateDoubleInternal(stck);
3056               *ptrToFill=stck.back();
3057               stck.pop_back();
3058             }
3059         }
3060       else
3061         {
3062           for(int i=0;i<nbOfTuples;i++,ptrToFill+=nbOfComp,ptr+=oldNbOfComp)
3063             {
3064               std::copy(ptr,ptr+oldNbOfComp,buffPtr);
3065               try
3066               {
3067                   expr.evaluateDoubleInternalSafe(stck);
3068                   *ptrToFill=stck.back();
3069                   stck.pop_back();
3070               }
3071               catch(INTERP_KERNEL::Exception& e)
3072               {
3073                   std::ostringstream oss; oss << "For tuple # " << i << " with value (";
3074                   std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
3075                   oss << ") : Evaluation of function failed !" << e.what();
3076                   throw INTERP_KERNEL::Exception(oss.str().c_str());
3077               }
3078             }
3079         }
3080     }
3081   return newArr.retn();
3082 }
3083
3084 void DataArrayDouble::applyFuncFast32(const std::string& func)
3085 {
3086   checkAllocated();
3087   INTERP_KERNEL::ExprParser expr(func);
3088   expr.parse();
3089   char *funcStr=expr.compileX86();
3090   MYFUNCPTR funcPtr;
3091   *((void **)&funcPtr)=funcStr;//he he...
3092   //
3093   double *ptr=getPointer();
3094   int nbOfComp=getNumberOfComponents();
3095   int nbOfTuples=getNumberOfTuples();
3096   int nbOfElems=nbOfTuples*nbOfComp;
3097   for(int i=0;i<nbOfElems;i++,ptr++)
3098     *ptr=funcPtr(*ptr);
3099   declareAsNew();
3100 }
3101
3102 void DataArrayDouble::applyFuncFast64(const std::string& func)
3103 {
3104   checkAllocated();
3105   INTERP_KERNEL::ExprParser expr(func);
3106   expr.parse();
3107   char *funcStr=expr.compileX86_64();
3108   MYFUNCPTR funcPtr;
3109   *((void **)&funcPtr)=funcStr;//he he...
3110   //
3111   double *ptr=getPointer();
3112   int nbOfComp=getNumberOfComponents();
3113   int nbOfTuples=getNumberOfTuples();
3114   int nbOfElems=nbOfTuples*nbOfComp;
3115   for(int i=0;i<nbOfElems;i++,ptr++)
3116     *ptr=funcPtr(*ptr);
3117   declareAsNew();
3118 }
3119
3120 /*!
3121  * \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.
3122  */
3123 MCAuto<DataArrayDouble> DataArrayDouble::symmetry3DPlane(const double point[3], const double normalVector[3]) const
3124 {
3125   checkAllocated();
3126   if(getNumberOfComponents()!=3)
3127     throw INTERP_KERNEL::Exception("DataArrayDouble::symmetry3DPlane : this is excepted to have 3 components !");
3128   int nbTuples(getNumberOfTuples());
3129   MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
3130   ret->alloc(nbTuples,3);
3131   Symmetry3DPlane(point,normalVector,nbTuples,begin(),ret->getPointer());
3132   return ret;
3133 }
3134
3135 DataArrayDoubleIterator *DataArrayDouble::iterator()
3136 {
3137   return new DataArrayDoubleIterator(this);
3138 }
3139
3140 /*!
3141  * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional
3142  * array whose values are within a given range. Textual data is not copied.
3143  *  \param [in] vmin - a lowest acceptable value (included).
3144  *  \param [in] vmax - a greatest acceptable value (included).
3145  *  \return DataArrayInt * - the new instance of DataArrayInt.
3146  *          The caller is to delete this result array using decrRef() as it is no more
3147  *          needed.
3148  *  \throw If \a this->getNumberOfComponents() != 1.
3149  *
3150  *  \sa DataArrayDouble::findIdsNotInRange
3151  *
3152  *  \if ENABLE_EXAMPLES
3153  *  \ref cpp_mcdataarraydouble_getidsinrange "Here is a C++ example".<br>
3154  *  \ref py_mcdataarraydouble_getidsinrange "Here is a Python example".
3155  *  \endif
3156  */
3157 DataArrayInt *DataArrayDouble::findIdsInRange(double vmin, double vmax) const
3158 {
3159   checkAllocated();
3160   if(getNumberOfComponents()!=1)
3161     throw INTERP_KERNEL::Exception("DataArrayDouble::findIdsInRange : this must have exactly one component !");
3162   const double *cptr(begin());
3163   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
3164   int nbOfTuples(getNumberOfTuples());
3165   for(int i=0;i<nbOfTuples;i++,cptr++)
3166     if(*cptr>=vmin && *cptr<=vmax)
3167       ret->pushBackSilent(i);
3168   return ret.retn();
3169 }
3170
3171 /*!
3172  * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional
3173  * array whose values are not within a given range. Textual data is not copied.
3174  *  \param [in] vmin - a lowest not acceptable value (excluded).
3175  *  \param [in] vmax - a greatest not acceptable value (excluded).
3176  *  \return DataArrayInt * - the new instance of DataArrayInt.
3177  *          The caller is to delete this result array using decrRef() as it is no more
3178  *          needed.
3179  *  \throw If \a this->getNumberOfComponents() != 1.
3180  *
3181  *  \sa DataArrayDouble::findIdsInRange
3182  */
3183 DataArrayInt *DataArrayDouble::findIdsNotInRange(double vmin, double vmax) const
3184 {
3185   checkAllocated();
3186   if(getNumberOfComponents()!=1)
3187     throw INTERP_KERNEL::Exception("DataArrayDouble::findIdsNotInRange : this must have exactly one component !");
3188   const double *cptr(begin());
3189   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
3190   int nbOfTuples(getNumberOfTuples());
3191   for(int i=0;i<nbOfTuples;i++,cptr++)
3192     if(*cptr<vmin || *cptr>vmax)
3193       ret->pushBackSilent(i);
3194   return ret.retn();
3195 }
3196
3197 /*!
3198  * Returns a new DataArrayDouble by concatenating two given arrays, so that (1) the number
3199  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
3200  * the number of component in the result array is same as that of each of given arrays.
3201  * Info on components is copied from the first of the given arrays. Number of components
3202  * in the given arrays must be  the same.
3203  *  \param [in] a1 - an array to include in the result array.
3204  *  \param [in] a2 - another array to include in the result array.
3205  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3206  *          The caller is to delete this result array using decrRef() as it is no more
3207  *          needed.
3208  *  \throw If both \a a1 and \a a2 are NULL.
3209  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
3210  */
3211 DataArrayDouble *DataArrayDouble::Aggregate(const DataArrayDouble *a1, const DataArrayDouble *a2)
3212 {
3213   std::vector<const DataArrayDouble *> tmp(2);
3214   tmp[0]=a1; tmp[1]=a2;
3215   return Aggregate(tmp);
3216 }
3217
3218 /*!
3219  * Returns a new DataArrayDouble by concatenating all given arrays, so that (1) the number
3220  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
3221  * the number of component in the result array is same as that of each of given arrays.
3222  * Info on components is copied from the first of the given arrays. Number of components
3223  * in the given arrays must be  the same.
3224  * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it
3225  * not the object itself.
3226  *  \param [in] arr - a sequence of arrays to include in the result array.
3227  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3228  *          The caller is to delete this result array using decrRef() as it is no more
3229  *          needed.
3230  *  \throw If all arrays within \a arr are NULL.
3231  *  \throw If getNumberOfComponents() of arrays within \a arr.
3232  */
3233 DataArrayDouble *DataArrayDouble::Aggregate(const std::vector<const DataArrayDouble *>& arr)
3234 {
3235   std::vector<const DataArrayDouble *> a;
3236   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
3237     if(*it4)
3238       a.push_back(*it4);
3239   if(a.empty())
3240     throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : input list must contain at least one NON EMPTY DataArrayDouble !");
3241   std::vector<const DataArrayDouble *>::const_iterator it=a.begin();
3242   int nbOfComp=(*it)->getNumberOfComponents();
3243   int nbt=(*it++)->getNumberOfTuples();
3244   for(int i=1;it!=a.end();it++,i++)
3245     {
3246       if((*it)->getNumberOfComponents()!=nbOfComp)
3247         throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : Nb of components mismatch for array aggregation !");
3248       nbt+=(*it)->getNumberOfTuples();
3249     }
3250   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
3251   ret->alloc(nbt,nbOfComp);
3252   double *pt=ret->getPointer();
3253   for(it=a.begin();it!=a.end();it++)
3254     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
3255   ret->copyStringInfoFrom(*(a[0]));
3256   return ret.retn();
3257 }
3258
3259 /*!
3260  * Returns a new DataArrayDouble containing a dot product of two given arrays, so that
3261  * the i-th tuple of the result array is a sum of products of j-th components of i-th
3262  * tuples of given arrays (\f$ a_i = \sum_{j=1}^n a1_j * a2_j \f$).
3263  * Info on components and name is copied from the first of the given arrays.
3264  * Number of tuples and components in the given arrays must be the same.
3265  *  \param [in] a1 - a given array.
3266  *  \param [in] a2 - another given array.
3267  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3268  *          The caller is to delete this result array using decrRef() as it is no more
3269  *          needed.
3270  *  \throw If either \a a1 or \a a2 is NULL.
3271  *  \throw If any given array is not allocated.
3272  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3273  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
3274  */
3275 DataArrayDouble *DataArrayDouble::Dot(const DataArrayDouble *a1, const DataArrayDouble *a2)
3276 {
3277   if(!a1 || !a2)
3278     throw INTERP_KERNEL::Exception("DataArrayDouble::Dot : input DataArrayDouble instance is NULL !");
3279   a1->checkAllocated();
3280   a2->checkAllocated();
3281   int nbOfComp=a1->getNumberOfComponents();
3282   if(nbOfComp!=a2->getNumberOfComponents())
3283     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Dot !");
3284   int nbOfTuple=a1->getNumberOfTuples();
3285   if(nbOfTuple!=a2->getNumberOfTuples())
3286     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Dot !");
3287   DataArrayDouble *ret=DataArrayDouble::New();
3288   ret->alloc(nbOfTuple,1);
3289   double *retPtr=ret->getPointer();
3290   const double *a1Ptr=a1->getConstPointer();
3291   const double *a2Ptr=a2->getConstPointer();
3292   for(int i=0;i<nbOfTuple;i++)
3293     {
3294       double sum=0.;
3295       for(int j=0;j<nbOfComp;j++)
3296         sum+=a1Ptr[i*nbOfComp+j]*a2Ptr[i*nbOfComp+j];
3297       retPtr[i]=sum;
3298     }
3299   ret->setInfoOnComponent(0,a1->getInfoOnComponent(0));
3300   ret->setName(a1->getName());
3301   return ret;
3302 }
3303
3304 /*!
3305  * Returns a new DataArrayDouble containing a cross product of two given arrays, so that
3306  * the i-th tuple of the result array contains 3 components of a vector which is a cross
3307  * product of two vectors defined by the i-th tuples of given arrays.
3308  * Info on components is copied from the first of the given arrays.
3309  * Number of tuples in the given arrays must be the same.
3310  * Number of components in the given arrays must be 3.
3311  *  \param [in] a1 - a given array.
3312  *  \param [in] a2 - another given array.
3313  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3314  *          The caller is to delete this result array using decrRef() as it is no more
3315  *          needed.
3316  *  \throw If either \a a1 or \a a2 is NULL.
3317  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3318  *  \throw If \a a1->getNumberOfComponents() != 3
3319  *  \throw If \a a2->getNumberOfComponents() != 3
3320  */
3321 DataArrayDouble *DataArrayDouble::CrossProduct(const DataArrayDouble *a1, const DataArrayDouble *a2)
3322 {
3323   if(!a1 || !a2)
3324     throw INTERP_KERNEL::Exception("DataArrayDouble::CrossProduct : input DataArrayDouble instance is NULL !");
3325   int nbOfComp=a1->getNumberOfComponents();
3326   if(nbOfComp!=a2->getNumberOfComponents())
3327     throw INTERP_KERNEL::Exception("Nb of components mismatch for array crossProduct !");
3328   if(nbOfComp!=3)
3329     throw INTERP_KERNEL::Exception("Nb of components must be equal to 3 for array crossProduct !");
3330   int nbOfTuple=a1->getNumberOfTuples();
3331   if(nbOfTuple!=a2->getNumberOfTuples())
3332     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array crossProduct !");
3333   DataArrayDouble *ret=DataArrayDouble::New();
3334   ret->alloc(nbOfTuple,3);
3335   double *retPtr=ret->getPointer();
3336   const double *a1Ptr=a1->getConstPointer();
3337   const double *a2Ptr=a2->getConstPointer();
3338   for(int i=0;i<nbOfTuple;i++)
3339     {
3340       retPtr[3*i]=a1Ptr[3*i+1]*a2Ptr[3*i+2]-a1Ptr[3*i+2]*a2Ptr[3*i+1];
3341       retPtr[3*i+1]=a1Ptr[3*i+2]*a2Ptr[3*i]-a1Ptr[3*i]*a2Ptr[3*i+2];
3342       retPtr[3*i+2]=a1Ptr[3*i]*a2Ptr[3*i+1]-a1Ptr[3*i+1]*a2Ptr[3*i];
3343     }
3344   ret->copyStringInfoFrom(*a1);
3345   return ret;
3346 }
3347
3348 /*!
3349  * Returns a new DataArrayDouble containing maximal values of two given arrays.
3350  * Info on components is copied from the first of the given arrays.
3351  * Number of tuples and components in the given arrays must be the same.
3352  *  \param [in] a1 - an array to compare values with another one.
3353  *  \param [in] a2 - another array to compare values with the first one.
3354  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3355  *          The caller is to delete this result array using decrRef() as it is no more
3356  *          needed.
3357  *  \throw If either \a a1 or \a a2 is NULL.
3358  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3359  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
3360  */
3361 DataArrayDouble *DataArrayDouble::Max(const DataArrayDouble *a1, const DataArrayDouble *a2)
3362 {
3363   if(!a1 || !a2)
3364     throw INTERP_KERNEL::Exception("DataArrayDouble::Max : input DataArrayDouble instance is NULL !");
3365   int nbOfComp=a1->getNumberOfComponents();
3366   if(nbOfComp!=a2->getNumberOfComponents())
3367     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Max !");
3368   int nbOfTuple=a1->getNumberOfTuples();
3369   if(nbOfTuple!=a2->getNumberOfTuples())
3370     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Max !");
3371   DataArrayDouble *ret=DataArrayDouble::New();
3372   ret->alloc(nbOfTuple,nbOfComp);
3373   double *retPtr=ret->getPointer();
3374   const double *a1Ptr=a1->getConstPointer();
3375   const double *a2Ptr=a2->getConstPointer();
3376   int nbElem=nbOfTuple*nbOfComp;
3377   for(int i=0;i<nbElem;i++)
3378     retPtr[i]=std::max(a1Ptr[i],a2Ptr[i]);
3379   ret->copyStringInfoFrom(*a1);
3380   return ret;
3381 }
3382
3383 /*!
3384  * Returns a new DataArrayDouble containing minimal values of two given arrays.
3385  * Info on components is copied from the first of the given arrays.
3386  * Number of tuples and components in the given arrays must be the same.
3387  *  \param [in] a1 - an array to compare values with another one.
3388  *  \param [in] a2 - another array to compare values with the first one.
3389  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3390  *          The caller is to delete this result array using decrRef() as it is no more
3391  *          needed.
3392  *  \throw If either \a a1 or \a a2 is NULL.
3393  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3394  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
3395  */
3396 DataArrayDouble *DataArrayDouble::Min(const DataArrayDouble *a1, const DataArrayDouble *a2)
3397 {
3398   if(!a1 || !a2)
3399     throw INTERP_KERNEL::Exception("DataArrayDouble::Min : input DataArrayDouble instance is NULL !");
3400   int nbOfComp=a1->getNumberOfComponents();
3401   if(nbOfComp!=a2->getNumberOfComponents())
3402     throw INTERP_KERNEL::Exception("Nb of components mismatch for array min !");
3403   int nbOfTuple=a1->getNumberOfTuples();
3404   if(nbOfTuple!=a2->getNumberOfTuples())
3405     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array min !");
3406   DataArrayDouble *ret=DataArrayDouble::New();
3407   ret->alloc(nbOfTuple,nbOfComp);
3408   double *retPtr=ret->getPointer();
3409   const double *a1Ptr=a1->getConstPointer();
3410   const double *a2Ptr=a2->getConstPointer();
3411   int nbElem=nbOfTuple*nbOfComp;
3412   for(int i=0;i<nbElem;i++)
3413     retPtr[i]=std::min(a1Ptr[i],a2Ptr[i]);
3414   ret->copyStringInfoFrom(*a1);
3415   return ret;
3416 }
3417
3418 /*!
3419  * Returns a new DataArrayDouble that is the result of pow of two given arrays. There are 3
3420  * valid cases.
3421  *
3422  *  \param [in] a1 - an array to pow up.
3423  *  \param [in] a2 - another array to sum up.
3424  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3425  *          The caller is to delete this result array using decrRef() as it is no more
3426  *          needed.
3427  *  \throw If either \a a1 or \a a2 is NULL.
3428  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3429  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
3430  *  \throw If there is a negative value in \a a1.
3431  */
3432 DataArrayDouble *DataArrayDouble::Pow(const DataArrayDouble *a1, const DataArrayDouble *a2)
3433 {
3434   if(!a1 || !a2)
3435     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : at least one of input instances is null !");
3436   int nbOfTuple=a1->getNumberOfTuples();
3437   int nbOfTuple2=a2->getNumberOfTuples();
3438   int nbOfComp=a1->getNumberOfComponents();
3439   int nbOfComp2=a2->getNumberOfComponents();
3440   if(nbOfTuple!=nbOfTuple2)
3441     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of tuples mismatches !");
3442   if(nbOfComp!=1 || nbOfComp2!=1)
3443     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of components of both arrays must be equal to 1 !");
3444   MCAuto<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbOfTuple,1);
3445   const double *ptr1(a1->begin()),*ptr2(a2->begin());
3446   double *ptr=ret->getPointer();
3447   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
3448     {
3449       if(*ptr1>=0)
3450         {
3451           *ptr=pow(*ptr1,*ptr2);
3452         }
3453       else
3454         {
3455           std::ostringstream oss; oss << "DataArrayDouble::Pow : on tuple #" << i << " of a1 value is < 0 (" << *ptr1 << ") !";
3456           throw INTERP_KERNEL::Exception(oss.str().c_str());
3457         }
3458     }
3459   return ret.retn();
3460 }
3461
3462 /*!
3463  * Apply pow on values of another DataArrayDouble to values of \a this one.
3464  *
3465  *  \param [in] other - an array to pow to \a this one.
3466  *  \throw If \a other is NULL.
3467  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
3468  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
3469  *  \throw If there is a negative value in \a this.
3470  */
3471 void DataArrayDouble::powEqual(const DataArrayDouble *other)
3472 {
3473   if(!other)
3474     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : input instance is null !");
3475   int nbOfTuple=getNumberOfTuples();
3476   int nbOfTuple2=other->getNumberOfTuples();
3477   int nbOfComp=getNumberOfComponents();
3478   int nbOfComp2=other->getNumberOfComponents();
3479   if(nbOfTuple!=nbOfTuple2)
3480     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of tuples mismatches !");
3481   if(nbOfComp!=1 || nbOfComp2!=1)
3482     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of components of both arrays must be equal to 1 !");
3483   double *ptr=getPointer();
3484   const double *ptrc=other->begin();
3485   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
3486     {
3487       if(*ptr>=0)
3488         *ptr=pow(*ptr,*ptrc);
3489       else
3490         {
3491           std::ostringstream oss; oss << "DataArrayDouble::powEqual : on tuple #" << i << " of this value is < 0 (" << *ptr << ") !";
3492           throw INTERP_KERNEL::Exception(oss.str().c_str());
3493         }
3494     }
3495   declareAsNew();
3496 }
3497
3498 /*!
3499  * This method is \b NOT wrapped into python because it can be useful only for performance reasons in C++ context.
3500  * All values in \a this must be 0. or 1. within eps error. 0 means false, 1 means true.
3501  * If an another value than 0 or 1 appear (within eps precision) an INTERP_KERNEL::Exception will be thrown.
3502  *
3503  * \throw if \a this is not allocated.
3504  * \throw if \a this has not exactly one component.
3505  */
3506 std::vector<bool> DataArrayDouble::toVectorOfBool(double eps) const
3507 {
3508   checkAllocated();
3509   if(getNumberOfComponents()!=1)
3510     throw INTERP_KERNEL::Exception("DataArrayDouble::toVectorOfBool : must be applied on single component array !");
3511   int nbt(getNumberOfTuples());
3512   std::vector<bool> ret(nbt);
3513   const double *pt(begin());
3514   for(int i=0;i<nbt;i++)
3515     {
3516       if(fabs(pt[i])<eps)
3517         ret[i]=false;
3518       else if(fabs(pt[i]-1.)<eps)
3519         ret[i]=true;
3520       else
3521         {
3522           std::ostringstream oss; oss << "DataArrayDouble::toVectorOfBool : the tuple #" << i << " has value " << pt[i] << " is invalid ! must be 0. or 1. !";
3523           throw INTERP_KERNEL::Exception(oss.str().c_str());
3524         }
3525     }
3526   return ret;
3527 }
3528
3529 /*!
3530  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
3531  * Server side.
3532  */
3533 void DataArrayDouble::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
3534 {
3535   tinyInfo.resize(2);
3536   if(isAllocated())
3537     {
3538       tinyInfo[0]=getNumberOfTuples();
3539       tinyInfo[1]=getNumberOfComponents();
3540     }
3541   else
3542     {
3543       tinyInfo[0]=-1;
3544       tinyInfo[1]=-1;
3545     }
3546 }
3547
3548 /*!
3549  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
3550  * Server side.
3551  */
3552 void DataArrayDouble::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
3553 {
3554   if(isAllocated())
3555     {
3556       int nbOfCompo=getNumberOfComponents();
3557       tinyInfo.resize(nbOfCompo+1);
3558       tinyInfo[0]=getName();
3559       for(int i=0;i<nbOfCompo;i++)
3560         tinyInfo[i+1]=getInfoOnComponent(i);
3561     }
3562   else
3563     {
3564       tinyInfo.resize(1);
3565       tinyInfo[0]=getName();
3566     }
3567 }
3568
3569 /*!
3570  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
3571  * This method returns if a feeding is needed.
3572  */
3573 bool DataArrayDouble::resizeForUnserialization(const std::vector<int>& tinyInfoI)
3574 {
3575   int nbOfTuple=tinyInfoI[0];
3576   int nbOfComp=tinyInfoI[1];
3577   if(nbOfTuple!=-1 || nbOfComp!=-1)
3578     {
3579       alloc(nbOfTuple,nbOfComp);
3580       return true;
3581     }
3582   return false;
3583 }
3584
3585 /*!
3586  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
3587  */
3588 void DataArrayDouble::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
3589 {
3590   setName(tinyInfoS[0]);
3591   if(isAllocated())
3592     {
3593       int nbOfCompo=getNumberOfComponents();
3594       for(int i=0;i<nbOfCompo;i++)
3595         setInfoOnComponent(i,tinyInfoS[i+1]);
3596     }
3597 }
3598
3599 /*!
3600  * Low static method that operates 3D rotation of 'nbNodes' 3D nodes whose coordinates are arranged in \a coordsIn
3601  * around an axe ( \a center, \a vect) and with angle \a angle.
3602  */
3603 void DataArrayDouble::Rotate3DAlg(const double *center, const double *vect, double angle, int nbNodes, const double *coordsIn, double *coordsOut)
3604 {
3605   if(!center || !vect)
3606     throw INTERP_KERNEL::Exception("DataArrayDouble::Rotate3DAlg : null vector in input !");
3607   double sina(sin(angle));
3608   double cosa(cos(angle));
3609   double vectorNorm[3];
3610   double matrix[9];
3611   double matrixTmp[9];
3612   double norm(sqrt(vect[0]*vect[0]+vect[1]*vect[1]+vect[2]*vect[2]));
3613   if(norm<std::numeric_limits<double>::min())
3614     throw INTERP_KERNEL::Exception("DataArrayDouble::Rotate3DAlg : magnitude of input vector is too close of 0. !");
3615   std::transform(vect,vect+3,vectorNorm,std::bind2nd(std::multiplies<double>(),1/norm));
3616   //rotation matrix computation
3617   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;
3618   matrixTmp[0]=vectorNorm[0]*vectorNorm[0]; matrixTmp[1]=vectorNorm[0]*vectorNorm[1]; matrixTmp[2]=vectorNorm[0]*vectorNorm[2];
3619   matrixTmp[3]=vectorNorm[1]*vectorNorm[0]; matrixTmp[4]=vectorNorm[1]*vectorNorm[1]; matrixTmp[5]=vectorNorm[1]*vectorNorm[2];
3620   matrixTmp[6]=vectorNorm[2]*vectorNorm[0]; matrixTmp[7]=vectorNorm[2]*vectorNorm[1]; matrixTmp[8]=vectorNorm[2]*vectorNorm[2];
3621   std::transform(matrixTmp,matrixTmp+9,matrixTmp,std::bind2nd(std::multiplies<double>(),1-cosa));
3622   std::transform(matrix,matrix+9,matrixTmp,matrix,std::plus<double>());
3623   matrixTmp[0]=0.; matrixTmp[1]=-vectorNorm[2]; matrixTmp[2]=vectorNorm[1];
3624   matrixTmp[3]=vectorNorm[2]; matrixTmp[4]=0.; matrixTmp[5]=-vectorNorm[0];
3625   matrixTmp[6]=-vectorNorm[1]; matrixTmp[7]=vectorNorm[0]; matrixTmp[8]=0.;
3626   std::transform(matrixTmp,matrixTmp+9,matrixTmp,std::bind2nd(std::multiplies<double>(),sina));
3627   std::transform(matrix,matrix+9,matrixTmp,matrix,std::plus<double>());
3628   //rotation matrix computed.
3629   double tmp[3];
3630   for(int i=0; i<nbNodes; i++)
3631     {
3632       std::transform(coordsIn+i*3,coordsIn+(i+1)*3,center,tmp,std::minus<double>());
3633       coordsOut[i*3]=matrix[0]*tmp[0]+matrix[1]*tmp[1]+matrix[2]*tmp[2]+center[0];
3634       coordsOut[i*3+1]=matrix[3]*tmp[0]+matrix[4]*tmp[1]+matrix[5]*tmp[2]+center[1];
3635       coordsOut[i*3+2]=matrix[6]*tmp[0]+matrix[7]*tmp[1]+matrix[8]*tmp[2]+center[2];
3636     }
3637 }
3638
3639 void DataArrayDouble::Symmetry3DPlane(const double point[3], const double normalVector[3], int nbNodes, const double *coordsIn, double *coordsOut)
3640 {
3641   double matrix[9],matrix2[9],matrix3[9];
3642   double vect[3],crossVect[3];
3643   INTERP_KERNEL::orthogonalVect3(normalVector,vect);
3644   crossVect[0]=normalVector[1]*vect[2]-normalVector[2]*vect[1];
3645   crossVect[1]=normalVector[2]*vect[0]-normalVector[0]*vect[2];
3646   crossVect[2]=normalVector[0]*vect[1]-normalVector[1]*vect[0];
3647   double nv(INTERP_KERNEL::norm<3>(vect)),ni(INTERP_KERNEL::norm<3>(normalVector)),nc(INTERP_KERNEL::norm<3>(crossVect));
3648   matrix[0]=vect[0]/nv; matrix[1]=crossVect[0]/nc; matrix[2]=-normalVector[0]/ni;
3649   matrix[3]=vect[1]/nv; matrix[4]=crossVect[1]/nc; matrix[5]=-normalVector[1]/ni;
3650   matrix[6]=vect[2]/nv; matrix[7]=crossVect[2]/nc; matrix[8]=-normalVector[2]/ni;
3651   matrix2[0]=vect[0]/nv; matrix2[1]=vect[1]/nv; matrix2[2]=vect[2]/nv;
3652   matrix2[3]=crossVect[0]/nc; matrix2[4]=crossVect[1]/nc; matrix2[5]=crossVect[2]/nc;
3653   matrix2[6]=normalVector[0]/ni; matrix2[7]=normalVector[1]/ni; matrix2[8]=normalVector[2]/ni;
3654   for(int i=0;i<3;i++)
3655     for(int j=0;j<3;j++)
3656       {
3657         double val(0.);
3658         for(int k=0;k<3;k++)
3659           val+=matrix[3*i+k]*matrix2[3*k+j];
3660         matrix3[3*i+j]=val;
3661       }
3662   //rotation matrix computed.
3663   double tmp[3];
3664   for(int i=0; i<nbNodes; i++)
3665     {
3666       std::transform(coordsIn+i*3,coordsIn+(i+1)*3,point,tmp,std::minus<double>());
3667       coordsOut[i*3]=matrix3[0]*tmp[0]+matrix3[1]*tmp[1]+matrix3[2]*tmp[2]+point[0];
3668       coordsOut[i*3+1]=matrix3[3]*tmp[0]+matrix3[4]*tmp[1]+matrix3[5]*tmp[2]+point[1];
3669       coordsOut[i*3+2]=matrix3[6]*tmp[0]+matrix3[7]*tmp[1]+matrix3[8]*tmp[2]+point[2];
3670     }
3671 }
3672
3673 void DataArrayDouble::GiveBaseForPlane(const double normalVector[3], double baseOfPlane[9])
3674 {
3675   double vect[3],crossVect[3];
3676   INTERP_KERNEL::orthogonalVect3(normalVector,vect);
3677   crossVect[0]=normalVector[1]*vect[2]-normalVector[2]*vect[1];
3678   crossVect[1]=normalVector[2]*vect[0]-normalVector[0]*vect[2];
3679   crossVect[2]=normalVector[0]*vect[1]-normalVector[1]*vect[0];
3680   double nv(INTERP_KERNEL::norm<3>(vect)),ni(INTERP_KERNEL::norm<3>(normalVector)),nc(INTERP_KERNEL::norm<3>(crossVect));
3681   baseOfPlane[0]=vect[0]/nv; baseOfPlane[1]=vect[1]/nv; baseOfPlane[2]=vect[2]/nv;
3682   baseOfPlane[3]=crossVect[0]/nc; baseOfPlane[4]=crossVect[1]/nc; baseOfPlane[5]=crossVect[2]/nc;
3683   baseOfPlane[6]=normalVector[0]/ni; baseOfPlane[7]=normalVector[1]/ni; baseOfPlane[8]=normalVector[2]/ni;
3684 }
3685
3686 /*!
3687  * Low static method that operates 3D rotation of \a nbNodes 3D nodes whose coordinates are arranged in \a coords
3688  * around the center point \a center and with angle \a angle.
3689  */
3690 void DataArrayDouble::Rotate2DAlg(const double *center, double angle, int nbNodes, const double *coordsIn, double *coordsOut)
3691 {
3692   double cosa=cos(angle);
3693   double sina=sin(angle);
3694   double matrix[4];
3695   matrix[0]=cosa; matrix[1]=-sina; matrix[2]=sina; matrix[3]=cosa;
3696   double tmp[2];
3697   for(int i=0; i<nbNodes; i++)
3698     {
3699       std::transform(coordsIn+i*2,coordsIn+(i+1)*2,center,tmp,std::minus<double>());
3700       coordsOut[i*2]=matrix[0]*tmp[0]+matrix[1]*tmp[1]+center[0];
3701       coordsOut[i*2+1]=matrix[2]*tmp[0]+matrix[3]*tmp[1]+center[1];
3702     }
3703 }
3704
3705 DataArrayDoubleIterator::DataArrayDoubleIterator(DataArrayDouble *da):DataArrayIterator<double>(da)
3706 {
3707 }
3708
3709 DataArrayDoubleTuple::DataArrayDoubleTuple(double *pt, int nbOfComp):DataArrayTuple<double>(pt,nbOfComp)
3710 {
3711 }
3712
3713
3714 std::string DataArrayDoubleTuple::repr() const
3715 {
3716   std::ostringstream oss; oss.precision(17); oss << "(";
3717   for(int i=0;i<_nb_of_compo-1;i++)
3718     oss << _pt[i] << ", ";
3719   oss << _pt[_nb_of_compo-1] << ")";
3720   return oss.str();
3721 }
3722
3723 double DataArrayDoubleTuple::doubleValue() const
3724 {
3725   return this->zeValue();
3726 }
3727
3728 /*!
3729  * This method returns a newly allocated instance the caller should dealed with by a MEDCoupling::DataArrayDouble::decrRef.
3730  * This method performs \b no copy of data. The content is only referenced using MEDCoupling::DataArrayDouble::useArray with ownership set to \b false.
3731  * 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
3732  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
3733  */
3734 DataArrayDouble *DataArrayDoubleTuple::buildDADouble(int nbOfTuples, int nbOfCompo) const
3735 {
3736   return this->buildDA(nbOfTuples,nbOfCompo);
3737 }
3738
3739 /*!
3740  * Returns a new instance of DataArrayInt. The caller is to delete this array
3741  * using decrRef() as it is no more needed. 
3742  */
3743 DataArrayInt *DataArrayInt::New()
3744 {
3745   return new DataArrayInt;
3746 }
3747
3748 /*!
3749  * Returns the only one value in \a this, if and only if number of elements
3750  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
3751  *  \return double - the sole value stored in \a this array.
3752  *  \throw If at least one of conditions stated above is not fulfilled.
3753  */
3754 int DataArrayInt::intValue() const
3755 {
3756   if(isAllocated())
3757     {
3758       if(getNbOfElems()==1)
3759         {
3760           return *getConstPointer();
3761         }
3762       else
3763         throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is allocated but number of elements is not equal to 1 !");
3764     }
3765   else
3766     throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is not allocated !");
3767 }
3768
3769 /*!
3770  * Returns an integer value characterizing \a this array, which is useful for a quick
3771  * comparison of many instances of DataArrayInt.
3772  *  \return int - the hash value.
3773  *  \throw If \a this is not allocated.
3774  */
3775 int DataArrayInt::getHashCode() const
3776 {
3777   checkAllocated();
3778   std::size_t nbOfElems=getNbOfElems();
3779   int ret=nbOfElems*65536;
3780   int delta=3;
3781   if(nbOfElems>48)
3782     delta=nbOfElems/8;
3783   int ret0=0;
3784   const int *pt=begin();
3785   for(std::size_t i=0;i<nbOfElems;i+=delta)
3786     ret0+=pt[i] & 0x1FFF;
3787   return ret+ret0;
3788 }
3789
3790 /*!
3791  * Returns a full copy of \a this. For more info on copying data arrays see
3792  * \ref MEDCouplingArrayBasicsCopyDeep.
3793  *  \return DataArrayInt * - a new instance of DataArrayInt.
3794  */
3795 DataArrayInt *DataArrayInt::deepCopy() const
3796 {
3797   return new DataArrayInt(*this);
3798 }
3799
3800 /*!
3801  * Returns either a \a deep or \a shallow copy of this array. For more info see
3802  * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
3803  *  \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
3804  *  \return DataArrayInt * - either a new instance of DataArrayInt (if \a dCpy
3805  *          == \a true) or \a this instance (if \a dCpy == \a false).
3806  */
3807 DataArrayInt *DataArrayInt::performCopyOrIncrRef(bool dCpy) const
3808 {
3809   return DataArrayTemplateClassic<int>::PerformCopyOrIncrRef(dCpy,*this);
3810 }
3811
3812 /*!
3813  * Assign zero to all values in \a this array. To know more on filling arrays see
3814  * \ref MEDCouplingArrayFill.
3815  * \throw If \a this is not allocated.
3816  */
3817 void DataArrayInt::fillWithZero()
3818 {
3819   fillWithValue(0);
3820 }
3821
3822 /*!
3823  * Set all values in \a this array so that the i-th element equals to \a init + i
3824  * (i starts from zero). To know more on filling arrays see \ref MEDCouplingArrayFill.
3825  *  \param [in] init - value to assign to the first element of array.
3826  *  \throw If \a this->getNumberOfComponents() != 1
3827  *  \throw If \a this is not allocated.
3828  */
3829 void DataArrayInt::iota(int init)
3830 {
3831   checkAllocated();
3832   if(getNumberOfComponents()!=1)
3833     throw INTERP_KERNEL::Exception("DataArrayInt::iota : works only for arrays with only one component, you can call 'rearrange' method before !");
3834   int *ptr=getPointer();
3835   int ntuples=getNumberOfTuples();
3836   for(int i=0;i<ntuples;i++)
3837     ptr[i]=init+i;
3838   declareAsNew();
3839 }
3840
3841 /*!
3842  * Returns a textual and human readable representation of \a this instance of
3843  * DataArrayInt. This text is shown when a DataArrayInt is printed in Python.
3844  * \return std::string - text describing \a this DataArrayInt.
3845  * 
3846  * \sa reprNotTooLong, reprZip
3847  */
3848 std::string DataArrayInt::repr() const
3849 {
3850   std::ostringstream ret;
3851   reprStream(ret);
3852   return ret.str();
3853 }
3854
3855 std::string DataArrayInt::reprZip() const
3856 {
3857   std::ostringstream ret;
3858   reprZipStream(ret);
3859   return ret.str();
3860 }
3861
3862 /*!
3863  * This method is close to repr method except that when \a this has more than 1000 tuples, all tuples are not
3864  * printed out to avoid to consume too much space in interpretor.
3865  * \sa repr
3866  */
3867 std::string DataArrayInt::reprNotTooLong() const
3868 {
3869   std::ostringstream ret;
3870   reprNotTooLongStream(ret);
3871   return ret.str();
3872 }
3873
3874 void DataArrayInt::writeVTK(std::ostream& ofs, int indent, const std::string& type, const std::string& nameInFile, DataArrayByte *byteArr) const
3875 {
3876   static const char SPACE[4]={' ',' ',' ',' '};
3877   checkAllocated();
3878   std::string idt(indent,' ');
3879   ofs << idt << "<DataArray type=\"" << type << "\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
3880   if(byteArr)
3881     {
3882       ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
3883       if(std::string(type)=="Int32")
3884         {
3885           const char *data(reinterpret_cast<const char *>(begin()));
3886           std::size_t sz(getNbOfElems()*sizeof(int));
3887           byteArr->insertAtTheEnd(data,data+sz);
3888           byteArr->insertAtTheEnd(SPACE,SPACE+4);
3889         }
3890       else if(std::string(type)=="Int8")
3891         {
3892           INTERP_KERNEL::AutoPtr<char> tmp(new char[getNbOfElems()]);
3893           std::copy(begin(),end(),(char *)tmp);
3894           byteArr->insertAtTheEnd((char *)tmp,(char *)tmp+getNbOfElems());
3895           byteArr->insertAtTheEnd(SPACE,SPACE+4);
3896         }
3897       else if(std::string(type)=="UInt8")
3898         {
3899           INTERP_KERNEL::AutoPtr<unsigned char> tmp(new unsigned char[getNbOfElems()]);
3900           std::copy(begin(),end(),(unsigned char *)tmp);
3901           byteArr->insertAtTheEnd((unsigned char *)tmp,(unsigned char *)tmp+getNbOfElems());
3902           byteArr->insertAtTheEnd(SPACE,SPACE+4);
3903         }
3904       else
3905         throw INTERP_KERNEL::Exception("DataArrayInt::writeVTK : Only Int32, Int8 and UInt8 supported !");
3906     }
3907   else
3908     {
3909       ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
3910       std::copy(begin(),end(),std::ostream_iterator<int>(ofs," "));
3911     }
3912   ofs << std::endl << idt << "</DataArray>\n";
3913 }
3914
3915 void DataArrayInt::reprStream(std::ostream& stream) const
3916 {
3917   stream << "Name of int array : \"" << _name << "\"\n";
3918   reprWithoutNameStream(stream);
3919 }
3920
3921 void DataArrayInt::reprZipStream(std::ostream& stream) const
3922 {
3923   stream << "Name of int array : \"" << _name << "\"\n";
3924   reprZipWithoutNameStream(stream);
3925 }
3926
3927 void DataArrayInt::reprNotTooLongStream(std::ostream& stream) const
3928 {
3929   stream << "Name of int array : \"" << _name << "\"\n";
3930   reprNotTooLongWithoutNameStream(stream);
3931 }
3932
3933 void DataArrayInt::reprWithoutNameStream(std::ostream& stream) const
3934 {
3935   DataArray::reprWithoutNameStream(stream);
3936   _mem.repr(getNumberOfComponents(),stream);
3937 }
3938
3939 void DataArrayInt::reprZipWithoutNameStream(std::ostream& stream) const
3940 {
3941   DataArray::reprWithoutNameStream(stream);
3942   _mem.reprZip(getNumberOfComponents(),stream);
3943 }
3944
3945 void DataArrayInt::reprNotTooLongWithoutNameStream(std::ostream& stream) const
3946 {
3947   DataArray::reprWithoutNameStream(stream);
3948   stream.precision(17);
3949   _mem.reprNotTooLong(getNumberOfComponents(),stream);
3950 }
3951
3952 void DataArrayInt::reprCppStream(const std::string& varName, std::ostream& stream) const
3953 {
3954   int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
3955   const int *data=getConstPointer();
3956   stream << "DataArrayInt *" << varName << "=DataArrayInt::New();" << std::endl;
3957   if(nbTuples*nbComp>=1)
3958     {
3959       stream << "const int " << varName << "Data[" << nbTuples*nbComp << "]={";
3960       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<int>(stream,","));
3961       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
3962       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
3963     }
3964   else
3965     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
3966   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
3967 }
3968
3969 /*!
3970  * Method that gives a quick overvien of \a this for python.
3971  */
3972 void DataArrayInt::reprQuickOverview(std::ostream& stream) const
3973 {
3974   static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
3975   stream << "DataArrayInt C++ instance at " << this << ". ";
3976   if(isAllocated())
3977     {
3978       int nbOfCompo=(int)_info_on_compo.size();
3979       if(nbOfCompo>=1)
3980         {
3981           int nbOfTuples=getNumberOfTuples();
3982           stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
3983           reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
3984         }
3985       else
3986         stream << "Number of components : 0.";
3987     }
3988   else
3989     stream << "*** No data allocated ****";
3990 }
3991
3992 void DataArrayInt::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
3993 {
3994   const int *data=begin();
3995   int nbOfTuples=getNumberOfTuples();
3996   int nbOfCompo=(int)_info_on_compo.size();
3997   std::ostringstream oss2; oss2 << "[";
3998   std::string oss2Str(oss2.str());
3999   bool isFinished=true;
4000   for(int i=0;i<nbOfTuples && isFinished;i++)
4001     {
4002       if(nbOfCompo>1)
4003         {
4004           oss2 << "(";
4005           for(int j=0;j<nbOfCompo;j++,data++)
4006             {
4007               oss2 << *data;
4008               if(j!=nbOfCompo-1) oss2 << ", ";
4009             }
4010           oss2 << ")";
4011         }
4012       else
4013         oss2 << *data++;
4014       if(i!=nbOfTuples-1) oss2 << ", ";
4015       std::string oss3Str(oss2.str());
4016       if(oss3Str.length()<maxNbOfByteInRepr)
4017         oss2Str=oss3Str;
4018       else
4019         isFinished=false;
4020     }
4021   stream << oss2Str;
4022   if(!isFinished)
4023     stream << "... ";
4024   stream << "]";
4025 }
4026
4027 /*!
4028  * Modifies in place \a this one-dimensional array so that each value \a v = \a indArrBg[ \a v ],
4029  * i.e. a current value is used as in index to get a new value from \a indArrBg.
4030  *  \param [in] indArrBg - pointer to the first element of array of new values to assign
4031  *         to \a this array.
4032  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
4033  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
4034  *  \throw If \a this->getNumberOfComponents() != 1
4035  *  \throw If any value of \a this can't be used as a valid index for 
4036  *         [\a indArrBg, \a indArrEnd).
4037  *
4038  *  \sa changeValue
4039  */
4040 void DataArrayInt::transformWithIndArr(const int *indArrBg, const int *indArrEnd)
4041 {
4042   checkAllocated();
4043   if(getNumberOfComponents()!=1)
4044     throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
4045   int nbElemsIn((int)std::distance(indArrBg,indArrEnd)),nbOfTuples(getNumberOfTuples()),*pt(getPointer());
4046   for(int i=0;i<nbOfTuples;i++,pt++)
4047     {
4048       if(*pt>=0 && *pt<nbElemsIn)
4049         *pt=indArrBg[*pt];
4050       else
4051         {
4052           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " of this value is " << *pt << ", should be in [0," << nbElemsIn << ") !";
4053           throw INTERP_KERNEL::Exception(oss.str().c_str());
4054         }
4055     }
4056   declareAsNew();
4057 }
4058
4059 /*!
4060  * Computes distribution of values of \a this one-dimensional array between given value
4061  * ranges (casts). This method is typically useful for entity number spliting by types,
4062  * for example. 
4063  *  \warning The values contained in \a arrBg should be sorted ascendently. No
4064  *           check of this is be done. If not, the result is not warranted. 
4065  *  \param [in] arrBg - the array of ascending values defining the value ranges. The i-th
4066  *         value of \a arrBg (\a arrBg[ i ]) gives the lowest value of the i-th range,
4067  *         and the greatest value of the i-th range equals to \a arrBg[ i+1 ] - 1. \a
4068  *         arrBg containing \a n values defines \a n-1 ranges. The last value of \a arrBg
4069  *         should be more than every value in \a this array.
4070  *  \param [in] arrEnd - specifies the end of the array \a arrBg, so that
4071  *              the last value of \a arrBg is \a arrEnd[ -1 ].
4072  *  \param [out] castArr - a new instance of DataArrayInt, of same size as \a this array
4073  *         (same number of tuples and components), the caller is to delete 
4074  *         using decrRef() as it is no more needed.
4075  *         This array contains indices of ranges for every value of \a this array. I.e.
4076  *         the i-th value of \a castArr gives the index of range the i-th value of \a this
4077  *         belongs to. Or, in other words, this parameter contains for each tuple in \a
4078  *         this in which cast it holds.
4079  *  \param [out] rankInsideCast - a new instance of DataArrayInt, of same size as \a this
4080  *         array, the caller is to delete using decrRef() as it is no more needed.
4081  *         This array contains ranks of values of \a this array within ranges
4082  *         they belongs to. I.e. the i-th value of \a rankInsideCast gives the rank of
4083  *         the i-th value of \a this array within the \a castArr[ i ]-th range, to which
4084  *         the i-th value of \a this belongs to. Or, in other words, this param contains 
4085  *         for each tuple its rank inside its cast. The rank is computed as difference
4086  *         between the value and the lowest value of range.
4087  *  \param [out] castsPresent - a new instance of DataArrayInt, containing indices of
4088  *         ranges (casts) to which at least one value of \a this array belongs.
4089  *         Or, in other words, this param contains the casts that \a this contains.
4090  *         The caller is to delete this array using decrRef() as it is no more needed.
4091  *
4092  * \b Example: If \a this contains [6,5,0,3,2,7,8,1,4] and \a arrBg contains [0,4,9] then
4093  *            the output of this method will be : 
4094  * - \a castArr       : [1,1,0,0,0,1,1,0,1]
4095  * - \a rankInsideCast: [2,1,0,3,2,3,4,1,0]
4096  * - \a castsPresent  : [0,1]
4097  *
4098  * I.e. values of \a this array belong to 2 ranges: #0 and #1. Value 6 belongs to the
4099  * range #1 and its rank within this range is 2; etc.
4100  *
4101  *  \throw If \a this->getNumberOfComponents() != 1.
4102  *  \throw If \a arrEnd - arrBg < 2.
4103  *  \throw If any value of \a this is not less than \a arrEnd[-1].
4104  */
4105 void DataArrayInt::splitByValueRange(const int *arrBg, const int *arrEnd,
4106                                      DataArrayInt *& castArr, DataArrayInt *& rankInsideCast, DataArrayInt *& castsPresent) const
4107 {
4108   checkAllocated();
4109   if(getNumberOfComponents()!=1)
4110     throw INTERP_KERNEL::Exception("Call splitByValueRange  method on DataArrayInt with only one component, you can call 'rearrange' method before !");
4111   int nbOfTuples=getNumberOfTuples();
4112   std::size_t nbOfCast=std::distance(arrBg,arrEnd);
4113   if(nbOfCast<2)
4114     throw INTERP_KERNEL::Exception("DataArrayInt::splitByValueRange : The input array giving the cast range values should be of size >=2 !");
4115   nbOfCast--;
4116   const int *work=getConstPointer();
4117   typedef std::reverse_iterator<const int *> rintstart;
4118   rintstart bg(arrEnd);//OK no problem because size of 'arr' is greater or equal 2
4119   rintstart end2(arrBg);
4120   MCAuto<DataArrayInt> ret1=DataArrayInt::New();
4121   MCAuto<DataArrayInt> ret2=DataArrayInt::New();
4122   MCAuto<DataArrayInt> ret3=DataArrayInt::New();
4123   ret1->alloc(nbOfTuples,1);
4124   ret2->alloc(nbOfTuples,1);
4125   int *ret1Ptr=ret1->getPointer();
4126   int *ret2Ptr=ret2->getPointer();
4127   std::set<std::size_t> castsDetected;
4128   for(int i=0;i<nbOfTuples;i++)
4129     {
4130       rintstart res=std::find_if(bg,end2,std::bind2nd(std::less_equal<int>(), work[i]));
4131       std::size_t pos=std::distance(bg,res);
4132       std::size_t pos2=nbOfCast-pos;
4133       if(pos2<nbOfCast)
4134         {
4135           ret1Ptr[i]=(int)pos2;
4136           ret2Ptr[i]=work[i]-arrBg[pos2];
4137           castsDetected.insert(pos2);
4138         }
4139       else
4140         {
4141           std::ostringstream oss; oss << "DataArrayInt::splitByValueRange : At rank #" << i << " the value is " << work[i] << " should be in [0," << *bg << ") !";
4142           throw INTERP_KERNEL::Exception(oss.str().c_str());
4143         }
4144     }
4145   ret3->alloc((int)castsDetected.size(),1);
4146   std::copy(castsDetected.begin(),castsDetected.end(),ret3->getPointer());
4147   castArr=ret1.retn();
4148   rankInsideCast=ret2.retn();
4149   castsPresent=ret3.retn();
4150 }
4151
4152 /*!
4153  * 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 ).
4154  * 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 ).
4155  * This method works only if \a this is allocated and single component. If not an exception will be thrown.
4156  *
4157  * \param [out] strt - the start of the range (included) if true is returned.
4158  * \param [out] sttoopp - the end of the range (not included) if true is returned.
4159  * \param [out] stteepp - the step of the range if true is returned.
4160  * \return the verdict of the check.
4161  *
4162  * \sa DataArray::GetNumberOfItemGivenBES
4163  */
4164 bool DataArrayInt::isRange(int& strt, int& sttoopp, int& stteepp) const
4165 {
4166   checkAllocated();
4167   if(getNumberOfComponents()!=1)
4168     throw INTERP_KERNEL::Exception("DataArrayInt::isRange : this must be single component array !");
4169   int nbTuples(getNumberOfTuples());
4170   if(nbTuples==0)
4171     { strt=0; sttoopp=0; stteepp=1; return true; }
4172   const int *pt(begin());
4173   strt=*pt; 
4174   if(nbTuples==1)
4175     { sttoopp=strt+1; stteepp=1; return true; }
4176   strt=*pt; sttoopp=pt[nbTuples-1];
4177   if(strt==sttoopp)
4178     return false;
4179   if(sttoopp>strt)
4180     {
4181       sttoopp++;
4182       int a(sttoopp-1-strt),tmp(strt);
4183       if(a%(nbTuples-1)!=0)
4184         return false;
4185       stteepp=a/(nbTuples-1);
4186       for(int i=0;i<nbTuples;i++,tmp+=stteepp)
4187         if(pt[i]!=tmp)
4188           return false;
4189       return true;
4190     }
4191   else
4192     {
4193       sttoopp--;
4194       int a(strt-sttoopp-1),tmp(strt);
4195       if(a%(nbTuples-1)!=0)
4196         return false;
4197       stteepp=-(a/(nbTuples-1));
4198       for(int i=0;i<nbTuples;i++,tmp+=stteepp)
4199         if(pt[i]!=tmp)
4200           return false;
4201       return true;
4202     }
4203 }
4204
4205 /*!
4206  * Creates a one-dimensional DataArrayInt (\a res) whose contents are computed from 
4207  * values of \a this (\a a) and the given (\a indArr) arrays as follows:
4208  * \a res[ \a indArr[ \a a[ i ]]] = i. I.e. for each value in place i \a v = \a a[ i ],
4209  * new value in place \a indArr[ \a v ] is i.
4210  *  \param [in] indArrBg - the array holding indices within the result array to assign
4211  *         indices of values of \a this array pointing to values of \a indArrBg.
4212  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
4213  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
4214  *  \return DataArrayInt * - the new instance of DataArrayInt.
4215  *          The caller is to delete this result array using decrRef() as it is no more
4216  *          needed.
4217  *  \throw If \a this->getNumberOfComponents() != 1.
4218  *  \throw If any value of \a this array is not a valid index for \a indArrBg array.
4219  *  \throw If any value of \a indArrBg is not a valid index for \a this array.
4220  */
4221 DataArrayInt *DataArrayInt::transformWithIndArrR(const int *indArrBg, const int *indArrEnd) const
4222 {
4223   checkAllocated();
4224   if(getNumberOfComponents()!=1)
4225     throw INTERP_KERNEL::Exception("Call transformWithIndArrR method on DataArrayInt with only one component, you can call 'rearrange' method before !");
4226   int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
4227   int nbOfTuples=getNumberOfTuples();
4228   const int *pt=getConstPointer();
4229   MCAuto<DataArrayInt> ret=DataArrayInt::New();
4230   ret->alloc(nbOfTuples,1);
4231   ret->fillWithValue(-1);
4232   int *tmp=ret->getPointer();
4233   for(int i=0;i<nbOfTuples;i++,pt++)
4234     {
4235       if(*pt>=0 && *pt<nbElemsIn)
4236         {
4237           int pos=indArrBg[*pt];
4238           if(pos>=0 && pos<nbOfTuples)
4239             tmp[pos]=i;
4240           else
4241             {
4242               std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value of new pos is " << pos << " ( indArrBg[" << *pt << "]) ! Should be in [0," << nbOfTuples << ") !";
4243               throw INTERP_KERNEL::Exception(oss.str().c_str());
4244             }
4245         }
4246       else
4247         {
4248           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn << " !";
4249           throw INTERP_KERNEL::Exception(oss.str().c_str());
4250         }
4251     }
4252   return ret.retn();
4253 }
4254
4255 /*!
4256  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
4257  * from values of \a this array, which is supposed to contain a renumbering map in 
4258  * "Old to New" mode. The result array contains a renumbering map in "New to Old" mode.
4259  * To know how to use the renumbering maps see \ref numbering.
4260  *  \param [in] newNbOfElem - the number of tuples in the result array.
4261  *  \return DataArrayInt * - the new instance of DataArrayInt.
4262  *          The caller is to delete this result array using decrRef() as it is no more
4263  *          needed.
4264  * 
4265  *  \if ENABLE_EXAMPLES
4266  *  \ref cpp_mcdataarrayint_invertarrayo2n2n2o "Here is a C++ example".<br>
4267  *  \ref py_mcdataarrayint_invertarrayo2n2n2o  "Here is a Python example".
4268  *  \endif
4269  */
4270 DataArrayInt *DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const
4271 {
4272   MCAuto<DataArrayInt> ret=DataArrayInt::New();
4273   ret->alloc(newNbOfElem,1);
4274   int nbOfOldNodes=getNumberOfTuples();
4275   const int *old2New=getConstPointer();
4276   int *pt=ret->getPointer();
4277   for(int i=0;i!=nbOfOldNodes;i++)
4278     {
4279       int newp(old2New[i]);
4280       if(newp!=-1)
4281         {
4282           if(newp>=0 && newp<newNbOfElem)
4283             pt[newp]=i;
4284           else
4285             {
4286               std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2O : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
4287               throw INTERP_KERNEL::Exception(oss.str().c_str());
4288             }
4289         }
4290     }
4291   return ret.retn();
4292 }
4293
4294 /*!
4295  * This method is similar to DataArrayInt::invertArrayO2N2N2O except that 
4296  * 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]
4297  */
4298 DataArrayInt *DataArrayInt::invertArrayO2N2N2OBis(int newNbOfElem) const
4299 {
4300   MCAuto<DataArrayInt> ret=DataArrayInt::New();
4301   ret->alloc(newNbOfElem,1);
4302   int nbOfOldNodes=getNumberOfTuples();
4303   const int *old2New=getConstPointer();
4304   int *pt=ret->getPointer();
4305   for(int i=nbOfOldNodes-1;i>=0;i--)
4306     {
4307       int newp(old2New[i]);
4308       if(newp!=-1)
4309         {
4310           if(newp>=0 && newp<newNbOfElem)
4311             pt[newp]=i;
4312           else
4313             {
4314               std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2OBis : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
4315               throw INTERP_KERNEL::Exception(oss.str().c_str());
4316             }
4317         }
4318     }
4319   return ret.retn();
4320 }
4321
4322 /*!
4323  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
4324  * from values of \a this array, which is supposed to contain a renumbering map in 
4325  * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
4326  * To know how to use the renumbering maps see \ref numbering.
4327  *  \param [in] newNbOfElem - the number of tuples in the result array.
4328  *  \return DataArrayInt * - the new instance of DataArrayInt.
4329  *          The caller is to delete this result array using decrRef() as it is no more
4330  *          needed.
4331  * 
4332  *  \if ENABLE_EXAMPLES
4333  *  \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
4334  *
4335  *  \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
4336  *  \endif
4337  */
4338 DataArrayInt *DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const
4339 {
4340   checkAllocated();
4341   MCAuto<DataArrayInt> ret=DataArrayInt::New();
4342   ret->alloc(oldNbOfElem,1);
4343   const int *new2Old=getConstPointer();
4344   int *pt=ret->getPointer();
4345   std::fill(pt,pt+oldNbOfElem,-1);
4346   int nbOfNewElems=getNumberOfTuples();
4347   for(int i=0;i<nbOfNewElems;i++)
4348     {
4349       int v(new2Old[i]);
4350       if(v>=0 && v<oldNbOfElem)
4351         pt[v]=i;
4352       else
4353         {
4354           std::ostringstream oss; oss << "DataArrayInt::invertArrayN2O2O2N : in new id #" << i << " old value is " << v << " expected to be in [0," << oldNbOfElem << ") !";
4355           throw INTERP_KERNEL::Exception(oss.str().c_str());
4356         }
4357     }
4358   return ret.retn();
4359 }
4360
4361 /*!
4362  * Equivalent to DataArrayInt::isEqual except that if false the reason of
4363  * mismatch is given.
4364  * 
4365  * \param [in] other the instance to be compared with \a this
4366  * \param [out] reason In case of inequality returns the reason.
4367  * \sa DataArrayInt::isEqual
4368  */
4369 bool DataArrayInt::isEqualIfNotWhy(const DataArrayInt& other, std::string& reason) const
4370 {
4371   if(!areInfoEqualsIfNotWhy(other,reason))
4372     return false;
4373   return _mem.isEqual(other._mem,0,reason);
4374 }
4375
4376 /*!
4377  * Checks if \a this and another DataArrayInt are fully equal. For more info see
4378  * \ref MEDCouplingArrayBasicsCompare.
4379  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
4380  *  \return bool - \a true if the two arrays are equal, \a false else.
4381  */
4382 bool DataArrayInt::isEqual(const DataArrayInt& other) const
4383 {
4384   std::string tmp;
4385   return isEqualIfNotWhy(other,tmp);
4386 }
4387
4388 /*!
4389  * Checks if values of \a this and another DataArrayInt are equal. For more info see
4390  * \ref MEDCouplingArrayBasicsCompare.
4391  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
4392  *  \return bool - \a true if the values of two arrays are equal, \a false else.
4393  */
4394 bool DataArrayInt::isEqualWithoutConsideringStr(const DataArrayInt& other) const
4395 {
4396   std::string tmp;
4397   return _mem.isEqual(other._mem,0,tmp);
4398 }
4399
4400 /*!
4401  * Checks if values of \a this and another DataArrayInt are equal. Comparison is
4402  * performed on sorted value sequences.
4403  * For more info see\ref MEDCouplingArrayBasicsCompare.
4404  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
4405  *  \return bool - \a true if the sorted values of two arrays are equal, \a false else.
4406  */
4407 bool DataArrayInt::isEqualWithoutConsideringStrAndOrder(const DataArrayInt& other) const
4408 {
4409   MCAuto<DataArrayInt> a=deepCopy();
4410   MCAuto<DataArrayInt> b=other.deepCopy();
4411   a->sort();
4412   b->sort();
4413   return a->isEqualWithoutConsideringStr(*b);
4414 }
4415
4416 /*!
4417  * This method compares content of input vector \a v and \a this.
4418  * 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.
4419  * For performance reasons \a this is expected to be sorted ascendingly. If not an exception will be thrown.
4420  *
4421  * \param [in] v - the vector of 'flags' to be compared with \a this.
4422  *
4423  * \throw If \a this is not sorted ascendingly.
4424  * \throw If \a this has not exactly one component.
4425  * \throw If \a this is not allocated.
4426  */
4427 bool DataArrayInt::isFittingWith(const std::vector<bool>& v) const
4428 {
4429   checkAllocated();
4430   if(getNumberOfComponents()!=1)
4431     throw INTERP_KERNEL::Exception("DataArrayInt::isFittingWith : number of components of this should be equal to one !");
4432   const int *w(begin()),*end2(end());
4433   int refVal=-std::numeric_limits<int>::max();
4434   int i=0;
4435   std::vector<bool>::const_iterator it(v.begin());
4436   for(;it!=v.end();it++,i++)
4437     {
4438       if(*it)
4439         {
4440           if(w!=end2)
4441             {
4442               if(*w++==i)
4443                 {
4444                   if(i>refVal)
4445                     refVal=i;
4446                   else
4447                     {
4448                       std::ostringstream oss; oss << "DataArrayInt::isFittingWith : At pos #" << std::distance(begin(),w-1) << " this is not sorted ascendingly !";
4449                       throw INTERP_KERNEL::Exception(oss.str().c_str());
4450                     }
4451                 }
4452               else
4453                 return false;
4454             }
4455           else
4456             return false;
4457         }
4458     }
4459   return w==end2;
4460 }
4461
4462 /*!
4463  * 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
4464  * put True to the corresponding entry in \a vec.
4465  * \a vec is expected to be with the same size than the number of tuples of \a this.
4466  *
4467  *  \sa DataArrayInt::switchOnTupleNotEqualTo.
4468  */
4469 void DataArrayInt::switchOnTupleEqualTo(int val, std::vector<bool>& vec) const
4470 {
4471   checkAllocated();
4472   if(getNumberOfComponents()!=1)
4473     throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleEqualTo : number of components of this should be equal to one !");
4474   int nbOfTuples(getNumberOfTuples());
4475   if(nbOfTuples!=(int)vec.size())
4476     throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleEqualTo : number of tuples of this should be equal to size of input vector of bool !");
4477   const int *pt(begin());
4478   for(int i=0;i<nbOfTuples;i++)
4479     if(pt[i]==val)
4480       vec[i]=true;
4481 }
4482
4483 /*!
4484  * 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
4485  * put True to the corresponding entry in \a vec.
4486  * \a vec is expected to be with the same size than the number of tuples of \a this.
4487  * 
4488  *  \sa DataArrayInt::switchOnTupleEqualTo.
4489  */
4490 void DataArrayInt::switchOnTupleNotEqualTo(int val, std::vector<bool>& vec) const
4491 {
4492   checkAllocated();
4493   if(getNumberOfComponents()!=1)
4494     throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleNotEqualTo : number of components of this should be equal to one !");
4495   int nbOfTuples(getNumberOfTuples());
4496   if(nbOfTuples!=(int)vec.size())
4497     throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleNotEqualTo : number of tuples of this should be equal to size of input vector of bool !");
4498   const int *pt(begin());
4499   for(int i=0;i<nbOfTuples;i++)
4500     if(pt[i]!=val)
4501       vec[i]=true;
4502 }
4503
4504 /*!
4505  * Computes for each tuple the sum of number of components values in the tuple and return it.
4506  * 
4507  * \return DataArrayInt * - the new instance of DataArrayInt containing the
4508  *          same number of tuples as \a this array and one component.
4509  *          The caller is to delete this result array using decrRef() as it is no more
4510  *          needed.
4511  *  \throw If \a this is not allocated.
4512  */
4513 DataArrayInt *DataArrayInt::sumPerTuple() const
4514 {
4515   checkAllocated();
4516   int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
4517   MCAuto<DataArrayInt> ret(DataArrayInt::New());
4518   ret->alloc(nbOfTuple,1);
4519   const int *src(getConstPointer());
4520   int *dest(ret->getPointer());
4521   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
4522     *dest=std::accumulate(src,src+nbOfComp,0);
4523   return ret.retn();
4524 }
4525
4526 /*!
4527  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
4528  * If not an exception is thrown.
4529  *  \param [in] increasing - if \a true, the array values should be increasing.
4530  *  \throw If sequence of values is not strictly monotonic in agreement with \a
4531  *         increasing arg.
4532  *  \throw If \a this->getNumberOfComponents() != 1.
4533  *  \throw If \a this is not allocated.
4534  */
4535 void DataArrayInt::checkMonotonic(bool increasing) const
4536 {
4537   if(!isMonotonic(increasing))
4538     {
4539       if (increasing)
4540         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not INCREASING monotonic !");
4541       else
4542         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not DECREASING monotonic !");
4543     }
4544 }
4545
4546 /*!
4547  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
4548  *  \param [in] increasing - if \a true, array values should be increasing.
4549  *  \return bool - \a true if values change in accordance with \a increasing arg.
4550  *  \throw If \a this->getNumberOfComponents() != 1.
4551  *  \throw If \a this is not allocated.
4552  */
4553 bool DataArrayInt::isMonotonic(bool increasing) const
4554 {
4555   checkAllocated();
4556   if(getNumberOfComponents()!=1)
4557     throw INTERP_KERNEL::Exception("DataArrayInt::isMonotonic : only supported with 'this' array with ONE component !");
4558   int nbOfElements=getNumberOfTuples();
4559   const int *ptr=getConstPointer();
4560   if(nbOfElements==0)
4561     return true;
4562   int ref=ptr[0];
4563   if(increasing)
4564     {
4565       for(int i=1;i<nbOfElements;i++)
4566         {
4567           if(ptr[i]>=ref)
4568             ref=ptr[i];
4569           else
4570             return false;
4571         }
4572     }
4573   else
4574     {
4575       for(int i=1;i<nbOfElements;i++)
4576         {
4577           if(ptr[i]<=ref)
4578             ref=ptr[i];
4579           else
4580             return false;
4581         }
4582     }
4583   return true;
4584 }
4585
4586 /*!
4587  * This method check that array consistently INCREASING or DECREASING in value.
4588  */
4589 bool DataArrayInt::isStrictlyMonotonic(bool increasing) const
4590 {
4591   checkAllocated();
4592   if(getNumberOfComponents()!=1)
4593     throw INTERP_KERNEL::Exception("DataArrayInt::isStrictlyMonotonic : only supported with 'this' array with ONE component !");
4594   int nbOfElements=getNumberOfTuples();
4595   const int *ptr=getConstPointer();
4596   if(nbOfElements==0)
4597     return true;
4598   int ref=ptr[0];
4599   if(increasing)
4600     {
4601       for(int i=1;i<nbOfElements;i++)
4602         {
4603           if(ptr[i]>ref)
4604             ref=ptr[i];
4605           else
4606             return false;
4607         }
4608     }
4609   else
4610     {
4611       for(int i=1;i<nbOfElements;i++)
4612         {
4613           if(ptr[i]<ref)
4614             ref=ptr[i];
4615           else
4616             return false;
4617         }
4618     }
4619   return true;
4620 }
4621
4622 /*!
4623  * This method check that array consistently INCREASING or DECREASING in value.
4624  */
4625 void DataArrayInt::checkStrictlyMonotonic(bool increasing) const
4626 {
4627   if(!isStrictlyMonotonic(increasing))
4628     {
4629       if (increasing)
4630         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly INCREASING monotonic !");
4631       else
4632         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly DECREASING monotonic !");
4633     }
4634 }
4635
4636 /*!
4637  * Creates a new one-dimensional DataArrayInt of the same size as \a this and a given
4638  * one-dimensional arrays that must be of the same length. The result array describes
4639  * correspondence between \a this and \a other arrays, so that 
4640  * <em> other.getIJ(i,0) == this->getIJ(ret->getIJ(i),0)</em>. If such a permutation is
4641  * not possible because some element in \a other is not in \a this, an exception is thrown.
4642  *  \param [in] other - an array to compute permutation to.
4643  *  \return DataArrayInt * - a new instance of DataArrayInt, which is a permutation array
4644  * from \a this to \a other. The caller is to delete this array using decrRef() as it is
4645  * no more needed.
4646  *  \throw If \a this->getNumberOfComponents() != 1.
4647  *  \throw If \a other->getNumberOfComponents() != 1.
4648  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples().
4649  *  \throw If \a other includes a value which is not in \a this array.
4650  * 
4651  *  \if ENABLE_EXAMPLES
4652  *  \ref cpp_mcdataarrayint_buildpermutationarr "Here is a C++ example".
4653  *
4654  *  \ref py_mcdataarrayint_buildpermutationarr "Here is a Python example".
4655  *  \endif
4656  */
4657 DataArrayInt *DataArrayInt::buildPermutationArr(const DataArrayInt& other) const
4658 {
4659   checkAllocated();
4660   if(getNumberOfComponents()!=1 || other.getNumberOfComponents()!=1)
4661     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' have to have exactly ONE component !");
4662   int nbTuple=getNumberOfTuples();
4663   other.checkAllocated();
4664   if(nbTuple!=other.getNumberOfTuples())
4665     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' must have the same number of tuple !");
4666   MCAuto<DataArrayInt> ret=DataArrayInt::New();
4667   ret->alloc(nbTuple,1);
4668   ret->fillWithValue(-1);
4669   const int *pt=getConstPointer();
4670   std::map<int,int> mm;
4671   for(int i=0;i<nbTuple;i++)
4672     mm[pt[i]]=i;
4673   pt=other.getConstPointer();
4674   int *retToFill=ret->getPointer();
4675   for(int i=0;i<nbTuple;i++)
4676     {
4677       std::map<int,int>::const_iterator it=mm.find(pt[i]);
4678       if(it==mm.end())
4679         {
4680           std::ostringstream oss; oss << "DataArrayInt::buildPermutationArr : Arrays mismatch : element (" << pt[i] << ") in 'other' not findable in 'this' !";
4681           throw INTERP_KERNEL::Exception(oss.str().c_str());
4682         }
4683       retToFill[i]=(*it).second;
4684     }
4685   return ret.retn();
4686 }
4687
4688 /*!
4689  * Elements of \a partOfThis are expected to be included in \a this.
4690  * The returned array \a ret is so that this[ret]==partOfThis
4691  *
4692  * 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]
4693  * the return array will contain [3,2,5,7].
4694  *
4695  * \a this is expected to be a 1 compo allocated array.
4696  * \param [in] partOfThis - A 1 compo allocated array
4697  * \return - A newly allocated array to be dealed by caller having the same number of tuples than \a partOfThis.
4698  * \throw if two same element is present twice in \a this
4699  * \throw if an element in \a partOfThis is \b NOT in \a this.
4700  */
4701 DataArrayInt *DataArrayInt::indicesOfSubPart(const DataArrayInt& partOfThis) const
4702 {
4703   if(getNumberOfComponents()!=1 || partOfThis.getNumberOfComponents()!=1)
4704     throw INTERP_KERNEL::Exception("DataArrayInt::indicesOfSubPart : this and input array must be one component array !");
4705   checkAllocated(); partOfThis.checkAllocated();
4706   int thisNbTuples(getNumberOfTuples()),nbTuples(partOfThis.getNumberOfTuples());
4707   const int *thisPt(begin()),*pt(partOfThis.begin());
4708   MCAuto<DataArrayInt> ret(DataArrayInt::New());
4709   ret->alloc(nbTuples,1);
4710   int *retPt(ret->getPointer());
4711   std::map<int,int> m;
4712   for(int i=0;i<thisNbTuples;i++,thisPt++)
4713     m[*thisPt]=i;
4714   if(m.size()!=thisNbTuples)
4715     throw INTERP_KERNEL::Exception("DataArrayInt::indicesOfSubPart : some elements appears more than once !");
4716   for(int i=0;i<nbTuples;i++,retPt++,pt++)
4717     {
4718       std::map<int,int>::const_iterator it(m.find(*pt));
4719       if(it!=m.end())
4720         *retPt=(*it).second;
4721       else
4722         {
4723           std::ostringstream oss; oss << "DataArrayInt::indicesOfSubPart : At pos #" << i << " of input array value is " << *pt << " not in this !";
4724           throw INTERP_KERNEL::Exception(oss.str());
4725         }
4726     }
4727   return ret.retn();
4728 }
4729
4730 /*!
4731  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode.
4732  * This map, if applied to \a this array, would make it sorted. For example, if
4733  * \a this array contents are [9,10,0,6,4,11,3,7] then the contents of the result array
4734  * are [5,6,0,3,2,7,1,4]; if this result array (\a res) is used as an argument in call
4735  * \a this->renumber(\a res) then the returned array contains [0,3,4,6,7,9,10,11].
4736  * This method is useful for renumbering (in MED file for example). For more info
4737  * on renumbering see \ref numbering.
4738  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4739  *          array using decrRef() as it is no more needed.
4740  *  \throw If \a this is not allocated.
4741  *  \throw If \a this->getNumberOfComponents() != 1.
4742  *  \throw If there are equal values in \a this array.
4743  */
4744 DataArrayInt *DataArrayInt::checkAndPreparePermutation() const
4745 {
4746   checkAllocated();
4747   if(getNumberOfComponents()!=1)
4748     throw INTERP_KERNEL::Exception("DataArrayInt::checkAndPreparePermutation : number of components must == 1 !");
4749   int nbTuples=getNumberOfTuples();
4750   const int *pt=getConstPointer();
4751   int *pt2=CheckAndPreparePermutation(pt,pt+nbTuples);
4752   DataArrayInt *ret=DataArrayInt::New();
4753   ret->useArray(pt2,true,C_DEALLOC,nbTuples,1);
4754   return ret;
4755 }
4756
4757 /*!
4758  * 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
4759  * input array \a ids2.
4760  * \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.
4761  * 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
4762  * inversely.
4763  * In case of success (no throw) : \c ids1->renumber(ret)->isEqual(ids2) where \a ret is the return of this method.
4764  *
4765  * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4766  *          array using decrRef() as it is no more needed.
4767  * \throw If either ids1 or ids2 is null not allocated or not with one components.
4768  * 
4769  */
4770 DataArrayInt *DataArrayInt::FindPermutationFromFirstToSecond(const DataArrayInt *ids1, const DataArrayInt *ids2)
4771 {
4772   if(!ids1 || !ids2)
4773     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be not null !");
4774   if(!ids1->isAllocated() || !ids2->isAllocated())
4775     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be allocated !");
4776   if(ids1->getNumberOfComponents()!=1 || ids2->getNumberOfComponents()!=1)
4777     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays have exactly one component !");
4778   if(ids1->getNumberOfTuples()!=ids2->getNumberOfTuples())
4779     {
4780       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 !";
4781       throw INTERP_KERNEL::Exception(oss.str().c_str());
4782     }
4783   MCAuto<DataArrayInt> p1(ids1->deepCopy());
4784   MCAuto<DataArrayInt> p2(ids2->deepCopy());
4785   p1->sort(true); p2->sort(true);
4786   if(!p1->isEqualWithoutConsideringStr(*p2))
4787     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two arrays are not lying on same ids ! Impossible to find a permutation between the 2 arrays !");
4788   p1=ids1->checkAndPreparePermutation();
4789   p2=ids2->checkAndPreparePermutation();
4790   p2=p2->invertArrayO2N2N2O(p2->getNumberOfTuples());
4791   p2=p2->selectByTupleIdSafe(p1->begin(),p1->end());
4792   return p2.retn();
4793 }
4794
4795 /*!
4796  * Returns two arrays describing a surjective mapping from \a this set of values (\a A)
4797  * onto a set of values of size \a targetNb (\a B). The surjective function is 
4798  * \a B[ \a A[ i ]] = i. That is to say that for each \a id in [0,\a targetNb), where \a
4799  * targetNb < \a this->getNumberOfTuples(), there exists at least one tupleId (\a tid) so
4800  * that <em> this->getIJ( tid, 0 ) == id</em>. <br>
4801  * The first of out arrays returns indices of elements of \a this array, grouped by their
4802  * place in the set \a B. The second out array is the index of the first one; it shows how
4803  * many elements of \a A are mapped into each element of \a B. <br>
4804  * For more info on
4805  * mapping and its usage in renumbering see \ref numbering. <br>
4806  * \b Example:
4807  * - \a this: [0,3,2,3,2,2,1,2]
4808  * - \a targetNb: 4
4809  * - \a arr:  [0,  6,  2,4,5,7,  1,3]
4810  * - \a arrI: [0,1,2,6,8]
4811  *
4812  * This result means: <br>
4813  * the element of \a B 0 encounters within \a A once (\a arrI[ 0+1 ] - \a arrI[ 0 ]) and
4814  * its index within \a A is 0 ( \a arr[ 0:1 ] == \a arr[ \a arrI[ 0 ] : \a arrI[ 0+1 ]]);<br>
4815  * the element of \a B 2 encounters within \a A 4 times (\a arrI[ 2+1 ] - \a arrI[ 2 ]) and
4816  * its indices within \a A are [2,4,5,7] ( \a arr[ 2:6 ] == \a arr[ \a arrI[ 2 ] : 
4817  * \a arrI[ 2+1 ]]); <br> etc.
4818  *  \param [in] targetNb - the size of the set \a B. \a targetNb must be equal or more
4819  *         than the maximal value of \a A.
4820  *  \param [out] arr - a new instance of DataArrayInt returning indices of
4821  *         elements of \a this, grouped by their place in the set \a B. The caller is to delete
4822  *         this array using decrRef() as it is no more needed.
4823  *  \param [out] arrI - a new instance of DataArrayInt returning size of groups of equal
4824  *         elements of \a this. The caller is to delete this array using decrRef() as it
4825  *         is no more needed.
4826  *  \throw If \a this is not allocated.
4827  *  \throw If \a this->getNumberOfComponents() != 1.
4828  *  \throw If any value in \a this is more or equal to \a targetNb.
4829  */
4830 void DataArrayInt::changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, DataArrayInt *&arrI) const
4831 {
4832   checkAllocated();
4833   if(getNumberOfComponents()!=1)
4834     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : number of components must == 1 !");
4835   int nbOfTuples=getNumberOfTuples();
4836   MCAuto<DataArrayInt> ret(DataArrayInt::New());
4837   MCAuto<DataArrayInt> retI(DataArrayInt::New());
4838   retI->alloc(targetNb+1,1);
4839   const int *input=getConstPointer();
4840   std::vector< std::vector<int> > tmp(targetNb);
4841   for(int i=0;i<nbOfTuples;i++)
4842     {
4843       int tmp2=input[i];
4844       if(tmp2>=0 && tmp2<targetNb)
4845         tmp[tmp2].push_back(i);
4846       else
4847         {
4848           std::ostringstream oss; oss << "DataArrayInt::changeSurjectiveFormat : At pos " << i << " presence of element " << tmp2 << " ! should be in [0," << targetNb << ") !";
4849           throw INTERP_KERNEL::Exception(oss.str().c_str());
4850         }
4851     }
4852   int *retIPtr=retI->getPointer();
4853   *retIPtr=0;
4854   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++,retIPtr++)
4855     retIPtr[1]=retIPtr[0]+(int)((*it1).size());
4856   if(nbOfTuples!=retI->getIJ(targetNb,0))
4857     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : big problem should never happen !");
4858   ret->alloc(nbOfTuples,1);
4859   int *retPtr=ret->getPointer();
4860   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++)
4861     retPtr=std::copy((*it1).begin(),(*it1).end(),retPtr);
4862   arr=ret.retn();
4863   arrI=retI.retn();
4864 }
4865
4866
4867 /*!
4868  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode computed
4869  * from a zip representation of a surjective format (returned e.g. by
4870  * \ref MEDCoupling::DataArrayDouble::findCommonTuples() "DataArrayDouble::findCommonTuples()"
4871  * for example). The result array minimizes the permutation. <br>
4872  * For more info on renumbering see \ref numbering. <br>
4873  * \b Example: <br>
4874  * - \a nbOfOldTuples: 10 
4875  * - \a arr          : [0,3, 5,7,9]
4876  * - \a arrIBg       : [0,2,5]
4877  * - \a newNbOfTuples: 7
4878  * - result array    : [0,1,2,0,3,4,5,4,6,4]
4879  *
4880  *  \param [in] nbOfOldTuples - number of tuples in the initial array \a arr.
4881  *  \param [in] arr - the array of tuple indices grouped by \a arrIBg array.
4882  *  \param [in] arrIBg - the array dividing all indices stored in \a arr into groups of
4883  *         (indices of) equal values. Its every element (except the last one) points to
4884  *         the first element of a group of equal values.
4885  *  \param [in] arrIEnd - specifies the end of \a arrIBg, so that the last element of \a
4886  *          arrIBg is \a arrIEnd[ -1 ].
4887  *  \param [out] newNbOfTuples - number of tuples after surjection application.
4888  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4889  *          array using decrRef() as it is no more needed.
4890  *  \throw If any value of \a arr breaks condition ( 0 <= \a arr[ i ] < \a nbOfOldTuples ).
4891  */
4892 DataArrayInt *DataArrayInt::ConvertIndexArrayToO2N(int nbOfOldTuples, const int *arr, const int *arrIBg, const int *arrIEnd, int &newNbOfTuples)
4893 {
4894   MCAuto<DataArrayInt> ret=DataArrayInt::New();
4895   ret->alloc(nbOfOldTuples,1);
4896   int *pt=ret->getPointer();
4897   std::fill(pt,pt+nbOfOldTuples,-1);
4898   int nbOfGrps=((int)std::distance(arrIBg,arrIEnd))-1;
4899   const int *cIPtr=arrIBg;
4900   for(int i=0;i<nbOfGrps;i++)
4901     pt[arr[cIPtr[i]]]=-(i+2);
4902   int newNb=0;
4903   for(int iNode=0;iNode<nbOfOldTuples;iNode++)
4904     {
4905       if(pt[iNode]<0)
4906         {
4907           if(pt[iNode]==-1)
4908             pt[iNode]=newNb++;
4909           else
4910             {
4911               int grpId=-(pt[iNode]+2);
4912               for(int j=cIPtr[grpId];j<cIPtr[grpId+1];j++)
4913                 {
4914                   if(arr[j]>=0 && arr[j]<nbOfOldTuples)
4915                     pt[arr[j]]=newNb;
4916                   else
4917                     {
4918                       std::ostringstream oss; oss << "DataArrayInt::ConvertIndexArrayToO2N : With element #" << j << " value is " << arr[j] << " should be in [0," << nbOfOldTuples << ") !";
4919                       throw INTERP_KERNEL::Exception(oss.str().c_str());
4920                     }
4921                 }
4922               newNb++;
4923             }
4924         }
4925     }
4926   newNbOfTuples=newNb;
4927   return ret.retn();
4928 }
4929
4930 /*!
4931  * Returns a new DataArrayInt containing a renumbering map in "New to Old" mode,
4932  * which if applied to \a this array would make it sorted ascendingly.
4933  * For more info on renumbering see \ref numbering. <br>
4934  * \b Example: <br>
4935  * - \a this: [2,0,1,1,0,1,2,0,1,1,0,0]
4936  * - result: [10,0,5,6,1,7,11,2,8,9,3,4]
4937  * - after applying result to \a this: [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2] 
4938  *
4939  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4940  *          array using decrRef() as it is no more needed.
4941  *  \throw If \a this is not allocated.
4942  *  \throw If \a this->getNumberOfComponents() != 1.
4943  */
4944 DataArrayInt *DataArrayInt::buildPermArrPerLevel() const
4945 {
4946   checkAllocated();
4947   if(getNumberOfComponents()!=1)
4948     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermArrPerLevel : number of components must == 1 !");
4949   int nbOfTuples=getNumberOfTuples();
4950   const int *pt=getConstPointer();
4951   std::map<int,int> m;
4952   MCAuto<DataArrayInt> ret=DataArrayInt::New();
4953   ret->alloc(nbOfTuples,1);
4954   int *opt=ret->getPointer();
4955   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
4956     {
4957       int val=*pt;
4958       std::map<int,int>::iterator it=m.find(val);
4959       if(it!=m.end())
4960         {
4961           *opt=(*it).second;
4962           (*it).second++;
4963         }
4964       else
4965         {
4966           *opt=0;
4967           m.insert(std::pair<int,int>(val,1));
4968         }
4969     }
4970   int sum=0;
4971   for(std::map<int,int>::iterator it=m.begin();it!=m.end();it++)
4972     {
4973       int vt=(*it).second;
4974       (*it).second=sum;
4975       sum+=vt;
4976     }
4977   pt=getConstPointer();
4978   opt=ret->getPointer();
4979   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
4980     *opt+=m[*pt];
4981   //
4982   return ret.retn();
4983 }
4984
4985 /*!
4986  * Checks if \a this array has the given size, and if its contents is equal to an array filled with
4987  * iota(). This method is particularly useful for DataArrayInt instances that represent
4988  * a renumbering array, to check if there is a real need in renumbering.
4989  * This method checks than \a this can be considered as an identity mapping
4990  * of a set having \a sizeExpected elements into itself.
4991  *
4992  *  \param [in] sizeExpected - The number of elements expected.
4993  *  \return bool - \a true if \a this array contents == \a range( \a this->getNumberOfTuples())
4994  *  \throw If \a this is not allocated.
4995  *  \throw If \a this->getNumberOfComponents() != 1.
4996  */
4997 bool DataArrayInt::isIota(int sizeExpected) const
4998 {
4999   checkAllocated();
5000   if(getNumberOfComponents()!=1)
5001     return false;
5002   int nbOfTuples(getNumberOfTuples());
5003   if(nbOfTuples!=sizeExpected)
5004     return false;
5005   const int *pt=getConstPointer();
5006   for(int i=0;i<nbOfTuples;i++,pt++)
5007     if(*pt!=i)
5008       return false;
5009   return true;
5010 }
5011
5012 /*!
5013  * Checks if all values in \a this array are equal to \a val.
5014  *  \param [in] val - value to check equality of array values to.
5015  *  \return bool - \a true if all values are \a val.
5016  *  \throw If \a this is not allocated.
5017  *  \throw If \a this->getNumberOfComponents() != 1
5018  */
5019 bool DataArrayInt::isUniform(int val) const
5020 {
5021   checkAllocated();
5022   if(getNumberOfComponents()!=1)
5023     throw INTERP_KERNEL::Exception("DataArrayInt::isUniform : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
5024   int nbOfTuples=getNumberOfTuples();
5025   const int *w=getConstPointer();
5026   const int *end2=w+nbOfTuples;
5027   for(;w!=end2;w++)
5028     if(*w!=val)
5029       return false;
5030   return true;
5031 }
5032
5033 /*!
5034  * Checks if all values in \a this array are unique.
5035  *  \return bool - \a true if condition above is true
5036  *  \throw If \a this is not allocated.
5037  *  \throw If \a this->getNumberOfComponents() != 1
5038  */
5039 bool DataArrayInt::hasUniqueValues() const
5040 {
5041   checkAllocated();
5042   if(getNumberOfComponents()!=1)
5043     throw INTERP_KERNEL::Exception("DataArrayInt::hasOnlyUniqueValues: must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
5044   int nbOfTuples(getNumberOfTuples());
5045   std::set<int> s(begin(),end());  // in C++11, should use unordered_set (O(1) complexity)
5046   if (s.size() != nbOfTuples)
5047     return false;
5048   return true;
5049 }
5050
5051 /*!
5052  * Copy all components in a specified order from another DataArrayInt.
5053  * The specified components become the first ones in \a this array.
5054  * Both numerical and textual data is copied. The number of tuples in \a this and
5055  * the other array can be different.
5056  *  \param [in] a - the array to copy data from.
5057  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
5058  *              to be copied.
5059  *  \throw If \a a is NULL.
5060  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
5061  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
5062  *
5063  *  \if ENABLE_EXAMPLES
5064  *  \ref py_mcdataarrayint_setselectedcomponents "Here is a Python example".
5065  *  \endif
5066  */
5067 void DataArrayInt::setSelectedComponents(const DataArrayInt *a, const std::vector<int>& compoIds)
5068 {
5069   if(!a)
5070     throw INTERP_KERNEL::Exception("DataArrayInt::setSelectedComponents : input DataArrayInt is NULL !");
5071   checkAllocated();
5072   a->checkAllocated();
5073   copyPartOfStringInfoFrom2(compoIds,*a);
5074   std::size_t partOfCompoSz=compoIds.size();
5075   int nbOfCompo=getNumberOfComponents();
5076   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
5077   const int *ac=a->getConstPointer();
5078   int *nc=getPointer();
5079   for(int i=0;i<nbOfTuples;i++)
5080     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
5081       nc[nbOfCompo*i+compoIds[j]]=*ac;
5082 }
5083
5084 DataArrayIntIterator *DataArrayInt::iterator()
5085 {
5086   return new DataArrayIntIterator(this);
5087 }
5088
5089 /*!
5090  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to a
5091  * given one. The ids are sorted in the ascending order.
5092  *  \param [in] val - the value to find within \a this.
5093  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5094  *          array using decrRef() as it is no more needed.
5095  *  \throw If \a this is not allocated.
5096  *  \throw If \a this->getNumberOfComponents() != 1.
5097  *  \sa DataArrayInt::findIdsEqualTuple
5098  */
5099 DataArrayInt *DataArrayInt::findIdsEqual(int val) const
5100 {
5101   checkAllocated();
5102   if(getNumberOfComponents()!=1)
5103     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqual : the array must have only one component, you can call 'rearrange' method before !");
5104   const int *cptr(getConstPointer());
5105   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
5106   int nbOfTuples=getNumberOfTuples();
5107   for(int i=0;i<nbOfTuples;i++,cptr++)
5108     if(*cptr==val)
5109       ret->pushBackSilent(i);
5110   return ret.retn();
5111 }
5112
5113 /*!
5114  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value \b not
5115  * equal to a given one. 
5116  *  \param [in] val - the value to ignore within \a this.
5117  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5118  *          array using decrRef() as it is no more needed.
5119  *  \throw If \a this is not allocated.
5120  *  \throw If \a this->getNumberOfComponents() != 1.
5121  */
5122 DataArrayInt *DataArrayInt::findIdsNotEqual(int val) const
5123 {
5124   checkAllocated();
5125   if(getNumberOfComponents()!=1)
5126     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotEqual : the array must have only one component, you can call 'rearrange' method before !");
5127   const int *cptr(getConstPointer());
5128   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
5129   int nbOfTuples=getNumberOfTuples();
5130   for(int i=0;i<nbOfTuples;i++,cptr++)
5131     if(*cptr!=val)
5132       ret->pushBackSilent(i);
5133   return ret.retn();
5134 }
5135
5136 /*!
5137  * Creates a new DataArrayInt containing IDs (indices) of tuples holding tuple equal to those defined by [ \a tupleBg , \a tupleEnd )
5138  * This method is an extension of  DataArrayInt::findIdsEqual method.
5139  *
5140  *  \param [in] tupleBg - the begin (included) of the input tuple to find within \a this.
5141  *  \param [in] tupleEnd - the end (excluded) of the input tuple to find within \a this.
5142  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5143  *          array using decrRef() as it is no more needed.
5144  *  \throw If \a this is not allocated.
5145  *  \throw If \a this->getNumberOfComponents() != std::distance(tupleBg,tupleEnd).
5146  * \throw If \a this->getNumberOfComponents() is equal to 0.
5147  * \sa DataArrayInt::findIdsEqual
5148  */
5149 DataArrayInt *DataArrayInt::findIdsEqualTuple(const int *tupleBg, const int *tupleEnd) const
5150 {
5151   std::size_t nbOfCompoExp(std::distance(tupleBg,tupleEnd));
5152   checkAllocated();
5153   if(getNumberOfComponents()!=(int)nbOfCompoExp)
5154     {
5155       std::ostringstream oss; oss << "DataArrayInt::findIdsEqualTuple : mismatch of number of components. Input tuple has " << nbOfCompoExp << " whereas this array has " << getNumberOfComponents() << " components !";
5156       throw INTERP_KERNEL::Exception(oss.str().c_str());
5157     }
5158   if(nbOfCompoExp==0)
5159     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqualTuple : number of components should be > 0 !");
5160   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
5161   const int *bg(begin()),*end2(end()),*work(begin());
5162   while(work!=end2)
5163     {
5164       work=std::search(work,end2,tupleBg,tupleEnd);
5165       if(work!=end2)
5166         {
5167           std::size_t pos(std::distance(bg,work));
5168           if(pos%nbOfCompoExp==0)
5169             ret->pushBackSilent(pos/nbOfCompoExp);
5170           work++;
5171         }
5172     }
5173   return ret.retn();
5174 }
5175
5176 /*!
5177  * Assigns \a newValue to all elements holding \a oldValue within \a this
5178  * one-dimensional array.
5179  *  \param [in] oldValue - the value to replace.
5180  *  \param [in] newValue - the value to assign.
5181  *  \return int - number of replacements performed.
5182  *  \throw If \a this is not allocated.
5183  *  \throw If \a this->getNumberOfComponents() != 1.
5184  */
5185 int DataArrayInt::changeValue(int oldValue, int newValue)
5186 {
5187   checkAllocated();
5188   if(getNumberOfComponents()!=1)
5189     throw INTERP_KERNEL::Exception("DataArrayInt::changeValue : the array must have only one component, you can call 'rearrange' method before !");
5190   if(oldValue==newValue)
5191     return 0;
5192   int *start(getPointer()),*end2(start+getNbOfElems());
5193   int ret(0);
5194   for(int *val=start;val!=end2;val++)
5195     {
5196       if(*val==oldValue)
5197         {
5198           *val=newValue;
5199           ret++;
5200         }
5201     }
5202   if(ret>0)
5203     declareAsNew();
5204   return ret;
5205 }
5206
5207 /*!
5208  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to
5209  * one of given values.
5210  *  \param [in] valsBg - an array of values to find within \a this array.
5211  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
5212  *              the last value of \a valsBg is \a valsEnd[ -1 ].
5213  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5214  *          array using decrRef() as it is no more needed.
5215  *  \throw If \a this->getNumberOfComponents() != 1.
5216  */
5217 DataArrayInt *DataArrayInt::findIdsEqualList(const int *valsBg, const int *valsEnd) const
5218 {
5219   if(getNumberOfComponents()!=1)
5220     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqualList : the array must have only one component, you can call 'rearrange' method before !");
5221   std::set<int> vals2(valsBg,valsEnd);
5222   const int *cptr(getConstPointer());
5223   std::vector<int> res;
5224   int nbOfTuples(getNumberOfTuples());
5225   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
5226   for(int i=0;i<nbOfTuples;i++,cptr++)
5227     if(vals2.find(*cptr)!=vals2.end())
5228       ret->pushBackSilent(i);
5229   return ret.retn();
5230 }
5231
5232 /*!
5233  * Creates a new DataArrayInt containing IDs (indices) of tuples holding values \b not
5234  * equal to any of given values.
5235  *  \param [in] valsBg - an array of values to ignore within \a this array.
5236  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
5237  *              the last value of \a valsBg is \a valsEnd[ -1 ].
5238  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5239  *          array using decrRef() as it is no more needed.
5240  *  \throw If \a this->getNumberOfComponents() != 1.
5241  */
5242 DataArrayInt *DataArrayInt::findIdsNotEqualList(const int *valsBg, const int *valsEnd) const
5243 {
5244   if(getNumberOfComponents()!=1)
5245     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotEqualList : the array must have only one component, you can call 'rearrange' method before !");
5246   std::set<int> vals2(valsBg,valsEnd);
5247   const int *cptr=getConstPointer();
5248   std::vector<int> res;
5249   int nbOfTuples=getNumberOfTuples();
5250   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
5251   for(int i=0;i<nbOfTuples;i++,cptr++)
5252     if(vals2.find(*cptr)==vals2.end())
5253       ret->pushBackSilent(i);
5254   return ret.retn();
5255 }
5256
5257 /*!
5258  * This method is an extension of DataArrayInt::findIdFirstEqual method because this method works for DataArrayInt with
5259  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
5260  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
5261  * If any the tuple id is returned. If not -1 is returned.
5262  * 
5263  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
5264  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
5265  *
5266  * \return tuple id where \b tupl is. -1 if no such tuple exists in \b this.
5267  * \sa DataArrayInt::findIdSequence, DataArrayInt::presenceOfTuple.
5268  */
5269 int DataArrayInt::findIdFirstEqualTuple(const std::vector<int>& tupl) const
5270 {
5271   checkAllocated();
5272   int nbOfCompo=getNumberOfComponents();
5273   if(nbOfCompo==0)
5274     throw INTERP_KERNEL::Exception("DataArrayInt::findIdFirstEqualTuple : 0 components in 'this' !");
5275   if(nbOfCompo!=(int)tupl.size())
5276     {
5277       std::ostringstream oss; oss << "DataArrayInt::findIdFirstEqualTuple : 'this' contains " << nbOfCompo << " components and searching for a tuple of length " << tupl.size() << " !";
5278       throw INTERP_KERNEL::Exception(oss.str().c_str());
5279     }
5280   const int *cptr=getConstPointer();
5281   std::size_t nbOfVals=getNbOfElems();
5282   for(const int *work=cptr;work!=cptr+nbOfVals;)
5283     {
5284       work=std::search(work,cptr+nbOfVals,tupl.begin(),tupl.end());
5285       if(work!=cptr+nbOfVals)
5286         {
5287           if(std::distance(cptr,work)%nbOfCompo!=0)
5288             work++;
5289           else
5290             return std::distance(cptr,work)/nbOfCompo;
5291         }
5292     }
5293   return -1;
5294 }
5295
5296 /*!
5297  * This method searches the sequence specified in input parameter \b vals in \b this.
5298  * This works only for DataArrayInt having number of components equal to one (if not an INTERP_KERNEL::Exception will be thrown).
5299  * This method differs from DataArrayInt::findIdFirstEqualTuple in that the position is internal raw data is not considered here contrary to DataArrayInt::findIdFirstEqualTuple.
5300  * \sa DataArrayInt::findIdFirstEqualTuple
5301  */
5302 int DataArrayInt::findIdSequence(const std::vector<int>& vals) const
5303 {
5304   checkAllocated();
5305   int nbOfCompo=getNumberOfComponents();
5306   if(nbOfCompo!=1)
5307     throw INTERP_KERNEL::Exception("DataArrayInt::findIdSequence : works only for DataArrayInt instance with one component !");
5308   const int *cptr=getConstPointer();
5309   std::size_t nbOfVals=getNbOfElems();
5310   const int *loc=std::search(cptr,cptr+nbOfVals,vals.begin(),vals.end());
5311   if(loc!=cptr+nbOfVals)
5312     return std::distance(cptr,loc);
5313   return -1;
5314 }
5315
5316 /*!
5317  * This method expects to be called when number of components of this is equal to one.
5318  * This method returns the tuple id, if it exists, of the first tuple equal to \b value.
5319  * If not any tuple contains \b value -1 is returned.
5320  * \sa DataArrayInt::presenceOfValue
5321  */
5322 int DataArrayInt::findIdFirstEqual(int value) const
5323 {
5324   checkAllocated();
5325   if(getNumberOfComponents()!=1)
5326     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
5327   const int *cptr=getConstPointer();
5328   int nbOfTuples=getNumberOfTuples();
5329   const int *ret=std::find(cptr,cptr+nbOfTuples,value);
5330   if(ret!=cptr+nbOfTuples)
5331     return std::distance(cptr,ret);
5332   return -1;
5333 }
5334
5335 /*!
5336  * This method expects to be called when number of components of this is equal to one.
5337  * This method returns the tuple id, if it exists, of the first tuple so that the value is contained in \b vals.
5338  * If not any tuple contains one of the values contained in 'vals' -1 is returned.
5339  * \sa DataArrayInt::presenceOfValue
5340  */
5341 int DataArrayInt::findIdFirstEqual(const std::vector<int>& vals) const
5342 {
5343   checkAllocated();
5344   if(getNumberOfComponents()!=1)
5345     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
5346   std::set<int> vals2(vals.begin(),vals.end());
5347   const int *cptr=getConstPointer();
5348   int nbOfTuples=getNumberOfTuples();
5349   for(const int *w=cptr;w!=cptr+nbOfTuples;w++)
5350     if(vals2.find(*w)!=vals2.end())
5351       return std::distance(cptr,w);
5352   return -1;
5353 }
5354
5355 /*!
5356  * This method returns the number of values in \a this that are equals to input parameter \a value.
5357  * This method only works for single component array.
5358  *
5359  * \return a value in [ 0, \c this->getNumberOfTuples() )
5360  *
5361  * \throw If \a this is not allocated
5362  *
5363  */
5364 int DataArrayInt::count(int value) const
5365 {
5366   int ret=0;
5367   checkAllocated();
5368   if(getNumberOfComponents()!=1)
5369     throw INTERP_KERNEL::Exception("DataArrayInt::count : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
5370   const int *vals=begin();
5371   int nbOfTuples=getNumberOfTuples();
5372   for(int i=0;i<nbOfTuples;i++,vals++)
5373     if(*vals==value)
5374       ret++;
5375   return ret;
5376 }
5377
5378 /*!
5379  * This method is an extension of DataArrayInt::presenceOfValue method because this method works for DataArrayInt with
5380  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
5381  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
5382  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
5383  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
5384  * \sa DataArrayInt::findIdFirstEqualTuple
5385  */
5386 bool DataArrayInt::presenceOfTuple(const std::vector<int>& tupl) const
5387 {
5388   return findIdFirstEqualTuple(tupl)!=-1;
5389 }
5390
5391
5392 /*!
5393  * Returns \a true if a given value is present within \a this one-dimensional array.
5394  *  \param [in] value - the value to find within \a this array.
5395  *  \return bool - \a true in case if \a value is present within \a this array.
5396  *  \throw If \a this is not allocated.
5397  *  \throw If \a this->getNumberOfComponents() != 1.
5398  *  \sa findIdFirstEqual()
5399  */
5400 bool DataArrayInt::presenceOfValue(int value) const
5401 {
5402   return findIdFirstEqual(value)!=-1;
5403 }
5404
5405 /*!
5406  * This method expects to be called when number of components of this is equal to one.
5407  * This method returns true if it exists a tuple so that the value is contained in \b vals.
5408  * If not any tuple contains one of the values contained in 'vals' false is returned.
5409  * \sa DataArrayInt::findIdFirstEqual
5410  */
5411 bool DataArrayInt::presenceOfValue(const std::vector<int>& vals) const
5412 {
5413   return findIdFirstEqual(vals)!=-1;
5414 }
5415
5416 /*!
5417  * Accumulates values of each component of \a this array.
5418  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
5419  *         by the caller, that is filled by this method with sum value for each
5420  *         component.
5421  *  \throw If \a this is not allocated.
5422  */
5423 void DataArrayInt::accumulate(int *res) const
5424 {
5425   checkAllocated();
5426   const int *ptr=getConstPointer();
5427   int nbTuple=getNumberOfTuples();
5428   int nbComps=getNumberOfComponents();
5429   std::fill(res,res+nbComps,0);
5430   for(int i=0;i<nbTuple;i++)
5431     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<int>());
5432 }
5433
5434 int DataArrayInt::accumulate(int compId) const
5435 {
5436   checkAllocated();
5437   const int *ptr=getConstPointer();
5438   int nbTuple=getNumberOfTuples();
5439   int nbComps=getNumberOfComponents();
5440   if(compId<0 || compId>=nbComps)
5441     throw INTERP_KERNEL::Exception("DataArrayInt::accumulate : Invalid compId specified : No such nb of components !");
5442   int ret=0;
5443   for(int i=0;i<nbTuple;i++)
5444     ret+=ptr[i*nbComps+compId];
5445   return ret;
5446 }
5447
5448 /*!
5449  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
5450  * The returned array will have same number of components than \a this and number of tuples equal to
5451  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
5452  *
5453  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
5454  *
5455  * \param [in] bgOfIndex - begin (included) of the input index array.
5456  * \param [in] endOfIndex - end (excluded) of the input index array.
5457  * \return DataArrayInt * - the new instance having the same number of components than \a this.
5458  * 
5459  * \throw If bgOfIndex or end is NULL.
5460  * \throw If input index array is not ascendingly sorted.
5461  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
5462  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
5463  */
5464 DataArrayInt *DataArrayInt::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
5465 {
5466   if(!bgOfIndex || !endOfIndex)
5467     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : input pointer NULL !");
5468   checkAllocated();
5469   int nbCompo=getNumberOfComponents();
5470   int nbOfTuples=getNumberOfTuples();
5471   int sz=(int)std::distance(bgOfIndex,endOfIndex);
5472   if(sz<1)
5473     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : invalid size of input index array !");
5474   sz--;
5475   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(sz,nbCompo);
5476   const int *w=bgOfIndex;
5477   if(*w<0 || *w>=nbOfTuples)
5478     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
5479   const int *srcPt=begin()+(*w)*nbCompo;
5480   int *tmp=ret->getPointer();
5481   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
5482     {
5483       std::fill(tmp,tmp+nbCompo,0);
5484       if(w[1]>=w[0])
5485         {
5486           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
5487             {
5488               if(j>=0 && j<nbOfTuples)
5489                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<int>());
5490               else
5491                 {
5492                   std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
5493                   throw INTERP_KERNEL::Exception(oss.str().c_str());
5494                 }
5495             }
5496         }
5497       else
5498         {
5499           std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
5500           throw INTERP_KERNEL::Exception(oss.str().c_str());
5501         }
5502     }
5503   ret->copyStringInfoFrom(*this);
5504   return ret.retn();
5505 }
5506
5507 /*!
5508  * Returns a new DataArrayInt by concatenating two given arrays, so that (1) the number
5509  * of tuples in the result array is <em> a1->getNumberOfTuples() + a2->getNumberOfTuples() -
5510  * offsetA2</em> and (2)
5511  * the number of component in the result array is same as that of each of given arrays.
5512  * First \a offsetA2 tuples of \a a2 are skipped and thus are missing from the result array.
5513  * Info on components is copied from the first of the given arrays. Number of components
5514  * in the given arrays must be the same.
5515  *  \param [in] a1 - an array to include in the result array.
5516  *  \param [in] a2 - another array to include in the result array.
5517  *  \param [in] offsetA2 - number of tuples of \a a2 to skip.
5518  *  \return DataArrayInt * - the new instance of DataArrayInt.
5519  *          The caller is to delete this result array using decrRef() as it is no more
5520  *          needed.
5521  *  \throw If either \a a1 or \a a2 is NULL.
5522  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
5523  */
5524 DataArrayInt *DataArrayInt::Aggregate(const DataArrayInt *a1, const DataArrayInt *a2, int offsetA2)
5525 {
5526   if(!a1 || !a2)
5527     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input DataArrayInt instance is NULL !");
5528   int nbOfComp=a1->getNumberOfComponents();
5529   if(nbOfComp!=a2->getNumberOfComponents())
5530     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Aggregation !");
5531   int nbOfTuple1=a1->getNumberOfTuples();
5532   int nbOfTuple2=a2->getNumberOfTuples();
5533   DataArrayInt *ret=DataArrayInt::New();
5534   ret->alloc(nbOfTuple1+nbOfTuple2-offsetA2,nbOfComp);
5535   int *pt=std::copy(a1->getConstPointer(),a1->getConstPointer()+nbOfTuple1*nbOfComp,ret->getPointer());
5536   std::copy(a2->getConstPointer()+offsetA2*nbOfComp,a2->getConstPointer()+nbOfTuple2*nbOfComp,pt);
5537   ret->copyStringInfoFrom(*a1);
5538   return ret;
5539 }
5540
5541 /*!
5542  * Returns a new DataArrayInt by concatenating all given arrays, so that (1) the number
5543  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
5544  * the number of component in the result array is same as that of each of given arrays.
5545  * Info on components is copied from the first of the given arrays. Number of components
5546  * in the given arrays must be  the same.
5547  * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it
5548  * not the object itself.
5549  *  \param [in] arr - a sequence of arrays to include in the result array.
5550  *  \return DataArrayInt * - the new instance of DataArrayInt.
5551  *          The caller is to delete this result array using decrRef() as it is no more
5552  *          needed.
5553  *  \throw If all arrays within \a arr are NULL.
5554  *  \throw If getNumberOfComponents() of arrays within \a arr.
5555  */
5556 DataArrayInt *DataArrayInt::Aggregate(const std::vector<const DataArrayInt *>& arr)
5557 {
5558   std::vector<const DataArrayInt *> a;
5559   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
5560     if(*it4)
5561       a.push_back(*it4);
5562   if(a.empty())
5563     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input list must be NON EMPTY !");
5564   std::vector<const DataArrayInt *>::const_iterator it=a.begin();
5565   int nbOfComp=(*it)->getNumberOfComponents();
5566   int nbt=(*it++)->getNumberOfTuples();
5567   for(int i=1;it!=a.end();it++,i++)
5568     {
5569       if((*it)->getNumberOfComponents()!=nbOfComp)
5570         throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : Nb of components mismatch for array aggregation !");
5571       nbt+=(*it)->getNumberOfTuples();
5572     }
5573   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5574   ret->alloc(nbt,nbOfComp);
5575   int *pt=ret->getPointer();
5576   for(it=a.begin();it!=a.end();it++)
5577     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
5578   ret->copyStringInfoFrom(*(a[0]));
5579   return ret.retn();
5580 }
5581
5582 /*!
5583  * This method takes as input a list of DataArrayInt instances \a arrs that represent each a packed index arrays.
5584  * A packed index array is an allocated array with one component, and at least one tuple. The first element
5585  * of each array in \a arrs must be 0. Each array in \a arrs is expected to be increasingly monotonic.
5586  * 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.
5587  * 
5588  * \return DataArrayInt * - a new object to be managed by the caller.
5589  */
5590 DataArrayInt *DataArrayInt::AggregateIndexes(const std::vector<const DataArrayInt *>& arrs)
5591 {
5592   int retSz=1;
5593   for(std::vector<const DataArrayInt *>::const_iterator it4=arrs.begin();it4!=arrs.end();it4++)
5594     {
5595       if(*it4)
5596         {
5597           (*it4)->checkAllocated();
5598           if((*it4)->getNumberOfComponents()!=1)
5599             {
5600               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of compo != 1 at pos " << std::distance(arrs.begin(),it4) << " !";
5601               throw INTERP_KERNEL::Exception(oss.str().c_str());
5602             }
5603           int nbTupl=(*it4)->getNumberOfTuples();
5604           if(nbTupl<1)
5605             {
5606               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of tuples < 1 at pos " << std::distance(arrs.begin(),it4) << " !";
5607               throw INTERP_KERNEL::Exception(oss.str().c_str());
5608             }
5609           if((*it4)->front()!=0)
5610             {
5611               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with front value != 0 at pos " << std::distance(arrs.begin(),it4) << " !";
5612               throw INTERP_KERNEL::Exception(oss.str().c_str());
5613             }
5614           retSz+=nbTupl-1;
5615         }
5616       else
5617         {
5618           std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a null instance at pos " << std::distance(arrs.begin(),it4) << " !";
5619           throw INTERP_KERNEL::Exception(oss.str().c_str());
5620         }
5621     }
5622   if(arrs.empty())
5623     throw INTERP_KERNEL::Exception("DataArrayInt::AggregateIndexes : input list must be NON EMPTY !");
5624   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5625   ret->alloc(retSz,1);
5626   int *pt=ret->getPointer(); *pt++=0;
5627   for(std::vector<const DataArrayInt *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
5628     pt=std::transform((*it)->begin()+1,(*it)->end(),pt,std::bind2nd(std::plus<int>(),pt[-1]));
5629   ret->copyStringInfoFrom(*(arrs[0]));
5630   return ret.retn();
5631 }
5632
5633 /*!
5634  * Returns in a single walk in \a this the min value and the max value in \a this.
5635  * \a this is expected to be single component array.
5636  *
5637  * \param [out] minValue - the min value in \a this.
5638  * \param [out] maxValue - the max value in \a this.
5639  *
5640  * \sa getMinValueInArray, getMinValue, getMaxValueInArray, getMaxValue
5641  */
5642 void DataArrayInt::getMinMaxValues(int& minValue, int& maxValue) const
5643 {
5644   checkAllocated();
5645   if(getNumberOfComponents()!=1)
5646     throw INTERP_KERNEL::Exception("DataArrayInt::getMinMaxValues : must be applied on DataArrayInt with only one component !");
5647   int nbTuples(getNumberOfTuples());
5648   const int *pt(begin());
5649   minValue=std::numeric_limits<int>::max(); maxValue=-std::numeric_limits<int>::max();
5650   for(int i=0;i<nbTuples;i++,pt++)
5651     {
5652       if(*pt<minValue)
5653         minValue=*pt;
5654       if(*pt>maxValue)
5655         maxValue=*pt;
5656     }
5657 }
5658
5659 /*!
5660  * Converts every value of \a this array to its absolute value.
5661  * \b WARNING this method is non const. If a new DataArrayInt instance should be built containing the result of abs DataArrayInt::computeAbs
5662  * should be called instead.
5663  *
5664  * \throw If \a this is not allocated.
5665  * \sa DataArrayInt::computeAbs
5666  */
5667 void DataArrayInt::abs()
5668 {
5669   checkAllocated();
5670   int *ptr(getPointer());
5671   std::size_t nbOfElems(getNbOfElems());
5672   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<int,int>(std::abs));
5673   declareAsNew();
5674 }
5675
5676 /*!
5677  * This method builds a new instance of \a this object containing the result of std::abs applied of all elements in \a this.
5678  * This method is a const method (that do not change any values in \a this) contrary to  DataArrayInt::abs method.
5679  *
5680  * \return DataArrayInt * - the new instance of DataArrayInt containing the
5681  *         same number of tuples and component as \a this array.
5682  *         The caller is to delete this result array using decrRef() as it is no more
5683  *         needed.
5684  * \throw If \a this is not allocated.
5685  * \sa DataArrayInt::abs
5686  */
5687 DataArrayInt *DataArrayInt::computeAbs() const
5688 {
5689   checkAllocated();
5690   DataArrayInt *newArr(DataArrayInt::New());
5691   int nbOfTuples(getNumberOfTuples());
5692   int nbOfComp(getNumberOfComponents());
5693   newArr->alloc(nbOfTuples,nbOfComp);
5694   std::transform(begin(),end(),newArr->getPointer(),std::ptr_fun<int,int>(std::abs));
5695   newArr->copyStringInfoFrom(*this);
5696   return newArr;
5697 }
5698
5699 /*!
5700  * Modify all elements of \a this array, so that
5701  * an element _x_ becomes \f$ numerator / x \f$.
5702  *  \warning If an exception is thrown because of presence of 0 element in \a this 
5703  *           array, all elements processed before detection of the zero element remain
5704  *           modified.
5705  *  \param [in] numerator - the numerator used to modify array elements.
5706  *  \throw If \a this is not allocated.
5707  *  \throw If there is an element equal to 0 in \a this array.
5708  */
5709 void DataArrayInt::applyInv(int numerator)
5710 {
5711   checkAllocated();
5712   int *ptr=getPointer();
5713   std::size_t nbOfElems=getNbOfElems();
5714   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
5715     {
5716       if(*ptr!=0)
5717         {
5718           *ptr=numerator/(*ptr);
5719         }
5720       else
5721         {
5722           std::ostringstream oss; oss << "DataArrayInt::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
5723           oss << " !";
5724           throw INTERP_KERNEL::Exception(oss.str().c_str());
5725         }
5726     }
5727   declareAsNew();
5728 }
5729
5730 /*!
5731  * Modify all elements of \a this array, so that
5732  * an element _x_ becomes \f$ x / val \f$.
5733  *  \param [in] val - the denominator used to modify array elements.
5734  *  \throw If \a this is not allocated.
5735  *  \throw If \a val == 0.
5736  */
5737 void DataArrayInt::applyDivideBy(int val)
5738 {
5739   if(val==0)
5740     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to divide by 0 !");
5741   checkAllocated();
5742   int *ptr=getPointer();
5743   std::size_t nbOfElems=getNbOfElems();
5744   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::divides<int>(),val));
5745   declareAsNew();
5746 }
5747
5748 /*!
5749  * Modify all elements of \a this array, so that
5750  * an element _x_ becomes  <em> x % val </em>.
5751  *  \param [in] val - the divisor used to modify array elements.
5752  *  \throw If \a this is not allocated.
5753  *  \throw If \a val <= 0.
5754  */
5755 void DataArrayInt::applyModulus(int val)
5756 {
5757   if(val<=0)
5758     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to operate modulus on value <= 0 !");
5759   checkAllocated();
5760   int *ptr=getPointer();
5761   std::size_t nbOfElems=getNbOfElems();
5762   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::modulus<int>(),val));
5763   declareAsNew();
5764 }
5765
5766 /*!
5767  * This method works only on data array with one component.
5768  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
5769  * this[*id] in [\b vmin,\b vmax)
5770  * 
5771  * \param [in] vmin begin of range. This value is included in range (included).
5772  * \param [in] vmax end of range. This value is \b not included in range (excluded).
5773  * \return a newly allocated data array that the caller should deal with.
5774  *
5775  * \sa DataArrayInt::findIdsNotInRange , DataArrayInt::findIdsStricltyNegative
5776  */
5777 DataArrayInt *DataArrayInt::findIdsInRange(int vmin, int vmax) const
5778 {
5779   InRange<int> ir(vmin,vmax);
5780   MCAuto<DataArrayInt> ret(findIdsAdv(ir));
5781   return ret.retn();
5782 }
5783
5784 /*!
5785  * This method works only on data array with one component.
5786  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
5787  * this[*id] \b not in [\b vmin,\b vmax)
5788  * 
5789  * \param [in] vmin begin of range. This value is \b not included in range (excluded).
5790  * \param [in] vmax end of range. This value is included in range (included).
5791  * \return a newly allocated data array that the caller should deal with.
5792  * 
5793  * \sa DataArrayInt::findIdsInRange , DataArrayInt::findIdsStricltyNegative
5794  */
5795 DataArrayInt *DataArrayInt::findIdsNotInRange(int vmin, int vmax) const
5796 {
5797   NotInRange<int> nir(vmin,vmax);
5798   MCAuto<DataArrayInt> ret(findIdsAdv(nir));
5799   return ret.retn();
5800 }
5801
5802 /*!
5803  * This method works only on data array with one component.
5804  * 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.
5805  * 
5806  * \param [in] vmin begin of range. This value is included in range (included).
5807  * \param [in] vmax end of range. This value is \b not included in range (excluded).
5808  * \return if all ids in \a this are so that (*this)[i]==i for all i in [ 0, \c this->getNumberOfTuples() ). */
5809 bool DataArrayInt::checkAllIdsInRange(int vmin, int vmax) const
5810 {
5811   checkAllocated();
5812   if(getNumberOfComponents()!=1)
5813     throw INTERP_KERNEL::Exception("DataArrayInt::checkAllIdsInRange : this must have exactly one component !");
5814   int nbOfTuples=getNumberOfTuples();
5815   bool ret=true;
5816   const int *cptr=getConstPointer();
5817   for(int i=0;i<nbOfTuples;i++,cptr++)
5818     {
5819       if(*cptr>=vmin && *cptr<vmax)
5820         { ret=ret && *cptr==i; }
5821       else
5822         {
5823           std::ostringstream oss; oss << "DataArrayInt::checkAllIdsInRange : tuple #" << i << " has value " << *cptr << " should be in [" << vmin << "," << vmax << ") !";
5824           throw INTERP_KERNEL::Exception(oss.str().c_str());
5825         }
5826     }
5827   return ret;
5828 }
5829
5830 /*!
5831  * Modify all elements of \a this array, so that
5832  * an element _x_ becomes <em> val % x </em>.
5833  *  \warning If an exception is thrown because of presence of an element <= 0 in \a this 
5834  *           array, all elements processed before detection of the zero element remain
5835  *           modified.
5836  *  \param [in] val - the divident used to modify array elements.
5837  *  \throw If \a this is not allocated.
5838  *  \throw If there is an element equal to or less than 0 in \a this array.
5839  */
5840 void DataArrayInt::applyRModulus(int val)
5841 {
5842   checkAllocated();
5843   int *ptr=getPointer();
5844   std::size_t nbOfElems=getNbOfElems();
5845   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
5846     {
5847       if(*ptr>0)
5848         {
5849           *ptr=val%(*ptr);
5850         }
5851       else
5852         {
5853           std::ostringstream oss; oss << "DataArrayInt::applyRModulus : presence of value <=0 in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
5854           oss << " !";
5855           throw INTERP_KERNEL::Exception(oss.str().c_str());
5856         }
5857     }
5858   declareAsNew();
5859 }
5860
5861 /*!
5862  * Modify all elements of \a this array, so that
5863  * an element _x_ becomes <em> val ^ x </em>.
5864  *  \param [in] val - the value used to apply pow on all array elements.
5865  *  \throw If \a this is not allocated.
5866  *  \throw If \a val < 0.
5867  */
5868 void DataArrayInt::applyPow(int val)
5869 {
5870   checkAllocated();
5871   if(val<0)
5872     throw INTERP_KERNEL::Exception("DataArrayInt::applyPow : input pow in < 0 !");
5873   int *ptr=getPointer();
5874   std::size_t nbOfElems=getNbOfElems();
5875   if(val==0)
5876     {
5877       std::fill(ptr,ptr+nbOfElems,1);
5878       return ;
5879     }
5880   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
5881     {
5882       int tmp=1;
5883       for(int j=0;j<val;j++)
5884         tmp*=*ptr;
5885       *ptr=tmp;
5886     }
5887   declareAsNew();
5888 }
5889
5890 /*!
5891  * Modify all elements of \a this array, so that
5892  * an element _x_ becomes \f$ val ^ x \f$.
5893  *  \param [in] val - the value used to apply pow on all array elements.
5894  *  \throw If \a this is not allocated.
5895  *  \throw If there is an element < 0 in \a this array.
5896  *  \warning If an exception is thrown because of presence of 0 element in \a this 
5897  *           array, all elements processed before detection of the zero element remain
5898  *           modified.
5899  */
5900 void DataArrayInt::applyRPow(int val)
5901 {
5902   checkAllocated();
5903   int *ptr=getPointer();
5904   std::size_t nbOfElems=getNbOfElems();
5905   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
5906     {
5907       if(*ptr>=0)
5908         {
5909           int tmp=1;
5910           for(int j=0;j<*ptr;j++)
5911             tmp*=val;
5912           *ptr=tmp;
5913         }
5914       else
5915         {
5916           std::ostringstream oss; oss << "DataArrayInt::applyRPow : presence of negative value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
5917           oss << " !";
5918           throw INTERP_KERNEL::Exception(oss.str().c_str());
5919         }
5920     }
5921   declareAsNew();
5922 }
5923
5924 /*!
5925  * Returns a new DataArrayInt which is a minimal partition of elements of \a groups.
5926  * The i-th item of the result array is an ID of a set of elements belonging to a
5927  * unique set of groups, which the i-th element is a part of. This set of elements
5928  * belonging to a unique set of groups is called \a family, so the result array contains
5929  * IDs of families each element belongs to.
5930  *
5931  * \b Example: if we have two groups of elements: \a group1 [0,4] and \a group2 [ 0,1,2 ],
5932  * then there are 3 families:
5933  * - \a family1 (with ID 1) contains element [0] belonging to ( \a group1 + \a group2 ),
5934  * - \a family2 (with ID 2) contains elements [4] belonging to ( \a group1 ),
5935  * - \a family3 (with ID 3) contains element [1,2] belonging to ( \a group2 ), <br>
5936  * and the result array contains IDs of families [ 1,3,3,0,2 ]. <br> Note a family ID 0 which
5937  * stands for the element #3 which is in none of groups.
5938  *
5939  *  \param [in] groups - sequence of groups of element IDs.
5940  *  \param [in] newNb - total number of elements; it must be more than max ID of element
5941  *         in \a groups.
5942  *  \param [out] fidsOfGroups - IDs of families the elements of each group belong to.
5943  *  \return DataArrayInt * - a new instance of DataArrayInt containing IDs of families
5944  *         each element with ID from range [0, \a newNb ) belongs to. The caller is to
5945  *         delete this array using decrRef() as it is no more needed.
5946  *  \throw If any element ID in \a groups violates condition ( 0 <= ID < \a newNb ).
5947  */
5948 DataArrayInt *DataArrayInt::MakePartition(const std::vector<const DataArrayInt *>& groups, int newNb, std::vector< std::vector<int> >& fidsOfGroups)
5949 {
5950   std::vector<const DataArrayInt *> groups2;
5951   for(std::vector<const DataArrayInt *>::const_iterator it4=groups.begin();it4!=groups.end();it4++)
5952     if(*it4)
5953       groups2.push_back(*it4);
5954   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5955   ret->alloc(newNb,1);
5956   int *retPtr=ret->getPointer();
5957   std::fill(retPtr,retPtr+newNb,0);
5958   int fid=1;
5959   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++)
5960     {
5961       const int *ptr=(*iter)->getConstPointer();
5962       std::size_t nbOfElem=(*iter)->getNbOfElems();
5963       int sfid=fid;
5964       for(int j=0;j<sfid;j++)
5965         {
5966           bool found=false;
5967           for(std::size_t i=0;i<nbOfElem;i++)
5968             {
5969               if(ptr[i]>=0 && ptr[i]<newNb)
5970                 {
5971                   if(retPtr[ptr[i]]==j)
5972                     {
5973                       retPtr[ptr[i]]=fid;
5974                       found=true;
5975                     }
5976                 }
5977               else
5978                 {
5979                   std::ostringstream oss; oss << "DataArrayInt::MakePartition : In group \"" << (*iter)->getName() << "\" in tuple #" << i << " value = " << ptr[i] << " ! Should be in [0," << newNb;
5980                   oss << ") !";
5981                   throw INTERP_KERNEL::Exception(oss.str().c_str());
5982                 }
5983             }
5984           if(found)
5985             fid++;
5986         }
5987     }
5988   fidsOfGroups.clear();
5989   fidsOfGroups.resize(groups2.size());
5990   int grId=0;
5991   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++,grId++)
5992     {
5993       std::set<int> tmp;
5994       const int *ptr=(*iter)->getConstPointer();
5995       std::size_t nbOfElem=(*iter)->getNbOfElems();
5996       for(const int *p=ptr;p!=ptr+nbOfElem;p++)
5997         tmp.insert(retPtr[*p]);
5998       fidsOfGroups[grId].insert(fidsOfGroups[grId].end(),tmp.begin(),tmp.end());
5999     }
6000   return ret.retn();
6001 }
6002
6003 /*!
6004  * Returns a new DataArrayInt which contains all elements of given one-dimensional
6005  * arrays. The result array does not contain any duplicates and its values
6006  * are sorted in ascending order.
6007  *  \param [in] arr - sequence of DataArrayInt's to unite.
6008  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6009  *         array using decrRef() as it is no more needed.
6010  *  \throw If any \a arr[i] is not allocated.
6011  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
6012  */
6013 DataArrayInt *DataArrayInt::BuildUnion(const std::vector<const DataArrayInt *>& arr)
6014 {
6015   std::vector<const DataArrayInt *> a;
6016   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
6017     if(*it4)
6018       a.push_back(*it4);
6019   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
6020     {
6021       (*it)->checkAllocated();
6022       if((*it)->getNumberOfComponents()!=1)
6023         throw INTERP_KERNEL::Exception("DataArrayInt::BuildUnion : only single component allowed !");
6024     }
6025   //
6026   std::set<int> r;
6027   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
6028     {
6029       const int *pt=(*it)->getConstPointer();
6030       int nbOfTuples=(*it)->getNumberOfTuples();
6031       r.insert(pt,pt+nbOfTuples);
6032     }
6033   DataArrayInt *ret=DataArrayInt::New();
6034   ret->alloc((int)r.size(),1);
6035   std::copy(r.begin(),r.end(),ret->getPointer());
6036   return ret;
6037 }
6038
6039 /*!
6040  * Returns a new DataArrayInt which contains elements present in each of given one-dimensional
6041  * arrays. The result array does not contain any duplicates and its values
6042  * are sorted in ascending order.
6043  *  \param [in] arr - sequence of DataArrayInt's to intersect.
6044  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6045  *         array using decrRef() as it is no more needed.
6046  *  \throw If any \a arr[i] is not allocated.
6047  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
6048  */
6049 DataArrayInt *DataArrayInt::BuildIntersection(const std::vector<const DataArrayInt *>& arr)
6050 {
6051   std::vector<const DataArrayInt *> a;
6052   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
6053     if(*it4)
6054       a.push_back(*it4);
6055   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
6056     {
6057       (*it)->checkAllocated();
6058       if((*it)->getNumberOfComponents()!=1)
6059         throw INTERP_KERNEL::Exception("DataArrayInt::BuildIntersection : only single component allowed !");
6060     }
6061   //
6062   std::set<int> r;
6063   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
6064     {
6065       const int *pt=(*it)->getConstPointer();
6066       int nbOfTuples=(*it)->getNumberOfTuples();
6067       std::set<int> s1(pt,pt+nbOfTuples);
6068       if(it!=a.begin())
6069         {
6070           std::set<int> r2;
6071           std::set_intersection(r.begin(),r.end(),s1.begin(),s1.end(),inserter(r2,r2.end()));
6072           r=r2;
6073         }
6074       else
6075         r=s1;
6076     }
6077   DataArrayInt *ret(DataArrayInt::New());
6078   ret->alloc((int)r.size(),1);
6079   std::copy(r.begin(),r.end(),ret->getPointer());
6080   return ret;
6081 }
6082
6083 /// @cond INTERNAL
6084 namespace MEDCouplingImpl
6085 {
6086   class OpSwitchedOn
6087   {
6088   public:
6089     OpSwitchedOn(int *pt):_pt(pt),_cnt(0) { }
6090     void operator()(const bool& b) { if(b) *_pt++=_cnt; _cnt++; }
6091   private:
6092     int *_pt;
6093     int _cnt;
6094   };
6095
6096   class OpSwitchedOff
6097   {
6098   public:
6099     OpSwitchedOff(int *pt):_pt(pt),_cnt(0) { }
6100     void operator()(const bool& b) { if(!b) *_pt++=_cnt; _cnt++; }
6101   private:
6102     int *_pt;
6103     int _cnt;
6104   };
6105 }
6106 /// @endcond
6107
6108 /*!
6109  * This method returns the list of ids in ascending mode so that v[id]==true.
6110  */
6111 DataArrayInt *DataArrayInt::BuildListOfSwitchedOn(const std::vector<bool>& v)
6112 {
6113   int sz((int)std::count(v.begin(),v.end(),true));
6114   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
6115   std::for_each(v.begin(),v.end(),MEDCouplingImpl::OpSwitchedOn(ret->getPointer()));
6116   return ret.retn();
6117 }
6118
6119 /*!
6120  * This method returns the list of ids in ascending mode so that v[id]==false.
6121  */
6122 DataArrayInt *DataArrayInt::BuildListOfSwitchedOff(const std::vector<bool>& v)
6123 {
6124   int sz((int)std::count(v.begin(),v.end(),false));
6125   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
6126   std::for_each(v.begin(),v.end(),MEDCouplingImpl::OpSwitchedOff(ret->getPointer()));
6127   return ret.retn();
6128 }
6129
6130 /*!
6131  * This method allows to put a vector of vector of integer into a more compact data stucture (skyline). 
6132  * This method is not available into python because no available optimized data structure available to map std::vector< std::vector<int> >.
6133  *
6134  * \param [in] v the input data structure to be translate into skyline format.
6135  * \param [out] data the first element of the skyline format. The user is expected to deal with newly allocated array.
6136  * \param [out] dataIndex the second element of the skyline format.
6137  */
6138 void DataArrayInt::PutIntoToSkylineFrmt(const std::vector< std::vector<int> >& v, DataArrayInt *& data, DataArrayInt *& dataIndex)
6139 {
6140   int sz((int)v.size());
6141   MCAuto<DataArrayInt> ret0(DataArrayInt::New()),ret1(DataArrayInt::New());
6142   ret1->alloc(sz+1,1);
6143   int *pt(ret1->getPointer()); *pt=0;
6144   for(int i=0;i<sz;i++,pt++)
6145     pt[1]=pt[0]+(int)v[i].size();
6146   ret0->alloc(ret1->back(),1);
6147   pt=ret0->getPointer();
6148   for(int i=0;i<sz;i++)
6149     pt=std::copy(v[i].begin(),v[i].end(),pt);
6150   data=ret0.retn(); dataIndex=ret1.retn();
6151 }
6152
6153 /*!
6154  * Returns a new DataArrayInt which contains a complement of elements of \a this
6155  * one-dimensional array. I.e. the result array contains all elements from the range [0,
6156  * \a nbOfElement) not present in \a this array.
6157  *  \param [in] nbOfElement - maximal size of the result array.
6158  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6159  *         array using decrRef() as it is no more needed.
6160  *  \throw If \a this is not allocated.
6161  *  \throw If \a this->getNumberOfComponents() != 1.
6162  *  \throw If any element \a x of \a this array violates condition ( 0 <= \a x < \a
6163  *         nbOfElement ).
6164  */
6165 DataArrayInt *DataArrayInt::buildComplement(int nbOfElement) const
6166 {
6167   checkAllocated();
6168   if(getNumberOfComponents()!=1)
6169     throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : only single component allowed !");
6170   std::vector<bool> tmp(nbOfElement);
6171   const int *pt=getConstPointer();
6172   int nbOfTuples=getNumberOfTuples();
6173   for(const int *w=pt;w!=pt+nbOfTuples;w++)
6174     if(*w>=0 && *w<nbOfElement)
6175       tmp[*w]=true;
6176     else
6177       throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : an element is not in valid range : [0,nbOfElement) !");
6178   int nbOfRetVal=(int)std::count(tmp.begin(),tmp.end(),false);
6179   DataArrayInt *ret=DataArrayInt::New();
6180   ret->alloc(nbOfRetVal,1);
6181   int j=0;
6182   int *retPtr=ret->getPointer();
6183   for(int i=0;i<nbOfElement;i++)
6184     if(!tmp[i])
6185       retPtr[j++]=i;
6186   return ret;
6187 }
6188
6189 /*!
6190  * Returns a new DataArrayInt containing elements of \a this one-dimensional missing
6191  * from an \a other one-dimensional array.
6192  *  \param [in] other - a DataArrayInt containing elements not to include in the result array.
6193  *  \return DataArrayInt * - a new instance of DataArrayInt with one component. The
6194  *         caller is to delete this array using decrRef() as it is no more needed.
6195  *  \throw If \a other is NULL.
6196  *  \throw If \a other is not allocated.
6197  *  \throw If \a other->getNumberOfComponents() != 1.
6198  *  \throw If \a this is not allocated.
6199  *  \throw If \a this->getNumberOfComponents() != 1.
6200  *  \sa DataArrayInt::buildSubstractionOptimized()
6201  */
6202 DataArrayInt *DataArrayInt::buildSubstraction(const DataArrayInt *other) const
6203 {
6204   if(!other)
6205     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : DataArrayInt pointer in input is NULL !");
6206   checkAllocated();
6207   other->checkAllocated();
6208   if(getNumberOfComponents()!=1)
6209     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed !");
6210   if(other->getNumberOfComponents()!=1)
6211     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed for other type !");
6212   const int *pt=getConstPointer();
6213   int nbOfTuples=getNumberOfTuples();
6214   std::set<int> s1(pt,pt+nbOfTuples);
6215   pt=other->getConstPointer();
6216   nbOfTuples=other->getNumberOfTuples();
6217   std::set<int> s2(pt,pt+nbOfTuples);
6218   std::vector<int> r;
6219   std::set_difference(s1.begin(),s1.end(),s2.begin(),s2.end(),std::back_insert_iterator< std::vector<int> >(r));
6220   DataArrayInt *ret=DataArrayInt::New();
6221   ret->alloc((int)r.size(),1);
6222   std::copy(r.begin(),r.end(),ret->getPointer());
6223   return ret;
6224 }
6225
6226 /*!
6227  * \a this is expected to have one component and to be sorted ascendingly (as for \a other).
6228  * \a other is expected to be a part of \a this. If not DataArrayInt::buildSubstraction should be called instead.
6229  * 
6230  * \param [in] other an array with one component and expected to be sorted ascendingly.
6231  * \ret list of ids in \a this but not in \a other.
6232  * \sa DataArrayInt::buildSubstraction
6233  */
6234 DataArrayInt *DataArrayInt::buildSubstractionOptimized(const DataArrayInt *other) const
6235 {
6236   static const char *MSG="DataArrayInt::buildSubstractionOptimized : only single component allowed !";
6237   if(!other) throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstractionOptimized : NULL input array !");
6238   checkAllocated(); other->checkAllocated();
6239   if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
6240   if(other->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
6241   const int *pt1Bg(begin()),*pt1End(end()),*pt2Bg(other->begin()),*pt2End(other->end());
6242   const int *work1(pt1Bg),*work2(pt2Bg);
6243   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6244   for(;work1!=pt1End;work1++)
6245     {
6246       if(work2!=pt2End && *work1==*work2)
6247         work2++;
6248       else
6249         ret->pushBackSilent(*work1);
6250     }
6251   return ret.retn();
6252 }
6253
6254
6255 /*!
6256  * Returns a new DataArrayInt which contains all elements of \a this and a given
6257  * one-dimensional arrays. The result array does not contain any duplicates
6258  * and its values are sorted in ascending order.
6259  *  \param [in] other - an array to unite with \a this one.
6260  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6261  *         array using decrRef() as it is no more needed.
6262  *  \throw If \a this or \a other is not allocated.
6263  *  \throw If \a this->getNumberOfComponents() != 1.
6264  *  \throw If \a other->getNumberOfComponents() != 1.
6265  */
6266 DataArrayInt *DataArrayInt::buildUnion(const DataArrayInt *other) const
6267 {
6268   std::vector<const DataArrayInt *>arrs(2);
6269   arrs[0]=this; arrs[1]=other;
6270   return BuildUnion(arrs);
6271 }
6272
6273
6274 /*!
6275  * Returns a new DataArrayInt which contains elements present in both \a this and a given
6276  * one-dimensional arrays. The result array does not contain any duplicates
6277  * and its values are sorted in ascending order.
6278  *  \param [in] other - an array to intersect with \a this one.
6279  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6280  *         array using decrRef() as it is no more needed.
6281  *  \throw If \a this or \a other is not allocated.
6282  *  \throw If \a this->getNumberOfComponents() != 1.
6283  *  \throw If \a other->getNumberOfComponents() != 1.
6284  */
6285 DataArrayInt *DataArrayInt::buildIntersection(const DataArrayInt *other) const
6286 {
6287   std::vector<const DataArrayInt *>arrs(2);
6288   arrs[0]=this; arrs[1]=other;
6289   return BuildIntersection(arrs);
6290 }
6291
6292 /*!
6293  * This method can be applied on allocated with one component DataArrayInt instance.
6294  * This method is typically relevant for sorted arrays. All consecutive duplicated items in \a this will appear only once in returned DataArrayInt instance.
6295  * 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]
6296  * 
6297  * \return a newly allocated array that contain the result of the unique operation applied on \a this.
6298  * \throw if \a this is not allocated or if \a this has not exactly one component.
6299  * \sa DataArrayInt::buildUniqueNotSorted
6300  */
6301 DataArrayInt *DataArrayInt::buildUnique() const
6302 {
6303   checkAllocated();
6304   if(getNumberOfComponents()!=1)
6305     throw INTERP_KERNEL::Exception("DataArrayInt::buildUnique : only single component allowed !");
6306   int nbOfTuples=getNumberOfTuples();
6307   MCAuto<DataArrayInt> tmp=deepCopy();
6308   int *data=tmp->getPointer();
6309   int *last=std::unique(data,data+nbOfTuples);
6310   MCAuto<DataArrayInt> ret=DataArrayInt::New();
6311   ret->alloc(std::distance(data,last),1);
6312   std::copy(data,last,ret->getPointer());
6313   return ret.retn();
6314 }
6315
6316 /*!
6317  * This method can be applied on allocated with one component DataArrayInt instance.
6318  * This method keep elements only once by keeping the same order in \a this that is not expected to be sorted.
6319  *
6320  * \return a newly allocated array that contain the result of the unique operation applied on \a this.
6321  *
6322  * \throw if \a this is not allocated or if \a this has not exactly one component.
6323  *
6324  * \sa DataArrayInt::buildUnique
6325  */
6326 DataArrayInt *DataArrayInt::buildUniqueNotSorted() const
6327 {
6328   checkAllocated();
6329     if(getNumberOfComponents()!=1)
6330       throw INTERP_KERNEL::Exception("DataArrayInt::buildUniqueNotSorted : only single component allowed !");
6331   int minVal,maxVal;
6332   getMinMaxValues(minVal,maxVal);
6333   std::vector<bool> b(maxVal-minVal+1,false);
6334   const int *ptBg(begin()),*endBg(end());
6335   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6336   for(const int *pt=ptBg;pt!=endBg;pt++)
6337     {
6338       if(!b[*pt-minVal])
6339         {
6340           ret->pushBackSilent(*pt);
6341           b[*pt-minVal]=true;
6342         }
6343     }
6344   ret->copyStringInfoFrom(*this);
6345   return ret.retn();
6346 }
6347
6348 /*!
6349  * Returns a new DataArrayInt which contains size of every of groups described by \a this
6350  * "index" array. Such "index" array is returned for example by 
6351  * \ref MEDCoupling::MEDCouplingUMesh::buildDescendingConnectivity
6352  * "MEDCouplingUMesh::buildDescendingConnectivity" and
6353  * \ref MEDCoupling::MEDCouplingUMesh::getNodalConnectivityIndex
6354  * "MEDCouplingUMesh::getNodalConnectivityIndex" etc.
6355  * This method preforms the reverse operation of DataArrayInt::computeOffsetsFull.
6356  *  \return DataArrayInt * - a new instance of DataArrayInt, whose number of tuples
6357  *          equals to \a this->getNumberOfComponents() - 1, and number of components is 1.
6358  *          The caller is to delete this array using decrRef() as it is no more needed. 
6359  *  \throw If \a this is not allocated.
6360  *  \throw If \a this->getNumberOfComponents() != 1.
6361  *  \throw If \a this->getNumberOfTuples() < 2.
6362  *
6363  *  \b Example: <br> 
6364  *         - this contains [1,3,6,7,7,9,15]
6365  *         - result array contains [2,3,1,0,2,6],
6366  *          where 2 = 3 - 1, 3 = 6 - 3, 1 = 7 - 6 etc.
6367  *
6368  * \sa DataArrayInt::computeOffsetsFull
6369  */
6370 DataArrayInt *DataArrayInt::deltaShiftIndex() const
6371 {
6372   checkAllocated();
6373   if(getNumberOfComponents()!=1)
6374     throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : only single component allowed !");
6375   int nbOfTuples=getNumberOfTuples();
6376   if(nbOfTuples<2)
6377     throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : 1 tuple at least must be present in 'this' !");
6378   const int *ptr=getConstPointer();
6379   DataArrayInt *ret=DataArrayInt::New();
6380   ret->alloc(nbOfTuples-1,1);
6381   int *out=ret->getPointer();
6382   std::transform(ptr+1,ptr+nbOfTuples,ptr,out,std::minus<int>());
6383   return ret;
6384 }
6385
6386 /*!
6387  * Modifies \a this one-dimensional array so that value of each element \a x
6388  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
6389  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number of tuples
6390  * and components remains the same.<br>
6391  * This method is useful for allToAllV in MPI with contiguous policy. This method
6392  * differs from computeOffsetsFull() in that the number of tuples is \b not changed by
6393  * this one.
6394  *  \throw If \a this is not allocated.
6395  *  \throw If \a this->getNumberOfComponents() != 1.
6396  *
6397  *  \b Example: <br>
6398  *          - Before \a this contains [3,5,1,2,0,8]
6399  *          - After \a this contains  [0,3,8,9,11,11]<br>
6400  *          Note that the last element 19 = 11 + 8 is missing because size of \a this
6401  *          array is retained and thus there is no space to store the last element.
6402  */
6403 void DataArrayInt::computeOffsets()
6404 {
6405   checkAllocated();
6406   if(getNumberOfComponents()!=1)
6407     throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets : only single component allowed !");
6408   int nbOfTuples=getNumberOfTuples();
6409   if(nbOfTuples==0)
6410     return ;
6411   int *work=getPointer();
6412   int tmp=work[0];
6413   work[0]=0;
6414   for(int i=1;i<nbOfTuples;i++)
6415     {
6416       int tmp2=work[i];
6417       work[i]=work[i-1]+tmp;
6418       tmp=tmp2;
6419     }
6420   declareAsNew();
6421 }
6422
6423
6424 /*!
6425  * Modifies \a this one-dimensional array so that value of each element \a x
6426  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
6427  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number
6428  * components remains the same and number of tuples is inceamented by one.<br>
6429  * This method is useful for allToAllV in MPI with contiguous policy. This method
6430  * differs from computeOffsets() in that the number of tuples is changed by this one.
6431  * This method preforms the reverse operation of DataArrayInt::deltaShiftIndex.
6432  *  \throw If \a this is not allocated.
6433  *  \throw If \a this->getNumberOfComponents() != 1.
6434  *
6435  *  \b Example: <br>
6436  *          - Before \a this contains [3,5,1,2,0,8]
6437  *          - After \a this contains  [0,3,8,9,11,11,19]<br>
6438  * \sa DataArrayInt::deltaShiftIndex
6439  */
6440 void DataArrayInt::computeOffsetsFull()
6441 {
6442   checkAllocated();
6443   if(getNumberOfComponents()!=1)
6444     throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsetsFull : only single component allowed !");
6445   int nbOfTuples=getNumberOfTuples();
6446   int *ret=(int *)malloc((nbOfTuples+1)*sizeof(int));
6447   const int *work=getConstPointer();
6448   ret[0]=0;
6449   for(int i=0;i<nbOfTuples;i++)
6450     ret[i+1]=work[i]+ret[i];
6451   useArray(ret,true,C_DEALLOC,nbOfTuples+1,1);
6452   declareAsNew();
6453 }
6454
6455 /*!
6456  * Returns two new DataArrayInt instances whose contents is computed from that of \a this and \a listOfIds arrays as follows.
6457  * \a this is expected to be an offset format ( as returned by DataArrayInt::computeOffsetsFull ) that is to say with one component
6458  * and ** sorted strictly increasingly **. \a listOfIds is expected to be sorted ascendingly (not strictly needed for \a listOfIds).
6459  * This methods searches in \a this, considered as a set of contiguous \c this->getNumberOfComponents() ranges, all ids in \a listOfIds
6460  * filling completely one of the ranges in \a this.
6461  *
6462  * \param [in] listOfIds a list of ids that has to be sorted ascendingly.
6463  * \param [out] rangeIdsFetched the range ids fetched
6464  * \param [out] idsInInputListThatFetch contains the list of ids in \a listOfIds that are \b fully included in a range in \a this. So
6465  *              \a idsInInputListThatFetch is a part of input \a listOfIds.
6466  *
6467  * \sa DataArrayInt::computeOffsetsFull
6468  *
6469  *  \b Example: <br>
6470  *          - \a this : [0,3,7,9,15,18]
6471  *          - \a listOfIds contains  [0,1,2,3,7,8,15,16,17]
6472  *          - \a rangeIdsFetched result array: [0,2,4]
6473  *          - \a idsInInputListThatFetch result array: [0,1,2,7,8,15,16,17]
6474  * In this example id 3 in input \a listOfIds is alone so it do not appear in output \a idsInInputListThatFetch.
6475  * <br>
6476  */
6477 void DataArrayInt::findIdsRangesInListOfIds(const DataArrayInt *listOfIds, DataArrayInt *& rangeIdsFetched, DataArrayInt *& idsInInputListThatFetch) const
6478 {
6479   if(!listOfIds)
6480     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : input list of ids is null !");
6481   listOfIds->checkAllocated(); checkAllocated();
6482   if(listOfIds->getNumberOfComponents()!=1)
6483     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : input list of ids must have exactly one component !");
6484   if(getNumberOfComponents()!=1)
6485     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : this must have exactly one component !");
6486   MCAuto<DataArrayInt> ret0=DataArrayInt::New(); ret0->alloc(0,1);
6487   MCAuto<DataArrayInt> ret1=DataArrayInt::New(); ret1->alloc(0,1);
6488   const int *tupEnd(listOfIds->end()),*offBg(begin()),*offEnd(end()-1);
6489   const int *tupPtr(listOfIds->begin()),*offPtr(offBg);
6490   while(tupPtr!=tupEnd && offPtr!=offEnd)
6491     {
6492       if(*tupPtr==*offPtr)
6493         {
6494           int i=offPtr[0];
6495           while(i<offPtr[1] && *tupPtr==i && tupPtr!=tupEnd) { i++; tupPtr++; }
6496           if(i==offPtr[1])
6497             {
6498               ret0->pushBackSilent((int)std::distance(offBg,offPtr));
6499               ret1->pushBackValsSilent(tupPtr-(offPtr[1]-offPtr[0]),tupPtr);
6500               offPtr++;
6501             }
6502         }
6503       else
6504         { if(*tupPtr<*offPtr) tupPtr++; else offPtr++; }
6505     }
6506   rangeIdsFetched=ret0.retn();
6507   idsInInputListThatFetch=ret1.retn();
6508 }
6509
6510 /*!
6511  * Returns a new DataArrayInt whose contents is computed from that of \a this and \a
6512  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
6513  * "index" array of a "iota" array, thus, whose each element gives an index of a group
6514  * beginning within the "iota" array. And \a this is a one-dimensional array
6515  * considered as a selector of groups described by \a offsets to include into the result array.
6516  *  \throw If \a offsets is NULL.
6517  *  \throw If \a offsets is not allocated.
6518  *  \throw If \a offsets->getNumberOfComponents() != 1.
6519  *  \throw If \a offsets is not monotonically increasing.
6520  *  \throw If \a this is not allocated.
6521  *  \throw If \a this->getNumberOfComponents() != 1.
6522  *  \throw If any element of \a this is not a valid index for \a offsets array.
6523  *
6524  *  \b Example: <br>
6525  *          - \a this: [0,2,3]
6526  *          - \a offsets: [0,3,6,10,14,20]
6527  *          - result array: [0,1,2,6,7,8,9,10,11,12,13] == <br>
6528  *            \c range(0,3) + \c range(6,10) + \c range(10,14) ==<br>
6529  *            \c range( \a offsets[ \a this[0] ], offsets[ \a this[0]+1 ]) + 
6530  *            \c range( \a offsets[ \a this[1] ], offsets[ \a this[1]+1 ]) + 
6531  *            \c range( \a offsets[ \a this[2] ], offsets[ \a this[2]+1 ])
6532  */
6533 DataArrayInt *DataArrayInt::buildExplicitArrByRanges(const DataArrayInt *offsets) const
6534 {
6535   if(!offsets)
6536     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : DataArrayInt pointer in input is NULL !");
6537   checkAllocated();
6538   if(getNumberOfComponents()!=1)
6539     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : only single component allowed !");
6540   offsets->checkAllocated();
6541   if(offsets->getNumberOfComponents()!=1)
6542     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : input array should have only single component !");
6543   int othNbTuples=offsets->getNumberOfTuples()-1;
6544   int nbOfTuples=getNumberOfTuples();
6545   int retNbOftuples=0;
6546   const int *work=getConstPointer();
6547   const int *offPtr=offsets->getConstPointer();
6548   for(int i=0;i<nbOfTuples;i++)
6549     {
6550       int val=work[i];
6551       if(val>=0 && val<othNbTuples)
6552         {
6553           int delta=offPtr[val+1]-offPtr[val];
6554           if(delta>=0)
6555             retNbOftuples+=delta;
6556           else
6557             {
6558               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << val << " of offset array has a delta < 0 !";
6559               throw INTERP_KERNEL::Exception(oss.str().c_str());
6560             }
6561         }
6562       else
6563         {
6564           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << i << " in this contains " << val;
6565           oss << " whereas offsets array is of size " << othNbTuples+1 << " !";
6566           throw INTERP_KERNEL::Exception(oss.str().c_str());
6567         }
6568     }
6569   MCAuto<DataArrayInt> ret=DataArrayInt::New();
6570   ret->alloc(retNbOftuples,1);
6571   int *retPtr=ret->getPointer();
6572   for(int i=0;i<nbOfTuples;i++)
6573     {
6574       int val=work[i];
6575       int start=offPtr[val];
6576       int off=offPtr[val+1]-start;
6577       for(int j=0;j<off;j++,retPtr++)
6578         *retPtr=start+j;
6579     }
6580   return ret.retn();
6581 }
6582
6583 /*!
6584  * Returns a new DataArrayInt whose contents is computed using \a this that must be a 
6585  * scaled array (monotonically increasing).
6586 from that of \a this and \a
6587  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
6588  * "index" array of a "iota" array, thus, whose each element gives an index of a group
6589  * beginning within the "iota" array. And \a this is a one-dimensional array
6590  * considered as a selector of groups described by \a offsets to include into the result array.
6591  *  \throw If \a  is NULL.
6592  *  \throw If \a this is not allocated.
6593  *  \throw If \a this->getNumberOfComponents() != 1.
6594  *  \throw If \a this->getNumberOfTuples() == 0.
6595  *  \throw If \a this is not monotonically increasing.
6596  *  \throw If any element of ids in ( \a bg \a stop \a step ) points outside the scale in \a this.
6597  *
6598  *  \b Example: <br>
6599  *          - \a bg , \a stop and \a step : (0,5,2)
6600  *          - \a this: [0,3,6,10,14,20]
6601  *          - result array: [0,0,0, 2,2,2,2, 4,4,4,4,4,4] == <br>
6602  */
6603 DataArrayInt *DataArrayInt::buildExplicitArrOfSliceOnScaledArr(int bg, int stop, int step) const
6604 {
6605   if(!isAllocated())
6606     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : not allocated array !");
6607   if(getNumberOfComponents()!=1)
6608     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of components is expected to be equal to one !");
6609   int nbOfTuples(getNumberOfTuples());
6610   if(nbOfTuples==0)
6611     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of tuples must be != 0 !");
6612   const int *ids(begin());
6613   int nbOfEltsInSlc(GetNumberOfItemGivenBESRelative(bg,stop,step,"DataArrayInt::buildExplicitArrOfSliceOnScaledArr")),sz(0),pos(bg);
6614   for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
6615     {
6616       if(pos>=0 && pos<nbOfTuples-1)
6617         {
6618           int delta(ids[pos+1]-ids[pos]);
6619           sz+=delta;
6620           if(delta<0)
6621             {
6622               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " and at this pos this is not monotonically increasing !";
6623               throw INTERP_KERNEL::Exception(oss.str().c_str());
6624             }          
6625         }
6626       else
6627         {
6628           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " should be in [0," << nbOfTuples-1 << ") !";  
6629           throw INTERP_KERNEL::Exception(oss.str().c_str());
6630         }
6631     }
6632   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
6633   int *retPtr(ret->getPointer());
6634   pos=bg;
6635   for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
6636     {
6637       int delta(ids[pos+1]-ids[pos]);
6638       for(int j=0;j<delta;j++,retPtr++)
6639         *retPtr=pos;
6640     }
6641   return ret.retn();
6642 }
6643
6644 /*!
6645  * 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.
6646  * 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
6647  * in tuple **i** of returned DataArrayInt.
6648  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the first range.
6649  *
6650  * 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)]
6651  * The return DataArrayInt will contain : **[0,4,1,2,2,3]**
6652  * 
6653  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
6654  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
6655  * \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
6656  *        is thrown if no ranges in \a ranges contains value in \a this.
6657  * 
6658  * \sa DataArrayInt::findIdInRangeForEachTuple
6659  */
6660 DataArrayInt *DataArrayInt::findRangeIdForEachTuple(const DataArrayInt *ranges) const
6661 {
6662   if(!ranges)
6663     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : null input pointer !");
6664   if(ranges->getNumberOfComponents()!=2)
6665     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : input DataArrayInt instance should have 2 components !");
6666   checkAllocated();
6667   if(getNumberOfComponents()!=1)
6668     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : this should have only one component !");
6669   int nbTuples=getNumberOfTuples();
6670   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
6671   int nbOfRanges=ranges->getNumberOfTuples();
6672   const int *rangesPtr=ranges->getConstPointer();
6673   int *retPtr=ret->getPointer();
6674   const int *inPtr=getConstPointer();
6675   for(int i=0;i<nbTuples;i++,retPtr++)
6676     {
6677       int val=inPtr[i];
6678       bool found=false;
6679       for(int j=0;j<nbOfRanges && !found;j++)
6680         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
6681           { *retPtr=j; found=true; }
6682       if(found)
6683         continue;
6684       else
6685         {
6686           std::ostringstream oss; oss << "DataArrayInt::findRangeIdForEachTuple : tuple #" << i << " not found by any ranges !";
6687           throw INTERP_KERNEL::Exception(oss.str().c_str());
6688         }
6689     }
6690   return ret.retn();
6691 }
6692
6693 /*!
6694  * 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.
6695  * 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
6696  * in tuple **i** of returned DataArrayInt.
6697  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the sub position of the first range.
6698  *
6699  * 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)]
6700  * The return DataArrayInt will contain : **[1,2,4,0,2,2]**
6701  * This method is often called in pair with DataArrayInt::findRangeIdForEachTuple method.
6702  * 
6703  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
6704  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
6705  * \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
6706  *        is thrown if no ranges in \a ranges contains value in \a this.
6707  * \sa DataArrayInt::findRangeIdForEachTuple
6708  */
6709 DataArrayInt *DataArrayInt::findIdInRangeForEachTuple(const DataArrayInt *ranges) const
6710 {
6711   if(!ranges)
6712     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : null input pointer !");
6713   if(ranges->getNumberOfComponents()!=2)
6714     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : input DataArrayInt instance should have 2 components !");
6715   checkAllocated();
6716   if(getNumberOfComponents()!=1)
6717     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : this should have only one component !");
6718   int nbTuples=getNumberOfTuples();
6719   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
6720   int nbOfRanges=ranges->getNumberOfTuples();
6721   const int *rangesPtr=ranges->getConstPointer();
6722   int *retPtr=ret->getPointer();
6723   const int *inPtr=getConstPointer();
6724   for(int i=0;i<nbTuples;i++,retPtr++)
6725     {
6726       int val=inPtr[i];
6727       bool found=false;
6728       for(int j=0;j<nbOfRanges && !found;j++)
6729         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
6730           { *retPtr=val-rangesPtr[2*j]; found=true; }
6731       if(found)
6732         continue;
6733       else
6734         {
6735           std::ostringstream oss; oss << "DataArrayInt::findIdInRangeForEachTuple : tuple #" << i << " not found by any ranges !";
6736           throw INTERP_KERNEL::Exception(oss.str().c_str());
6737         }
6738     }
6739   return ret.retn();
6740 }
6741
6742 /*!
6743  * \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).
6744  * 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).
6745  * 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 !
6746  * If this method has correctly worked, \a this will be able to be considered as a linked list.
6747  * This method does nothing if number of tuples is lower of equal to 1.
6748  *
6749  * This method is useful for users having an unstructured mesh having only SEG2 to rearrange internaly the connectibity without any coordinates consideration.
6750  *
6751  * \sa MEDCouplingUMesh::orderConsecutiveCells1D, DataArrayInt::fromLinkedListOfPairToList
6752  */
6753 void DataArrayInt::sortEachPairToMakeALinkedList()
6754 {
6755   checkAllocated();
6756   if(getNumberOfComponents()!=2)
6757     throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : Only works on DataArrayInt instance with nb of components equal to 2 !");
6758   int nbOfTuples(getNumberOfTuples());
6759   if(nbOfTuples<=1)
6760     return ;
6761   int *conn(getPointer());
6762   for(int i=1;i<nbOfTuples;i++,conn+=2)
6763     {
6764       if(i>1)
6765         {
6766           if(conn[2]==conn[3])
6767             {
6768               std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " presence of a pair filled with same ids !";
6769               throw INTERP_KERNEL::Exception(oss.str().c_str());
6770             }
6771           if(conn[2]!=conn[1] && conn[3]==conn[1] && conn[2]!=conn[0])
6772             std::swap(conn[2],conn[3]);
6773           //not(conn[2]==conn[1] && conn[3]!=conn[1] && conn[3]!=conn[0])
6774           if(conn[2]!=conn[1] || conn[3]==conn[1] || conn[3]==conn[0])
6775             {
6776               std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " something is invalid !";
6777               throw INTERP_KERNEL::Exception(oss.str().c_str());
6778             }
6779         }
6780       else
6781         {
6782           if(conn[0]==conn[1] || conn[2]==conn[3])
6783             throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : In the 2 first tuples presence of a pair filled with same ids !");
6784           int tmp[4];
6785           std::set<int> s;
6786           s.insert(conn,conn+4);
6787           if(s.size()!=3)
6788             throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : This can't be considered as a linked list regarding 2 first tuples !");
6789           if(std::count(conn,conn+4,conn[0])==2)
6790             {
6791               tmp[0]=conn[1];
6792               tmp[1]=conn[0];
6793               tmp[2]=conn[0];
6794               if(conn[2]==conn[0])
6795                 { tmp[3]=conn[3]; }
6796               else
6797                 { tmp[3]=conn[2];}
6798               std::copy(tmp,tmp+4,conn);
6799             }
6800           else
6801             {//here we are sure to have (std::count(conn,conn+4,conn[1])==2)
6802               if(conn[1]==conn[3])
6803                 std::swap(conn[2],conn[3]);
6804             }
6805         }
6806     }
6807 }
6808
6809 /*!
6810  * \a this is expected to be a correctly linked list of pairs.
6811  * 
6812  * \sa DataArrayInt::sortEachPairToMakeALinkedList
6813  */
6814 MCAuto<DataArrayInt> DataArrayInt::fromLinkedListOfPairToList() const
6815 {
6816   checkAllocated();
6817   checkNbOfComps(2,"DataArrayInt::fromLinkedListOfPairToList : this is expected to have 2 components");
6818   int nbTuples(getNumberOfTuples());
6819   if(nbTuples<1)
6820     throw INTERP_KERNEL::Exception("DataArrayInt::fromLinkedListOfPairToList : no tuples in this ! Not a linked list !");
6821   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbTuples+1,1);
6822   const int *thisPtr(begin());
6823   int *retPtr(ret->getPointer());
6824   retPtr[0]=thisPtr[0];
6825   for(int i=0;i<nbTuples;i++)
6826     {
6827       retPtr[i+1]=thisPtr[2*i+1];
6828       if(i<nbTuples-1)
6829         if(thisPtr[2*i+1]!=thisPtr[2*(i+1)+0])
6830           {
6831             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 ?";
6832             throw INTERP_KERNEL::Exception(oss.str());
6833           }
6834     }
6835   return ret;
6836 }
6837
6838 /*!
6839  * This method returns all different values found in \a this. This method throws if \a this has not been allocated.
6840  * But the number of components can be different from one.
6841  * \return a newly allocated array (that should be dealt by the caller) containing different values in \a this.
6842  */
6843 DataArrayInt *DataArrayInt::getDifferentValues() const
6844 {
6845   checkAllocated();
6846   std::set<int> ret;
6847   ret.insert(begin(),end());
6848   MCAuto<DataArrayInt> ret2=DataArrayInt::New(); ret2->alloc((int)ret.size(),1);
6849   std::copy(ret.begin(),ret.end(),ret2->getPointer());
6850   return ret2.retn();
6851 }
6852
6853 /*!
6854  * This method is a refinement of DataArrayInt::getDifferentValues because it returns not only different values in \a this but also, for each of
6855  * them it tells which tuple id have this id.
6856  * This method works only on arrays with one component (if it is not the case call DataArrayInt::rearrange(1) ).
6857  * This method returns two arrays having same size.
6858  * 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.
6859  * 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]]
6860  */
6861 std::vector<DataArrayInt *> DataArrayInt::partitionByDifferentValues(std::vector<int>& differentIds) const
6862 {
6863   checkAllocated();
6864   if(getNumberOfComponents()!=1)
6865     throw INTERP_KERNEL::Exception("DataArrayInt::partitionByDifferentValues : this should have only one component !");
6866   int id=0;
6867   std::map<int,int> m,m2,m3;
6868   for(const int *w=begin();w!=end();w++)
6869     m[*w]++;
6870   differentIds.resize(m.size());
6871   std::vector<DataArrayInt *> ret(m.size());
6872   std::vector<int *> retPtr(m.size());
6873   for(std::map<int,int>::const_iterator it=m.begin();it!=m.end();it++,id++)
6874     {
6875       m2[(*it).first]=id;
6876       ret[id]=DataArrayInt::New();
6877       ret[id]->alloc((*it).second,1);
6878       retPtr[id]=ret[id]->getPointer();
6879       differentIds[id]=(*it).first;
6880     }
6881   id=0;
6882   for(const int *w=begin();w!=end();w++,id++)
6883     {
6884       retPtr[m2[*w]][m3[*w]++]=id;
6885     }
6886   return ret;
6887 }
6888
6889 /*!
6890  * This method split ids in [0, \c this->getNumberOfTuples() ) using \a this array as a field of weight (>=0 each).
6891  * The aim of this method is to return a set of \a nbOfSlices chunk of contiguous ids as balanced as possible.
6892  *
6893  * \param [in] nbOfSlices - number of slices expected.
6894  * \return - a vector having a size equal to \a nbOfSlices giving the start (included) and the stop (excluded) of each chunks.
6895  * 
6896  * \sa DataArray::GetSlice
6897  * \throw If \a this is not allocated or not with exactly one component.
6898  * \throw If an element in \a this if < 0.
6899  */
6900 std::vector< std::pair<int,int> > DataArrayInt::splitInBalancedSlices(int nbOfSlices) const
6901 {
6902   if(!isAllocated() || getNumberOfComponents()!=1)
6903     throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : this array should have number of components equal to one and must be allocated !");
6904   if(nbOfSlices<=0)
6905     throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : number of slices must be >= 1 !");
6906   int sum(accumulate(0)),nbOfTuples(getNumberOfTuples());
6907   int sumPerSlc(sum/nbOfSlices),pos(0);
6908   const int *w(begin());
6909   std::vector< std::pair<int,int> > ret(nbOfSlices);
6910   for(int i=0;i<nbOfSlices;i++)
6911     {
6912       std::pair<int,int> p(pos,-1);
6913       int locSum(0);
6914       while(locSum<sumPerSlc && pos<nbOfTuples) { pos++; locSum+=*w++; }
6915       if(i!=nbOfSlices-1)
6916         p.second=pos;
6917       else
6918         p.second=nbOfTuples;
6919       ret[i]=p;
6920     }
6921   return ret;
6922 }
6923
6924 /*!
6925  * Returns a new DataArrayInt that is a modulus of two given arrays. There are 3
6926  * valid cases.
6927  * 1.  The arrays have same number of tuples and components. Then each value of
6928  *   the result array (_a_) is a division of the corresponding values of \a a1 and
6929  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, j ].
6930  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
6931  *   component. Then
6932  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, 0 ].
6933  * 3.  The arrays have same number of components and one array, say _a2_, has one
6934  *   tuple. Then
6935  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ 0, j ].
6936  *
6937  * Info on components is copied either from the first array (in the first case) or from
6938  * the array with maximal number of elements (getNbOfElems()).
6939  *  \warning No check of division by zero is performed!
6940  *  \param [in] a1 - a dividend array.
6941  *  \param [in] a2 - a divisor array.
6942  *  \return DataArrayInt * - the new instance of DataArrayInt.
6943  *          The caller is to delete this result array using decrRef() as it is no more
6944  *          needed.
6945  *  \throw If either \a a1 or \a a2 is NULL.
6946  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
6947  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
6948  *         none of them has number of tuples or components equal to 1.
6949  */
6950 DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt *a2)
6951 {
6952   if(!a1 || !a2)
6953     throw INTERP_KERNEL::Exception("DataArrayInt::Modulus : input DataArrayInt instance is NULL !");
6954   int nbOfTuple1=a1->getNumberOfTuples();
6955   int nbOfTuple2=a2->getNumberOfTuples();
6956   int nbOfComp1=a1->getNumberOfComponents();
6957   int nbOfComp2=a2->getNumberOfComponents();
6958   if(nbOfTuple2==nbOfTuple1)
6959     {
6960       if(nbOfComp1==nbOfComp2)
6961         {
6962           MCAuto<DataArrayInt> ret=DataArrayInt::New();
6963           ret->alloc(nbOfTuple2,nbOfComp1);
6964           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::modulus<int>());
6965           ret->copyStringInfoFrom(*a1);
6966           return ret.retn();
6967         }
6968       else if(nbOfComp2==1)
6969         {
6970           MCAuto<DataArrayInt> ret=DataArrayInt::New();
6971           ret->alloc(nbOfTuple1,nbOfComp1);
6972           const int *a2Ptr=a2->getConstPointer();
6973           const int *a1Ptr=a1->getConstPointer();
6974           int *res=ret->getPointer();
6975           for(int i=0;i<nbOfTuple1;i++)
6976             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::modulus<int>(),a2Ptr[i]));
6977           ret->copyStringInfoFrom(*a1);
6978           return ret.retn();
6979         }
6980       else
6981         {
6982           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
6983           return 0;
6984         }
6985     }
6986   else if(nbOfTuple2==1)
6987     {
6988       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
6989       MCAuto<DataArrayInt> ret=DataArrayInt::New();
6990       ret->alloc(nbOfTuple1,nbOfComp1);
6991       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
6992       int *pt=ret->getPointer();
6993       for(int i=0;i<nbOfTuple1;i++)
6994         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::modulus<int>());
6995       ret->copyStringInfoFrom(*a1);
6996       return ret.retn();
6997     }
6998   else
6999     {
7000       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Modulus !");//will always throw an exception
7001       return 0;
7002     }
7003 }
7004
7005 /*!
7006  * Modify \a this array so that each value becomes a modulus of division of this value by
7007  * a value of another DataArrayInt. There are 3 valid cases.
7008  * 1.  The arrays have same number of tuples and components. Then each value of
7009  *    \a this array is divided by the corresponding value of \a other one, i.e.:
7010  *   _a_ [ i, j ] %= _other_ [ i, j ].
7011  * 2.  The arrays have same number of tuples and \a other array has one component. Then
7012  *   _a_ [ i, j ] %= _other_ [ i, 0 ].
7013  * 3.  The arrays have same number of components and \a other array has one tuple. Then
7014  *   _a_ [ i, j ] %= _a2_ [ 0, j ].
7015  *
7016  *  \warning No check of division by zero is performed!
7017  *  \param [in] other - a divisor array.
7018  *  \throw If \a other is NULL.
7019  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
7020  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
7021  *         \a other has number of both tuples and components not equal to 1.
7022  */
7023 void DataArrayInt::modulusEqual(const DataArrayInt *other)
7024 {
7025   if(!other)
7026     throw INTERP_KERNEL::Exception("DataArrayInt::modulusEqual : input DataArrayInt instance is NULL !");
7027   const char *msg="Nb of tuples mismatch for DataArrayInt::modulusEqual !";
7028   checkAllocated(); other->checkAllocated();
7029   int nbOfTuple=getNumberOfTuples();
7030   int nbOfTuple2=other->getNumberOfTuples();
7031   int nbOfComp=getNumberOfComponents();
7032   int nbOfComp2=other->getNumberOfComponents();
7033   if(nbOfTuple==nbOfTuple2)
7034     {
7035       if(nbOfComp==nbOfComp2)
7036         {
7037           std::transform(begin(),end(),other->begin(),getPointer(),std::modulus<int>());
7038         }
7039       else if(nbOfComp2==1)
7040         {
7041           if(nbOfComp2==nbOfComp)
7042             {
7043               int *ptr=getPointer();
7044               const int *ptrc=other->getConstPointer();
7045               for(int i=0;i<nbOfTuple;i++)
7046                 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::modulus<int>(),*ptrc++));
7047             }
7048           else
7049             throw INTERP_KERNEL::Exception(msg);
7050         }
7051       else
7052         throw INTERP_KERNEL::Exception(msg);
7053     }
7054   else if(nbOfTuple2==1)
7055     {
7056       int *ptr=getPointer();
7057       const int *ptrc=other->getConstPointer();
7058       for(int i=0;i<nbOfTuple;i++)
7059         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::modulus<int>());
7060     }
7061   else
7062     throw INTERP_KERNEL::Exception(msg);
7063   declareAsNew();
7064 }
7065
7066 /*!
7067  * Returns a new DataArrayInt that is the result of pow of two given arrays. There are 3
7068  * valid cases.
7069  *
7070  *  \param [in] a1 - an array to pow up.
7071  *  \param [in] a2 - another array to sum up.
7072  *  \return DataArrayInt * - the new instance of DataArrayInt.
7073  *          The caller is to delete this result array using decrRef() as it is no more
7074  *          needed.
7075  *  \throw If either \a a1 or \a a2 is NULL.
7076  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
7077  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
7078  *  \throw If there is a negative value in \a a2.
7079  */
7080 DataArrayInt *DataArrayInt::Pow(const DataArrayInt *a1, const DataArrayInt *a2)
7081 {
7082   if(!a1 || !a2)
7083     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : at least one of input instances is null !");
7084   int nbOfTuple=a1->getNumberOfTuples();
7085   int nbOfTuple2=a2->getNumberOfTuples();
7086   int nbOfComp=a1->getNumberOfComponents();
7087   int nbOfComp2=a2->getNumberOfComponents();
7088   if(nbOfTuple!=nbOfTuple2)
7089     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of tuples mismatches !");
7090   if(nbOfComp!=1 || nbOfComp2!=1)
7091     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of components of both arrays must be equal to 1 !");
7092   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuple,1);
7093   const int *ptr1(a1->begin()),*ptr2(a2->begin());
7094   int *ptr=ret->getPointer();
7095   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
7096     {
7097       if(*ptr2>=0)
7098         {
7099           int tmp=1;
7100           for(int j=0;j<*ptr2;j++)
7101             tmp*=*ptr1;
7102           *ptr=tmp;
7103         }
7104       else
7105         {
7106           std::ostringstream oss; oss << "DataArrayInt::Pow : on tuple #" << i << " of a2 value is < 0 (" << *ptr2 << ") !";
7107           throw INTERP_KERNEL::Exception(oss.str().c_str());
7108         }
7109     }
7110   return ret.retn();
7111 }
7112
7113 /*!
7114  * Apply pow on values of another DataArrayInt to values of \a this one.
7115  *
7116  *  \param [in] other - an array to pow to \a this one.
7117  *  \throw If \a other is NULL.
7118  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
7119  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
7120  *  \throw If there is a negative value in \a other.
7121  */
7122 void DataArrayInt::powEqual(const DataArrayInt *other)
7123 {
7124   if(!other)
7125     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : input instance is null !");
7126   int nbOfTuple=getNumberOfTuples();
7127   int nbOfTuple2=other->getNumberOfTuples();
7128   int nbOfComp=getNumberOfComponents();
7129   int nbOfComp2=other->getNumberOfComponents();
7130   if(nbOfTuple!=nbOfTuple2)
7131     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of tuples mismatches !");
7132   if(nbOfComp!=1 || nbOfComp2!=1)
7133     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of components of both arrays must be equal to 1 !");
7134   int *ptr=getPointer();
7135   const int *ptrc=other->begin();
7136   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
7137     {
7138       if(*ptrc>=0)
7139         {
7140           int tmp=1;
7141           for(int j=0;j<*ptrc;j++)
7142             tmp*=*ptr;
7143           *ptr=tmp;
7144         }
7145       else
7146         {
7147           std::ostringstream oss; oss << "DataArrayInt::powEqual : on tuple #" << i << " of other value is < 0 (" << *ptrc << ") !";
7148           throw INTERP_KERNEL::Exception(oss.str().c_str());
7149         }
7150     }
7151   declareAsNew();
7152 }
7153
7154 /*!
7155  * Returns a C array which is a renumbering map in "Old to New" mode for the input array.
7156  * This map, if applied to \a start array, would make it sorted. For example, if
7157  * \a start array contents are [9,10,0,6,4,11,3,7] then the contents of the result array is
7158  * [5,6,0,3,2,7,1,4].
7159  *  \param [in] start - pointer to the first element of the array for which the
7160  *         permutation map is computed.
7161  *  \param [in] end - pointer specifying the end of the array \a start, so that
7162  *         the last value of \a start is \a end[ -1 ].
7163  *  \return int * - the result permutation array that the caller is to delete as it is no
7164  *         more needed.
7165  *  \throw If there are equal values in the input array.
7166  */
7167 int *DataArrayInt::CheckAndPreparePermutation(const int *start, const int *end)
7168 {
7169   std::size_t sz=std::distance(start,end);
7170   int *ret=(int *)malloc(sz*sizeof(int));
7171   int *work=new int[sz];
7172   std::copy(start,end,work);
7173   std::sort(work,work+sz);
7174   if(std::unique(work,work+sz)!=work+sz)
7175     {
7176       delete [] work;
7177       free(ret);
7178       throw INTERP_KERNEL::Exception("Some elements are equals in the specified array !");
7179     }
7180   std::map<int,int> m;
7181   for(int *workPt=work;workPt!=work+sz;workPt++)
7182     m[*workPt]=(int)std::distance(work,workPt);
7183   int *iter2=ret;
7184   for(const int *iter=start;iter!=end;iter++,iter2++)
7185     *iter2=m[*iter];
7186   delete [] work;
7187   return ret;
7188 }
7189
7190 /*!
7191  * Returns a new DataArrayInt containing an arithmetic progression
7192  * that is equal to the sequence returned by Python \c range(\a begin,\a  end,\a  step )
7193  * function.
7194  *  \param [in] begin - the start value of the result sequence.
7195  *  \param [in] end - limiting value, so that every value of the result array is less than
7196  *              \a end.
7197  *  \param [in] step - specifies the increment or decrement.
7198  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7199  *          array using decrRef() as it is no more needed.
7200  *  \throw If \a step == 0.
7201  *  \throw If \a end < \a begin && \a step > 0.
7202  *  \throw If \a end > \a begin && \a step < 0.
7203  */
7204 DataArrayInt *DataArrayInt::Range(int begin, int end, int step)
7205 {
7206   int nbOfTuples=GetNumberOfItemGivenBESRelative(begin,end,step,"DataArrayInt::Range");
7207   MCAuto<DataArrayInt> ret=DataArrayInt::New();
7208   ret->alloc(nbOfTuples,1);
7209   int *ptr=ret->getPointer();
7210   if(step>0)
7211     {
7212       for(int i=begin;i<end;i+=step,ptr++)
7213         *ptr=i;
7214     }
7215   else
7216     {
7217       for(int i=begin;i>end;i+=step,ptr++)
7218         *ptr=i;
7219     }
7220   return ret.retn();
7221 }
7222
7223 /*!
7224  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
7225  * Server side.
7226  */
7227 void DataArrayInt::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
7228 {
7229   tinyInfo.resize(2);
7230   if(isAllocated())
7231     {
7232       tinyInfo[0]=getNumberOfTuples();
7233       tinyInfo[1]=getNumberOfComponents();
7234     }
7235   else
7236     {
7237       tinyInfo[0]=-1;
7238       tinyInfo[1]=-1;
7239     }
7240 }
7241
7242 /*!
7243  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
7244  * Server side.
7245  */
7246 void DataArrayInt::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
7247 {
7248   if(isAllocated())
7249     {
7250       int nbOfCompo=getNumberOfComponents();
7251       tinyInfo.resize(nbOfCompo+1);
7252       tinyInfo[0]=getName();
7253       for(int i=0;i<nbOfCompo;i++)
7254         tinyInfo[i+1]=getInfoOnComponent(i);
7255     }
7256   else
7257     {
7258       tinyInfo.resize(1);
7259       tinyInfo[0]=getName();
7260     }
7261 }
7262
7263 /*!
7264  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
7265  * This method returns if a feeding is needed.
7266  */
7267 bool DataArrayInt::resizeForUnserialization(const std::vector<int>& tinyInfoI)
7268 {
7269   int nbOfTuple=tinyInfoI[0];
7270   int nbOfComp=tinyInfoI[1];
7271   if(nbOfTuple!=-1 || nbOfComp!=-1)
7272     {
7273       alloc(nbOfTuple,nbOfComp);
7274       return true;
7275     }
7276   return false;
7277 }
7278
7279 /*!
7280  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
7281  * This method returns if a feeding is needed.
7282  */
7283 void DataArrayInt::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
7284 {
7285   setName(tinyInfoS[0]);
7286   if(isAllocated())
7287     {
7288       int nbOfCompo=tinyInfoI[1];
7289       for(int i=0;i<nbOfCompo;i++)
7290         setInfoOnComponent(i,tinyInfoS[i+1]);
7291     }
7292 }
7293
7294 DataArrayIntIterator::DataArrayIntIterator(DataArrayInt *da):DataArrayIterator<int>(da)
7295 {
7296 }
7297
7298 DataArrayIntTuple::DataArrayIntTuple(int *pt, int nbOfComp):DataArrayTuple<int>(pt,nbOfComp)
7299 {
7300 }
7301
7302 std::string DataArrayIntTuple::repr() const
7303 {
7304   std::ostringstream oss; oss << "(";
7305   for(int i=0;i<_nb_of_compo-1;i++)
7306     oss << _pt[i] << ", ";
7307   oss << _pt[_nb_of_compo-1] << ")";
7308   return oss.str();
7309 }
7310
7311 int DataArrayIntTuple::intValue() const
7312 {
7313   return this->zeValue();
7314 }
7315
7316 /*!
7317  * This method returns a newly allocated instance the caller should dealed with by a MEDCoupling::DataArrayInt::decrRef.
7318  * This method performs \b no copy of data. The content is only referenced using MEDCoupling::DataArrayInt::useArray with ownership set to \b false.
7319  * 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
7320  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
7321  */
7322 DataArrayInt *DataArrayIntTuple::buildDAInt(int nbOfTuples, int nbOfCompo) const
7323 {
7324   return this->buildDA(nbOfTuples,nbOfCompo);
7325 }