Salome HOME
Useful method findIdsGreaterOrEqualTo findIdsGreaterThan findIdsLowerThan findIdsLowe...
[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
44 template<int SPACEDIM>
45 void DataArrayDouble::findCommonTuplesAlg(const double *bbox, int nbNodes, int limitNodeId, double prec, DataArrayInt *c, DataArrayInt *cI) const
46 {
47   const double *coordsPtr=getConstPointer();
48   BBTreePts<SPACEDIM,int> myTree(bbox,0,0,nbNodes,prec);
49   std::vector<bool> isDone(nbNodes);
50   for(int i=0;i<nbNodes;i++)
51     {
52       if(!isDone[i])
53         {
54           std::vector<int> intersectingElems;
55           myTree.getElementsAroundPoint(coordsPtr+i*SPACEDIM,intersectingElems);
56           if(intersectingElems.size()>1)
57             {
58               std::vector<int> commonNodes;
59               for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
60                 if(*it!=i)
61                   if(*it>=limitNodeId)
62                     {
63                       commonNodes.push_back(*it);
64                       isDone[*it]=true;
65                     }
66               if(!commonNodes.empty())
67                 {
68                   cI->pushBackSilent(cI->back()+(int)commonNodes.size()+1);
69                   c->pushBackSilent(i);
70                   c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
71                 }
72             }
73         }
74     }
75 }
76
77 template<int SPACEDIM>
78 void DataArrayDouble::FindTupleIdsNearTuplesAlg(const BBTreePts<SPACEDIM,int>& myTree, const double *pos, int nbOfTuples, double eps,
79                                                 DataArrayInt *c, DataArrayInt *cI)
80 {
81   for(int i=0;i<nbOfTuples;i++)
82     {
83       std::vector<int> intersectingElems;
84       myTree.getElementsAroundPoint(pos+i*SPACEDIM,intersectingElems);
85       std::vector<int> commonNodes;
86       for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
87         commonNodes.push_back(*it);
88       cI->pushBackSilent(cI->back()+(int)commonNodes.size());
89       c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
90     }
91 }
92
93 template<int SPACEDIM>
94 void DataArrayDouble::FindClosestTupleIdAlg(const BBTreePts<SPACEDIM,int>& myTree, double dist, const double *pos, int nbOfTuples, const double *thisPt, int thisNbOfTuples, int *res)
95 {
96   double distOpt(dist);
97   const double *p(pos);
98   int *r(res);
99   for(int i=0;i<nbOfTuples;i++,p+=SPACEDIM,r++)
100     {
101       while(true)
102         {
103           int elem=-1;
104           double ret=myTree.getElementsAroundPoint2(p,distOpt,elem);
105           if(ret!=std::numeric_limits<double>::max())
106             {
107               distOpt=std::max(ret,1e-4);
108               *r=elem;
109               break;
110             }
111           else
112             { distOpt=2*distOpt; continue; }
113         }
114     }
115 }
116
117 int DataArray::EffectiveCircPerm(int nbOfShift, int nbOfTuples)
118 {
119   if(nbOfTuples<=0)
120     throw INTERP_KERNEL::Exception("DataArray::EffectiveCircPerm : number of tuples is expected to be > 0 !");
121   if(nbOfShift>=0)
122     {
123       return nbOfShift%nbOfTuples;
124     }
125   else
126     {
127       int tmp(-nbOfShift);
128       tmp=tmp%nbOfTuples;
129       return nbOfTuples-tmp;
130     }
131 }
132
133 std::size_t DataArray::getHeapMemorySizeWithoutChildren() const
134 {
135   std::size_t sz1=_name.capacity();
136   std::size_t sz2=_info_on_compo.capacity();
137   std::size_t sz3=0;
138   for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
139     sz3+=(*it).capacity();
140   return sz1+sz2+sz3;
141 }
142
143 std::vector<const BigMemoryObject *> DataArray::getDirectChildrenWithNull() const
144 {
145   return std::vector<const BigMemoryObject *>();
146 }
147
148 /*!
149  * Sets the attribute \a _name of \a this array.
150  * See \ref MEDCouplingArrayBasicsName "DataArrays infos" for more information.
151  *  \param [in] name - new array name
152  */
153 void DataArray::setName(const std::string& name)
154 {
155   _name=name;
156 }
157
158 /*!
159  * Copies textual data from an \a other DataArray. The copied data are
160  * - the name attribute,
161  * - the information of components.
162  *
163  * For more information on these data see \ref MEDCouplingArrayBasicsName "DataArrays infos".
164  *
165  *  \param [in] other - another instance of DataArray to copy the textual data from.
166  *  \throw If number of components of \a this array differs from that of the \a other.
167  */
168 void DataArray::copyStringInfoFrom(const DataArray& other)
169 {
170   if(_info_on_compo.size()!=other._info_on_compo.size())
171     throw INTERP_KERNEL::Exception("Size of arrays mismatches on copyStringInfoFrom !");
172   _name=other._name;
173   _info_on_compo=other._info_on_compo;
174 }
175
176 void DataArray::copyPartOfStringInfoFrom(const DataArray& other, const std::vector<int>& compoIds)
177 {
178   int nbOfCompoOth=other.getNumberOfComponents();
179   std::size_t newNbOfCompo=compoIds.size();
180   for(std::size_t i=0;i<newNbOfCompo;i++)
181     if(compoIds[i]>=nbOfCompoOth || compoIds[i]<0)
182       {
183         std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompoOth << ")";
184         throw INTERP_KERNEL::Exception(oss.str().c_str());
185       }
186   for(std::size_t i=0;i<newNbOfCompo;i++)
187     setInfoOnComponent((int)i,other.getInfoOnComponent(compoIds[i]));
188 }
189
190 void DataArray::copyPartOfStringInfoFrom2(const std::vector<int>& compoIds, const DataArray& other)
191 {
192   int nbOfCompo=getNumberOfComponents();
193   std::size_t partOfCompoToSet=compoIds.size();
194   if((int)partOfCompoToSet!=other.getNumberOfComponents())
195     throw INTERP_KERNEL::Exception("Given compoIds has not the same size as number of components of given array !");
196   for(std::size_t i=0;i<partOfCompoToSet;i++)
197     if(compoIds[i]>=nbOfCompo || compoIds[i]<0)
198       {
199         std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompo << ")";
200         throw INTERP_KERNEL::Exception(oss.str().c_str());
201       }
202   for(std::size_t i=0;i<partOfCompoToSet;i++)
203     setInfoOnComponent(compoIds[i],other.getInfoOnComponent((int)i));
204 }
205
206 bool DataArray::areInfoEqualsIfNotWhy(const DataArray& other, std::string& reason) const
207 {
208   std::ostringstream oss;
209   if(_name!=other._name)
210     {
211       oss << "Names DataArray mismatch : this name=\"" << _name << " other name=\"" << other._name << "\" !";
212       reason=oss.str();
213       return false;
214     }
215   if(_info_on_compo!=other._info_on_compo)
216     {
217       oss << "Components DataArray mismatch : \nThis components=";
218       for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
219         oss << "\"" << *it << "\",";
220       oss << "\nOther components=";
221       for(std::vector<std::string>::const_iterator it=other._info_on_compo.begin();it!=other._info_on_compo.end();it++)
222         oss << "\"" << *it << "\",";
223       reason=oss.str();
224       return false;
225     }
226   return true;
227 }
228
229 /*!
230  * Compares textual information of \a this DataArray with that of an \a other one.
231  * The compared data are
232  * - the name attribute,
233  * - the information of components.
234  *
235  * For more information on these data see \ref MEDCouplingArrayBasicsName "DataArrays infos".
236  *  \param [in] other - another instance of DataArray to compare the textual data of.
237  *  \return bool - \a true if the textual information is same, \a false else.
238  */
239 bool DataArray::areInfoEquals(const DataArray& other) const
240 {
241   std::string tmp;
242   return areInfoEqualsIfNotWhy(other,tmp);
243 }
244
245 void DataArray::reprWithoutNameStream(std::ostream& stream) const
246 {
247   stream << "Number of components : "<< getNumberOfComponents() << "\n";
248   stream << "Info of these components : ";
249   for(std::vector<std::string>::const_iterator iter=_info_on_compo.begin();iter!=_info_on_compo.end();iter++)
250     stream << "\"" << *iter << "\"   ";
251   stream << "\n";
252 }
253
254 std::string DataArray::cppRepr(const std::string& varName) const
255 {
256   std::ostringstream ret;
257   reprCppStream(varName,ret);
258   return ret.str();
259 }
260
261 /*!
262  * Sets information on all components. To know more on format of this information
263  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
264  *  \param [in] info - a vector of strings.
265  *  \throw If size of \a info differs from the number of components of \a this.
266  */
267 void DataArray::setInfoOnComponents(const std::vector<std::string>& info)
268 {
269   if(getNumberOfComponents()!=(int)info.size())
270     {
271       std::ostringstream oss; oss << "DataArray::setInfoOnComponents : input is of size " << info.size() << " whereas number of components is equal to " << getNumberOfComponents() << " !";
272       throw INTERP_KERNEL::Exception(oss.str().c_str());
273     }
274   _info_on_compo=info;
275 }
276
277 /*!
278  * This method is only a dispatcher towards DataArrayDouble::setPartOfValues3, DataArrayInt::setPartOfValues3, DataArrayChar::setPartOfValues3 depending on the true
279  * type of \a this and \a aBase.
280  *
281  * \throw If \a aBase and \a this do not have the same type.
282  *
283  * \sa DataArrayDouble::setPartOfValues3, DataArrayInt::setPartOfValues3, DataArrayChar::setPartOfValues3.
284  */
285 void DataArray::setPartOfValuesBase3(const DataArray *aBase, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
286 {
287   if(!aBase)
288     throw INTERP_KERNEL::Exception("DataArray::setPartOfValuesBase3 : input aBase object is NULL !");
289   DataArrayDouble *this1(dynamic_cast<DataArrayDouble *>(this));
290   DataArrayInt *this2(dynamic_cast<DataArrayInt *>(this));
291   DataArrayChar *this3(dynamic_cast<DataArrayChar *>(this));
292   const DataArrayDouble *a1(dynamic_cast<const DataArrayDouble *>(aBase));
293   const DataArrayInt *a2(dynamic_cast<const DataArrayInt *>(aBase));
294   const DataArrayChar *a3(dynamic_cast<const DataArrayChar *>(aBase));
295   if(this1 && a1)
296     {
297       this1->setPartOfValues3(a1,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
298       return ;
299     }
300   if(this2 && a2)
301     {
302       this2->setPartOfValues3(a2,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
303       return ;
304     }
305   if(this3 && a3)
306     {
307       this3->setPartOfValues3(a3,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
308       return ;
309     }
310   throw INTERP_KERNEL::Exception("DataArray::setPartOfValuesBase3 : input aBase object and this do not have the same type !");
311 }
312
313 std::vector<std::string> DataArray::getVarsOnComponent() const
314 {
315   int nbOfCompo=(int)_info_on_compo.size();
316   std::vector<std::string> ret(nbOfCompo);
317   for(int i=0;i<nbOfCompo;i++)
318     ret[i]=getVarOnComponent(i);
319   return ret;
320 }
321
322 std::vector<std::string> DataArray::getUnitsOnComponent() const
323 {
324   int nbOfCompo=(int)_info_on_compo.size();
325   std::vector<std::string> ret(nbOfCompo);
326   for(int i=0;i<nbOfCompo;i++)
327     ret[i]=getUnitOnComponent(i);
328   return ret;
329 }
330
331 /*!
332  * Returns information on a component specified by an index.
333  * To know more on format of this information
334  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
335  *  \param [in] i - the index (zero based) of the component of interest.
336  *  \return std::string - a string containing the information on \a i-th component.
337  *  \throw If \a i is not a valid component index.
338  */
339 std::string DataArray::getInfoOnComponent(int i) const
340 {
341   if(i<(int)_info_on_compo.size() && i>=0)
342     return _info_on_compo[i];
343   else
344     {
345       std::ostringstream oss; oss << "DataArray::getInfoOnComponent : Specified component id is out of range (" << i << ") compared with nb of actual components (" << (int) _info_on_compo.size();
346       throw INTERP_KERNEL::Exception(oss.str().c_str());
347     }
348 }
349
350 /*!
351  * Returns the var part of the full information of the \a i-th component.
352  * For example, if \c getInfoOnComponent(0) returns "SIGXY [N/m^2]", then
353  * \c getVarOnComponent(0) returns "SIGXY".
354  * If a unit part of information is not detected by presence of
355  * two square brackets, then the full information is returned.
356  * To read more about the component information format, see
357  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
358  *  \param [in] i - the index (zero based) of the component of interest.
359  *  \return std::string - a string containing the var information, or the full info.
360  *  \throw If \a i is not a valid component index.
361  */
362 std::string DataArray::getVarOnComponent(int i) const
363 {
364   if(i<(int)_info_on_compo.size() && i>=0)
365     {
366       return GetVarNameFromInfo(_info_on_compo[i]);
367     }
368   else
369     {
370       std::ostringstream oss; oss << "DataArray::getVarOnComponent : Specified component id is out of range  (" << i << ") compared with nb of actual components (" << (int) _info_on_compo.size();
371       throw INTERP_KERNEL::Exception(oss.str().c_str());
372     }
373 }
374
375 /*!
376  * Returns the unit part of the full information of the \a i-th component.
377  * For example, if \c getInfoOnComponent(0) returns "SIGXY [ N/m^2]", then
378  * \c getUnitOnComponent(0) returns " N/m^2".
379  * If a unit part of information is not detected by presence of
380  * two square brackets, then an empty string is returned.
381  * To read more about the component information format, see
382  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
383  *  \param [in] i - the index (zero based) of the component of interest.
384  *  \return std::string - a string containing the unit information, if any, or "".
385  *  \throw If \a i is not a valid component index.
386  */
387 std::string DataArray::getUnitOnComponent(int i) const
388 {
389   if(i<(int)_info_on_compo.size() && i>=0)
390     {
391       return GetUnitFromInfo(_info_on_compo[i]);
392     }
393   else
394     {
395       std::ostringstream oss; oss << "DataArray::getUnitOnComponent : Specified component id is out of range  (" << i << ") compared with nb of actual components (" << (int) _info_on_compo.size();
396       throw INTERP_KERNEL::Exception(oss.str().c_str());
397     }
398 }
399
400 /*!
401  * Returns the var part of the full component information.
402  * For example, if \a info == "SIGXY [N/m^2]", then this method returns "SIGXY".
403  * If a unit part of information is not detected by presence of
404  * two square brackets, then the whole \a info is returned.
405  * To read more about the component information format, see
406  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
407  *  \param [in] info - the full component information.
408  *  \return std::string - a string containing only var information, or the \a info.
409  */
410 std::string DataArray::GetVarNameFromInfo(const std::string& info)
411 {
412   std::size_t p1=info.find_last_of('[');
413   std::size_t p2=info.find_last_of(']');
414   if(p1==std::string::npos || p2==std::string::npos)
415     return info;
416   if(p1>p2)
417     return info;
418   if(p1==0)
419     return std::string();
420   std::size_t p3=info.find_last_not_of(' ',p1-1);
421   return info.substr(0,p3+1);
422 }
423
424 /*!
425  * Returns the unit part of the full component information.
426  * For example, if \a info == "SIGXY [ N/m^2]", then this method returns " N/m^2".
427  * If a unit part of information is not detected by presence of
428  * two square brackets, then an empty string is returned.
429  * To read more about the component information format, see
430  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
431  *  \param [in] info - the full component information.
432  *  \return std::string - a string containing only unit information, if any, or "".
433  */
434 std::string DataArray::GetUnitFromInfo(const std::string& info)
435 {
436   std::size_t p1=info.find_last_of('[');
437   std::size_t p2=info.find_last_of(']');
438   if(p1==std::string::npos || p2==std::string::npos)
439     return std::string();
440   if(p1>p2)
441     return std::string();
442   return info.substr(p1+1,p2-p1-1);
443 }
444
445 /*!
446  * This method put in info format the result of the merge of \a var and \a unit.
447  * The standard format for that is "var [unit]".
448  * Inversely you can retrieve the var part or the unit part of info string using resp. GetVarNameFromInfo and GetUnitFromInfo.
449  */
450 std::string DataArray::BuildInfoFromVarAndUnit(const std::string& var, const std::string& unit)
451 {
452   std::ostringstream oss;
453   oss << var << " [" << unit << "]";
454   return oss.str();
455 }
456
457 std::string DataArray::GetAxisTypeRepr(MEDCouplingAxisType at)
458 {
459   switch(at)
460     {
461     case AX_CART:
462       return std::string("AX_CART");
463     case AX_CYL:
464       return std::string("AX_CYL");
465     case AX_SPHER:
466       return std::string("AX_SPHER");
467     default:
468       throw INTERP_KERNEL::Exception("DataArray::GetAxisTypeRepr : unrecognized axis type enum !");
469     }
470 }
471
472 /*!
473  * Returns a new DataArray by concatenating all given arrays, so that (1) the number
474  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
475  * the number of component in the result array is same as that of each of given arrays.
476  * Info on components is copied from the first of the given arrays. Number of components
477  * in the given arrays must be  the same.
478  *  \param [in] arrs - a sequence of arrays to include in the result array. All arrays must have the same type.
479  *  \return DataArray * - the new instance of DataArray (that can be either DataArrayInt, DataArrayDouble, DataArrayChar).
480  *          The caller is to delete this result array using decrRef() as it is no more
481  *          needed.
482  *  \throw If all arrays within \a arrs are NULL.
483  *  \throw If all not null arrays in \a arrs have not the same type.
484  *  \throw If getNumberOfComponents() of arrays within \a arrs.
485  */
486 DataArray *DataArray::Aggregate(const std::vector<const DataArray *>& arrs)
487 {
488   std::vector<const DataArray *> arr2;
489   for(std::vector<const DataArray *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
490     if(*it)
491       arr2.push_back(*it);
492   if(arr2.empty())
493     throw INTERP_KERNEL::Exception("DataArray::Aggregate : only null instance in input vector !");
494   std::vector<const DataArrayDouble *> arrd;
495   std::vector<const DataArrayInt *> arri;
496   std::vector<const DataArrayChar *> arrc;
497   for(std::vector<const DataArray *>::const_iterator it=arr2.begin();it!=arr2.end();it++)
498     {
499       const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(*it);
500       if(a)
501         { arrd.push_back(a); continue; }
502       const DataArrayInt *b=dynamic_cast<const DataArrayInt *>(*it);
503       if(b)
504         { arri.push_back(b); continue; }
505       const DataArrayChar *c=dynamic_cast<const DataArrayChar *>(*it);
506       if(c)
507         { arrc.push_back(c); continue; }
508       throw INTERP_KERNEL::Exception("DataArray::Aggregate : presence of not null instance in inuput that is not in [DataArrayDouble, DataArrayInt, DataArrayChar] !");
509     }
510   if(arr2.size()==arrd.size())
511     return DataArrayDouble::Aggregate(arrd);
512   if(arr2.size()==arri.size())
513     return DataArrayInt::Aggregate(arri);
514   if(arr2.size()==arrc.size())
515     return DataArrayChar::Aggregate(arrc);
516   throw INTERP_KERNEL::Exception("DataArray::Aggregate : all input arrays must have the same type !");
517 }
518
519 /*!
520  * Sets information on a component specified by an index.
521  * To know more on format of this information
522  * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
523  *  \warning Don't pass NULL as \a info!
524  *  \param [in] i - the index (zero based) of the component of interest.
525  *  \param [in] info - the string containing the information.
526  *  \throw If \a i is not a valid component index.
527  */
528 void DataArray::setInfoOnComponent(int i, const std::string& info)
529 {
530   if(i<(int)_info_on_compo.size() && i>=0)
531     _info_on_compo[i]=info;
532   else
533     {
534       std::ostringstream oss; oss << "DataArray::setInfoOnComponent : Specified component id is out of range  (" << i << ") compared with nb of actual components (" << (int) _info_on_compo.size();
535       throw INTERP_KERNEL::Exception(oss.str().c_str());
536     }
537 }
538
539 /*!
540  * Sets information on all components. This method can change number of components
541  * at certain conditions; if the conditions are not respected, an exception is thrown.
542  * The number of components can be changed in \a this only if \a this is not allocated.
543  * The condition of number of components must not be changed.
544  *
545  * To know more on format of the component information see
546  * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
547  *  \param [in] info - a vector of component infos.
548  *  \throw If \a this->getNumberOfComponents() != \a info.size() && \a this->isAllocated()
549  */
550 void DataArray::setInfoAndChangeNbOfCompo(const std::vector<std::string>& info)
551 {
552   if(getNumberOfComponents()!=(int)info.size())
553     {
554       if(!isAllocated())
555         _info_on_compo=info;
556       else
557         {
558           std::ostringstream oss; oss << "DataArray::setInfoAndChangeNbOfCompo : input is of size " << info.size() << " whereas number of components is equal to " << getNumberOfComponents() << "  and this is already allocated !";
559           throw INTERP_KERNEL::Exception(oss.str().c_str());
560         }
561     }
562   else
563     _info_on_compo=info;
564 }
565
566 void DataArray::checkNbOfTuples(int nbOfTuples, const std::string& msg) const
567 {
568   if(getNumberOfTuples()!=nbOfTuples)
569     {
570       std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " <<  nbOfTuples << " having " << getNumberOfTuples() << " !";
571       throw INTERP_KERNEL::Exception(oss.str().c_str());
572     }
573 }
574
575 void DataArray::checkNbOfComps(int nbOfCompo, const std::string& msg) const
576 {
577   if(getNumberOfComponents()!=nbOfCompo)
578     {
579       std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << nbOfCompo << " having " << getNumberOfComponents() << " !";
580       throw INTERP_KERNEL::Exception(oss.str().c_str());
581     }
582 }
583
584 void DataArray::checkNbOfElems(std::size_t nbOfElems, const std::string& msg) const
585 {
586   if(getNbOfElems()!=nbOfElems)
587     {
588       std::ostringstream oss; oss << msg << " : mismatch number of elems : Expected " << nbOfElems << " having " << getNbOfElems() << " !";
589       throw INTERP_KERNEL::Exception(oss.str().c_str());
590     }
591 }
592
593 void DataArray::checkNbOfTuplesAndComp(const DataArray& other, const std::string& msg) const
594 {
595   if(getNumberOfTuples()!=other.getNumberOfTuples())
596     {
597       std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " <<  other.getNumberOfTuples() << " having " << getNumberOfTuples() << " !";
598       throw INTERP_KERNEL::Exception(oss.str().c_str());
599     }
600   if(getNumberOfComponents()!=other.getNumberOfComponents())
601     {
602       std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << other.getNumberOfComponents() << " having " << getNumberOfComponents() << " !";
603       throw INTERP_KERNEL::Exception(oss.str().c_str());
604     }
605 }
606
607 void DataArray::checkNbOfTuplesAndComp(int nbOfTuples, int nbOfCompo, const std::string& msg) const
608 {
609   checkNbOfTuples(nbOfTuples,msg);
610   checkNbOfComps(nbOfCompo,msg);
611 }
612
613 /*!
614  * Simply this method checks that \b value is in [0,\b ref).
615  */
616 void DataArray::CheckValueInRange(int ref, int value, const std::string& msg)
617 {
618   if(value<0 || value>=ref)
619     {
620       std::ostringstream oss; oss << "DataArray::CheckValueInRange : " << msg  << " ! Expected in range [0," << ref << "[ having " << value << " !";
621       throw INTERP_KERNEL::Exception(oss.str().c_str());
622     }
623 }
624
625 /*!
626  * This method checks that [\b start, \b end) is compliant with ref length \b value.
627  * typicaly start in [0,\b value) and end in [0,\b value). If value==start and start==end, it is supported.
628  */
629 void DataArray::CheckValueInRangeEx(int value, int start, int end, const std::string& msg)
630 {
631   if(start<0 || start>=value)
632     {
633       if(value!=start || end!=start)
634         {
635           std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg  << " ! Expected start " << start << " of input range, in [0," << value << "[ !";
636           throw INTERP_KERNEL::Exception(oss.str().c_str());
637         }
638     }
639   if(end<0 || end>value)
640     {
641       std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg  << " ! Expected end " << end << " of input range, in [0," << value << "] !";
642       throw INTERP_KERNEL::Exception(oss.str().c_str());
643     }
644 }
645
646 void DataArray::CheckClosingParInRange(int ref, int value, const std::string& msg)
647 {
648   if(value<0 || value>ref)
649     {
650       std::ostringstream oss; oss << "DataArray::CheckClosingParInRange : " << msg  << " ! Expected input range in [0," << ref << "] having closing open parenthesis " << value << " !";
651       throw INTERP_KERNEL::Exception(oss.str().c_str());
652     }
653 }
654
655 /*!
656  * This method is useful to slice work among a pool of threads or processes. \a begin, \a end \a step is the input whole slice of work to perform, 
657  * typically it is a whole slice of tuples of DataArray or cells, nodes of a mesh...
658  *
659  * The input \a sliceId should be an id in [0, \a nbOfSlices) that specifies the slice of work.
660  *
661  * \param [in] start - the start of the input slice of the whole work to perform splitted into slices.
662  * \param [in] stop - the stop of the input slice of the whole work to perform splitted into slices.
663  * \param [in] step - the step (that can be <0) of the input slice of the whole work to perform splitted into slices.
664  * \param [in] sliceId - the slice id considered
665  * \param [in] nbOfSlices - the number of slices (typically the number of cores on which the work is expected to be sliced)
666  * \param [out] startSlice - the start of the slice considered
667  * \param [out] stopSlice - the stop of the slice consided
668  * 
669  * \throw If \a step == 0
670  * \throw If \a nbOfSlices not > 0
671  * \throw If \a sliceId not in [0,nbOfSlices)
672  */
673 void DataArray::GetSlice(int start, int stop, int step, int sliceId, int nbOfSlices, int& startSlice, int& stopSlice)
674 {
675   if(nbOfSlices<=0)
676     {
677       std::ostringstream oss; oss << "DataArray::GetSlice : nbOfSlices (" << nbOfSlices << ") must be > 0 !";
678       throw INTERP_KERNEL::Exception(oss.str().c_str());
679     }
680   if(sliceId<0 || sliceId>=nbOfSlices)
681     {
682       std::ostringstream oss; oss << "DataArray::GetSlice : sliceId (" << nbOfSlices << ") must be in [0 , nbOfSlices (" << nbOfSlices << ") ) !";
683       throw INTERP_KERNEL::Exception(oss.str().c_str());
684     }
685   int nbElems=GetNumberOfItemGivenBESRelative(start,stop,step,"DataArray::GetSlice");
686   int minNbOfElemsPerSlice=nbElems/nbOfSlices;
687   startSlice=start+minNbOfElemsPerSlice*step*sliceId;
688   if(sliceId<nbOfSlices-1)
689     stopSlice=start+minNbOfElemsPerSlice*step*(sliceId+1);
690   else
691     stopSlice=stop;
692 }
693
694 int DataArray::GetNumberOfItemGivenBES(int begin, int end, int step, const std::string& msg)
695 {
696   if(end<begin)
697     {
698       std::ostringstream oss; oss << msg << " : end before begin !";
699       throw INTERP_KERNEL::Exception(oss.str().c_str());
700     }
701   if(end==begin)
702     return 0;
703   if(step<=0)
704     {
705       std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
706       throw INTERP_KERNEL::Exception(oss.str().c_str());
707     }
708   return (end-1-begin)/step+1;
709 }
710
711 int DataArray::GetNumberOfItemGivenBESRelative(int begin, int end, int step, const std::string& msg)
712 {
713   if(step==0)
714     throw INTERP_KERNEL::Exception("DataArray::GetNumberOfItemGivenBES : step=0 is not allowed !");
715   if(end<begin && step>0)
716     {
717       std::ostringstream oss; oss << msg << " : end before begin whereas step is positive !";
718       throw INTERP_KERNEL::Exception(oss.str().c_str());
719     }
720   if(begin<end && step<0)
721     {
722       std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
723       throw INTERP_KERNEL::Exception(oss.str().c_str());
724     }
725   if(begin!=end)
726     return (std::max(begin,end)-1-std::min(begin,end))/std::abs(step)+1;
727   else
728     return 0;
729 }
730
731 int DataArray::GetPosOfItemGivenBESRelativeNoThrow(int value, int begin, int end, int step)
732 {
733   if(step!=0)
734     {
735       if(step>0)
736         {
737           if(begin<=value && value<end)
738             {
739               if((value-begin)%step==0)
740                 return (value-begin)/step;
741               else
742                 return -1;
743             }
744           else
745             return -1;
746         }
747       else
748         {
749           if(begin>=value && value>end)
750             {
751               if((begin-value)%(-step)==0)
752                 return (begin-value)/(-step);
753               else
754                 return -1;
755             }
756           else
757             return -1;
758         }
759     }
760   else
761     return -1;
762 }
763
764 /*!
765  * Returns a new instance of DataArrayDouble. The caller is to delete this array
766  * using decrRef() as it is no more needed. 
767  */
768 DataArrayDouble *DataArrayDouble::New()
769 {
770   return new DataArrayDouble;
771 }
772
773 /*!
774  * Returns the only one value in \a this, if and only if number of elements
775  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
776  *  \return double - the sole value stored in \a this array.
777  *  \throw If at least one of conditions stated above is not fulfilled.
778  */
779 double DataArrayDouble::doubleValue() const
780 {
781   if(isAllocated())
782     {
783       if(getNbOfElems()==1)
784         {
785           return *getConstPointer();
786         }
787       else
788         throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is allocated but number of elements is not equal to 1 !");
789     }
790   else
791     throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is not allocated !");
792 }
793
794 /*!
795  * Returns a full copy of \a this. For more info on copying data arrays see
796  * \ref MEDCouplingArrayBasicsCopyDeep.
797  *  \return DataArrayDouble * - a new instance of DataArrayDouble. The caller is to
798  *          delete this array using decrRef() as it is no more needed. 
799  */
800 DataArrayDouble *DataArrayDouble::deepCopy() const
801 {
802   return new DataArrayDouble(*this);
803 }
804
805 /*!
806  * Returns either a \a deep or \a shallow copy of this array. For more info see
807  * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
808  *  \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
809  *  \return DataArrayDouble * - either a new instance of DataArrayDouble (if \a dCpy
810  *          == \a true) or \a this instance (if \a dCpy == \a false).
811  */
812 DataArrayDouble *DataArrayDouble::performCopyOrIncrRef(bool dCpy) const
813 {
814   if(dCpy)
815     return deepCopy();
816   else
817     {
818       incrRef();
819       return const_cast<DataArrayDouble *>(this);
820     }
821 }
822
823 /*!
824  * Assign zero to all values in \a this array. To know more on filling arrays see
825  * \ref MEDCouplingArrayFill.
826  * \throw If \a this is not allocated.
827  */
828 void DataArrayDouble::fillWithZero()
829 {
830   fillWithValue(0.);
831 }
832
833 /*!
834  * Set all values in \a this array so that the i-th element equals to \a init + i
835  * (i starts from zero). To know more on filling arrays see \ref MEDCouplingArrayFill.
836  *  \param [in] init - value to assign to the first element of array.
837  *  \throw If \a this->getNumberOfComponents() != 1
838  *  \throw If \a this is not allocated.
839  */
840 void DataArrayDouble::iota(double init)
841 {
842   checkAllocated();
843   if(getNumberOfComponents()!=1)
844     throw INTERP_KERNEL::Exception("DataArrayDouble::iota : works only for arrays with only one component, you can call 'rearrange' method before !");
845   double *ptr=getPointer();
846   int ntuples=getNumberOfTuples();
847   for(int i=0;i<ntuples;i++)
848     ptr[i]=init+double(i);
849   declareAsNew();
850 }
851
852 /*!
853  * Checks if all values in \a this array are equal to \a val at precision \a eps.
854  *  \param [in] val - value to check equality of array values to.
855  *  \param [in] eps - precision to check the equality.
856  *  \return bool - \a true if all values are in range (_val_ - _eps_; _val_ + _eps_),
857  *                 \a false else.
858  *  \throw If \a this->getNumberOfComponents() != 1
859  *  \throw If \a this is not allocated.
860  */
861 bool DataArrayDouble::isUniform(double val, double eps) const
862 {
863   checkAllocated();
864   if(getNumberOfComponents()!=1)
865     throw INTERP_KERNEL::Exception("DataArrayDouble::isUniform : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
866   int nbOfTuples=getNumberOfTuples();
867   const double *w=getConstPointer();
868   const double *end2=w+nbOfTuples;
869   const double vmin=val-eps;
870   const double vmax=val+eps;
871   for(;w!=end2;w++)
872     if(*w<vmin || *w>vmax)
873       return false;
874   return true;
875 }
876
877 /*!
878  * Checks that \a this array is consistently **increasing** or **decreasing** in value,
879  * with at least absolute difference value of |\a eps| at each step.
880  * If not an exception is thrown.
881  *  \param [in] increasing - if \a true, the array values should be increasing.
882  *  \param [in] eps - minimal absolute difference between the neighbor values at which 
883  *                    the values are considered different.
884  *  \throw If sequence of values is not strictly monotonic in agreement with \a
885  *         increasing arg.
886  *  \throw If \a this->getNumberOfComponents() != 1.
887  *  \throw If \a this is not allocated.
888  */
889 void DataArrayDouble::checkMonotonic(bool increasing, double eps) const
890 {
891   if(!isMonotonic(increasing,eps))
892     {
893       if (increasing)
894         throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not INCREASING monotonic !");
895       else
896         throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not DECREASING monotonic !");
897     }
898 }
899
900 /*!
901  * Checks that \a this array is consistently **increasing** or **decreasing** in value,
902  * with at least absolute difference value of |\a eps| at each step.
903  *  \param [in] increasing - if \a true, array values should be increasing.
904  *  \param [in] eps - minimal absolute difference between the neighbor values at which 
905  *                    the values are considered different.
906  *  \return bool - \a true if values change in accordance with \a increasing arg.
907  *  \throw If \a this->getNumberOfComponents() != 1.
908  *  \throw If \a this is not allocated.
909  */
910 bool DataArrayDouble::isMonotonic(bool increasing, double eps) const
911 {
912   checkAllocated();
913   if(getNumberOfComponents()!=1)
914     throw INTERP_KERNEL::Exception("DataArrayDouble::isMonotonic : only supported with 'this' array with ONE component !");
915   int nbOfElements=getNumberOfTuples();
916   const double *ptr=getConstPointer();
917   if(nbOfElements==0)
918     return true;
919   double ref=ptr[0];
920   double absEps=fabs(eps);
921   if(increasing)
922     {
923       for(int i=1;i<nbOfElements;i++)
924         {
925           if(ptr[i]<(ref+absEps))
926             return false;
927           ref=ptr[i];
928         }
929       return true;
930     }
931   else
932     {
933       for(int i=1;i<nbOfElements;i++)
934         {
935           if(ptr[i]>(ref-absEps))
936             return false;
937           ref=ptr[i];
938         }
939       return true;
940     }
941 }
942
943 /*!
944  * Returns a textual and human readable representation of \a this instance of
945  * DataArrayDouble. This text is shown when a DataArrayDouble is printed in Python.
946  * \return std::string - text describing \a this DataArrayDouble.
947  *
948  * \sa reprNotTooLong, reprZip
949  */
950 std::string DataArrayDouble::repr() const
951 {
952   std::ostringstream ret;
953   reprStream(ret);
954   return ret.str();
955 }
956
957 std::string DataArrayDouble::reprZip() const
958 {
959   std::ostringstream ret;
960   reprZipStream(ret);
961   return ret.str();
962 }
963
964 /*!
965  * This method is close to repr method except that when \a this has more than 1000 tuples, all tuples are not
966  * printed out to avoid to consume too much space in interpretor.
967  * \sa repr
968  */
969 std::string DataArrayDouble::reprNotTooLong() const
970 {
971   std::ostringstream ret;
972   reprNotTooLongStream(ret);
973   return ret.str();
974 }
975
976 void DataArrayDouble::writeVTK(std::ostream& ofs, int indent, const std::string& nameInFile, DataArrayByte *byteArr) const
977 {
978   static const char SPACE[4]={' ',' ',' ',' '};
979   checkAllocated();
980   std::string idt(indent,' ');
981   ofs.precision(17);
982   ofs << idt << "<DataArray type=\"Float32\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
983   //
984   bool areAllEmpty(true);
985   for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
986     if(!(*it).empty())
987       areAllEmpty=false;
988   if(!areAllEmpty)
989     for(std::size_t i=0;i<_info_on_compo.size();i++)
990       ofs << " ComponentName" << i << "=\"" << _info_on_compo[i] << "\"";
991   //
992   if(byteArr)
993     {
994       ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
995       INTERP_KERNEL::AutoPtr<float> tmp(new float[getNbOfElems()]);
996       float *pt(tmp);
997       // to make Visual C++ happy : instead of std::copy(begin(),end(),(float *)tmp);
998       for(const double *src=begin();src!=end();src++,pt++)
999         *pt=float(*src);
1000       const char *data(reinterpret_cast<const char *>((float *)tmp));
1001       std::size_t sz(getNbOfElems()*sizeof(float));
1002       byteArr->insertAtTheEnd(data,data+sz);
1003       byteArr->insertAtTheEnd(SPACE,SPACE+4);
1004     }
1005   else
1006     {
1007       ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
1008       std::copy(begin(),end(),std::ostream_iterator<double>(ofs," "));
1009     }
1010   ofs << std::endl << idt << "</DataArray>\n";
1011 }
1012
1013 void DataArrayDouble::reprStream(std::ostream& stream) const
1014 {
1015   stream << "Name of double array : \"" << _name << "\"\n";
1016   reprWithoutNameStream(stream);
1017 }
1018
1019 void DataArrayDouble::reprZipStream(std::ostream& stream) const
1020 {
1021   stream << "Name of double array : \"" << _name << "\"\n";
1022   reprZipWithoutNameStream(stream);
1023 }
1024
1025 void DataArrayDouble::reprNotTooLongStream(std::ostream& stream) const
1026 {
1027   stream << "Name of double array : \"" << _name << "\"\n";
1028   reprNotTooLongWithoutNameStream(stream);
1029 }
1030
1031 void DataArrayDouble::reprWithoutNameStream(std::ostream& stream) const
1032 {
1033   DataArray::reprWithoutNameStream(stream);
1034   stream.precision(17);
1035   _mem.repr(getNumberOfComponents(),stream);
1036 }
1037
1038 void DataArrayDouble::reprZipWithoutNameStream(std::ostream& stream) const
1039 {
1040   DataArray::reprWithoutNameStream(stream);
1041   stream.precision(17);
1042   _mem.reprZip(getNumberOfComponents(),stream);
1043 }
1044
1045 void DataArrayDouble::reprNotTooLongWithoutNameStream(std::ostream& stream) const
1046 {
1047   DataArray::reprWithoutNameStream(stream);
1048   stream.precision(17);
1049   _mem.reprNotTooLong(getNumberOfComponents(),stream);
1050 }
1051
1052 void DataArrayDouble::reprCppStream(const std::string& varName, std::ostream& stream) const
1053 {
1054   int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
1055   const double *data=getConstPointer();
1056   stream.precision(17);
1057   stream << "DataArrayDouble *" << varName << "=DataArrayDouble::New();" << std::endl;
1058   if(nbTuples*nbComp>=1)
1059     {
1060       stream << "const double " << varName << "Data[" << nbTuples*nbComp << "]={";
1061       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<double>(stream,","));
1062       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
1063       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
1064     }
1065   else
1066     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
1067   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
1068 }
1069
1070 /*!
1071  * Method that gives a quick overvien of \a this for python.
1072  */
1073 void DataArrayDouble::reprQuickOverview(std::ostream& stream) const
1074 {
1075   static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
1076   stream << "DataArrayDouble C++ instance at " << this << ". ";
1077   if(isAllocated())
1078     {
1079       int nbOfCompo=(int)_info_on_compo.size();
1080       if(nbOfCompo>=1)
1081         {
1082           int nbOfTuples=getNumberOfTuples();
1083           stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
1084           reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
1085         }
1086       else
1087         stream << "Number of components : 0.";
1088     }
1089   else
1090     stream << "*** No data allocated ****";
1091 }
1092
1093 void DataArrayDouble::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
1094 {
1095   const double *data=begin();
1096   int nbOfTuples=getNumberOfTuples();
1097   int nbOfCompo=(int)_info_on_compo.size();
1098   std::ostringstream oss2; oss2 << "[";
1099   oss2.precision(17);
1100   std::string oss2Str(oss2.str());
1101   bool isFinished=true;
1102   for(int i=0;i<nbOfTuples && isFinished;i++)
1103     {
1104       if(nbOfCompo>1)
1105         {
1106           oss2 << "(";
1107           for(int j=0;j<nbOfCompo;j++,data++)
1108             {
1109               oss2 << *data;
1110               if(j!=nbOfCompo-1) oss2 << ", ";
1111             }
1112           oss2 << ")";
1113         }
1114       else
1115         oss2 << *data++;
1116       if(i!=nbOfTuples-1) oss2 << ", ";
1117       std::string oss3Str(oss2.str());
1118       if(oss3Str.length()<maxNbOfByteInRepr)
1119         oss2Str=oss3Str;
1120       else
1121         isFinished=false;
1122     }
1123   stream << oss2Str;
1124   if(!isFinished)
1125     stream << "... ";
1126   stream << "]";
1127 }
1128
1129 /*!
1130  * Equivalent to DataArrayDouble::isEqual except that if false the reason of
1131  * mismatch is given.
1132  * 
1133  * \param [in] other the instance to be compared with \a this
1134  * \param [in] prec the precision to compare numeric data of the arrays.
1135  * \param [out] reason In case of inequality returns the reason.
1136  * \sa DataArrayDouble::isEqual
1137  */
1138 bool DataArrayDouble::isEqualIfNotWhy(const DataArrayDouble& other, double prec, std::string& reason) const
1139 {
1140   if(!areInfoEqualsIfNotWhy(other,reason))
1141     return false;
1142   return _mem.isEqual(other._mem,prec,reason);
1143 }
1144
1145 /*!
1146  * Checks if \a this and another DataArrayDouble are fully equal. For more info see
1147  * \ref MEDCouplingArrayBasicsCompare.
1148  *  \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1149  *  \param [in] prec - precision value to compare numeric data of the arrays.
1150  *  \return bool - \a true if the two arrays are equal, \a false else.
1151  */
1152 bool DataArrayDouble::isEqual(const DataArrayDouble& other, double prec) const
1153 {
1154   std::string tmp;
1155   return isEqualIfNotWhy(other,prec,tmp);
1156 }
1157
1158 /*!
1159  * Checks if values of \a this and another DataArrayDouble are equal. For more info see
1160  * \ref MEDCouplingArrayBasicsCompare.
1161  *  \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1162  *  \param [in] prec - precision value to compare numeric data of the arrays.
1163  *  \return bool - \a true if the values of two arrays are equal, \a false else.
1164  */
1165 bool DataArrayDouble::isEqualWithoutConsideringStr(const DataArrayDouble& other, double prec) const
1166 {
1167   std::string tmp;
1168   return _mem.isEqual(other._mem,prec,tmp);
1169 }
1170
1171 /*!
1172  * Creates a new DataArrayInt and assigns all (textual and numerical) data of \a this
1173  * array to the new one.
1174  *  \return DataArrayInt * - the new instance of DataArrayInt.
1175  */
1176 DataArrayInt *DataArrayDouble::convertToIntArr() const
1177 {
1178   DataArrayInt *ret=DataArrayInt::New();
1179   ret->alloc(getNumberOfTuples(),getNumberOfComponents());
1180   int *dest=ret->getPointer();
1181   // to make Visual C++ happy : instead of std::size_t nbOfVals=getNbOfElems(); std::copy(src,src+nbOfVals,dest);
1182   for(const double *src=begin();src!=end();src++,dest++)
1183     *dest=(int)*src;
1184   ret->copyStringInfoFrom(*this);
1185   return ret;
1186 }
1187
1188 /*!
1189  * Returns a new DataArrayDouble holding the same values as \a this array but differently
1190  * arranged in memory. If \a this array holds 2 components of 3 values:
1191  * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
1192  * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
1193  *  \warning Do not confuse this method with transpose()!
1194  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1195  *          is to delete using decrRef() as it is no more needed.
1196  *  \throw If \a this is not allocated.
1197  */
1198 DataArrayDouble *DataArrayDouble::fromNoInterlace() const
1199 {
1200   if(_mem.isNull())
1201     throw INTERP_KERNEL::Exception("DataArrayDouble::fromNoInterlace : Not defined array !");
1202   double *tab=_mem.fromNoInterlace(getNumberOfComponents());
1203   DataArrayDouble *ret=DataArrayDouble::New();
1204   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
1205   return ret;
1206 }
1207
1208 /*!
1209  * Returns a new DataArrayDouble holding the same values as \a this array but differently
1210  * arranged in memory. If \a this array holds 2 components of 3 values:
1211  * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
1212  * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
1213  *  \warning Do not confuse this method with transpose()!
1214  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1215  *          is to delete using decrRef() as it is no more needed.
1216  *  \throw If \a this is not allocated.
1217  */
1218 DataArrayDouble *DataArrayDouble::toNoInterlace() const
1219 {
1220   if(_mem.isNull())
1221     throw INTERP_KERNEL::Exception("DataArrayDouble::toNoInterlace : Not defined array !");
1222   double *tab=_mem.toNoInterlace(getNumberOfComponents());
1223   DataArrayDouble *ret=DataArrayDouble::New();
1224   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
1225   return ret;
1226 }
1227
1228 /*!
1229  * Appends components of another array to components of \a this one, tuple by tuple.
1230  * So that the number of tuples of \a this array remains the same and the number of 
1231  * components increases.
1232  *  \param [in] other - the DataArrayDouble to append to \a this one.
1233  *  \throw If \a this is not allocated.
1234  *  \throw If \a this and \a other arrays have different number of tuples.
1235  *
1236  *  \if ENABLE_EXAMPLES
1237  *  \ref cpp_mcdataarraydouble_meldwith "Here is a C++ example".
1238  *
1239  *  \ref py_mcdataarraydouble_meldwith "Here is a Python example".
1240  *  \endif
1241  */
1242 void DataArrayDouble::meldWith(const DataArrayDouble *other)
1243 {
1244   checkAllocated();
1245   other->checkAllocated();
1246   int nbOfTuples=getNumberOfTuples();
1247   if(nbOfTuples!=other->getNumberOfTuples())
1248     throw INTERP_KERNEL::Exception("DataArrayDouble::meldWith : mismatch of number of tuples !");
1249   int nbOfComp1=getNumberOfComponents();
1250   int nbOfComp2=other->getNumberOfComponents();
1251   double *newArr=(double *)malloc((nbOfTuples*(nbOfComp1+nbOfComp2))*sizeof(double));
1252   double *w=newArr;
1253   const double *inp1=getConstPointer();
1254   const double *inp2=other->getConstPointer();
1255   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
1256     {
1257       w=std::copy(inp1,inp1+nbOfComp1,w);
1258       w=std::copy(inp2,inp2+nbOfComp2,w);
1259     }
1260   useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
1261   std::vector<int> compIds(nbOfComp2);
1262   for(int i=0;i<nbOfComp2;i++)
1263     compIds[i]=nbOfComp1+i;
1264   copyPartOfStringInfoFrom2(compIds,*other);
1265 }
1266
1267 /*!
1268  * This method checks that all tuples in \a other are in \a this.
1269  * If true, the output param \a tupleIds contains the tuples ids of \a this that correspond to tupes in \a this.
1270  * For each i in [ 0 , other->getNumberOfTuples() ) tuple #i in \a other is equal ( regarding input precision \a prec ) to tuple tupleIds[i] in \a this.
1271  *
1272  * \param [in] other - the array having the same number of components than \a this.
1273  * \param [out] tupleIds - the tuple ids containing the same number of tuples than \a other has.
1274  * \sa DataArrayDouble::findCommonTuples
1275  */
1276 bool DataArrayDouble::areIncludedInMe(const DataArrayDouble *other, double prec, DataArrayInt *&tupleIds) const
1277 {
1278   if(!other)
1279     throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : input array is NULL !");
1280   checkAllocated(); other->checkAllocated();
1281   if(getNumberOfComponents()!=other->getNumberOfComponents())
1282     throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : the number of components does not match !");
1283   MCAuto<DataArrayDouble> a=DataArrayDouble::Aggregate(this,other);
1284   DataArrayInt *c=0,*ci=0;
1285   a->findCommonTuples(prec,getNumberOfTuples(),c,ci);
1286   MCAuto<DataArrayInt> cSafe(c),ciSafe(ci);
1287   int newNbOfTuples=-1;
1288   MCAuto<DataArrayInt> ids=DataArrayInt::ConvertIndexArrayToO2N(a->getNumberOfTuples(),c->begin(),ci->begin(),ci->end(),newNbOfTuples);
1289   MCAuto<DataArrayInt> ret1=ids->selectByTupleIdSafeSlice(getNumberOfTuples(),a->getNumberOfTuples(),1);
1290   tupleIds=ret1.retn();
1291   return newNbOfTuples==getNumberOfTuples();
1292 }
1293
1294 /*!
1295  * Searches for tuples coincident within \a prec tolerance. Each tuple is considered
1296  * as coordinates of a point in getNumberOfComponents()-dimensional space. The
1297  * distance separating two points is computed with the infinite norm.
1298  *
1299  * Indices of coincident tuples are stored in output arrays.
1300  * A pair of arrays (\a comm, \a commIndex) is called "Surjective Format 2".
1301  *
1302  * This method is typically used by MEDCouplingPointSet::findCommonNodes() and
1303  * MEDCouplingUMesh::mergeNodes().
1304  *  \param [in] prec - minimal absolute distance between two tuples (infinite norm) at which they are
1305  *              considered not coincident.
1306  *  \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
1307  *              tuples have id strictly lower than \a limitTupleId then they are not returned.
1308  *  \param [out] comm - the array holding ids (== indices) of coincident tuples. 
1309  *               \a comm->getNumberOfComponents() == 1. 
1310  *               \a comm->getNumberOfTuples() == \a commIndex->back().
1311  *  \param [out] commIndex - the array dividing all indices stored in \a comm into
1312  *               groups of (indices of) coincident tuples. Its every value is a tuple
1313  *               index where a next group of tuples begins. For example the second
1314  *               group of tuples in \a comm is described by following range of indices:
1315  *               [ \a commIndex[1], \a commIndex[2] ). \a commIndex->getNumberOfTuples()-1
1316  *               gives the number of groups of coincident tuples.
1317  *  \throw If \a this is not allocated.
1318  *  \throw If the number of components is not in [1,2,3,4].
1319  *
1320  *  \if ENABLE_EXAMPLES
1321  *  \ref cpp_mcdataarraydouble_findcommontuples "Here is a C++ example".
1322  *
1323  *  \ref py_mcdataarraydouble_findcommontuples  "Here is a Python example".
1324  *  \endif
1325  *  \sa DataArrayInt::ConvertIndexArrayToO2N(), DataArrayDouble::areIncludedInMe
1326  */
1327 void DataArrayDouble::findCommonTuples(double prec, int limitTupleId, DataArrayInt *&comm, DataArrayInt *&commIndex) const
1328 {
1329   checkAllocated();
1330   int nbOfCompo=getNumberOfComponents();
1331   if ((nbOfCompo<1) || (nbOfCompo>4)) //test before work
1332     throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : Unexpected spacedim of coords. Must be 1, 2, 3 or 4.");
1333
1334   int nbOfTuples=getNumberOfTuples();
1335   //
1336   MCAuto<DataArrayInt> c(DataArrayInt::New()),cI(DataArrayInt::New()); c->alloc(0,1); cI->pushBackSilent(0);
1337   switch(nbOfCompo)
1338   {
1339     case 4:
1340       findCommonTuplesAlg<4>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1341       break;
1342     case 3:
1343       findCommonTuplesAlg<3>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1344       break;
1345     case 2:
1346       findCommonTuplesAlg<2>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1347       break;
1348     case 1:
1349       findCommonTuplesAlg<1>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1350       break;
1351     default:
1352       throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : nb of components managed are 1,2,3 and 4 ! not implemented for other number of components !");
1353   }
1354   comm=c.retn();
1355   commIndex=cI.retn();
1356 }
1357
1358 /*!
1359  * 
1360  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayDouble instance.
1361  *             \a nbTimes  should be at least equal to 1.
1362  * \return a newly allocated DataArrayDouble having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
1363  * \throw if \a this is not allocated or if \a this has not number of components set to one or if \a nbTimes is lower than 1.
1364  */
1365 DataArrayDouble *DataArrayDouble::duplicateEachTupleNTimes(int nbTimes) const
1366 {
1367   checkAllocated();
1368   if(getNumberOfComponents()!=1)
1369     throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : this should have only one component !");
1370   if(nbTimes<1)
1371     throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : nb times should be >= 1 !");
1372   int nbTuples=getNumberOfTuples();
1373   const double *inPtr=getConstPointer();
1374   MCAuto<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbTimes*nbTuples,1);
1375   double *retPtr=ret->getPointer();
1376   for(int i=0;i<nbTuples;i++,inPtr++)
1377     {
1378       double val=*inPtr;
1379       for(int j=0;j<nbTimes;j++,retPtr++)
1380         *retPtr=val;
1381     }
1382   ret->copyStringInfoFrom(*this);
1383   return ret.retn();
1384 }
1385
1386 /*!
1387  * This methods returns the minimal distance between the two set of points \a this and \a other.
1388  * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
1389  * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
1390  *
1391  * \param [out] thisTupleId the tuple id in \a this corresponding to the returned minimal distance
1392  * \param [out] otherTupleId the tuple id in \a other corresponding to the returned minimal distance
1393  * \return the minimal distance between the two set of points \a this and \a other.
1394  * \sa DataArrayDouble::findClosestTupleId
1395  */
1396 double DataArrayDouble::minimalDistanceTo(const DataArrayDouble *other, int& thisTupleId, int& otherTupleId) const
1397 {
1398   MCAuto<DataArrayInt> part1=findClosestTupleId(other);
1399   int nbOfCompo(getNumberOfComponents());
1400   int otherNbTuples(other->getNumberOfTuples());
1401   const double *thisPt(begin()),*otherPt(other->begin());
1402   const int *part1Pt(part1->begin());
1403   double ret=std::numeric_limits<double>::max();
1404   for(int i=0;i<otherNbTuples;i++,part1Pt++,otherPt+=nbOfCompo)
1405     {
1406       double tmp(0.);
1407       for(int j=0;j<nbOfCompo;j++)
1408         tmp+=(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j])*(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j]);
1409       if(tmp<ret)
1410         { ret=tmp; thisTupleId=*part1Pt; otherTupleId=i; }
1411     }
1412   return sqrt(ret);
1413 }
1414
1415 /*!
1416  * This methods returns for each tuple in \a other which tuple in \a this is the closest.
1417  * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
1418  * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
1419  *
1420  * \return a newly allocated (new object to be dealt by the caller) DataArrayInt having \c other->getNumberOfTuples() tuples and one components.
1421  * \sa DataArrayDouble::minimalDistanceTo
1422  */
1423 DataArrayInt *DataArrayDouble::findClosestTupleId(const DataArrayDouble *other) const
1424 {
1425   if(!other)
1426     throw INTERP_KERNEL::Exception("DataArrayDouble::findClosestTupleId : other instance is NULL !");
1427   checkAllocated(); other->checkAllocated();
1428   int nbOfCompo=getNumberOfComponents();
1429   if(nbOfCompo!=other->getNumberOfComponents())
1430     {
1431       std::ostringstream oss; oss << "DataArrayDouble::findClosestTupleId : number of components in this is " << nbOfCompo;
1432       oss << ", whereas number of components in other is " << other->getNumberOfComponents() << "! Should be equal !";
1433       throw INTERP_KERNEL::Exception(oss.str().c_str());
1434     }
1435   int nbOfTuples=other->getNumberOfTuples();
1436   int thisNbOfTuples=getNumberOfTuples();
1437   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuples,1);
1438   double bounds[6];
1439   getMinMaxPerComponent(bounds);
1440   switch(nbOfCompo)
1441   {
1442     case 3:
1443       {
1444         double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2])),zDelta(fabs(bounds[5]-bounds[4]));
1445         double delta=std::max(xDelta,yDelta); delta=std::max(delta,zDelta);
1446         double characSize=pow((delta*delta*delta)/((double)thisNbOfTuples),1./3.);
1447         BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1448         FindClosestTupleIdAlg<3>(myTree,3.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1449         break;
1450       }
1451     case 2:
1452       {
1453         double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2]));
1454         double delta=std::max(xDelta,yDelta);
1455         double characSize=sqrt(delta/(double)thisNbOfTuples);
1456         BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1457         FindClosestTupleIdAlg<2>(myTree,2.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1458         break;
1459       }
1460     case 1:
1461       {
1462         double characSize=fabs(bounds[1]-bounds[0])/thisNbOfTuples;
1463         BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1464         FindClosestTupleIdAlg<1>(myTree,1.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1465         break;
1466       }
1467     default:
1468       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for findClosestTupleId. Must be 1, 2 or 3.");
1469   }
1470   return ret.retn();
1471 }
1472
1473 /*!
1474  * This method expects that \a this and \a otherBBoxFrmt arrays are bounding box arrays ( as the output of MEDCouplingPointSet::getBoundingBoxForBBTree method ).
1475  * This method will return a DataArrayInt array having the same number of tuples than \a this. This returned array tells for each cell in \a this
1476  * how many bounding boxes in \a otherBBoxFrmt.
1477  * So, this method expects that \a this and \a otherBBoxFrmt have the same number of components.
1478  *
1479  * \param [in] otherBBoxFrmt - It is an array .
1480  * \param [in] eps - the absolute precision of the detection. when eps < 0 the bboxes are enlarged so more interactions are detected. Inversely when > 0 the bboxes are stretched.
1481  * \sa MEDCouplingPointSet::getBoundingBoxForBBTree
1482  * \throw If \a this and \a otherBBoxFrmt have not the same number of components.
1483  * \throw If \a this and \a otherBBoxFrmt number of components is not even (BBox format).
1484  */
1485 DataArrayInt *DataArrayDouble::computeNbOfInteractionsWith(const DataArrayDouble *otherBBoxFrmt, double eps) const
1486 {
1487   if(!otherBBoxFrmt)
1488     throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : input array is NULL !");
1489   if(!isAllocated() || !otherBBoxFrmt->isAllocated())
1490     throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : this and input array must be allocated !");
1491   int nbOfComp(getNumberOfComponents()),nbOfTuples(getNumberOfTuples());
1492   if(nbOfComp!=otherBBoxFrmt->getNumberOfComponents())
1493     {
1494       std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : this number of components (" << nbOfComp << ") must be equal to the number of components of input array (" << otherBBoxFrmt->getNumberOfComponents() << ") !";
1495       throw INTERP_KERNEL::Exception(oss.str().c_str());
1496     }
1497   if(nbOfComp%2!=0)
1498     {
1499       std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : Number of components (" << nbOfComp << ") is not even ! It should be to be compatible with bbox format !";
1500       throw INTERP_KERNEL::Exception(oss.str().c_str());
1501     }
1502   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbOfTuples,1);
1503   const double *thisBBPtr(begin());
1504   int *retPtr(ret->getPointer());
1505   switch(nbOfComp/2)
1506   {
1507     case 3:
1508       {
1509         BBTree<3,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
1510         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
1511           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
1512         break;
1513       }
1514     case 2:
1515       {
1516         BBTree<2,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
1517         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
1518           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
1519         break;
1520       }
1521     case 1:
1522       {
1523         BBTree<1,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
1524         for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
1525           *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
1526         break;
1527       }
1528     default:
1529       throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : space dimension supported are [1,2,3] !");
1530   }
1531
1532   return ret.retn();
1533 }
1534
1535 /*!
1536  * Returns a copy of \a this array by excluding coincident tuples. Each tuple is
1537  * considered as coordinates of a point in getNumberOfComponents()-dimensional
1538  * space. The distance between tuples is computed using norm2. If several tuples are
1539  * not far each from other than \a prec, only one of them remains in the result
1540  * array. The order of tuples in the result array is same as in \a this one except
1541  * that coincident tuples are excluded.
1542  *  \param [in] prec - minimal absolute distance between two tuples at which they are
1543  *              considered not coincident.
1544  *  \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
1545  *              tuples have id strictly lower than \a limitTupleId then they are not excluded.
1546  *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1547  *          is to delete using decrRef() as it is no more needed.
1548  *  \throw If \a this is not allocated.
1549  *  \throw If the number of components is not in [1,2,3,4].
1550  *
1551  *  \if ENABLE_EXAMPLES
1552  *  \ref py_mcdataarraydouble_getdifferentvalues "Here is a Python example".
1553  *  \endif
1554  */
1555 DataArrayDouble *DataArrayDouble::getDifferentValues(double prec, int limitTupleId) const
1556 {
1557   checkAllocated();
1558   DataArrayInt *c0=0,*cI0=0;
1559   findCommonTuples(prec,limitTupleId,c0,cI0);
1560   MCAuto<DataArrayInt> c(c0),cI(cI0);
1561   int newNbOfTuples=-1;
1562   MCAuto<DataArrayInt> o2n=DataArrayInt::ConvertIndexArrayToO2N(getNumberOfTuples(),c0->begin(),cI0->begin(),cI0->end(),newNbOfTuples);
1563   return renumberAndReduce(o2n->getConstPointer(),newNbOfTuples);
1564 }
1565
1566 /*!
1567  * Copy all components in a specified order from another DataArrayDouble.
1568  * Both numerical and textual data is copied. The number of tuples in \a this and
1569  * the other array can be different.
1570  *  \param [in] a - the array to copy data from.
1571  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
1572  *              to be copied.
1573  *  \throw If \a a is NULL.
1574  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
1575  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
1576  *
1577  *  \if ENABLE_EXAMPLES
1578  *  \ref py_mcdataarraydouble_setselectedcomponents "Here is a Python example".
1579  *  \endif
1580  */
1581 void DataArrayDouble::setSelectedComponents(const DataArrayDouble *a, const std::vector<int>& compoIds)
1582 {
1583   if(!a)
1584     throw INTERP_KERNEL::Exception("DataArrayDouble::setSelectedComponents : input DataArrayDouble is NULL !");
1585   checkAllocated();
1586   copyPartOfStringInfoFrom2(compoIds,*a);
1587   std::size_t partOfCompoSz=compoIds.size();
1588   int nbOfCompo=getNumberOfComponents();
1589   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
1590   const double *ac=a->getConstPointer();
1591   double *nc=getPointer();
1592   for(int i=0;i<nbOfTuples;i++)
1593     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
1594       nc[nbOfCompo*i+compoIds[j]]=*ac;
1595 }
1596
1597 void DataArrayDouble::SetArrayIn(DataArrayDouble *newArray, DataArrayDouble* &arrayToSet)
1598 {
1599   if(newArray!=arrayToSet)
1600     {
1601       if(arrayToSet)
1602         arrayToSet->decrRef();
1603       arrayToSet=newArray;
1604       if(arrayToSet)
1605         arrayToSet->incrRef();
1606     }
1607 }
1608
1609 void DataArrayDouble::aggregate(const DataArrayDouble *other)
1610 {
1611   if(!other)
1612     throw INTERP_KERNEL::Exception("DataArrayDouble::aggregate : null pointer !");
1613   if(getNumberOfComponents()!=other->getNumberOfComponents())
1614     throw INTERP_KERNEL::Exception("DataArrayDouble::aggregate : mismatch number of components !");
1615   _mem.insertAtTheEnd(other->begin(),other->end());
1616 }
1617
1618 /*!
1619  * Checks if 0.0 value is present in \a this array. If it is the case, an exception
1620  * is thrown.
1621  * \throw If zero is found in \a this array.
1622  */
1623 void DataArrayDouble::checkNoNullValues() const
1624 {
1625   const double *tmp=getConstPointer();
1626   std::size_t nbOfElems=getNbOfElems();
1627   const double *where=std::find(tmp,tmp+nbOfElems,0.);
1628   if(where!=tmp+nbOfElems)
1629     throw INTERP_KERNEL::Exception("A value 0.0 have been detected !");
1630 }
1631
1632 /*!
1633  * Computes minimal and maximal value in each component. An output array is filled
1634  * with \c 2 * \a this->getNumberOfComponents() values, so the caller is to allocate
1635  * enough memory before calling this method.
1636  *  \param [out] bounds - array of size at least 2 *\a this->getNumberOfComponents().
1637  *               It is filled as follows:<br>
1638  *               \a bounds[0] = \c min_of_component_0 <br>
1639  *               \a bounds[1] = \c max_of_component_0 <br>
1640  *               \a bounds[2] = \c min_of_component_1 <br>
1641  *               \a bounds[3] = \c max_of_component_1 <br>
1642  *               ...
1643  */
1644 void DataArrayDouble::getMinMaxPerComponent(double *bounds) const
1645 {
1646   checkAllocated();
1647   int dim=getNumberOfComponents();
1648   for (int idim=0; idim<dim; idim++)
1649     {
1650       bounds[idim*2]=std::numeric_limits<double>::max();
1651       bounds[idim*2+1]=-std::numeric_limits<double>::max();
1652     } 
1653   const double *ptr=getConstPointer();
1654   int nbOfTuples=getNumberOfTuples();
1655   for(int i=0;i<nbOfTuples;i++)
1656     {
1657       for(int idim=0;idim<dim;idim++)
1658         {
1659           if(bounds[idim*2]>ptr[i*dim+idim])
1660             {
1661               bounds[idim*2]=ptr[i*dim+idim];
1662             }
1663           if(bounds[idim*2+1]<ptr[i*dim+idim])
1664             {
1665               bounds[idim*2+1]=ptr[i*dim+idim];
1666             }
1667         }
1668     }
1669 }
1670
1671 /*!
1672  * This method retrieves a newly allocated DataArrayDouble instance having same number of tuples than \a this and twice number of components than \a this
1673  * to store both the min and max per component of each tuples. 
1674  * \param [in] epsilon the width of the bbox (identical in each direction) - 0.0 by default
1675  *
1676  * \return a newly created DataArrayDouble instance having \c this->getNumberOfTuples() tuples and 2 * \c this->getNumberOfComponent() components
1677  *
1678  * \throw If \a this is not allocated yet.
1679  */
1680 DataArrayDouble *DataArrayDouble::computeBBoxPerTuple(double epsilon) const
1681 {
1682   checkAllocated();
1683   const double *dataPtr=getConstPointer();
1684   int nbOfCompo=getNumberOfComponents();
1685   int nbTuples=getNumberOfTuples();
1686   MCAuto<DataArrayDouble> bbox=DataArrayDouble::New();
1687   bbox->alloc(nbTuples,2*nbOfCompo);
1688   double *bboxPtr=bbox->getPointer();
1689   for(int i=0;i<nbTuples;i++)
1690     {
1691       for(int j=0;j<nbOfCompo;j++)
1692         {
1693           bboxPtr[2*nbOfCompo*i+2*j]=dataPtr[nbOfCompo*i+j]-epsilon;
1694           bboxPtr[2*nbOfCompo*i+2*j+1]=dataPtr[nbOfCompo*i+j]+epsilon;
1695         }
1696     }
1697   return bbox.retn();
1698 }
1699
1700 /*!
1701  * For each tuples **t** in \a other, this method retrieves tuples in \a this that are equal to **t**.
1702  * Two tuples are considered equal if the euclidian distance between the two tuples is lower than \a eps.
1703  * 
1704  * \param [in] other a DataArrayDouble having same number of components than \a this.
1705  * \param [in] eps absolute precision representing distance (using infinite norm) between 2 tuples behind which 2 tuples are considered equal.
1706  * \param [out] c will contain the set of tuple ids in \a this that are equal to to the tuple ids in \a other contiguously.
1707  *             \a cI allows to extract information in \a c.
1708  * \param [out] cI is an indirection array that allows to extract the data contained in \a c.
1709  *
1710  * \throw In case of:
1711  *  - \a this is not allocated
1712  *  - \a other is not allocated or null
1713  *  - \a this and \a other do not have the same number of components
1714  *  - if number of components of \a this is not in [1,2,3]
1715  *
1716  * \sa MEDCouplingPointSet::getNodeIdsNearPoints, DataArrayDouble::getDifferentValues
1717  */
1718 void DataArrayDouble::computeTupleIdsNearTuples(const DataArrayDouble *other, double eps, DataArrayInt *& c, DataArrayInt *& cI) const
1719 {
1720   if(!other)
1721     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : input pointer other is null !");
1722   checkAllocated();
1723   other->checkAllocated();
1724   int nbOfCompo=getNumberOfComponents();
1725   int otherNbOfCompo=other->getNumberOfComponents();
1726   if(nbOfCompo!=otherNbOfCompo)
1727     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : number of components should be equal between this and other !");
1728   int nbOfTuplesOther=other->getNumberOfTuples();
1729   MCAuto<DataArrayInt> cArr(DataArrayInt::New()),cIArr(DataArrayInt::New()); cArr->alloc(0,1); cIArr->pushBackSilent(0);
1730   switch(nbOfCompo)
1731   {
1732     case 3:
1733       {
1734         BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
1735         FindTupleIdsNearTuplesAlg<3>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
1736         break;
1737       }
1738     case 2:
1739       {
1740         BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
1741         FindTupleIdsNearTuplesAlg<2>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
1742         break;
1743       }
1744     case 1:
1745       {
1746         BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
1747         FindTupleIdsNearTuplesAlg<1>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
1748         break;
1749       }
1750     default:
1751       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for computeTupleIdsNearTuples. Must be 1, 2 or 3.");
1752   }
1753   c=cArr.retn(); cI=cIArr.retn();
1754 }
1755
1756 /*!
1757  * This method recenter tuples in \b this in order to be centered at the origin to benefit about the advantages of maximal precision to be around the box
1758  * around origin of 'radius' 1.
1759  * 
1760  * \param [in] eps absolute epsilon. under that value of delta between max and min no scale is performed.
1761  */
1762 void DataArrayDouble::recenterForMaxPrecision(double eps)
1763 {
1764   checkAllocated();
1765   int dim=getNumberOfComponents();
1766   std::vector<double> bounds(2*dim);
1767   getMinMaxPerComponent(&bounds[0]);
1768   for(int i=0;i<dim;i++)
1769     {
1770       double delta=bounds[2*i+1]-bounds[2*i];
1771       double offset=(bounds[2*i]+bounds[2*i+1])/2.;
1772       if(delta>eps)
1773         applyLin(1./delta,-offset/delta,i);
1774       else
1775         applyLin(1.,-offset,i);
1776     }
1777 }
1778
1779 /*!
1780  * Returns the maximal value and all its locations within \a this one-dimensional array.
1781  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
1782  *               tuples holding the maximal value. The caller is to delete it using
1783  *               decrRef() as it is no more needed.
1784  *  \return double - the maximal value among all values of \a this array.
1785  *  \throw If \a this->getNumberOfComponents() != 1
1786  *  \throw If \a this->getNumberOfTuples() < 1
1787  */
1788 double DataArrayDouble::getMaxValue2(DataArrayInt*& tupleIds) const
1789 {
1790   int tmp;
1791   tupleIds=0;
1792   double ret=getMaxValue(tmp);
1793   tupleIds=findIdsInRange(ret,ret);
1794   return ret;
1795 }
1796
1797 /*!
1798  * Returns the minimal value and all its locations within \a this one-dimensional array.
1799  *  \param [out] tupleIds - a new instance of DataArrayInt containg indices of
1800  *               tuples holding the minimal value. The caller is to delete it using
1801  *               decrRef() as it is no more needed.
1802  *  \return double - the minimal value among all values of \a this array.
1803  *  \throw If \a this->getNumberOfComponents() != 1
1804  *  \throw If \a this->getNumberOfTuples() < 1
1805  */
1806 double DataArrayDouble::getMinValue2(DataArrayInt*& tupleIds) const
1807 {
1808   int tmp;
1809   tupleIds=0;
1810   double ret=getMinValue(tmp);
1811   tupleIds=findIdsInRange(ret,ret);
1812   return ret;
1813 }
1814
1815 /*!
1816  * This method returns the number of values in \a this that are equals ( within an absolute precision of \a eps ) to input parameter \a value.
1817  * This method only works for single component array.
1818  *
1819  * \return a value in [ 0, \c this->getNumberOfTuples() )
1820  *
1821  * \throw If \a this is not allocated
1822  *
1823  */
1824 int DataArrayDouble::count(double value, double eps) const
1825 {
1826   int ret=0;
1827   checkAllocated();
1828   if(getNumberOfComponents()!=1)
1829     throw INTERP_KERNEL::Exception("DataArrayDouble::count : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
1830   const double *vals=begin();
1831   int nbOfTuples=getNumberOfTuples();
1832   for(int i=0;i<nbOfTuples;i++,vals++)
1833     if(fabs(*vals-value)<=eps)
1834       ret++;
1835   return ret;
1836 }
1837
1838 /*!
1839  * Returns the average value of \a this one-dimensional array.
1840  *  \return double - the average value over all values of \a this array.
1841  *  \throw If \a this->getNumberOfComponents() != 1
1842  *  \throw If \a this->getNumberOfTuples() < 1
1843  */
1844 double DataArrayDouble::getAverageValue() const
1845 {
1846   if(getNumberOfComponents()!=1)
1847     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
1848   int nbOfTuples=getNumberOfTuples();
1849   if(nbOfTuples<=0)
1850     throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : array exists but number of tuples must be > 0 !");
1851   const double *vals=getConstPointer();
1852   double ret=std::accumulate(vals,vals+nbOfTuples,0.);
1853   return ret/nbOfTuples;
1854 }
1855
1856 /*!
1857  * Returns the Euclidean norm of the vector defined by \a this array.
1858  *  \return double - the value of the Euclidean norm, i.e.
1859  *          the square root of the inner product of vector.
1860  *  \throw If \a this is not allocated.
1861  */
1862 double DataArrayDouble::norm2() const
1863 {
1864   checkAllocated();
1865   double ret=0.;
1866   std::size_t nbOfElems=getNbOfElems();
1867   const double *pt=getConstPointer();
1868   for(std::size_t i=0;i<nbOfElems;i++,pt++)
1869     ret+=(*pt)*(*pt);
1870   return sqrt(ret);
1871 }
1872
1873 /*!
1874  * Returns the maximum norm of the vector defined by \a this array.
1875  * This method works even if the number of components is diferent from one.
1876  * If the number of elements in \a this is 0, -1. is returned.
1877  *  \return double - the value of the maximum norm, i.e.
1878  *          the maximal absolute value among values of \a this array (whatever its number of components).
1879  *  \throw If \a this is not allocated.
1880  */
1881 double DataArrayDouble::normMax() const
1882 {
1883   checkAllocated();
1884   double ret(-1.);
1885   std::size_t nbOfElems(getNbOfElems());
1886   const double *pt(getConstPointer());
1887   for(std::size_t i=0;i<nbOfElems;i++,pt++)
1888     {
1889       double val(std::abs(*pt));
1890       if(val>ret)
1891         ret=val;
1892     }
1893   return ret;
1894 }
1895
1896 /*!
1897  * Returns the minimum norm (absolute value) of the vector defined by \a this array.
1898  * This method works even if the number of components is diferent from one.
1899  * If the number of elements in \a this is 0, std::numeric_limits<double>::max() is returned.
1900  *  \return double - the value of the minimum norm, i.e.
1901  *          the minimal absolute value among values of \a this array (whatever its number of components).
1902  *  \throw If \a this is not allocated.
1903  */
1904 double DataArrayDouble::normMin() const
1905 {
1906   checkAllocated();
1907   double ret(std::numeric_limits<double>::max());
1908   std::size_t nbOfElems(getNbOfElems());
1909   const double *pt(getConstPointer());
1910   for(std::size_t i=0;i<nbOfElems;i++,pt++)
1911     {
1912       double val(std::abs(*pt));
1913       if(val<ret)
1914         ret=val;
1915     }
1916   return ret;
1917 }
1918
1919 /*!
1920  * Accumulates values of each component of \a this array.
1921  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
1922  *         by the caller, that is filled by this method with sum value for each
1923  *         component.
1924  *  \throw If \a this is not allocated.
1925  */
1926 void DataArrayDouble::accumulate(double *res) const
1927 {
1928   checkAllocated();
1929   const double *ptr=getConstPointer();
1930   int nbTuple=getNumberOfTuples();
1931   int nbComps=getNumberOfComponents();
1932   std::fill(res,res+nbComps,0.);
1933   for(int i=0;i<nbTuple;i++)
1934     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<double>());
1935 }
1936
1937 /*!
1938  * This method returns the min distance from an external tuple defined by [ \a tupleBg , \a tupleEnd ) to \a this and
1939  * the first tuple in \a this that matches the returned distance. If there is no tuples in \a this an exception will be thrown.
1940  *
1941  *
1942  * \a this is expected to be allocated and expected to have a number of components equal to the distance from \a tupleBg to
1943  * \a tupleEnd. If not an exception will be thrown.
1944  *
1945  * \param [in] tupleBg start pointer (included) of input external tuple
1946  * \param [in] tupleEnd end pointer (not included) of input external tuple
1947  * \param [out] tupleId the tuple id in \a this that matches the min of distance between \a this and input external tuple
1948  * \return the min distance.
1949  * \sa MEDCouplingUMesh::distanceToPoint
1950  */
1951 double DataArrayDouble::distanceToTuple(const double *tupleBg, const double *tupleEnd, int& tupleId) const
1952 {
1953   checkAllocated();
1954   int nbTuple=getNumberOfTuples();
1955   int nbComps=getNumberOfComponents();
1956   if(nbComps!=(int)std::distance(tupleBg,tupleEnd))
1957     { std::ostringstream oss; oss << "DataArrayDouble::distanceToTuple : size of input tuple is " << std::distance(tupleBg,tupleEnd) << " should be equal to the number of components in this : " << nbComps << " !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); }
1958   if(nbTuple==0)
1959     throw INTERP_KERNEL::Exception("DataArrayDouble::distanceToTuple : no tuple in this ! No distance to compute !");
1960   double ret0=std::numeric_limits<double>::max();
1961   tupleId=-1;
1962   const double *work=getConstPointer();
1963   for(int i=0;i<nbTuple;i++)
1964     {
1965       double val=0.;
1966       for(int j=0;j<nbComps;j++,work++) 
1967         val+=(*work-tupleBg[j])*((*work-tupleBg[j]));
1968       if(val>=ret0)
1969         continue;
1970       else
1971         { ret0=val; tupleId=i; }
1972     }
1973   return sqrt(ret0);
1974 }
1975
1976 /*!
1977  * Accumulate values of the given component of \a this array.
1978  *  \param [in] compId - the index of the component of interest.
1979  *  \return double - a sum value of \a compId-th component.
1980  *  \throw If \a this is not allocated.
1981  *  \throw If \a the condition ( 0 <= \a compId < \a this->getNumberOfComponents() ) is
1982  *         not respected.
1983  */
1984 double DataArrayDouble::accumulate(int compId) const
1985 {
1986   checkAllocated();
1987   const double *ptr=getConstPointer();
1988   int nbTuple=getNumberOfTuples();
1989   int nbComps=getNumberOfComponents();
1990   if(compId<0 || compId>=nbComps)
1991     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulate : Invalid compId specified : No such nb of components !");
1992   double ret=0.;
1993   for(int i=0;i<nbTuple;i++)
1994     ret+=ptr[i*nbComps+compId];
1995   return ret;
1996 }
1997
1998 /*!
1999  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
2000  * The returned array will have same number of components than \a this and number of tuples equal to
2001  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
2002  *
2003  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
2004  * This method is quite useful for users that need to put a field on cells to field on nodes on the same mesh without a need of conservation.
2005  *
2006  * \param [in] bgOfIndex - begin (included) of the input index array.
2007  * \param [in] endOfIndex - end (excluded) of the input index array.
2008  * \return DataArrayDouble * - the new instance having the same number of components than \a this.
2009  * 
2010  * \throw If bgOfIndex or end is NULL.
2011  * \throw If input index array is not ascendingly sorted.
2012  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
2013  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
2014  */
2015 DataArrayDouble *DataArrayDouble::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
2016 {
2017   if(!bgOfIndex || !endOfIndex)
2018     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : input pointer NULL !");
2019   checkAllocated();
2020   int nbCompo=getNumberOfComponents();
2021   int nbOfTuples=getNumberOfTuples();
2022   int sz=(int)std::distance(bgOfIndex,endOfIndex);
2023   if(sz<1)
2024     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : invalid size of input index array !");
2025   sz--;
2026   MCAuto<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(sz,nbCompo);
2027   const int *w=bgOfIndex;
2028   if(*w<0 || *w>=nbOfTuples)
2029     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
2030   const double *srcPt=begin()+(*w)*nbCompo;
2031   double *tmp=ret->getPointer();
2032   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
2033     {
2034       std::fill(tmp,tmp+nbCompo,0.);
2035       if(w[1]>=w[0])
2036         {
2037           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
2038             {
2039               if(j>=0 && j<nbOfTuples)
2040                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<double>());
2041               else
2042                 {
2043                   std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
2044                   throw INTERP_KERNEL::Exception(oss.str().c_str());
2045                 }
2046             }
2047         }
2048       else
2049         {
2050           std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
2051           throw INTERP_KERNEL::Exception(oss.str().c_str());
2052         }
2053     }
2054   ret->copyStringInfoFrom(*this);
2055   return ret.retn();
2056 }
2057
2058 /*!
2059  * 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.
2060  * This method expects that \a this as only one component. The returned array will have \a this->getNumberOfTuples()+1 tuple with also one component.
2061  * The ith element of returned array is equal to the sum of elements in \a this with rank strictly lower than i.
2062  *
2063  * \return DataArrayDouble - A newly built array containing cum sum of \a this.
2064  */
2065 MCAuto<DataArrayDouble> DataArrayDouble::cumSum() const
2066 {
2067   checkAllocated();
2068   checkNbOfComps(1,"DataArrayDouble::cumSum : this is expected to be single component");
2069   int nbOfTuple(getNumberOfTuples());
2070   MCAuto<DataArrayDouble> ret(DataArrayDouble::New()); ret->alloc(nbOfTuple+1,1);
2071   double *ptr(ret->getPointer());
2072   ptr[0]=0.;
2073   const double *thisPtr(begin());
2074   for(int i=0;i<nbOfTuple;i++)
2075     ptr[i+1]=ptr[i]+thisPtr[i];
2076   return ret;
2077 }
2078
2079 /*!
2080  * Converts each 2D point defined by the tuple of \a this array from the Polar to the
2081  * Cartesian coordinate system. The two components of the tuple of \a this array are 
2082  * considered to contain (1) radius and (2) angle of the point in the Polar CS.
2083  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
2084  *          contains X and Y coordinates of the point in the Cartesian CS. The caller
2085  *          is to delete this array using decrRef() as it is no more needed. The array
2086  *          does not contain any textual info on components.
2087  *  \throw If \a this->getNumberOfComponents() != 2.
2088  * \sa fromCartToPolar
2089  */
2090 DataArrayDouble *DataArrayDouble::fromPolarToCart() const
2091 {
2092   checkAllocated();
2093   int nbOfComp(getNumberOfComponents());
2094   if(nbOfComp!=2)
2095     throw INTERP_KERNEL::Exception("DataArrayDouble::fromPolarToCart : must be an array with exactly 2 components !");
2096   int nbOfTuple(getNumberOfTuples());
2097   DataArrayDouble *ret(DataArrayDouble::New());
2098   ret->alloc(nbOfTuple,2);
2099   double *w(ret->getPointer());
2100   const double *wIn(getConstPointer());
2101   for(int i=0;i<nbOfTuple;i++,w+=2,wIn+=2)
2102     {
2103       w[0]=wIn[0]*cos(wIn[1]);
2104       w[1]=wIn[0]*sin(wIn[1]);
2105     }
2106   return ret;
2107 }
2108
2109 /*!
2110  * Converts each 3D point defined by the tuple of \a this array from the Cylindrical to
2111  * the Cartesian coordinate system. The three components of the tuple of \a this array 
2112  * are considered to contain (1) radius, (2) azimuth and (3) altitude of the point in
2113  * the Cylindrical CS.
2114  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
2115  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
2116  *          on the third component is copied from \a this array. The caller
2117  *          is to delete this array using decrRef() as it is no more needed. 
2118  *  \throw If \a this->getNumberOfComponents() != 3.
2119  * \sa fromCartToCyl
2120  */
2121 DataArrayDouble *DataArrayDouble::fromCylToCart() const
2122 {
2123   checkAllocated();
2124   int nbOfComp(getNumberOfComponents());
2125   if(nbOfComp!=3)
2126     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCylToCart : must be an array with exactly 3 components !");
2127   int nbOfTuple(getNumberOfTuples());
2128   DataArrayDouble *ret(DataArrayDouble::New());
2129   ret->alloc(getNumberOfTuples(),3);
2130   double *w(ret->getPointer());
2131   const double *wIn(getConstPointer());
2132   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
2133     {
2134       w[0]=wIn[0]*cos(wIn[1]);
2135       w[1]=wIn[0]*sin(wIn[1]);
2136       w[2]=wIn[2];
2137     }
2138   ret->setInfoOnComponent(2,getInfoOnComponent(2));
2139   return ret;
2140 }
2141
2142 /*!
2143  * Converts each 3D point defined by the tuple of \a this array from the Spherical to
2144  * the Cartesian coordinate system. The three components of the tuple of \a this array 
2145  * are considered to contain (1) radius, (2) polar angle and (3) azimuthal angle of the
2146  * point in the Cylindrical CS.
2147  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
2148  *          contains X, Y and Z coordinates of the point in the Cartesian CS. The info
2149  *          on the third component is copied from \a this array. The caller
2150  *          is to delete this array using decrRef() as it is no more needed.
2151  *  \throw If \a this->getNumberOfComponents() != 3.
2152  * \sa fromCartToSpher
2153  */
2154 DataArrayDouble *DataArrayDouble::fromSpherToCart() const
2155 {
2156   checkAllocated();
2157   int nbOfComp(getNumberOfComponents());
2158   if(nbOfComp!=3)
2159     throw INTERP_KERNEL::Exception("DataArrayDouble::fromSpherToCart : must be an array with exactly 3 components !");
2160   int nbOfTuple(getNumberOfTuples());
2161   DataArrayDouble *ret(DataArrayDouble::New());
2162   ret->alloc(getNumberOfTuples(),3);
2163   double *w(ret->getPointer());
2164   const double *wIn(getConstPointer());
2165   for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
2166     {
2167       w[0]=wIn[0]*cos(wIn[2])*sin(wIn[1]);
2168       w[1]=wIn[0]*sin(wIn[2])*sin(wIn[1]);
2169       w[2]=wIn[0]*cos(wIn[1]);
2170     }
2171   return ret;
2172 }
2173
2174 /*!
2175  * 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.
2176  * 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.
2177  * If \a at equals to AX_CYL the returned array will be the result of operation cylindric to cartesian of \a this...
2178  *
2179  * \param [in] atOfThis - The axis type of \a this.
2180  * \return DataArrayDouble * - the new instance of DataArrayDouble (that must be dealed by caller) containing the result of the cartesianizification of \a this.
2181  */
2182 DataArrayDouble *DataArrayDouble::cartesianize(MEDCouplingAxisType atOfThis) const
2183 {
2184   checkAllocated();
2185   int nbOfComp(getNumberOfComponents());
2186   MCAuto<DataArrayDouble> ret;
2187   switch(atOfThis)
2188     {
2189     case AX_CART:
2190       ret=deepCopy();
2191     case AX_CYL:
2192       if(nbOfComp==3)
2193         {
2194           ret=fromCylToCart();
2195           break;
2196         }
2197       if(nbOfComp==2)
2198         {
2199           ret=fromPolarToCart();
2200           break;
2201         }
2202       else
2203         throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : For AX_CYL, number of components must be in [2,3] !");
2204     case AX_SPHER:
2205       if(nbOfComp==3)
2206         {
2207           ret=fromSpherToCart();
2208           break;
2209         }
2210       if(nbOfComp==2)
2211         {
2212           ret=fromPolarToCart();
2213           break;
2214         }
2215       else
2216         throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : For AX_CYL, number of components must be in [2,3] !");
2217     default:
2218       throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : not recognized axis type ! Only AX_CART, AX_CYL and AX_SPHER supported !");
2219     }
2220   ret->copyStringInfoFrom(*this);
2221   return ret.retn();
2222 }
2223
2224 /*!
2225  * This method returns a newly created array to be deallocated that contains the result of conversion from cartesian to polar.
2226  * This method expects that \a this has exactly 2 components.
2227  * \sa fromPolarToCart
2228  */
2229 DataArrayDouble *DataArrayDouble::fromCartToPolar() const
2230 {
2231   MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2232   checkAllocated();
2233   int nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2234   if(nbOfComp!=2)
2235     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToPolar : must be an array with exactly 2 components !");
2236   ret->alloc(nbTuples,2);
2237   double *retPtr(ret->getPointer());
2238   const double *ptr(begin());
2239   for(int i=0;i<nbTuples;i++,ptr+=2,retPtr+=2)
2240     {
2241       retPtr[0]=sqrt(ptr[0]*ptr[0]+ptr[1]*ptr[1]);
2242       retPtr[1]=atan2(ptr[1],ptr[0]);
2243     }
2244   return ret.retn();
2245 }
2246
2247 /*!
2248  * This method returns a newly created array to be deallocated that contains the result of conversion from cartesian to cylindrical.
2249  * This method expects that \a this has exactly 3 components.
2250  * \sa fromCylToCart
2251  */
2252 DataArrayDouble *DataArrayDouble::fromCartToCyl() const
2253 {
2254   MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2255   checkAllocated();
2256   int nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2257   if(nbOfComp!=3)
2258     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCyl : must be an array with exactly 3 components !");
2259   ret->alloc(nbTuples,3);
2260   double *retPtr(ret->getPointer());
2261   const double *ptr(begin());
2262   for(int i=0;i<nbTuples;i++,ptr+=3,retPtr+=3)
2263     {
2264       retPtr[0]=sqrt(ptr[0]*ptr[0]+ptr[1]*ptr[1]);
2265       retPtr[1]=atan2(ptr[1],ptr[0]);
2266       retPtr[2]=ptr[2];
2267     }
2268   return ret.retn();
2269 }
2270
2271 /*!
2272  * This method returns a newly created array to be deallocated that contains the result of conversion from cartesian to spherical coordinates.
2273  * \sa fromSpherToCart
2274  */
2275 DataArrayDouble *DataArrayDouble::fromCartToSpher() const
2276 {
2277   MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2278   checkAllocated();
2279   int nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2280   if(nbOfComp!=3)
2281     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToSpher : must be an array with exactly 3 components !");
2282   ret->alloc(nbTuples,3);
2283   double *retPtr(ret->getPointer());
2284   const double *ptr(begin());
2285   for(int i=0;i<nbTuples;i++,ptr+=3,retPtr+=3)
2286     {
2287       retPtr[0]=sqrt(ptr[0]*ptr[0]+ptr[1]*ptr[1]+ptr[2]*ptr[2]);
2288       retPtr[1]=acos(ptr[2]/retPtr[0]);
2289       retPtr[2]=atan2(ptr[1],ptr[0]);
2290     }
2291   return ret.retn();
2292 }
2293
2294 /*!
2295  * 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.
2296  * This method expects that \a this has exactly 3 components.
2297  * \sa MEDCouplingFieldDouble::computeVectorFieldCyl
2298  */
2299 DataArrayDouble *DataArrayDouble::fromCartToCylGiven(const DataArrayDouble *coords, const double center[3], const double vect[3]) const
2300 {
2301   if(!coords)
2302     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : input coords are NULL !");
2303   MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2304   checkAllocated(); coords->checkAllocated();
2305   int nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2306   if(nbOfComp!=3)
2307     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : must be an array with exactly 3 components !");
2308   if(coords->getNumberOfComponents()!=3)
2309     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : coords array must have exactly 3 components !");
2310   if(coords->getNumberOfTuples()!=nbTuples)
2311     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : coords array must have the same number of tuples !");
2312   ret->alloc(nbTuples,nbOfComp);
2313   double magOfVect(sqrt(vect[0]*vect[0]+vect[1]*vect[1]+vect[2]*vect[2]));
2314   if(magOfVect<1e-12)
2315     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : magnitude of vect is too low !");
2316   double Ur[3],Uteta[3],Uz[3],*retPtr(ret->getPointer());
2317   const double *coo(coords->begin()),*vectField(begin());
2318   std::transform(vect,vect+3,Uz,std::bind2nd(std::multiplies<double>(),1./magOfVect));
2319   for(int i=0;i<nbTuples;i++,vectField+=3,retPtr+=3,coo+=3)
2320     {
2321       std::transform(coo,coo+3,center,Ur,std::minus<double>());
2322       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];
2323       double magOfTeta(sqrt(Uteta[0]*Uteta[0]+Uteta[1]*Uteta[1]+Uteta[2]*Uteta[2]));
2324       std::transform(Uteta,Uteta+3,Uteta,std::bind2nd(std::multiplies<double>(),1./magOfTeta));
2325       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];
2326       retPtr[0]=Ur[0]*vectField[0]+Ur[1]*vectField[1]+Ur[2]*vectField[2];
2327       retPtr[1]=Uteta[0]*vectField[0]+Uteta[1]*vectField[1]+Uteta[2]*vectField[2];
2328       retPtr[2]=Uz[0]*vectField[0]+Uz[1]*vectField[1]+Uz[2]*vectField[2];
2329     }
2330   ret->copyStringInfoFrom(*this);
2331   return ret.retn();
2332 }
2333
2334 /*!
2335  * Computes the doubly contracted product of every tensor defined by the tuple of \a this
2336  * array contating 6 components.
2337  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
2338  *          is calculated from the tuple <em>(t)</em> of \a this array as follows:
2339  *          \f$ t[0]^2+t[1]^2+t[2]^2+2*t[3]^2+2*t[4]^2+2*t[5]^2\f$.
2340  *         The caller is to delete this result array using decrRef() as it is no more needed. 
2341  *  \throw If \a this->getNumberOfComponents() != 6.
2342  */
2343 DataArrayDouble *DataArrayDouble::doublyContractedProduct() const
2344 {
2345   checkAllocated();
2346   int nbOfComp(getNumberOfComponents());
2347   if(nbOfComp!=6)
2348     throw INTERP_KERNEL::Exception("DataArrayDouble::doublyContractedProduct : must be an array with exactly 6 components !");
2349   DataArrayDouble *ret=DataArrayDouble::New();
2350   int nbOfTuple=getNumberOfTuples();
2351   ret->alloc(nbOfTuple,1);
2352   const double *src=getConstPointer();
2353   double *dest=ret->getPointer();
2354   for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
2355     *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];
2356   return ret;
2357 }
2358
2359 /*!
2360  * Computes the determinant of every square matrix defined by the tuple of \a this
2361  * array, which contains either 4, 6 or 9 components. The case of 6 components
2362  * corresponds to that of the upper triangular matrix.
2363  *  \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
2364  *          is the determinant of matrix of the corresponding tuple of \a this array.
2365  *          The caller is to delete this result array using decrRef() as it is no more
2366  *          needed. 
2367  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2368  */
2369 DataArrayDouble *DataArrayDouble::determinant() const
2370 {
2371   checkAllocated();
2372   DataArrayDouble *ret=DataArrayDouble::New();
2373   int nbOfTuple=getNumberOfTuples();
2374   ret->alloc(nbOfTuple,1);
2375   const double *src=getConstPointer();
2376   double *dest=ret->getPointer();
2377   switch(getNumberOfComponents())
2378   {
2379     case 6:
2380       for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
2381         *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];
2382       return ret;
2383     case 4:
2384       for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
2385         *dest=src[0]*src[3]-src[1]*src[2];
2386       return ret;
2387     case 9:
2388       for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
2389         *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];
2390       return ret;
2391     default:
2392       ret->decrRef();
2393       throw INTERP_KERNEL::Exception("DataArrayDouble::determinant : Invalid number of components ! must be in 4,6,9 !");
2394   }
2395 }
2396
2397 /*!
2398  * Computes 3 eigenvalues of every upper triangular matrix defined by the tuple of
2399  * \a this array, which contains 6 components.
2400  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 3
2401  *          components, whose each tuple contains the eigenvalues of the matrix of
2402  *          corresponding tuple of \a this array. 
2403  *          The caller is to delete this result array using decrRef() as it is no more
2404  *          needed. 
2405  *  \throw If \a this->getNumberOfComponents() != 6.
2406  */
2407 DataArrayDouble *DataArrayDouble::eigenValues() const
2408 {
2409   checkAllocated();
2410   int nbOfComp=getNumberOfComponents();
2411   if(nbOfComp!=6)
2412     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenValues : must be an array with exactly 6 components !");
2413   DataArrayDouble *ret=DataArrayDouble::New();
2414   int nbOfTuple=getNumberOfTuples();
2415   ret->alloc(nbOfTuple,3);
2416   const double *src=getConstPointer();
2417   double *dest=ret->getPointer();
2418   for(int i=0;i<nbOfTuple;i++,dest+=3,src+=6)
2419     INTERP_KERNEL::computeEigenValues6(src,dest);
2420   return ret;
2421 }
2422
2423 /*!
2424  * Computes 3 eigenvectors of every upper triangular matrix defined by the tuple of
2425  * \a this array, which contains 6 components.
2426  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 9
2427  *          components, whose each tuple contains 3 eigenvectors of the matrix of
2428  *          corresponding tuple of \a this array.
2429  *          The caller is to delete this result array using decrRef() as it is no more
2430  *          needed.
2431  *  \throw If \a this->getNumberOfComponents() != 6.
2432  */
2433 DataArrayDouble *DataArrayDouble::eigenVectors() const
2434 {
2435   checkAllocated();
2436   int nbOfComp=getNumberOfComponents();
2437   if(nbOfComp!=6)
2438     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenVectors : must be an array with exactly 6 components !");
2439   DataArrayDouble *ret=DataArrayDouble::New();
2440   int nbOfTuple=getNumberOfTuples();
2441   ret->alloc(nbOfTuple,9);
2442   const double *src=getConstPointer();
2443   double *dest=ret->getPointer();
2444   for(int i=0;i<nbOfTuple;i++,src+=6)
2445     {
2446       double tmp[3];
2447       INTERP_KERNEL::computeEigenValues6(src,tmp);
2448       for(int j=0;j<3;j++,dest+=3)
2449         INTERP_KERNEL::computeEigenVectorForEigenValue6(src,tmp[j],1e-12,dest);
2450     }
2451   return ret;
2452 }
2453
2454 /*!
2455  * Computes the inverse matrix of every matrix defined by the tuple of \a this
2456  * array, which contains either 4, 6 or 9 components. The case of 6 components
2457  * corresponds to that of the upper triangular matrix.
2458  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2459  *          same number of components as \a this one, whose each tuple is the inverse
2460  *          matrix of the matrix of corresponding tuple of \a this array. 
2461  *          The caller is to delete this result array using decrRef() as it is no more
2462  *          needed. 
2463  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2464  */
2465 DataArrayDouble *DataArrayDouble::inverse() const
2466 {
2467   checkAllocated();
2468   int nbOfComp=getNumberOfComponents();
2469   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
2470     throw INTERP_KERNEL::Exception("DataArrayDouble::inversion : must be an array with 4,6 or 9 components !");
2471   DataArrayDouble *ret=DataArrayDouble::New();
2472   int nbOfTuple=getNumberOfTuples();
2473   ret->alloc(nbOfTuple,nbOfComp);
2474   const double *src=getConstPointer();
2475   double *dest=ret->getPointer();
2476   if(nbOfComp==6)
2477     for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
2478       {
2479         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];
2480         dest[0]=(src[1]*src[2]-src[4]*src[4])/det;
2481         dest[1]=(src[0]*src[2]-src[5]*src[5])/det;
2482         dest[2]=(src[0]*src[1]-src[3]*src[3])/det;
2483         dest[3]=(src[5]*src[4]-src[3]*src[2])/det;
2484         dest[4]=(src[5]*src[3]-src[0]*src[4])/det;
2485         dest[5]=(src[3]*src[4]-src[1]*src[5])/det;
2486       }
2487   else if(nbOfComp==4)
2488     for(int i=0;i<nbOfTuple;i++,dest+=4,src+=4)
2489       {
2490         double det=src[0]*src[3]-src[1]*src[2];
2491         dest[0]=src[3]/det;
2492         dest[1]=-src[1]/det;
2493         dest[2]=-src[2]/det;
2494         dest[3]=src[0]/det;
2495       }
2496   else
2497     for(int i=0;i<nbOfTuple;i++,dest+=9,src+=9)
2498       {
2499         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];
2500         dest[0]=(src[4]*src[8]-src[7]*src[5])/det;
2501         dest[1]=(src[7]*src[2]-src[1]*src[8])/det;
2502         dest[2]=(src[1]*src[5]-src[4]*src[2])/det;
2503         dest[3]=(src[6]*src[5]-src[3]*src[8])/det;
2504         dest[4]=(src[0]*src[8]-src[6]*src[2])/det;
2505         dest[5]=(src[2]*src[3]-src[0]*src[5])/det;
2506         dest[6]=(src[3]*src[7]-src[6]*src[4])/det;
2507         dest[7]=(src[6]*src[1]-src[0]*src[7])/det;
2508         dest[8]=(src[0]*src[4]-src[1]*src[3])/det;
2509       }
2510   return ret;
2511 }
2512
2513 /*!
2514  * Computes the trace of every matrix defined by the tuple of \a this
2515  * array, which contains either 4, 6 or 9 components. The case of 6 components
2516  * corresponds to that of the upper triangular matrix.
2517  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing 
2518  *          1 component, whose each tuple is the trace of
2519  *          the matrix of corresponding tuple of \a this array. 
2520  *          The caller is to delete this result array using decrRef() as it is no more
2521  *          needed. 
2522  *  \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2523  */
2524 DataArrayDouble *DataArrayDouble::trace() const
2525 {
2526   checkAllocated();
2527   int nbOfComp=getNumberOfComponents();
2528   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
2529     throw INTERP_KERNEL::Exception("DataArrayDouble::trace : must be an array with 4,6 or 9 components !");
2530   DataArrayDouble *ret=DataArrayDouble::New();
2531   int nbOfTuple=getNumberOfTuples();
2532   ret->alloc(nbOfTuple,1);
2533   const double *src=getConstPointer();
2534   double *dest=ret->getPointer();
2535   if(nbOfComp==6)
2536     for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
2537       *dest=src[0]+src[1]+src[2];
2538   else if(nbOfComp==4)
2539     for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
2540       *dest=src[0]+src[3];
2541   else
2542     for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
2543       *dest=src[0]+src[4]+src[8];
2544   return ret;
2545 }
2546
2547 /*!
2548  * Computes the stress deviator tensor of every stress tensor defined by the tuple of
2549  * \a this array, which contains 6 components.
2550  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2551  *          same number of components and tuples as \a this array.
2552  *          The caller is to delete this result array using decrRef() as it is no more
2553  *          needed.
2554  *  \throw If \a this->getNumberOfComponents() != 6.
2555  */
2556 DataArrayDouble *DataArrayDouble::deviator() const
2557 {
2558   checkAllocated();
2559   int nbOfComp=getNumberOfComponents();
2560   if(nbOfComp!=6)
2561     throw INTERP_KERNEL::Exception("DataArrayDouble::deviator : must be an array with exactly 6 components !");
2562   DataArrayDouble *ret=DataArrayDouble::New();
2563   int nbOfTuple=getNumberOfTuples();
2564   ret->alloc(nbOfTuple,6);
2565   const double *src=getConstPointer();
2566   double *dest=ret->getPointer();
2567   for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
2568     {
2569       double tr=(src[0]+src[1]+src[2])/3.;
2570       dest[0]=src[0]-tr;
2571       dest[1]=src[1]-tr;
2572       dest[2]=src[2]-tr;
2573       dest[3]=src[3];
2574       dest[4]=src[4];
2575       dest[5]=src[5];
2576     }
2577   return ret;
2578 }
2579
2580 /*!
2581  * Computes the magnitude of every vector defined by the tuple of
2582  * \a this array.
2583  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2584  *          same number of tuples as \a this array and one component.
2585  *          The caller is to delete this result array using decrRef() as it is no more
2586  *          needed.
2587  *  \throw If \a this is not allocated.
2588  */
2589 DataArrayDouble *DataArrayDouble::magnitude() const
2590 {
2591   checkAllocated();
2592   int nbOfComp=getNumberOfComponents();
2593   DataArrayDouble *ret=DataArrayDouble::New();
2594   int nbOfTuple=getNumberOfTuples();
2595   ret->alloc(nbOfTuple,1);
2596   const double *src=getConstPointer();
2597   double *dest=ret->getPointer();
2598   for(int i=0;i<nbOfTuple;i++,dest++)
2599     {
2600       double sum=0.;
2601       for(int j=0;j<nbOfComp;j++,src++)
2602         sum+=(*src)*(*src);
2603       *dest=sqrt(sum);
2604     }
2605   return ret;
2606 }
2607
2608 /*!
2609  * Computes for each tuple the sum of number of components values in the tuple and return it.
2610  * 
2611  * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2612  *          same number of tuples as \a this array and one component.
2613  *          The caller is to delete this result array using decrRef() as it is no more
2614  *          needed.
2615  *  \throw If \a this is not allocated.
2616  */
2617 DataArrayDouble *DataArrayDouble::sumPerTuple() const
2618 {
2619   checkAllocated();
2620   int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
2621   MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2622   ret->alloc(nbOfTuple,1);
2623   const double *src(getConstPointer());
2624   double *dest(ret->getPointer());
2625   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
2626     *dest=std::accumulate(src,src+nbOfComp,0.);
2627   return ret.retn();
2628 }
2629
2630 /*!
2631  * Computes the maximal value within every tuple of \a this array.
2632  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2633  *          same number of tuples as \a this array and one component.
2634  *          The caller is to delete this result array using decrRef() as it is no more
2635  *          needed.
2636  *  \throw If \a this is not allocated.
2637  *  \sa DataArrayDouble::maxPerTupleWithCompoId
2638  */
2639 DataArrayDouble *DataArrayDouble::maxPerTuple() const
2640 {
2641   checkAllocated();
2642   int nbOfComp=getNumberOfComponents();
2643   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
2644   int nbOfTuple=getNumberOfTuples();
2645   ret->alloc(nbOfTuple,1);
2646   const double *src=getConstPointer();
2647   double *dest=ret->getPointer();
2648   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
2649     *dest=*std::max_element(src,src+nbOfComp);
2650   return ret.retn();
2651 }
2652
2653 /*!
2654  * Computes the maximal value within every tuple of \a this array and it returns the first component
2655  * id for each tuple that corresponds to the maximal value within the tuple.
2656  * 
2657  *  \param [out] compoIdOfMaxPerTuple - the new new instance of DataArrayInt containing the
2658  *          same number of tuples and only one component.
2659  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2660  *          same number of tuples as \a this array and one component.
2661  *          The caller is to delete this result array using decrRef() as it is no more
2662  *          needed.
2663  *  \throw If \a this is not allocated.
2664  *  \sa DataArrayDouble::maxPerTuple
2665  */
2666 DataArrayDouble *DataArrayDouble::maxPerTupleWithCompoId(DataArrayInt* &compoIdOfMaxPerTuple) const
2667 {
2668   checkAllocated();
2669   int nbOfComp=getNumberOfComponents();
2670   MCAuto<DataArrayDouble> ret0=DataArrayDouble::New();
2671   MCAuto<DataArrayInt> ret1=DataArrayInt::New();
2672   int nbOfTuple=getNumberOfTuples();
2673   ret0->alloc(nbOfTuple,1); ret1->alloc(nbOfTuple,1);
2674   const double *src=getConstPointer();
2675   double *dest=ret0->getPointer(); int *dest1=ret1->getPointer();
2676   for(int i=0;i<nbOfTuple;i++,dest++,dest1++,src+=nbOfComp)
2677     {
2678       const double *loc=std::max_element(src,src+nbOfComp);
2679       *dest=*loc;
2680       *dest1=(int)std::distance(src,loc);
2681     }
2682   compoIdOfMaxPerTuple=ret1.retn();
2683   return ret0.retn();
2684 }
2685
2686 /*!
2687  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c this->getNumberOfTuples() tuples.
2688  * \n This returned array contains the euclidian distance for each tuple in \a this. 
2689  * \n So the returned array can be seen as a dense symmetrical matrix whose diagonal elements are equal to 0.
2690  * \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)
2691  *
2692  * \warning use this method with care because it can leads to big amount of consumed memory !
2693  * 
2694  * \return A newly allocated (huge) MEDCoupling::DataArrayDouble instance that the caller should deal with.
2695  *
2696  * \throw If \a this is not allocated.
2697  *
2698  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrixWith
2699  */
2700 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrix() const
2701 {
2702   checkAllocated();
2703   int nbOfComp=getNumberOfComponents();
2704   int nbOfTuples=getNumberOfTuples();
2705   const double *inData=getConstPointer();
2706   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
2707   ret->alloc(nbOfTuples*nbOfTuples,1);
2708   double *outData=ret->getPointer();
2709   for(int i=0;i<nbOfTuples;i++)
2710     {
2711       outData[i*nbOfTuples+i]=0.;
2712       for(int j=i+1;j<nbOfTuples;j++)
2713         {
2714           double dist=0.;
2715           for(int k=0;k<nbOfComp;k++)
2716             { double delta=inData[i*nbOfComp+k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
2717           dist=sqrt(dist);
2718           outData[i*nbOfTuples+j]=dist;
2719           outData[j*nbOfTuples+i]=dist;
2720         }
2721     }
2722   return ret.retn();
2723 }
2724
2725 /*!
2726  * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c other->getNumberOfTuples() tuples.
2727  * \n This returned array contains the euclidian distance for each tuple in \a other with each tuple in \a this. 
2728  * \n So the returned array can be seen as a dense rectangular matrix with \c other->getNumberOfTuples() rows and \c this->getNumberOfTuples() columns.
2729  * \n Output rectangular matrix is sorted along rows.
2730  * \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)
2731  *
2732  * \warning use this method with care because it can leads to big amount of consumed memory !
2733  * 
2734  * \param [in] other DataArrayDouble instance having same number of components than \a this.
2735  * \return A newly allocated (huge) MEDCoupling::DataArrayDouble instance that the caller should deal with.
2736  *
2737  * \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.
2738  *
2739  * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrix
2740  */
2741 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrixWith(const DataArrayDouble *other) const
2742 {
2743   if(!other)
2744     throw INTERP_KERNEL::Exception("DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : input parameter is null !");
2745   checkAllocated();
2746   other->checkAllocated();
2747   int nbOfComp=getNumberOfComponents();
2748   int otherNbOfComp=other->getNumberOfComponents();
2749   if(nbOfComp!=otherNbOfComp)
2750     {
2751       std::ostringstream oss; oss << "DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : this nb of compo=" << nbOfComp << " and other nb of compo=" << otherNbOfComp << ". It should match !";
2752       throw INTERP_KERNEL::Exception(oss.str().c_str());
2753     }
2754   int nbOfTuples=getNumberOfTuples();
2755   int otherNbOfTuples=other->getNumberOfTuples();
2756   const double *inData=getConstPointer();
2757   const double *inDataOther=other->getConstPointer();
2758   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
2759   ret->alloc(otherNbOfTuples*nbOfTuples,1);
2760   double *outData=ret->getPointer();
2761   for(int i=0;i<otherNbOfTuples;i++,inDataOther+=nbOfComp)
2762     {
2763       for(int j=0;j<nbOfTuples;j++)
2764         {
2765           double dist=0.;
2766           for(int k=0;k<nbOfComp;k++)
2767             { double delta=inDataOther[k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
2768           dist=sqrt(dist);
2769           outData[i*nbOfTuples+j]=dist;
2770         }
2771     }
2772   return ret.retn();
2773 }
2774
2775 /*!
2776  * Sorts value within every tuple of \a this array.
2777  *  \param [in] asc - if \a true, the values are sorted in ascending order, else,
2778  *              in descending order.
2779  *  \throw If \a this is not allocated.
2780  */
2781 void DataArrayDouble::sortPerTuple(bool asc)
2782 {
2783   checkAllocated();
2784   double *pt=getPointer();
2785   int nbOfTuple=getNumberOfTuples();
2786   int nbOfComp=getNumberOfComponents();
2787   if(asc)
2788     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
2789       std::sort(pt,pt+nbOfComp);
2790   else
2791     for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
2792       std::sort(pt,pt+nbOfComp,std::greater<double>());
2793   declareAsNew();
2794 }
2795
2796 /*!
2797  * Converts every value of \a this array to its absolute value.
2798  * \b WARNING this method is non const. If a new DataArrayDouble instance should be built containing the result of abs DataArrayDouble::computeAbs
2799  * should be called instead.
2800  *
2801  * \throw If \a this is not allocated.
2802  * \sa DataArrayDouble::computeAbs
2803  */
2804 void DataArrayDouble::abs()
2805 {
2806   checkAllocated();
2807   double *ptr(getPointer());
2808   std::size_t nbOfElems(getNbOfElems());
2809   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<double,double>(fabs));
2810   declareAsNew();
2811 }
2812
2813 /*!
2814  * This method builds a new instance of \a this object containing the result of std::abs applied of all elements in \a this.
2815  * This method is a const method (that do not change any values in \a this) contrary to  DataArrayDouble::abs method.
2816  *
2817  * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2818  *         same number of tuples and component as \a this array.
2819  *         The caller is to delete this result array using decrRef() as it is no more
2820  *         needed.
2821  * \throw If \a this is not allocated.
2822  * \sa DataArrayDouble::abs
2823  */
2824 DataArrayDouble *DataArrayDouble::computeAbs() const
2825 {
2826   checkAllocated();
2827   DataArrayDouble *newArr(DataArrayDouble::New());
2828   int nbOfTuples(getNumberOfTuples());
2829   int nbOfComp(getNumberOfComponents());
2830   newArr->alloc(nbOfTuples,nbOfComp);
2831   std::transform(begin(),end(),newArr->getPointer(),std::ptr_fun<double,double>(fabs));
2832   newArr->copyStringInfoFrom(*this);
2833   return newArr;
2834 }
2835
2836 /*!
2837  * Apply a linear function to a given component of \a this array, so that
2838  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
2839  *  \param [in] a - the first coefficient of the function.
2840  *  \param [in] b - the second coefficient of the function.
2841  *  \param [in] compoId - the index of component to modify.
2842  *  \throw If \a this is not allocated, or \a compoId is not in [0,\c this->getNumberOfComponents() ).
2843  */
2844 void DataArrayDouble::applyLin(double a, double b, int compoId)
2845 {
2846   checkAllocated();
2847   double *ptr(getPointer()+compoId);
2848   int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
2849   if(compoId<0 || compoId>=nbOfComp)
2850     {
2851       std::ostringstream oss; oss << "DataArrayDouble::applyLin : The compoId requested (" << compoId << ") is not valid ! Must be in [0," << nbOfComp << ") !";
2852       throw INTERP_KERNEL::Exception(oss.str().c_str());
2853     }
2854   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
2855     *ptr=a*(*ptr)+b;
2856   declareAsNew();
2857 }
2858
2859 /*!
2860  * Apply a linear function to all elements of \a this array, so that
2861  * an element _x_ becomes \f$ a * x + b \f$.
2862  *  \param [in] a - the first coefficient of the function.
2863  *  \param [in] b - the second coefficient of the function.
2864  *  \throw If \a this is not allocated.
2865  */
2866 void DataArrayDouble::applyLin(double a, double b)
2867 {
2868   checkAllocated();
2869   double *ptr=getPointer();
2870   std::size_t nbOfElems=getNbOfElems();
2871   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2872     *ptr=a*(*ptr)+b;
2873   declareAsNew();
2874 }
2875
2876 /*!
2877  * Modify all elements of \a this array, so that
2878  * an element _x_ becomes \f$ numerator / x \f$.
2879  *  \warning If an exception is thrown because of presence of 0.0 element in \a this 
2880  *           array, all elements processed before detection of the zero element remain
2881  *           modified.
2882  *  \param [in] numerator - the numerator used to modify array elements.
2883  *  \throw If \a this is not allocated.
2884  *  \throw If there is an element equal to 0.0 in \a this array.
2885  */
2886 void DataArrayDouble::applyInv(double numerator)
2887 {
2888   checkAllocated();
2889   double *ptr=getPointer();
2890   std::size_t nbOfElems=getNbOfElems();
2891   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2892     {
2893       if(std::abs(*ptr)>std::numeric_limits<double>::min())
2894         {
2895           *ptr=numerator/(*ptr);
2896         }
2897       else
2898         {
2899           std::ostringstream oss; oss << "DataArrayDouble::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
2900           oss << " !";
2901           throw INTERP_KERNEL::Exception(oss.str().c_str());
2902         }
2903     }
2904   declareAsNew();
2905 }
2906
2907 /*!
2908  * Returns a full copy of \a this array except that sign of all elements is reversed.
2909  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2910  *          same number of tuples and component as \a this array.
2911  *          The caller is to delete this result array using decrRef() as it is no more
2912  *          needed.
2913  *  \throw If \a this is not allocated.
2914  */
2915 DataArrayDouble *DataArrayDouble::negate() const
2916 {
2917   checkAllocated();
2918   DataArrayDouble *newArr=DataArrayDouble::New();
2919   int nbOfTuples=getNumberOfTuples();
2920   int nbOfComp=getNumberOfComponents();
2921   newArr->alloc(nbOfTuples,nbOfComp);
2922   const double *cptr=getConstPointer();
2923   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<double>());
2924   newArr->copyStringInfoFrom(*this);
2925   return newArr;
2926 }
2927
2928 /*!
2929  * Modify all elements of \a this array, so that
2930  * an element _x_ becomes <em> val ^ x </em>. Contrary to DataArrayInt::applyPow
2931  * all values in \a this have to be >= 0 if val is \b not integer.
2932  *  \param [in] val - the value used to apply pow on all array elements.
2933  *  \throw If \a this is not allocated.
2934  *  \warning If an exception is thrown because of presence of 0 element in \a this 
2935  *           array and \a val is \b not integer, all elements processed before detection of the zero element remain
2936  *           modified.
2937  */
2938 void DataArrayDouble::applyPow(double val)
2939 {
2940   checkAllocated();
2941   double *ptr=getPointer();
2942   std::size_t nbOfElems=getNbOfElems();
2943   int val2=(int)val;
2944   bool isInt=((double)val2)==val;
2945   if(!isInt)
2946     {
2947       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2948         {
2949           if(*ptr>=0)
2950             *ptr=pow(*ptr,val);
2951           else
2952             {
2953               std::ostringstream oss; oss << "DataArrayDouble::applyPow (double) : At elem # " << i << " value is " << *ptr << " ! must be >=0. !";
2954               throw INTERP_KERNEL::Exception(oss.str().c_str());
2955             }
2956         }
2957     }
2958   else
2959     {
2960       for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2961         *ptr=pow(*ptr,val2);
2962     }
2963   declareAsNew();
2964 }
2965
2966 /*!
2967  * Modify all elements of \a this array, so that
2968  * an element _x_ becomes \f$ val ^ x \f$.
2969  *  \param [in] val - the value used to apply pow on all array elements.
2970  *  \throw If \a this is not allocated.
2971  *  \throw If \a val < 0.
2972  *  \warning If an exception is thrown because of presence of 0 element in \a this 
2973  *           array, all elements processed before detection of the zero element remain
2974  *           modified.
2975  */
2976 void DataArrayDouble::applyRPow(double val)
2977 {
2978   checkAllocated();
2979   if(val<0.)
2980     throw INTERP_KERNEL::Exception("DataArrayDouble::applyRPow : the input value has to be >= 0 !");
2981   double *ptr=getPointer();
2982   std::size_t nbOfElems=getNbOfElems();
2983   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2984     *ptr=pow(val,*ptr);
2985   declareAsNew();
2986 }
2987
2988 /*!
2989  * Returns a new DataArrayDouble created from \a this one by applying \a
2990  * FunctionToEvaluate to every tuple of \a this array. Textual data is not copied.
2991  * For more info see \ref MEDCouplingArrayApplyFunc
2992  *  \param [in] nbOfComp - number of components in the result array.
2993  *  \param [in] func - the \a FunctionToEvaluate declared as 
2994  *              \c bool (*\a func)(\c const \c double *\a pos, \c double *\a res), 
2995  *              where \a pos points to the first component of a tuple of \a this array
2996  *              and \a res points to the first component of a tuple of the result array.
2997  *              Note that length (number of components) of \a pos can differ from
2998  *              that of \a res.
2999  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3000  *          same number of tuples as \a this array.
3001  *          The caller is to delete this result array using decrRef() as it is no more
3002  *          needed.
3003  *  \throw If \a this is not allocated.
3004  *  \throw If \a func returns \a false.
3005  */
3006 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, FunctionToEvaluate func) const
3007 {
3008   checkAllocated();
3009   DataArrayDouble *newArr=DataArrayDouble::New();
3010   int nbOfTuples=getNumberOfTuples();
3011   int oldNbOfComp=getNumberOfComponents();
3012   newArr->alloc(nbOfTuples,nbOfComp);
3013   const double *ptr=getConstPointer();
3014   double *ptrToFill=newArr->getPointer();
3015   for(int i=0;i<nbOfTuples;i++)
3016     {
3017       if(!func(ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp))
3018         {
3019           std::ostringstream oss; oss << "For tuple # " << i << " with value (";
3020           std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
3021           oss << ") : Evaluation of function failed !";
3022           newArr->decrRef();
3023           throw INTERP_KERNEL::Exception(oss.str().c_str());
3024         }
3025     }
3026   return newArr;
3027 }
3028
3029 /*!
3030  * Returns a new DataArrayDouble created from \a this one by applying a function to every
3031  * tuple of \a this array. Textual data is not copied.
3032  * For more info see \ref MEDCouplingArrayApplyFunc1.
3033  *  \param [in] nbOfComp - number of components in the result array.
3034  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
3035  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
3036  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
3037  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
3038  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3039  *          same number of tuples as \a this array and \a nbOfComp components.
3040  *          The caller is to delete this result array using decrRef() as it is no more
3041  *          needed.
3042  *  \throw If \a this is not allocated.
3043  *  \throw If computing \a func fails.
3044  */
3045 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, const std::string& func, bool isSafe) const
3046 {
3047   INTERP_KERNEL::ExprParser expr(func);
3048   expr.parse();
3049   std::set<std::string> vars;
3050   expr.getTrueSetOfVars(vars);
3051   std::vector<std::string> varsV(vars.begin(),vars.end());
3052   return applyFuncNamedCompo(nbOfComp,varsV,func,isSafe);
3053 }
3054
3055 /*!
3056  * Returns a new DataArrayDouble created from \a this one by applying a function to every
3057  * tuple of \a this array. Textual data is not copied. This method works by tuples (whatever its size).
3058  * If \a this is a one component array, call applyFuncOnThis instead that performs the same work faster.
3059  *
3060  * For more info see \ref MEDCouplingArrayApplyFunc0.
3061  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
3062  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
3063  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
3064  *                       If false the computation is carried on without any notification. When false the evaluation is a little faster.
3065  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3066  *          same number of tuples and components as \a this array.
3067  *          The caller is to delete this result array using decrRef() as it is no more
3068  *          needed.
3069  *  \sa applyFuncOnThis
3070  *  \throw If \a this is not allocated.
3071  *  \throw If computing \a func fails.
3072  */
3073 DataArrayDouble *DataArrayDouble::applyFunc(const std::string& func, bool isSafe) const
3074 {
3075   int nbOfComp(getNumberOfComponents());
3076   if(nbOfComp<=0)
3077     throw INTERP_KERNEL::Exception("DataArrayDouble::applyFunc : output number of component must be > 0 !");
3078   checkAllocated();
3079   int nbOfTuples(getNumberOfTuples());
3080   MCAuto<DataArrayDouble> newArr(DataArrayDouble::New());
3081   newArr->alloc(nbOfTuples,nbOfComp);
3082   INTERP_KERNEL::ExprParser expr(func);
3083   expr.parse();
3084   std::set<std::string> vars;
3085   expr.getTrueSetOfVars(vars);
3086   if((int)vars.size()>1)
3087     {
3088       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 : ";
3089       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
3090       throw INTERP_KERNEL::Exception(oss.str().c_str());
3091     }
3092   if(vars.empty())
3093     {
3094       expr.prepareFastEvaluator();
3095       newArr->rearrange(1);
3096       newArr->fillWithValue(expr.evaluateDouble());
3097       newArr->rearrange(nbOfComp);
3098       return newArr.retn();
3099     }
3100   std::vector<std::string> vars2(vars.begin(),vars.end());
3101   double buff,*ptrToFill(newArr->getPointer());
3102   const double *ptr(begin());
3103   std::vector<double> stck;
3104   expr.prepareExprEvaluationDouble(vars2,1,1,0,&buff,&buff+1);
3105   expr.prepareFastEvaluator();
3106   if(!isSafe)
3107     {
3108       for(int i=0;i<nbOfTuples;i++)
3109         {
3110           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
3111             {
3112               buff=*ptr;
3113               expr.evaluateDoubleInternal(stck);
3114               *ptrToFill=stck.back();
3115               stck.pop_back();
3116             }
3117         }
3118     }
3119   else
3120     {
3121       for(int i=0;i<nbOfTuples;i++)
3122         {
3123           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
3124             {
3125               buff=*ptr;
3126               try
3127               {
3128                   expr.evaluateDoubleInternalSafe(stck);
3129               }
3130               catch(INTERP_KERNEL::Exception& e)
3131               {
3132                   std::ostringstream oss; oss << "For tuple # " << i << " component # " << iComp << " with value (";
3133                   oss << buff;
3134                   oss << ") : Evaluation of function failed !" << e.what();
3135                   throw INTERP_KERNEL::Exception(oss.str().c_str());
3136               }
3137               *ptrToFill=stck.back();
3138               stck.pop_back();
3139             }
3140         }
3141     }
3142   return newArr.retn();
3143 }
3144
3145 /*!
3146  * This method is a non const method that modify the array in \a this.
3147  * This method only works on one component array. It means that function \a func must
3148  * contain at most one variable.
3149  * This method is a specialization of applyFunc method with one parameter on one component array.
3150  *
3151  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
3152  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
3153  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
3154  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
3155  *
3156  * \sa applyFunc
3157  */
3158 void DataArrayDouble::applyFuncOnThis(const std::string& func, bool isSafe)
3159 {
3160   int nbOfComp(getNumberOfComponents());
3161   if(nbOfComp<=0)
3162     throw INTERP_KERNEL::Exception("DataArrayDouble::applyFuncOnThis : output number of component must be > 0 !");
3163   checkAllocated();
3164   int nbOfTuples(getNumberOfTuples());
3165   INTERP_KERNEL::ExprParser expr(func);
3166   expr.parse();
3167   std::set<std::string> vars;
3168   expr.getTrueSetOfVars(vars);
3169   if((int)vars.size()>1)
3170     {
3171       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 : ";
3172       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
3173       throw INTERP_KERNEL::Exception(oss.str().c_str());
3174     }
3175   if(vars.empty())
3176     {
3177       expr.prepareFastEvaluator();
3178       std::vector<std::string> compInfo(getInfoOnComponents());
3179       rearrange(1);
3180       fillWithValue(expr.evaluateDouble());
3181       rearrange(nbOfComp);
3182       setInfoOnComponents(compInfo);
3183       return ;
3184     }
3185   std::vector<std::string> vars2(vars.begin(),vars.end());
3186   double buff,*ptrToFill(getPointer());
3187   const double *ptr(begin());
3188   std::vector<double> stck;
3189   expr.prepareExprEvaluationDouble(vars2,1,1,0,&buff,&buff+1);
3190   expr.prepareFastEvaluator();
3191   if(!isSafe)
3192     {
3193       for(int i=0;i<nbOfTuples;i++)
3194         {
3195           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
3196             {
3197               buff=*ptr;
3198               expr.evaluateDoubleInternal(stck);
3199               *ptrToFill=stck.back();
3200               stck.pop_back();
3201             }
3202         }
3203     }
3204   else
3205     {
3206       for(int i=0;i<nbOfTuples;i++)
3207         {
3208           for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
3209             {
3210               buff=*ptr;
3211               try
3212               {
3213                   expr.evaluateDoubleInternalSafe(stck);
3214               }
3215               catch(INTERP_KERNEL::Exception& e)
3216               {
3217                   std::ostringstream oss; oss << "For tuple # " << i << " component # " << iComp << " with value (";
3218                   oss << buff;
3219                   oss << ") : Evaluation of function failed !" << e.what();
3220                   throw INTERP_KERNEL::Exception(oss.str().c_str());
3221               }
3222               *ptrToFill=stck.back();
3223               stck.pop_back();
3224             }
3225         }
3226     }
3227 }
3228
3229 /*!
3230  * Returns a new DataArrayDouble created from \a this one by applying a function to every
3231  * tuple of \a this array. Textual data is not copied.
3232  * For more info see \ref MEDCouplingArrayApplyFunc2.
3233  *  \param [in] nbOfComp - number of components in the result array.
3234  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
3235  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
3236  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
3237  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
3238  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3239  *          same number of tuples as \a this array.
3240  *          The caller is to delete this result array using decrRef() as it is no more
3241  *          needed.
3242  *  \throw If \a this is not allocated.
3243  *  \throw If \a func contains vars that are not in \a this->getInfoOnComponent().
3244  *  \throw If computing \a func fails.
3245  */
3246 DataArrayDouble *DataArrayDouble::applyFuncCompo(int nbOfComp, const std::string& func, bool isSafe) const
3247 {
3248   return applyFuncNamedCompo(nbOfComp,getVarsOnComponent(),func,isSafe);
3249 }
3250
3251 /*!
3252  * Returns a new DataArrayDouble created from \a this one by applying a function to every
3253  * tuple of \a this array. Textual data is not copied.
3254  * For more info see \ref MEDCouplingArrayApplyFunc3.
3255  *  \param [in] nbOfComp - number of components in the result array.
3256  *  \param [in] varsOrder - sequence of vars defining their order.
3257  *  \param [in] func - the expression defining how to transform a tuple of \a this array.
3258  *              Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
3259  *  \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
3260  *              If false the computation is carried on without any notification. When false the evaluation is a little faster.
3261  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3262  *          same number of tuples as \a this array.
3263  *          The caller is to delete this result array using decrRef() as it is no more
3264  *          needed.
3265  *  \throw If \a this is not allocated.
3266  *  \throw If \a func contains vars not in \a varsOrder.
3267  *  \throw If computing \a func fails.
3268  */
3269 DataArrayDouble *DataArrayDouble::applyFuncNamedCompo(int nbOfComp, const std::vector<std::string>& varsOrder, const std::string& func, bool isSafe) const
3270 {
3271   if(nbOfComp<=0)
3272     throw INTERP_KERNEL::Exception("DataArrayDouble::applyFuncNamedCompo : output number of component must be > 0 !");
3273   std::vector<std::string> varsOrder2(varsOrder);
3274   int oldNbOfComp(getNumberOfComponents());
3275   for(int i=(int)varsOrder.size();i<oldNbOfComp;i++)
3276     varsOrder2.push_back(std::string());
3277   checkAllocated();
3278   int nbOfTuples(getNumberOfTuples());
3279   INTERP_KERNEL::ExprParser expr(func);
3280   expr.parse();
3281   std::set<std::string> vars;
3282   expr.getTrueSetOfVars(vars);
3283   if((int)vars.size()>oldNbOfComp)
3284     {
3285       std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
3286       oss << vars.size() << " variables : ";
3287       std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
3288       throw INTERP_KERNEL::Exception(oss.str().c_str());
3289     }
3290   MCAuto<DataArrayDouble> newArr(DataArrayDouble::New());
3291   newArr->alloc(nbOfTuples,nbOfComp);
3292   INTERP_KERNEL::AutoPtr<double> buff(new double[oldNbOfComp]);
3293   double *buffPtr(buff),*ptrToFill;
3294   std::vector<double> stck;
3295   for(int iComp=0;iComp<nbOfComp;iComp++)
3296     {
3297       expr.prepareExprEvaluationDouble(varsOrder2,oldNbOfComp,nbOfComp,iComp,buffPtr,buffPtr+oldNbOfComp);
3298       expr.prepareFastEvaluator();
3299       const double *ptr(getConstPointer());
3300       ptrToFill=newArr->getPointer()+iComp;
3301       if(!isSafe)
3302         {
3303           for(int i=0;i<nbOfTuples;i++,ptrToFill+=nbOfComp,ptr+=oldNbOfComp)
3304             {
3305               std::copy(ptr,ptr+oldNbOfComp,buffPtr);
3306               expr.evaluateDoubleInternal(stck);
3307               *ptrToFill=stck.back();
3308               stck.pop_back();
3309             }
3310         }
3311       else
3312         {
3313           for(int i=0;i<nbOfTuples;i++,ptrToFill+=nbOfComp,ptr+=oldNbOfComp)
3314             {
3315               std::copy(ptr,ptr+oldNbOfComp,buffPtr);
3316               try
3317               {
3318                   expr.evaluateDoubleInternalSafe(stck);
3319                   *ptrToFill=stck.back();
3320                   stck.pop_back();
3321               }
3322               catch(INTERP_KERNEL::Exception& e)
3323               {
3324                   std::ostringstream oss; oss << "For tuple # " << i << " with value (";
3325                   std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
3326                   oss << ") : Evaluation of function failed !" << e.what();
3327                   throw INTERP_KERNEL::Exception(oss.str().c_str());
3328               }
3329             }
3330         }
3331     }
3332   return newArr.retn();
3333 }
3334
3335 void DataArrayDouble::applyFuncFast32(const std::string& func)
3336 {
3337   checkAllocated();
3338   INTERP_KERNEL::ExprParser expr(func);
3339   expr.parse();
3340   char *funcStr=expr.compileX86();
3341   MYFUNCPTR funcPtr;
3342   *((void **)&funcPtr)=funcStr;//he he...
3343   //
3344   double *ptr=getPointer();
3345   int nbOfComp=getNumberOfComponents();
3346   int nbOfTuples=getNumberOfTuples();
3347   int nbOfElems=nbOfTuples*nbOfComp;
3348   for(int i=0;i<nbOfElems;i++,ptr++)
3349     *ptr=funcPtr(*ptr);
3350   declareAsNew();
3351 }
3352
3353 void DataArrayDouble::applyFuncFast64(const std::string& func)
3354 {
3355   checkAllocated();
3356   INTERP_KERNEL::ExprParser expr(func);
3357   expr.parse();
3358   char *funcStr=expr.compileX86_64();
3359   MYFUNCPTR funcPtr;
3360   *((void **)&funcPtr)=funcStr;//he he...
3361   //
3362   double *ptr=getPointer();
3363   int nbOfComp=getNumberOfComponents();
3364   int nbOfTuples=getNumberOfTuples();
3365   int nbOfElems=nbOfTuples*nbOfComp;
3366   for(int i=0;i<nbOfElems;i++,ptr++)
3367     *ptr=funcPtr(*ptr);
3368   declareAsNew();
3369 }
3370
3371 /*!
3372  * \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.
3373  */
3374 MCAuto<DataArrayDouble> DataArrayDouble::symmetry3DPlane(const double point[3], const double normalVector[3]) const
3375 {
3376   checkAllocated();
3377   if(getNumberOfComponents()!=3)
3378     throw INTERP_KERNEL::Exception("DataArrayDouble::symmetry3DPlane : this is excepted to have 3 components !");
3379   int nbTuples(getNumberOfTuples());
3380   MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
3381   ret->alloc(nbTuples,3);
3382   Symmetry3DPlane(point,normalVector,nbTuples,begin(),ret->getPointer());
3383   return ret;
3384 }
3385
3386 DataArrayDoubleIterator *DataArrayDouble::iterator()
3387 {
3388   return new DataArrayDoubleIterator(this);
3389 }
3390
3391 /*!
3392  * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional
3393  * array whose values are within a given range. Textual data is not copied.
3394  *  \param [in] vmin - a lowest acceptable value (included).
3395  *  \param [in] vmax - a greatest acceptable value (included).
3396  *  \return DataArrayInt * - the new instance of DataArrayInt.
3397  *          The caller is to delete this result array using decrRef() as it is no more
3398  *          needed.
3399  *  \throw If \a this->getNumberOfComponents() != 1.
3400  *
3401  *  \sa DataArrayDouble::findIdsNotInRange
3402  *
3403  *  \if ENABLE_EXAMPLES
3404  *  \ref cpp_mcdataarraydouble_getidsinrange "Here is a C++ example".<br>
3405  *  \ref py_mcdataarraydouble_getidsinrange "Here is a Python example".
3406  *  \endif
3407  */
3408 DataArrayInt *DataArrayDouble::findIdsInRange(double vmin, double vmax) const
3409 {
3410   checkAllocated();
3411   if(getNumberOfComponents()!=1)
3412     throw INTERP_KERNEL::Exception("DataArrayDouble::findIdsInRange : this must have exactly one component !");
3413   const double *cptr(begin());
3414   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
3415   int nbOfTuples(getNumberOfTuples());
3416   for(int i=0;i<nbOfTuples;i++,cptr++)
3417     if(*cptr>=vmin && *cptr<=vmax)
3418       ret->pushBackSilent(i);
3419   return ret.retn();
3420 }
3421
3422 /*!
3423  * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional
3424  * array whose values are not within a given range. Textual data is not copied.
3425  *  \param [in] vmin - a lowest not acceptable value (excluded).
3426  *  \param [in] vmax - a greatest not acceptable value (excluded).
3427  *  \return DataArrayInt * - the new instance of DataArrayInt.
3428  *          The caller is to delete this result array using decrRef() as it is no more
3429  *          needed.
3430  *  \throw If \a this->getNumberOfComponents() != 1.
3431  *
3432  *  \sa DataArrayDouble::findIdsInRange
3433  */
3434 DataArrayInt *DataArrayDouble::findIdsNotInRange(double vmin, double vmax) const
3435 {
3436   checkAllocated();
3437   if(getNumberOfComponents()!=1)
3438     throw INTERP_KERNEL::Exception("DataArrayDouble::findIdsNotInRange : this must have exactly one component !");
3439   const double *cptr(begin());
3440   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
3441   int nbOfTuples(getNumberOfTuples());
3442   for(int i=0;i<nbOfTuples;i++,cptr++)
3443     if(*cptr<vmin || *cptr>vmax)
3444       ret->pushBackSilent(i);
3445   return ret.retn();
3446 }
3447
3448 /*!
3449  * Returns a new DataArrayDouble by concatenating two given arrays, so that (1) the number
3450  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
3451  * the number of component in the result array is same as that of each of given arrays.
3452  * Info on components is copied from the first of the given arrays. Number of components
3453  * in the given arrays must be  the same.
3454  *  \param [in] a1 - an array to include in the result array.
3455  *  \param [in] a2 - another array to include in the result array.
3456  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3457  *          The caller is to delete this result array using decrRef() as it is no more
3458  *          needed.
3459  *  \throw If both \a a1 and \a a2 are NULL.
3460  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
3461  */
3462 DataArrayDouble *DataArrayDouble::Aggregate(const DataArrayDouble *a1, const DataArrayDouble *a2)
3463 {
3464   std::vector<const DataArrayDouble *> tmp(2);
3465   tmp[0]=a1; tmp[1]=a2;
3466   return Aggregate(tmp);
3467 }
3468
3469 /*!
3470  * Returns a new DataArrayDouble by concatenating all given arrays, so that (1) the number
3471  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
3472  * the number of component in the result array is same as that of each of given arrays.
3473  * Info on components is copied from the first of the given arrays. Number of components
3474  * in the given arrays must be  the same.
3475  * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it
3476  * not the object itself.
3477  *  \param [in] arr - a sequence of arrays to include in the result array.
3478  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3479  *          The caller is to delete this result array using decrRef() as it is no more
3480  *          needed.
3481  *  \throw If all arrays within \a arr are NULL.
3482  *  \throw If getNumberOfComponents() of arrays within \a arr.
3483  */
3484 DataArrayDouble *DataArrayDouble::Aggregate(const std::vector<const DataArrayDouble *>& arr)
3485 {
3486   std::vector<const DataArrayDouble *> a;
3487   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
3488     if(*it4)
3489       a.push_back(*it4);
3490   if(a.empty())
3491     throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : input list must contain at least one NON EMPTY DataArrayDouble !");
3492   std::vector<const DataArrayDouble *>::const_iterator it=a.begin();
3493   int nbOfComp=(*it)->getNumberOfComponents();
3494   int nbt=(*it++)->getNumberOfTuples();
3495   for(int i=1;it!=a.end();it++,i++)
3496     {
3497       if((*it)->getNumberOfComponents()!=nbOfComp)
3498         throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : Nb of components mismatch for array aggregation !");
3499       nbt+=(*it)->getNumberOfTuples();
3500     }
3501   MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
3502   ret->alloc(nbt,nbOfComp);
3503   double *pt=ret->getPointer();
3504   for(it=a.begin();it!=a.end();it++)
3505     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
3506   ret->copyStringInfoFrom(*(a[0]));
3507   return ret.retn();
3508 }
3509
3510 /*!
3511  * Returns a new DataArrayDouble by aggregating two given arrays, so that (1) the number
3512  * of components in the result array is a sum of the number of components of given arrays
3513  * and (2) the number of tuples in the result array is same as that of each of given
3514  * arrays. In other words the i-th tuple of result array includes all components of
3515  * i-th tuples of all given arrays.
3516  * Number of tuples in the given arrays must be  the same.
3517  *  \param [in] a1 - an array to include in the result array.
3518  *  \param [in] a2 - another array to include in the result array.
3519  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3520  *          The caller is to delete this result array using decrRef() as it is no more
3521  *          needed.
3522  *  \throw If both \a a1 and \a a2 are NULL.
3523  *  \throw If any given array is not allocated.
3524  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3525  */
3526 DataArrayDouble *DataArrayDouble::Meld(const DataArrayDouble *a1, const DataArrayDouble *a2)
3527 {
3528   std::vector<const DataArrayDouble *> arr(2);
3529   arr[0]=a1; arr[1]=a2;
3530   return Meld(arr);
3531 }
3532
3533 /*!
3534  * Returns a new DataArrayDouble by aggregating all given arrays, so that (1) the number
3535  * of components in the result array is a sum of the number of components of given arrays
3536  * and (2) the number of tuples in the result array is same as that of each of given
3537  * arrays. In other words the i-th tuple of result array includes all components of
3538  * i-th tuples of all given arrays.
3539  * Number of tuples in the given arrays must be  the same.
3540  *  \param [in] arr - a sequence of arrays to include in the result array.
3541  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3542  *          The caller is to delete this result array using decrRef() as it is no more
3543  *          needed.
3544  *  \throw If all arrays within \a arr are NULL.
3545  *  \throw If any given array is not allocated.
3546  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
3547  */
3548 DataArrayDouble *DataArrayDouble::Meld(const std::vector<const DataArrayDouble *>& arr)
3549 {
3550   std::vector<const DataArrayDouble *> a;
3551   for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
3552     if(*it4)
3553       a.push_back(*it4);
3554   if(a.empty())
3555     throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : input list must contain at least one NON EMPTY DataArrayDouble !");
3556   std::vector<const DataArrayDouble *>::const_iterator it;
3557   for(it=a.begin();it!=a.end();it++)
3558     (*it)->checkAllocated();
3559   it=a.begin();
3560   int nbOfTuples=(*it)->getNumberOfTuples();
3561   std::vector<int> nbc(a.size());
3562   std::vector<const double *> pts(a.size());
3563   nbc[0]=(*it)->getNumberOfComponents();
3564   pts[0]=(*it++)->getConstPointer();
3565   for(int i=1;it!=a.end();it++,i++)
3566     {
3567       if(nbOfTuples!=(*it)->getNumberOfTuples())
3568         throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : mismatch of number of tuples !");
3569       nbc[i]=(*it)->getNumberOfComponents();
3570       pts[i]=(*it)->getConstPointer();
3571     }
3572   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
3573   DataArrayDouble *ret=DataArrayDouble::New();
3574   ret->alloc(nbOfTuples,totalNbOfComp);
3575   double *retPtr=ret->getPointer();
3576   for(int i=0;i<nbOfTuples;i++)
3577     for(int j=0;j<(int)a.size();j++)
3578       {
3579         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
3580         pts[j]+=nbc[j];
3581       }
3582   int k=0;
3583   for(int i=0;i<(int)a.size();i++)
3584     for(int j=0;j<nbc[i];j++,k++)
3585       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j));
3586   return ret;
3587 }
3588
3589 /*!
3590  * Returns a new DataArrayDouble containing a dot product of two given arrays, so that
3591  * the i-th tuple of the result array is a sum of products of j-th components of i-th
3592  * tuples of given arrays (\f$ a_i = \sum_{j=1}^n a1_j * a2_j \f$).
3593  * Info on components and name is copied from the first of the given arrays.
3594  * Number of tuples and components in the given arrays must be the same.
3595  *  \param [in] a1 - a given array.
3596  *  \param [in] a2 - another given array.
3597  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3598  *          The caller is to delete this result array using decrRef() as it is no more
3599  *          needed.
3600  *  \throw If either \a a1 or \a a2 is NULL.
3601  *  \throw If any given array is not allocated.
3602  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3603  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
3604  */
3605 DataArrayDouble *DataArrayDouble::Dot(const DataArrayDouble *a1, const DataArrayDouble *a2)
3606 {
3607   if(!a1 || !a2)
3608     throw INTERP_KERNEL::Exception("DataArrayDouble::Dot : input DataArrayDouble instance is NULL !");
3609   a1->checkAllocated();
3610   a2->checkAllocated();
3611   int nbOfComp=a1->getNumberOfComponents();
3612   if(nbOfComp!=a2->getNumberOfComponents())
3613     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Dot !");
3614   int nbOfTuple=a1->getNumberOfTuples();
3615   if(nbOfTuple!=a2->getNumberOfTuples())
3616     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Dot !");
3617   DataArrayDouble *ret=DataArrayDouble::New();
3618   ret->alloc(nbOfTuple,1);
3619   double *retPtr=ret->getPointer();
3620   const double *a1Ptr=a1->getConstPointer();
3621   const double *a2Ptr=a2->getConstPointer();
3622   for(int i=0;i<nbOfTuple;i++)
3623     {
3624       double sum=0.;
3625       for(int j=0;j<nbOfComp;j++)
3626         sum+=a1Ptr[i*nbOfComp+j]*a2Ptr[i*nbOfComp+j];
3627       retPtr[i]=sum;
3628     }
3629   ret->setInfoOnComponent(0,a1->getInfoOnComponent(0));
3630   ret->setName(a1->getName());
3631   return ret;
3632 }
3633
3634 /*!
3635  * Returns a new DataArrayDouble containing a cross product of two given arrays, so that
3636  * the i-th tuple of the result array contains 3 components of a vector which is a cross
3637  * product of two vectors defined by the i-th tuples of given arrays.
3638  * Info on components is copied from the first of the given arrays.
3639  * Number of tuples in the given arrays must be the same.
3640  * Number of components in the given arrays must be 3.
3641  *  \param [in] a1 - a given array.
3642  *  \param [in] a2 - another given array.
3643  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3644  *          The caller is to delete this result array using decrRef() as it is no more
3645  *          needed.
3646  *  \throw If either \a a1 or \a a2 is NULL.
3647  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3648  *  \throw If \a a1->getNumberOfComponents() != 3
3649  *  \throw If \a a2->getNumberOfComponents() != 3
3650  */
3651 DataArrayDouble *DataArrayDouble::CrossProduct(const DataArrayDouble *a1, const DataArrayDouble *a2)
3652 {
3653   if(!a1 || !a2)
3654     throw INTERP_KERNEL::Exception("DataArrayDouble::CrossProduct : input DataArrayDouble instance is NULL !");
3655   int nbOfComp=a1->getNumberOfComponents();
3656   if(nbOfComp!=a2->getNumberOfComponents())
3657     throw INTERP_KERNEL::Exception("Nb of components mismatch for array crossProduct !");
3658   if(nbOfComp!=3)
3659     throw INTERP_KERNEL::Exception("Nb of components must be equal to 3 for array crossProduct !");
3660   int nbOfTuple=a1->getNumberOfTuples();
3661   if(nbOfTuple!=a2->getNumberOfTuples())
3662     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array crossProduct !");
3663   DataArrayDouble *ret=DataArrayDouble::New();
3664   ret->alloc(nbOfTuple,3);
3665   double *retPtr=ret->getPointer();
3666   const double *a1Ptr=a1->getConstPointer();
3667   const double *a2Ptr=a2->getConstPointer();
3668   for(int i=0;i<nbOfTuple;i++)
3669     {
3670       retPtr[3*i]=a1Ptr[3*i+1]*a2Ptr[3*i+2]-a1Ptr[3*i+2]*a2Ptr[3*i+1];
3671       retPtr[3*i+1]=a1Ptr[3*i+2]*a2Ptr[3*i]-a1Ptr[3*i]*a2Ptr[3*i+2];
3672       retPtr[3*i+2]=a1Ptr[3*i]*a2Ptr[3*i+1]-a1Ptr[3*i+1]*a2Ptr[3*i];
3673     }
3674   ret->copyStringInfoFrom(*a1);
3675   return ret;
3676 }
3677
3678 /*!
3679  * Returns a new DataArrayDouble containing maximal values of two given arrays.
3680  * Info on components is copied from the first of the given arrays.
3681  * Number of tuples and components in the given arrays must be the same.
3682  *  \param [in] a1 - an array to compare values with another one.
3683  *  \param [in] a2 - another array to compare values with the first one.
3684  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3685  *          The caller is to delete this result array using decrRef() as it is no more
3686  *          needed.
3687  *  \throw If either \a a1 or \a a2 is NULL.
3688  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3689  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
3690  */
3691 DataArrayDouble *DataArrayDouble::Max(const DataArrayDouble *a1, const DataArrayDouble *a2)
3692 {
3693   if(!a1 || !a2)
3694     throw INTERP_KERNEL::Exception("DataArrayDouble::Max : input DataArrayDouble instance is NULL !");
3695   int nbOfComp=a1->getNumberOfComponents();
3696   if(nbOfComp!=a2->getNumberOfComponents())
3697     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Max !");
3698   int nbOfTuple=a1->getNumberOfTuples();
3699   if(nbOfTuple!=a2->getNumberOfTuples())
3700     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Max !");
3701   DataArrayDouble *ret=DataArrayDouble::New();
3702   ret->alloc(nbOfTuple,nbOfComp);
3703   double *retPtr=ret->getPointer();
3704   const double *a1Ptr=a1->getConstPointer();
3705   const double *a2Ptr=a2->getConstPointer();
3706   int nbElem=nbOfTuple*nbOfComp;
3707   for(int i=0;i<nbElem;i++)
3708     retPtr[i]=std::max(a1Ptr[i],a2Ptr[i]);
3709   ret->copyStringInfoFrom(*a1);
3710   return ret;
3711 }
3712
3713 /*!
3714  * Returns a new DataArrayDouble containing minimal values of two given arrays.
3715  * Info on components is copied from the first of the given arrays.
3716  * Number of tuples and components in the given arrays must be the same.
3717  *  \param [in] a1 - an array to compare values with another one.
3718  *  \param [in] a2 - another array to compare values with the first one.
3719  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3720  *          The caller is to delete this result array using decrRef() as it is no more
3721  *          needed.
3722  *  \throw If either \a a1 or \a a2 is NULL.
3723  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3724  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
3725  */
3726 DataArrayDouble *DataArrayDouble::Min(const DataArrayDouble *a1, const DataArrayDouble *a2)
3727 {
3728   if(!a1 || !a2)
3729     throw INTERP_KERNEL::Exception("DataArrayDouble::Min : input DataArrayDouble instance is NULL !");
3730   int nbOfComp=a1->getNumberOfComponents();
3731   if(nbOfComp!=a2->getNumberOfComponents())
3732     throw INTERP_KERNEL::Exception("Nb of components mismatch for array min !");
3733   int nbOfTuple=a1->getNumberOfTuples();
3734   if(nbOfTuple!=a2->getNumberOfTuples())
3735     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array min !");
3736   DataArrayDouble *ret=DataArrayDouble::New();
3737   ret->alloc(nbOfTuple,nbOfComp);
3738   double *retPtr=ret->getPointer();
3739   const double *a1Ptr=a1->getConstPointer();
3740   const double *a2Ptr=a2->getConstPointer();
3741   int nbElem=nbOfTuple*nbOfComp;
3742   for(int i=0;i<nbElem;i++)
3743     retPtr[i]=std::min(a1Ptr[i],a2Ptr[i]);
3744   ret->copyStringInfoFrom(*a1);
3745   return ret;
3746 }
3747
3748 /*!
3749  * Returns a new DataArrayDouble that is a sum of two given arrays. There are 3
3750  * valid cases.
3751  * 1.  The arrays have same number of tuples and components. Then each value of
3752  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
3753  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
3754  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
3755  *   component. Then
3756  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
3757  * 3.  The arrays have same number of components and one array, say _a2_, has one
3758  *   tuple. Then
3759  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
3760  *
3761  * Info on components is copied either from the first array (in the first case) or from
3762  * the array with maximal number of elements (getNbOfElems()).
3763  *  \param [in] a1 - an array to sum up.
3764  *  \param [in] a2 - another array to sum up.
3765  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3766  *          The caller is to delete this result array using decrRef() as it is no more
3767  *          needed.
3768  *  \throw If either \a a1 or \a a2 is NULL.
3769  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
3770  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
3771  *         none of them has number of tuples or components equal to 1.
3772  */
3773 DataArrayDouble *DataArrayDouble::Add(const DataArrayDouble *a1, const DataArrayDouble *a2)
3774 {
3775   if(!a1 || !a2)
3776     throw INTERP_KERNEL::Exception("DataArrayDouble::Add : input DataArrayDouble instance is NULL !");
3777   int nbOfTuple=a1->getNumberOfTuples();
3778   int nbOfTuple2=a2->getNumberOfTuples();
3779   int nbOfComp=a1->getNumberOfComponents();
3780   int nbOfComp2=a2->getNumberOfComponents();
3781   MCAuto<DataArrayDouble> ret=0;
3782   if(nbOfTuple==nbOfTuple2)
3783     {
3784       if(nbOfComp==nbOfComp2)
3785         {
3786           ret=DataArrayDouble::New();
3787           ret->alloc(nbOfTuple,nbOfComp);
3788           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<double>());
3789           ret->copyStringInfoFrom(*a1);
3790         }
3791       else
3792         {
3793           int nbOfCompMin,nbOfCompMax;
3794           const DataArrayDouble *aMin, *aMax;
3795           if(nbOfComp>nbOfComp2)
3796             {
3797               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
3798               aMin=a2; aMax=a1;
3799             }
3800           else
3801             {
3802               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
3803               aMin=a1; aMax=a2;
3804             }
3805           if(nbOfCompMin==1)
3806             {
3807               ret=DataArrayDouble::New();
3808               ret->alloc(nbOfTuple,nbOfCompMax);
3809               const double *aMinPtr=aMin->getConstPointer();
3810               const double *aMaxPtr=aMax->getConstPointer();
3811               double *res=ret->getPointer();
3812               for(int i=0;i<nbOfTuple;i++)
3813                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<double>(),aMinPtr[i]));
3814               ret->copyStringInfoFrom(*aMax);
3815             }
3816           else
3817             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
3818         }
3819     }
3820   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
3821     {
3822       if(nbOfComp==nbOfComp2)
3823         {
3824           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
3825           const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
3826           const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
3827           const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
3828           ret=DataArrayDouble::New();
3829           ret->alloc(nbOfTupleMax,nbOfComp);
3830           double *res=ret->getPointer();
3831           for(int i=0;i<nbOfTupleMax;i++)
3832             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<double>());
3833           ret->copyStringInfoFrom(*aMax);
3834         }
3835       else
3836         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
3837     }
3838   else
3839     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
3840   return ret.retn();
3841 }
3842
3843 /*!
3844  * Adds values of another DataArrayDouble to values of \a this one. There are 3
3845  * valid cases.
3846  * 1.  The arrays have same number of tuples and components. Then each value of
3847  *   \a other array is added to the corresponding value of \a this array, i.e.:
3848  *   _a_ [ i, j ] += _other_ [ i, j ].
3849  * 2.  The arrays have same number of tuples and \a other array has one component. Then
3850  *   _a_ [ i, j ] += _other_ [ i, 0 ].
3851  * 3.  The arrays have same number of components and \a other array has one tuple. Then
3852  *   _a_ [ i, j ] += _a2_ [ 0, j ].
3853  *
3854  *  \param [in] other - an array to add to \a this one.
3855  *  \throw If \a other is NULL.
3856  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
3857  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
3858  *         \a other has number of both tuples and components not equal to 1.
3859  */
3860 void DataArrayDouble::addEqual(const DataArrayDouble *other)
3861 {
3862   if(!other)
3863     throw INTERP_KERNEL::Exception("DataArrayDouble::addEqual : input DataArrayDouble instance is NULL !");
3864   const char *msg="Nb of tuples mismatch for DataArrayDouble::addEqual  !";
3865   checkAllocated();
3866   other->checkAllocated();
3867   int nbOfTuple=getNumberOfTuples();
3868   int nbOfTuple2=other->getNumberOfTuples();
3869   int nbOfComp=getNumberOfComponents();
3870   int nbOfComp2=other->getNumberOfComponents();
3871   if(nbOfTuple==nbOfTuple2)
3872     {
3873       if(nbOfComp==nbOfComp2)
3874         {
3875           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<double>());
3876         }
3877       else if(nbOfComp2==1)
3878         {
3879           double *ptr=getPointer();
3880           const double *ptrc=other->getConstPointer();
3881           for(int i=0;i<nbOfTuple;i++)
3882             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<double>(),*ptrc++));
3883         }
3884       else
3885         throw INTERP_KERNEL::Exception(msg);
3886     }
3887   else if(nbOfTuple2==1)
3888     {
3889       if(nbOfComp2==nbOfComp)
3890         {
3891           double *ptr=getPointer();
3892           const double *ptrc=other->getConstPointer();
3893           for(int i=0;i<nbOfTuple;i++)
3894             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<double>());
3895         }
3896       else
3897         throw INTERP_KERNEL::Exception(msg);
3898     }
3899   else
3900     throw INTERP_KERNEL::Exception(msg);
3901   declareAsNew();
3902 }
3903
3904 /*!
3905  * Returns a new DataArrayDouble that is a subtraction of two given arrays. There are 3
3906  * valid cases.
3907  * 1.  The arrays have same number of tuples and components. Then each value of
3908  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
3909  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
3910  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
3911  *   component. Then
3912  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
3913  * 3.  The arrays have same number of components and one array, say _a2_, has one
3914  *   tuple. Then
3915  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
3916  *
3917  * Info on components is copied either from the first array (in the first case) or from
3918  * the array with maximal number of elements (getNbOfElems()).
3919  *  \param [in] a1 - an array to subtract from.
3920  *  \param [in] a2 - an array to subtract.
3921  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
3922  *          The caller is to delete this result array using decrRef() as it is no more
3923  *          needed.
3924  *  \throw If either \a a1 or \a a2 is NULL.
3925  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
3926  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
3927  *         none of them has number of tuples or components equal to 1.
3928  */
3929 DataArrayDouble *DataArrayDouble::Substract(const DataArrayDouble *a1, const DataArrayDouble *a2)
3930 {
3931   if(!a1 || !a2)
3932     throw INTERP_KERNEL::Exception("DataArrayDouble::Substract : input DataArrayDouble instance is NULL !");
3933   int nbOfTuple1=a1->getNumberOfTuples();
3934   int nbOfTuple2=a2->getNumberOfTuples();
3935   int nbOfComp1=a1->getNumberOfComponents();
3936   int nbOfComp2=a2->getNumberOfComponents();
3937   if(nbOfTuple2==nbOfTuple1)
3938     {
3939       if(nbOfComp1==nbOfComp2)
3940         {
3941           MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
3942           ret->alloc(nbOfTuple2,nbOfComp1);
3943           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<double>());
3944           ret->copyStringInfoFrom(*a1);
3945           return ret.retn();
3946         }
3947       else if(nbOfComp2==1)
3948         {
3949           MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
3950           ret->alloc(nbOfTuple1,nbOfComp1);
3951           const double *a2Ptr=a2->getConstPointer();
3952           const double *a1Ptr=a1->getConstPointer();
3953           double *res=ret->getPointer();
3954           for(int i=0;i<nbOfTuple1;i++)
3955             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<double>(),a2Ptr[i]));
3956           ret->copyStringInfoFrom(*a1);
3957           return ret.retn();
3958         }
3959       else
3960         {
3961           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
3962           return 0;
3963         }
3964     }
3965   else if(nbOfTuple2==1)
3966     {
3967       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
3968       MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
3969       ret->alloc(nbOfTuple1,nbOfComp1);
3970       const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
3971       double *pt=ret->getPointer();
3972       for(int i=0;i<nbOfTuple1;i++)
3973         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<double>());
3974       ret->copyStringInfoFrom(*a1);
3975       return ret.retn();
3976     }
3977   else
3978     {
3979       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
3980       return 0;
3981     }
3982 }
3983
3984 /*!
3985  * Subtract values of another DataArrayDouble from values of \a this one. There are 3
3986  * valid cases.
3987  * 1.  The arrays have same number of tuples and components. Then each value of
3988  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
3989  *   _a_ [ i, j ] -= _other_ [ i, j ].
3990  * 2.  The arrays have same number of tuples and \a other array has one component. Then
3991  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
3992  * 3.  The arrays have same number of components and \a other array has one tuple. Then
3993  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
3994  *
3995  *  \param [in] other - an array to subtract from \a this one.
3996  *  \throw If \a other is NULL.
3997  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
3998  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
3999  *         \a other has number of both tuples and components not equal to 1.
4000  */
4001 void DataArrayDouble::substractEqual(const DataArrayDouble *other)
4002 {
4003   if(!other)
4004     throw INTERP_KERNEL::Exception("DataArrayDouble::substractEqual : input DataArrayDouble instance is NULL !");
4005   const char *msg="Nb of tuples mismatch for DataArrayDouble::substractEqual  !";
4006   checkAllocated();
4007   other->checkAllocated();
4008   int nbOfTuple=getNumberOfTuples();
4009   int nbOfTuple2=other->getNumberOfTuples();
4010   int nbOfComp=getNumberOfComponents();
4011   int nbOfComp2=other->getNumberOfComponents();
4012   if(nbOfTuple==nbOfTuple2)
4013     {
4014       if(nbOfComp==nbOfComp2)
4015         {
4016           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<double>());
4017         }
4018       else if(nbOfComp2==1)
4019         {
4020           double *ptr=getPointer();
4021           const double *ptrc=other->getConstPointer();
4022           for(int i=0;i<nbOfTuple;i++)
4023             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<double>(),*ptrc++)); 
4024         }
4025       else
4026         throw INTERP_KERNEL::Exception(msg);
4027     }
4028   else if(nbOfTuple2==1)
4029     {
4030       if(nbOfComp2==nbOfComp)
4031         {
4032           double *ptr=getPointer();
4033           const double *ptrc=other->getConstPointer();
4034           for(int i=0;i<nbOfTuple;i++)
4035             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<double>());
4036         }
4037       else
4038         throw INTERP_KERNEL::Exception(msg);
4039     }
4040   else
4041     throw INTERP_KERNEL::Exception(msg);
4042   declareAsNew();
4043 }
4044
4045 /*!
4046  * Returns a new DataArrayDouble that is a product of two given arrays. There are 3
4047  * valid cases.
4048  * 1.  The arrays have same number of tuples and components. Then each value of
4049  *   the result array (_a_) is a product of the corresponding values of \a a1 and
4050  *   \a a2, i.e. _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
4051  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
4052  *   component. Then
4053  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
4054  * 3.  The arrays have same number of components and one array, say _a2_, has one
4055  *   tuple. Then
4056  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
4057  *
4058  * Info on components is copied either from the first array (in the first case) or from
4059  * the array with maximal number of elements (getNbOfElems()).
4060  *  \param [in] a1 - a factor array.
4061  *  \param [in] a2 - another factor array.
4062  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4063  *          The caller is to delete this result array using decrRef() as it is no more
4064  *          needed.
4065  *  \throw If either \a a1 or \a a2 is NULL.
4066  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
4067  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
4068  *         none of them has number of tuples or components equal to 1.
4069  */
4070 DataArrayDouble *DataArrayDouble::Multiply(const DataArrayDouble *a1, const DataArrayDouble *a2)
4071 {
4072   if(!a1 || !a2)
4073     throw INTERP_KERNEL::Exception("DataArrayDouble::Multiply : input DataArrayDouble instance is NULL !");
4074   int nbOfTuple=a1->getNumberOfTuples();
4075   int nbOfTuple2=a2->getNumberOfTuples();
4076   int nbOfComp=a1->getNumberOfComponents();
4077   int nbOfComp2=a2->getNumberOfComponents();
4078   MCAuto<DataArrayDouble> ret=0;
4079   if(nbOfTuple==nbOfTuple2)
4080     {
4081       if(nbOfComp==nbOfComp2)
4082         {
4083           ret=DataArrayDouble::New();
4084           ret->alloc(nbOfTuple,nbOfComp);
4085           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<double>());
4086           ret->copyStringInfoFrom(*a1);
4087         }
4088       else
4089         {
4090           int nbOfCompMin,nbOfCompMax;
4091           const DataArrayDouble *aMin, *aMax;
4092           if(nbOfComp>nbOfComp2)
4093             {
4094               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
4095               aMin=a2; aMax=a1;
4096             }
4097           else
4098             {
4099               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
4100               aMin=a1; aMax=a2;
4101             }
4102           if(nbOfCompMin==1)
4103             {
4104               ret=DataArrayDouble::New();
4105               ret->alloc(nbOfTuple,nbOfCompMax);
4106               const double *aMinPtr=aMin->getConstPointer();
4107               const double *aMaxPtr=aMax->getConstPointer();
4108               double *res=ret->getPointer();
4109               for(int i=0;i<nbOfTuple;i++)
4110                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<double>(),aMinPtr[i]));
4111               ret->copyStringInfoFrom(*aMax);
4112             }
4113           else
4114             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
4115         }
4116     }
4117   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
4118     {
4119       if(nbOfComp==nbOfComp2)
4120         {
4121           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
4122           const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
4123           const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
4124           const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
4125           ret=DataArrayDouble::New();
4126           ret->alloc(nbOfTupleMax,nbOfComp);
4127           double *res=ret->getPointer();
4128           for(int i=0;i<nbOfTupleMax;i++)
4129             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<double>());
4130           ret->copyStringInfoFrom(*aMax);
4131         }
4132       else
4133         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
4134     }
4135   else
4136     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
4137   return ret.retn();
4138 }
4139
4140 /*!
4141  * Multiply values of another DataArrayDouble to values of \a this one. There are 3
4142  * valid cases.
4143  * 1.  The arrays have same number of tuples and components. Then each value of
4144  *   \a other array is multiplied to the corresponding value of \a this array, i.e.
4145  *   _this_ [ i, j ] *= _other_ [ i, j ].
4146  * 2.  The arrays have same number of tuples and \a other array has one component. Then
4147  *   _this_ [ i, j ] *= _other_ [ i, 0 ].
4148  * 3.  The arrays have same number of components and \a other array has one tuple. Then
4149  *   _this_ [ i, j ] *= _a2_ [ 0, j ].
4150  *
4151  *  \param [in] other - an array to multiply to \a this one.
4152  *  \throw If \a other is NULL.
4153  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
4154  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
4155  *         \a other has number of both tuples and components not equal to 1.
4156  */
4157 void DataArrayDouble::multiplyEqual(const DataArrayDouble *other)
4158 {
4159   if(!other)
4160     throw INTERP_KERNEL::Exception("DataArrayDouble::multiplyEqual : input DataArrayDouble instance is NULL !");
4161   const char *msg="Nb of tuples mismatch for DataArrayDouble::multiplyEqual !";
4162   checkAllocated();
4163   other->checkAllocated();
4164   int nbOfTuple=getNumberOfTuples();
4165   int nbOfTuple2=other->getNumberOfTuples();
4166   int nbOfComp=getNumberOfComponents();
4167   int nbOfComp2=other->getNumberOfComponents();
4168   if(nbOfTuple==nbOfTuple2)
4169     {
4170       if(nbOfComp==nbOfComp2)
4171         {
4172           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<double>());
4173         }
4174       else if(nbOfComp2==1)
4175         {
4176           double *ptr=getPointer();
4177           const double *ptrc=other->getConstPointer();
4178           for(int i=0;i<nbOfTuple;i++)
4179             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<double>(),*ptrc++));
4180         }
4181       else
4182         throw INTERP_KERNEL::Exception(msg);
4183     }
4184   else if(nbOfTuple2==1)
4185     {
4186       if(nbOfComp2==nbOfComp)
4187         {
4188           double *ptr=getPointer();
4189           const double *ptrc=other->getConstPointer();
4190           for(int i=0;i<nbOfTuple;i++)
4191             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<double>());
4192         }
4193       else
4194         throw INTERP_KERNEL::Exception(msg);
4195     }
4196   else
4197     throw INTERP_KERNEL::Exception(msg);
4198   declareAsNew();
4199 }
4200
4201 /*!
4202  * Returns a new DataArrayDouble that is a division of two given arrays. There are 3
4203  * valid cases.
4204  * 1.  The arrays have same number of tuples and components. Then each value of
4205  *   the result array (_a_) is a division of the corresponding values of \a a1 and
4206  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
4207  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
4208  *   component. Then
4209  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
4210  * 3.  The arrays have same number of components and one array, say _a2_, has one
4211  *   tuple. Then
4212  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
4213  *
4214  * Info on components is copied either from the first array (in the first case) or from
4215  * the array with maximal number of elements (getNbOfElems()).
4216  *  \warning No check of division by zero is performed!
4217  *  \param [in] a1 - a numerator array.
4218  *  \param [in] a2 - a denominator array.
4219  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4220  *          The caller is to delete this result array using decrRef() as it is no more
4221  *          needed.
4222  *  \throw If either \a a1 or \a a2 is NULL.
4223  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
4224  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
4225  *         none of them has number of tuples or components equal to 1.
4226  */
4227 DataArrayDouble *DataArrayDouble::Divide(const DataArrayDouble *a1, const DataArrayDouble *a2)
4228 {
4229   if(!a1 || !a2)
4230     throw INTERP_KERNEL::Exception("DataArrayDouble::Divide : input DataArrayDouble instance is NULL !");
4231   int nbOfTuple1=a1->getNumberOfTuples();
4232   int nbOfTuple2=a2->getNumberOfTuples();
4233   int nbOfComp1=a1->getNumberOfComponents();
4234   int nbOfComp2=a2->getNumberOfComponents();
4235   if(nbOfTuple2==nbOfTuple1)
4236     {
4237       if(nbOfComp1==nbOfComp2)
4238         {
4239           MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
4240           ret->alloc(nbOfTuple2,nbOfComp1);
4241           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<double>());
4242           ret->copyStringInfoFrom(*a1);
4243           return ret.retn();
4244         }
4245       else if(nbOfComp2==1)
4246         {
4247           MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
4248           ret->alloc(nbOfTuple1,nbOfComp1);
4249           const double *a2Ptr=a2->getConstPointer();
4250           const double *a1Ptr=a1->getConstPointer();
4251           double *res=ret->getPointer();
4252           for(int i=0;i<nbOfTuple1;i++)
4253             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<double>(),a2Ptr[i]));
4254           ret->copyStringInfoFrom(*a1);
4255           return ret.retn();
4256         }
4257       else
4258         {
4259           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
4260           return 0;
4261         }
4262     }
4263   else if(nbOfTuple2==1)
4264     {
4265       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
4266       MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
4267       ret->alloc(nbOfTuple1,nbOfComp1);
4268       const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
4269       double *pt=ret->getPointer();
4270       for(int i=0;i<nbOfTuple1;i++)
4271         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<double>());
4272       ret->copyStringInfoFrom(*a1);
4273       return ret.retn();
4274     }
4275   else
4276     {
4277       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
4278       return 0;
4279     }
4280 }
4281
4282 /*!
4283  * Divide values of \a this array by values of another DataArrayDouble. There are 3
4284  * valid cases.
4285  * 1.  The arrays have same number of tuples and components. Then each value of
4286  *    \a this array is divided by the corresponding value of \a other one, i.e.:
4287  *   _a_ [ i, j ] /= _other_ [ i, j ].
4288  * 2.  The arrays have same number of tuples and \a other array has one component. Then
4289  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
4290  * 3.  The arrays have same number of components and \a other array has one tuple. Then
4291  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
4292  *
4293  *  \warning No check of division by zero is performed!
4294  *  \param [in] other - an array to divide \a this one by.
4295  *  \throw If \a other is NULL.
4296  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
4297  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
4298  *         \a other has number of both tuples and components not equal to 1.
4299  */
4300 void DataArrayDouble::divideEqual(const DataArrayDouble *other)
4301 {
4302   if(!other)
4303     throw INTERP_KERNEL::Exception("DataArrayDouble::divideEqual : input DataArrayDouble instance is NULL !");
4304   const char *msg="Nb of tuples mismatch for DataArrayDouble::divideEqual !";
4305   checkAllocated();
4306   other->checkAllocated();
4307   int nbOfTuple=getNumberOfTuples();
4308   int nbOfTuple2=other->getNumberOfTuples();
4309   int nbOfComp=getNumberOfComponents();
4310   int nbOfComp2=other->getNumberOfComponents();
4311   if(nbOfTuple==nbOfTuple2)
4312     {
4313       if(nbOfComp==nbOfComp2)
4314         {
4315           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<double>());
4316         }
4317       else if(nbOfComp2==1)
4318         {
4319           double *ptr=getPointer();
4320           const double *ptrc=other->getConstPointer();
4321           for(int i=0;i<nbOfTuple;i++)
4322             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<double>(),*ptrc++));
4323         }
4324       else
4325         throw INTERP_KERNEL::Exception(msg);
4326     }
4327   else if(nbOfTuple2==1)
4328     {
4329       if(nbOfComp2==nbOfComp)
4330         {
4331           double *ptr=getPointer();
4332           const double *ptrc=other->getConstPointer();
4333           for(int i=0;i<nbOfTuple;i++)
4334             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<double>());
4335         }
4336       else
4337         throw INTERP_KERNEL::Exception(msg);
4338     }
4339   else
4340     throw INTERP_KERNEL::Exception(msg);
4341   declareAsNew();
4342 }
4343
4344 /*!
4345  * Returns a new DataArrayDouble that is the result of pow of two given arrays. There are 3
4346  * valid cases.
4347  *
4348  *  \param [in] a1 - an array to pow up.
4349  *  \param [in] a2 - another array to sum up.
4350  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
4351  *          The caller is to delete this result array using decrRef() as it is no more
4352  *          needed.
4353  *  \throw If either \a a1 or \a a2 is NULL.
4354  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4355  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
4356  *  \throw If there is a negative value in \a a1.
4357  */
4358 DataArrayDouble *DataArrayDouble::Pow(const DataArrayDouble *a1, const DataArrayDouble *a2)
4359 {
4360   if(!a1 || !a2)
4361     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : at least one of input instances is null !");
4362   int nbOfTuple=a1->getNumberOfTuples();
4363   int nbOfTuple2=a2->getNumberOfTuples();
4364   int nbOfComp=a1->getNumberOfComponents();
4365   int nbOfComp2=a2->getNumberOfComponents();
4366   if(nbOfTuple!=nbOfTuple2)
4367     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of tuples mismatches !");
4368   if(nbOfComp!=1 || nbOfComp2!=1)
4369     throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of components of both arrays must be equal to 1 !");
4370   MCAuto<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbOfTuple,1);
4371   const double *ptr1(a1->begin()),*ptr2(a2->begin());
4372   double *ptr=ret->getPointer();
4373   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
4374     {
4375       if(*ptr1>=0)
4376         {
4377           *ptr=pow(*ptr1,*ptr2);
4378         }
4379       else
4380         {
4381           std::ostringstream oss; oss << "DataArrayDouble::Pow : on tuple #" << i << " of a1 value is < 0 (" << *ptr1 << ") !";
4382           throw INTERP_KERNEL::Exception(oss.str().c_str());
4383         }
4384     }
4385   return ret.retn();
4386 }
4387
4388 /*!
4389  * Apply pow on values of another DataArrayDouble to values of \a this one.
4390  *
4391  *  \param [in] other - an array to pow to \a this one.
4392  *  \throw If \a other is NULL.
4393  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
4394  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
4395  *  \throw If there is a negative value in \a this.
4396  */
4397 void DataArrayDouble::powEqual(const DataArrayDouble *other)
4398 {
4399   if(!other)
4400     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : input instance is null !");
4401   int nbOfTuple=getNumberOfTuples();
4402   int nbOfTuple2=other->getNumberOfTuples();
4403   int nbOfComp=getNumberOfComponents();
4404   int nbOfComp2=other->getNumberOfComponents();
4405   if(nbOfTuple!=nbOfTuple2)
4406     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of tuples mismatches !");
4407   if(nbOfComp!=1 || nbOfComp2!=1)
4408     throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of components of both arrays must be equal to 1 !");
4409   double *ptr=getPointer();
4410   const double *ptrc=other->begin();
4411   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
4412     {
4413       if(*ptr>=0)
4414         *ptr=pow(*ptr,*ptrc);
4415       else
4416         {
4417           std::ostringstream oss; oss << "DataArrayDouble::powEqual : on tuple #" << i << " of this value is < 0 (" << *ptr << ") !";
4418           throw INTERP_KERNEL::Exception(oss.str().c_str());
4419         }
4420     }
4421   declareAsNew();
4422 }
4423
4424 /*!
4425  * This method is \b NOT wrapped into python because it can be useful only for performance reasons in C++ context.
4426  * All values in \a this must be 0. or 1. within eps error. 0 means false, 1 means true.
4427  * If an another value than 0 or 1 appear (within eps precision) an INTERP_KERNEL::Exception will be thrown.
4428  *
4429  * \throw if \a this is not allocated.
4430  * \throw if \a this has not exactly one component.
4431  */
4432 std::vector<bool> DataArrayDouble::toVectorOfBool(double eps) const
4433 {
4434   checkAllocated();
4435   if(getNumberOfComponents()!=1)
4436     throw INTERP_KERNEL::Exception("DataArrayDouble::toVectorOfBool : must be applied on single component array !");
4437   int nbt(getNumberOfTuples());
4438   std::vector<bool> ret(nbt);
4439   const double *pt(begin());
4440   for(int i=0;i<nbt;i++)
4441     {
4442       if(fabs(pt[i])<eps)
4443         ret[i]=false;
4444       else if(fabs(pt[i]-1.)<eps)
4445         ret[i]=true;
4446       else
4447         {
4448           std::ostringstream oss; oss << "DataArrayDouble::toVectorOfBool : the tuple #" << i << " has value " << pt[i] << " is invalid ! must be 0. or 1. !";
4449           throw INTERP_KERNEL::Exception(oss.str().c_str());
4450         }
4451     }
4452   return ret;
4453 }
4454
4455 /*!
4456  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
4457  * Server side.
4458  */
4459 void DataArrayDouble::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
4460 {
4461   tinyInfo.resize(2);
4462   if(isAllocated())
4463     {
4464       tinyInfo[0]=getNumberOfTuples();
4465       tinyInfo[1]=getNumberOfComponents();
4466     }
4467   else
4468     {
4469       tinyInfo[0]=-1;
4470       tinyInfo[1]=-1;
4471     }
4472 }
4473
4474 /*!
4475  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
4476  * Server side.
4477  */
4478 void DataArrayDouble::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
4479 {
4480   if(isAllocated())
4481     {
4482       int nbOfCompo=getNumberOfComponents();
4483       tinyInfo.resize(nbOfCompo+1);
4484       tinyInfo[0]=getName();
4485       for(int i=0;i<nbOfCompo;i++)
4486         tinyInfo[i+1]=getInfoOnComponent(i);
4487     }
4488   else
4489     {
4490       tinyInfo.resize(1);
4491       tinyInfo[0]=getName();
4492     }
4493 }
4494
4495 /*!
4496  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
4497  * This method returns if a feeding is needed.
4498  */
4499 bool DataArrayDouble::resizeForUnserialization(const std::vector<int>& tinyInfoI)
4500 {
4501   int nbOfTuple=tinyInfoI[0];
4502   int nbOfComp=tinyInfoI[1];
4503   if(nbOfTuple!=-1 || nbOfComp!=-1)
4504     {
4505       alloc(nbOfTuple,nbOfComp);
4506       return true;
4507     }
4508   return false;
4509 }
4510
4511 /*!
4512  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
4513  */
4514 void DataArrayDouble::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
4515 {
4516   setName(tinyInfoS[0]);
4517   if(isAllocated())
4518     {
4519       int nbOfCompo=getNumberOfComponents();
4520       for(int i=0;i<nbOfCompo;i++)
4521         setInfoOnComponent(i,tinyInfoS[i+1]);
4522     }
4523 }
4524
4525 /*!
4526  * Low static method that operates 3D rotation of 'nbNodes' 3D nodes whose coordinates are arranged in \a coordsIn
4527  * around an axe ( \a center, \a vect) and with angle \a angle.
4528  */
4529 void DataArrayDouble::Rotate3DAlg(const double *center, const double *vect, double angle, int nbNodes, const double *coordsIn, double *coordsOut)
4530 {
4531   if(!center || !vect)
4532     throw INTERP_KERNEL::Exception("DataArrayDouble::Rotate3DAlg : null vector in input !");
4533   double sina(sin(angle));
4534   double cosa(cos(angle));
4535   double vectorNorm[3];
4536   double matrix[9];
4537   double matrixTmp[9];
4538   double norm(sqrt(vect[0]*vect[0]+vect[1]*vect[1]+vect[2]*vect[2]));
4539   if(norm<std::numeric_limits<double>::min())
4540     throw INTERP_KERNEL::Exception("DataArrayDouble::Rotate3DAlg : magnitude of input vector is too close of 0. !");
4541   std::transform(vect,vect+3,vectorNorm,std::bind2nd(std::multiplies<double>(),1/norm));
4542   //rotation matrix computation
4543   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;
4544   matrixTmp[0]=vectorNorm[0]*vectorNorm[0]; matrixTmp[1]=vectorNorm[0]*vectorNorm[1]; matrixTmp[2]=vectorNorm[0]*vectorNorm[2];
4545   matrixTmp[3]=vectorNorm[1]*vectorNorm[0]; matrixTmp[4]=vectorNorm[1]*vectorNorm[1]; matrixTmp[5]=vectorNorm[1]*vectorNorm[2];
4546   matrixTmp[6]=vectorNorm[2]*vectorNorm[0]; matrixTmp[7]=vectorNorm[2]*vectorNorm[1]; matrixTmp[8]=vectorNorm[2]*vectorNorm[2];
4547   std::transform(matrixTmp,matrixTmp+9,matrixTmp,std::bind2nd(std::multiplies<double>(),1-cosa));
4548   std::transform(matrix,matrix+9,matrixTmp,matrix,std::plus<double>());
4549   matrixTmp[0]=0.; matrixTmp[1]=-vectorNorm[2]; matrixTmp[2]=vectorNorm[1];
4550   matrixTmp[3]=vectorNorm[2]; matrixTmp[4]=0.; matrixTmp[5]=-vectorNorm[0];
4551   matrixTmp[6]=-vectorNorm[1]; matrixTmp[7]=vectorNorm[0]; matrixTmp[8]=0.;
4552   std::transform(matrixTmp,matrixTmp+9,matrixTmp,std::bind2nd(std::multiplies<double>(),sina));
4553   std::transform(matrix,matrix+9,matrixTmp,matrix,std::plus<double>());
4554   //rotation matrix computed.
4555   double tmp[3];
4556   for(int i=0; i<nbNodes; i++)
4557     {
4558       std::transform(coordsIn+i*3,coordsIn+(i+1)*3,center,tmp,std::minus<double>());
4559       coordsOut[i*3]=matrix[0]*tmp[0]+matrix[1]*tmp[1]+matrix[2]*tmp[2]+center[0];
4560       coordsOut[i*3+1]=matrix[3]*tmp[0]+matrix[4]*tmp[1]+matrix[5]*tmp[2]+center[1];
4561       coordsOut[i*3+2]=matrix[6]*tmp[0]+matrix[7]*tmp[1]+matrix[8]*tmp[2]+center[2];
4562     }
4563 }
4564
4565 void DataArrayDouble::Symmetry3DPlane(const double point[3], const double normalVector[3], int nbNodes, const double *coordsIn, double *coordsOut)
4566 {
4567   double matrix[9],matrix2[9],matrix3[9];
4568   double vect[3],crossVect[3];
4569   INTERP_KERNEL::orthogonalVect3(normalVector,vect);
4570   crossVect[0]=normalVector[1]*vect[2]-normalVector[2]*vect[1];
4571   crossVect[1]=normalVector[2]*vect[0]-normalVector[0]*vect[2];
4572   crossVect[2]=normalVector[0]*vect[1]-normalVector[1]*vect[0];
4573   double nv(INTERP_KERNEL::norm<3>(vect)),ni(INTERP_KERNEL::norm<3>(normalVector)),nc(INTERP_KERNEL::norm<3>(crossVect));
4574   matrix[0]=vect[0]/nv; matrix[1]=crossVect[0]/nc; matrix[2]=-normalVector[0]/ni;
4575   matrix[3]=vect[1]/nv; matrix[4]=crossVect[1]/nc; matrix[5]=-normalVector[1]/ni;
4576   matrix[6]=vect[2]/nv; matrix[7]=crossVect[2]/nc; matrix[8]=-normalVector[2]/ni;
4577   matrix2[0]=vect[0]/nv; matrix2[1]=vect[1]/nv; matrix2[2]=vect[2]/nv;
4578   matrix2[3]=crossVect[0]/nc; matrix2[4]=crossVect[1]/nc; matrix2[5]=crossVect[2]/nc;
4579   matrix2[6]=normalVector[0]/ni; matrix2[7]=normalVector[1]/ni; matrix2[8]=normalVector[2]/ni;
4580   for(int i=0;i<3;i++)
4581     for(int j=0;j<3;j++)
4582       {
4583         double val(0.);
4584         for(int k=0;k<3;k++)
4585           val+=matrix[3*i+k]*matrix2[3*k+j];
4586         matrix3[3*i+j]=val;
4587       }
4588   //rotation matrix computed.
4589   double tmp[3];
4590   for(int i=0; i<nbNodes; i++)
4591     {
4592       std::transform(coordsIn+i*3,coordsIn+(i+1)*3,point,tmp,std::minus<double>());
4593       coordsOut[i*3]=matrix3[0]*tmp[0]+matrix3[1]*tmp[1]+matrix3[2]*tmp[2]+point[0];
4594       coordsOut[i*3+1]=matrix3[3]*tmp[0]+matrix3[4]*tmp[1]+matrix3[5]*tmp[2]+point[1];
4595       coordsOut[i*3+2]=matrix3[6]*tmp[0]+matrix3[7]*tmp[1]+matrix3[8]*tmp[2]+point[2];
4596     }
4597 }
4598
4599 void DataArrayDouble::GiveBaseForPlane(const double normalVector[3], double baseOfPlane[9])
4600 {
4601   double vect[3],crossVect[3];
4602   INTERP_KERNEL::orthogonalVect3(normalVector,vect);
4603   crossVect[0]=normalVector[1]*vect[2]-normalVector[2]*vect[1];
4604   crossVect[1]=normalVector[2]*vect[0]-normalVector[0]*vect[2];
4605   crossVect[2]=normalVector[0]*vect[1]-normalVector[1]*vect[0];
4606   double nv(INTERP_KERNEL::norm<3>(vect)),ni(INTERP_KERNEL::norm<3>(normalVector)),nc(INTERP_KERNEL::norm<3>(crossVect));
4607   baseOfPlane[0]=vect[0]/nv; baseOfPlane[1]=vect[1]/nv; baseOfPlane[2]=vect[2]/nv;
4608   baseOfPlane[3]=crossVect[0]/nc; baseOfPlane[4]=crossVect[1]/nc; baseOfPlane[5]=crossVect[2]/nc;
4609   baseOfPlane[6]=normalVector[0]/ni; baseOfPlane[7]=normalVector[1]/ni; baseOfPlane[8]=normalVector[2]/ni;
4610 }
4611
4612 /*!
4613  * Low static method that operates 3D rotation of \a nbNodes 3D nodes whose coordinates are arranged in \a coords
4614  * around the center point \a center and with angle \a angle.
4615  */
4616 void DataArrayDouble::Rotate2DAlg(const double *center, double angle, int nbNodes, const double *coordsIn, double *coordsOut)
4617 {
4618   double cosa=cos(angle);
4619   double sina=sin(angle);
4620   double matrix[4];
4621   matrix[0]=cosa; matrix[1]=-sina; matrix[2]=sina; matrix[3]=cosa;
4622   double tmp[2];
4623   for(int i=0; i<nbNodes; i++)
4624     {
4625       std::transform(coordsIn+i*2,coordsIn+(i+1)*2,center,tmp,std::minus<double>());
4626       coordsOut[i*2]=matrix[0]*tmp[0]+matrix[1]*tmp[1]+center[0];
4627       coordsOut[i*2+1]=matrix[2]*tmp[0]+matrix[3]*tmp[1]+center[1];
4628     }
4629 }
4630
4631 DataArrayDoubleIterator::DataArrayDoubleIterator(DataArrayDouble *da):_da(da),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
4632 {
4633   if(_da)
4634     {
4635       _da->incrRef();
4636       if(_da->isAllocated())
4637         {
4638           _nb_comp=da->getNumberOfComponents();
4639           _nb_tuple=da->getNumberOfTuples();
4640           _pt=da->getPointer();
4641         }
4642     }
4643 }
4644
4645 DataArrayDoubleIterator::~DataArrayDoubleIterator()
4646 {
4647   if(_da)
4648     _da->decrRef();
4649 }
4650
4651 DataArrayDoubleTuple *DataArrayDoubleIterator::nextt()
4652 {
4653   if(_tuple_id<_nb_tuple)
4654     {
4655       _tuple_id++;
4656       DataArrayDoubleTuple *ret=new DataArrayDoubleTuple(_pt,_nb_comp);
4657       _pt+=_nb_comp;
4658       return ret;
4659     }
4660   else
4661     return 0;
4662 }
4663
4664 DataArrayDoubleTuple::DataArrayDoubleTuple(double *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
4665 {
4666 }
4667
4668
4669 std::string DataArrayDoubleTuple::repr() const
4670 {
4671   std::ostringstream oss; oss.precision(17); oss << "(";
4672   for(int i=0;i<_nb_of_compo-1;i++)
4673     oss << _pt[i] << ", ";
4674   oss << _pt[_nb_of_compo-1] << ")";
4675   return oss.str();
4676 }
4677
4678 double DataArrayDoubleTuple::doubleValue() const
4679 {
4680   if(_nb_of_compo==1)
4681     return *_pt;
4682   throw INTERP_KERNEL::Exception("DataArrayDoubleTuple::doubleValue : DataArrayDoubleTuple instance has not exactly 1 component -> Not possible to convert it into a double precision float !");
4683 }
4684
4685 /*!
4686  * This method returns a newly allocated instance the caller should dealed with by a MEDCoupling::DataArrayDouble::decrRef.
4687  * This method performs \b no copy of data. The content is only referenced using MEDCoupling::DataArrayDouble::useArray with ownership set to \b false.
4688  * 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
4689  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
4690  */
4691 DataArrayDouble *DataArrayDoubleTuple::buildDADouble(int nbOfTuples, int nbOfCompo) const
4692 {
4693   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
4694     {
4695       DataArrayDouble *ret=DataArrayDouble::New();
4696       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
4697       return ret;
4698     }
4699   else
4700     {
4701       std::ostringstream oss; oss << "DataArrayDoubleTuple::buildDADouble : unable to build a requested DataArrayDouble instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
4702       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
4703       throw INTERP_KERNEL::Exception(oss.str().c_str());
4704     }
4705 }
4706
4707 /*!
4708  * Returns a new instance of DataArrayInt. The caller is to delete this array
4709  * using decrRef() as it is no more needed. 
4710  */
4711 DataArrayInt *DataArrayInt::New()
4712 {
4713   return new DataArrayInt;
4714 }
4715
4716 /*!
4717  * Returns the only one value in \a this, if and only if number of elements
4718  * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
4719  *  \return double - the sole value stored in \a this array.
4720  *  \throw If at least one of conditions stated above is not fulfilled.
4721  */
4722 int DataArrayInt::intValue() const
4723 {
4724   if(isAllocated())
4725     {
4726       if(getNbOfElems()==1)
4727         {
4728           return *getConstPointer();
4729         }
4730       else
4731         throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is allocated but number of elements is not equal to 1 !");
4732     }
4733   else
4734     throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is not allocated !");
4735 }
4736
4737 /*!
4738  * Returns an integer value characterizing \a this array, which is useful for a quick
4739  * comparison of many instances of DataArrayInt.
4740  *  \return int - the hash value.
4741  *  \throw If \a this is not allocated.
4742  */
4743 int DataArrayInt::getHashCode() const
4744 {
4745   checkAllocated();
4746   std::size_t nbOfElems=getNbOfElems();
4747   int ret=nbOfElems*65536;
4748   int delta=3;
4749   if(nbOfElems>48)
4750     delta=nbOfElems/8;
4751   int ret0=0;
4752   const int *pt=begin();
4753   for(std::size_t i=0;i<nbOfElems;i+=delta)
4754     ret0+=pt[i] & 0x1FFF;
4755   return ret+ret0;
4756 }
4757
4758 /*!
4759  * Returns a full copy of \a this. For more info on copying data arrays see
4760  * \ref MEDCouplingArrayBasicsCopyDeep.
4761  *  \return DataArrayInt * - a new instance of DataArrayInt.
4762  */
4763 DataArrayInt *DataArrayInt::deepCopy() const
4764 {
4765   return new DataArrayInt(*this);
4766 }
4767
4768 /*!
4769  * Returns either a \a deep or \a shallow copy of this array. For more info see
4770  * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
4771  *  \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
4772  *  \return DataArrayInt * - either a new instance of DataArrayInt (if \a dCpy
4773  *          == \a true) or \a this instance (if \a dCpy == \a false).
4774  */
4775 DataArrayInt *DataArrayInt::performCopyOrIncrRef(bool dCpy) const
4776 {
4777   if(dCpy)
4778     return deepCopy();
4779   else
4780     {
4781       incrRef();
4782       return const_cast<DataArrayInt *>(this);
4783     }
4784 }
4785
4786 /*!
4787  * Assign zero to all values in \a this array. To know more on filling arrays see
4788  * \ref MEDCouplingArrayFill.
4789  * \throw If \a this is not allocated.
4790  */
4791 void DataArrayInt::fillWithZero()
4792 {
4793   fillWithValue(0);
4794 }
4795
4796 /*!
4797  * Set all values in \a this array so that the i-th element equals to \a init + i
4798  * (i starts from zero). To know more on filling arrays see \ref MEDCouplingArrayFill.
4799  *  \param [in] init - value to assign to the first element of array.
4800  *  \throw If \a this->getNumberOfComponents() != 1
4801  *  \throw If \a this is not allocated.
4802  */
4803 void DataArrayInt::iota(int init)
4804 {
4805   checkAllocated();
4806   if(getNumberOfComponents()!=1)
4807     throw INTERP_KERNEL::Exception("DataArrayInt::iota : works only for arrays with only one component, you can call 'rearrange' method before !");
4808   int *ptr=getPointer();
4809   int ntuples=getNumberOfTuples();
4810   for(int i=0;i<ntuples;i++)
4811     ptr[i]=init+i;
4812   declareAsNew();
4813 }
4814
4815 /*!
4816  * Returns a textual and human readable representation of \a this instance of
4817  * DataArrayInt. This text is shown when a DataArrayInt is printed in Python.
4818  * \return std::string - text describing \a this DataArrayInt.
4819  * 
4820  * \sa reprNotTooLong, reprZip
4821  */
4822 std::string DataArrayInt::repr() const
4823 {
4824   std::ostringstream ret;
4825   reprStream(ret);
4826   return ret.str();
4827 }
4828
4829 std::string DataArrayInt::reprZip() const
4830 {
4831   std::ostringstream ret;
4832   reprZipStream(ret);
4833   return ret.str();
4834 }
4835
4836 /*!
4837  * This method is close to repr method except that when \a this has more than 1000 tuples, all tuples are not
4838  * printed out to avoid to consume too much space in interpretor.
4839  * \sa repr
4840  */
4841 std::string DataArrayInt::reprNotTooLong() const
4842 {
4843   std::ostringstream ret;
4844   reprNotTooLongStream(ret);
4845   return ret.str();
4846 }
4847
4848 void DataArrayInt::writeVTK(std::ostream& ofs, int indent, const std::string& type, const std::string& nameInFile, DataArrayByte *byteArr) const
4849 {
4850   static const char SPACE[4]={' ',' ',' ',' '};
4851   checkAllocated();
4852   std::string idt(indent,' ');
4853   ofs << idt << "<DataArray type=\"" << type << "\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
4854   if(byteArr)
4855     {
4856       ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
4857       if(std::string(type)=="Int32")
4858         {
4859           const char *data(reinterpret_cast<const char *>(begin()));
4860           std::size_t sz(getNbOfElems()*sizeof(int));
4861           byteArr->insertAtTheEnd(data,data+sz);
4862           byteArr->insertAtTheEnd(SPACE,SPACE+4);
4863         }
4864       else if(std::string(type)=="Int8")
4865         {
4866           INTERP_KERNEL::AutoPtr<char> tmp(new char[getNbOfElems()]);
4867           std::copy(begin(),end(),(char *)tmp);
4868           byteArr->insertAtTheEnd((char *)tmp,(char *)tmp+getNbOfElems());
4869           byteArr->insertAtTheEnd(SPACE,SPACE+4);
4870         }
4871       else if(std::string(type)=="UInt8")
4872         {
4873           INTERP_KERNEL::AutoPtr<unsigned char> tmp(new unsigned char[getNbOfElems()]);
4874           std::copy(begin(),end(),(unsigned char *)tmp);
4875           byteArr->insertAtTheEnd((unsigned char *)tmp,(unsigned char *)tmp+getNbOfElems());
4876           byteArr->insertAtTheEnd(SPACE,SPACE+4);
4877         }
4878       else
4879         throw INTERP_KERNEL::Exception("DataArrayInt::writeVTK : Only Int32, Int8 and UInt8 supported !");
4880     }
4881   else
4882     {
4883       ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
4884       std::copy(begin(),end(),std::ostream_iterator<int>(ofs," "));
4885     }
4886   ofs << std::endl << idt << "</DataArray>\n";
4887 }
4888
4889 void DataArrayInt::reprStream(std::ostream& stream) const
4890 {
4891   stream << "Name of int array : \"" << _name << "\"\n";
4892   reprWithoutNameStream(stream);
4893 }
4894
4895 void DataArrayInt::reprZipStream(std::ostream& stream) const
4896 {
4897   stream << "Name of int array : \"" << _name << "\"\n";
4898   reprZipWithoutNameStream(stream);
4899 }
4900
4901 void DataArrayInt::reprNotTooLongStream(std::ostream& stream) const
4902 {
4903   stream << "Name of int array : \"" << _name << "\"\n";
4904   reprNotTooLongWithoutNameStream(stream);
4905 }
4906
4907 void DataArrayInt::reprWithoutNameStream(std::ostream& stream) const
4908 {
4909   DataArray::reprWithoutNameStream(stream);
4910   _mem.repr(getNumberOfComponents(),stream);
4911 }
4912
4913 void DataArrayInt::reprZipWithoutNameStream(std::ostream& stream) const
4914 {
4915   DataArray::reprWithoutNameStream(stream);
4916   _mem.reprZip(getNumberOfComponents(),stream);
4917 }
4918
4919 void DataArrayInt::reprNotTooLongWithoutNameStream(std::ostream& stream) const
4920 {
4921   DataArray::reprWithoutNameStream(stream);
4922   stream.precision(17);
4923   _mem.reprNotTooLong(getNumberOfComponents(),stream);
4924 }
4925
4926 void DataArrayInt::reprCppStream(const std::string& varName, std::ostream& stream) const
4927 {
4928   int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
4929   const int *data=getConstPointer();
4930   stream << "DataArrayInt *" << varName << "=DataArrayInt::New();" << std::endl;
4931   if(nbTuples*nbComp>=1)
4932     {
4933       stream << "const int " << varName << "Data[" << nbTuples*nbComp << "]={";
4934       std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<int>(stream,","));
4935       stream << data[nbTuples*nbComp-1] << "};" << std::endl;
4936       stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
4937     }
4938   else
4939     stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
4940   stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
4941 }
4942
4943 /*!
4944  * Method that gives a quick overvien of \a this for python.
4945  */
4946 void DataArrayInt::reprQuickOverview(std::ostream& stream) const
4947 {
4948   static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
4949   stream << "DataArrayInt C++ instance at " << this << ". ";
4950   if(isAllocated())
4951     {
4952       int nbOfCompo=(int)_info_on_compo.size();
4953       if(nbOfCompo>=1)
4954         {
4955           int nbOfTuples=getNumberOfTuples();
4956           stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
4957           reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
4958         }
4959       else
4960         stream << "Number of components : 0.";
4961     }
4962   else
4963     stream << "*** No data allocated ****";
4964 }
4965
4966 void DataArrayInt::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
4967 {
4968   const int *data=begin();
4969   int nbOfTuples=getNumberOfTuples();
4970   int nbOfCompo=(int)_info_on_compo.size();
4971   std::ostringstream oss2; oss2 << "[";
4972   std::string oss2Str(oss2.str());
4973   bool isFinished=true;
4974   for(int i=0;i<nbOfTuples && isFinished;i++)
4975     {
4976       if(nbOfCompo>1)
4977         {
4978           oss2 << "(";
4979           for(int j=0;j<nbOfCompo;j++,data++)
4980             {
4981               oss2 << *data;
4982               if(j!=nbOfCompo-1) oss2 << ", ";
4983             }
4984           oss2 << ")";
4985         }
4986       else
4987         oss2 << *data++;
4988       if(i!=nbOfTuples-1) oss2 << ", ";
4989       std::string oss3Str(oss2.str());
4990       if(oss3Str.length()<maxNbOfByteInRepr)
4991         oss2Str=oss3Str;
4992       else
4993         isFinished=false;
4994     }
4995   stream << oss2Str;
4996   if(!isFinished)
4997     stream << "... ";
4998   stream << "]";
4999 }
5000
5001 /*!
5002  * Modifies in place \a this one-dimensional array so that each value \a v = \a indArrBg[ \a v ],
5003  * i.e. a current value is used as in index to get a new value from \a indArrBg.
5004  *  \param [in] indArrBg - pointer to the first element of array of new values to assign
5005  *         to \a this array.
5006  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
5007  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
5008  *  \throw If \a this->getNumberOfComponents() != 1
5009  *  \throw If any value of \a this can't be used as a valid index for 
5010  *         [\a indArrBg, \a indArrEnd).
5011  *
5012  *  \sa changeValue
5013  */
5014 void DataArrayInt::transformWithIndArr(const int *indArrBg, const int *indArrEnd)
5015 {
5016   checkAllocated();
5017   if(getNumberOfComponents()!=1)
5018     throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
5019   int nbElemsIn((int)std::distance(indArrBg,indArrEnd)),nbOfTuples(getNumberOfTuples()),*pt(getPointer());
5020   for(int i=0;i<nbOfTuples;i++,pt++)
5021     {
5022       if(*pt>=0 && *pt<nbElemsIn)
5023         *pt=indArrBg[*pt];
5024       else
5025         {
5026           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " of this value is " << *pt << ", should be in [0," << nbElemsIn << ") !";
5027           throw INTERP_KERNEL::Exception(oss.str().c_str());
5028         }
5029     }
5030   declareAsNew();
5031 }
5032
5033 /*!
5034  * Computes distribution of values of \a this one-dimensional array between given value
5035  * ranges (casts). This method is typically useful for entity number spliting by types,
5036  * for example. 
5037  *  \warning The values contained in \a arrBg should be sorted ascendently. No
5038  *           check of this is be done. If not, the result is not warranted. 
5039  *  \param [in] arrBg - the array of ascending values defining the value ranges. The i-th
5040  *         value of \a arrBg (\a arrBg[ i ]) gives the lowest value of the i-th range,
5041  *         and the greatest value of the i-th range equals to \a arrBg[ i+1 ] - 1. \a
5042  *         arrBg containing \a n values defines \a n-1 ranges. The last value of \a arrBg
5043  *         should be more than every value in \a this array.
5044  *  \param [in] arrEnd - specifies the end of the array \a arrBg, so that
5045  *              the last value of \a arrBg is \a arrEnd[ -1 ].
5046  *  \param [out] castArr - a new instance of DataArrayInt, of same size as \a this array
5047  *         (same number of tuples and components), the caller is to delete 
5048  *         using decrRef() as it is no more needed.
5049  *         This array contains indices of ranges for every value of \a this array. I.e.
5050  *         the i-th value of \a castArr gives the index of range the i-th value of \a this
5051  *         belongs to. Or, in other words, this parameter contains for each tuple in \a
5052  *         this in which cast it holds.
5053  *  \param [out] rankInsideCast - a new instance of DataArrayInt, of same size as \a this
5054  *         array, the caller is to delete using decrRef() as it is no more needed.
5055  *         This array contains ranks of values of \a this array within ranges
5056  *         they belongs to. I.e. the i-th value of \a rankInsideCast gives the rank of
5057  *         the i-th value of \a this array within the \a castArr[ i ]-th range, to which
5058  *         the i-th value of \a this belongs to. Or, in other words, this param contains 
5059  *         for each tuple its rank inside its cast. The rank is computed as difference
5060  *         between the value and the lowest value of range.
5061  *  \param [out] castsPresent - a new instance of DataArrayInt, containing indices of
5062  *         ranges (casts) to which at least one value of \a this array belongs.
5063  *         Or, in other words, this param contains the casts that \a this contains.
5064  *         The caller is to delete this array using decrRef() as it is no more needed.
5065  *
5066  * \b Example: If \a this contains [6,5,0,3,2,7,8,1,4] and \a arrBg contains [0,4,9] then
5067  *            the output of this method will be : 
5068  * - \a castArr       : [1,1,0,0,0,1,1,0,1]
5069  * - \a rankInsideCast: [2,1,0,3,2,3,4,1,0]
5070  * - \a castsPresent  : [0,1]
5071  *
5072  * I.e. values of \a this array belong to 2 ranges: #0 and #1. Value 6 belongs to the
5073  * range #1 and its rank within this range is 2; etc.
5074  *
5075  *  \throw If \a this->getNumberOfComponents() != 1.
5076  *  \throw If \a arrEnd - arrBg < 2.
5077  *  \throw If any value of \a this is not less than \a arrEnd[-1].
5078  */
5079 void DataArrayInt::splitByValueRange(const int *arrBg, const int *arrEnd,
5080                                      DataArrayInt *& castArr, DataArrayInt *& rankInsideCast, DataArrayInt *& castsPresent) const
5081 {
5082   checkAllocated();
5083   if(getNumberOfComponents()!=1)
5084     throw INTERP_KERNEL::Exception("Call splitByValueRange  method on DataArrayInt with only one component, you can call 'rearrange' method before !");
5085   int nbOfTuples=getNumberOfTuples();
5086   std::size_t nbOfCast=std::distance(arrBg,arrEnd);
5087   if(nbOfCast<2)
5088     throw INTERP_KERNEL::Exception("DataArrayInt::splitByValueRange : The input array giving the cast range values should be of size >=2 !");
5089   nbOfCast--;
5090   const int *work=getConstPointer();
5091   typedef std::reverse_iterator<const int *> rintstart;
5092   rintstart bg(arrEnd);//OK no problem because size of 'arr' is greater or equal 2
5093   rintstart end2(arrBg);
5094   MCAuto<DataArrayInt> ret1=DataArrayInt::New();
5095   MCAuto<DataArrayInt> ret2=DataArrayInt::New();
5096   MCAuto<DataArrayInt> ret3=DataArrayInt::New();
5097   ret1->alloc(nbOfTuples,1);
5098   ret2->alloc(nbOfTuples,1);
5099   int *ret1Ptr=ret1->getPointer();
5100   int *ret2Ptr=ret2->getPointer();
5101   std::set<std::size_t> castsDetected;
5102   for(int i=0;i<nbOfTuples;i++)
5103     {
5104       rintstart res=std::find_if(bg,end2,std::bind2nd(std::less_equal<int>(), work[i]));
5105       std::size_t pos=std::distance(bg,res);
5106       std::size_t pos2=nbOfCast-pos;
5107       if(pos2<nbOfCast)
5108         {
5109           ret1Ptr[i]=(int)pos2;
5110           ret2Ptr[i]=work[i]-arrBg[pos2];
5111           castsDetected.insert(pos2);
5112         }
5113       else
5114         {
5115           std::ostringstream oss; oss << "DataArrayInt::splitByValueRange : At rank #" << i << " the value is " << work[i] << " should be in [0," << *bg << ") !";
5116           throw INTERP_KERNEL::Exception(oss.str().c_str());
5117         }
5118     }
5119   ret3->alloc((int)castsDetected.size(),1);
5120   std::copy(castsDetected.begin(),castsDetected.end(),ret3->getPointer());
5121   castArr=ret1.retn();
5122   rankInsideCast=ret2.retn();
5123   castsPresent=ret3.retn();
5124 }
5125
5126 /*!
5127  * 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 ).
5128  * 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 ).
5129  * This method works only if \a this is allocated and single component. If not an exception will be thrown.
5130  *
5131  * \param [out] strt - the start of the range (included) if true is returned.
5132  * \param [out] sttoopp - the end of the range (not included) if true is returned.
5133  * \param [out] stteepp - the step of the range if true is returned.
5134  * \return the verdict of the check.
5135  *
5136  * \sa DataArray::GetNumberOfItemGivenBES
5137  */
5138 bool DataArrayInt::isRange(int& strt, int& sttoopp, int& stteepp) const
5139 {
5140   checkAllocated();
5141   if(getNumberOfComponents()!=1)
5142     throw INTERP_KERNEL::Exception("DataArrayInt::isRange : this must be single component array !");
5143   int nbTuples(getNumberOfTuples());
5144   if(nbTuples==0)
5145     { strt=0; sttoopp=0; stteepp=1; return true; }
5146   const int *pt(begin());
5147   strt=*pt; 
5148   if(nbTuples==1)
5149     { sttoopp=strt+1; stteepp=1; return true; }
5150   strt=*pt; sttoopp=pt[nbTuples-1];
5151   if(strt==sttoopp)
5152     return false;
5153   if(sttoopp>strt)
5154     {
5155       sttoopp++;
5156       int a(sttoopp-1-strt),tmp(strt);
5157       if(a%(nbTuples-1)!=0)
5158         return false;
5159       stteepp=a/(nbTuples-1);
5160       for(int i=0;i<nbTuples;i++,tmp+=stteepp)
5161         if(pt[i]!=tmp)
5162           return false;
5163       return true;
5164     }
5165   else
5166     {
5167       sttoopp--;
5168       int a(strt-sttoopp-1),tmp(strt);
5169       if(a%(nbTuples-1)!=0)
5170         return false;
5171       stteepp=-(a/(nbTuples-1));
5172       for(int i=0;i<nbTuples;i++,tmp+=stteepp)
5173         if(pt[i]!=tmp)
5174           return false;
5175       return true;
5176     }
5177 }
5178
5179 /*!
5180  * Creates a one-dimensional DataArrayInt (\a res) whose contents are computed from 
5181  * values of \a this (\a a) and the given (\a indArr) arrays as follows:
5182  * \a res[ \a indArr[ \a a[ i ]]] = i. I.e. for each value in place i \a v = \a a[ i ],
5183  * new value in place \a indArr[ \a v ] is i.
5184  *  \param [in] indArrBg - the array holding indices within the result array to assign
5185  *         indices of values of \a this array pointing to values of \a indArrBg.
5186  *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
5187  *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
5188  *  \return DataArrayInt * - the new instance of DataArrayInt.
5189  *          The caller is to delete this result array using decrRef() as it is no more
5190  *          needed.
5191  *  \throw If \a this->getNumberOfComponents() != 1.
5192  *  \throw If any value of \a this array is not a valid index for \a indArrBg array.
5193  *  \throw If any value of \a indArrBg is not a valid index for \a this array.
5194  */
5195 DataArrayInt *DataArrayInt::transformWithIndArrR(const int *indArrBg, const int *indArrEnd) const
5196 {
5197   checkAllocated();
5198   if(getNumberOfComponents()!=1)
5199     throw INTERP_KERNEL::Exception("Call transformWithIndArrR method on DataArrayInt with only one component, you can call 'rearrange' method before !");
5200   int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
5201   int nbOfTuples=getNumberOfTuples();
5202   const int *pt=getConstPointer();
5203   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5204   ret->alloc(nbOfTuples,1);
5205   ret->fillWithValue(-1);
5206   int *tmp=ret->getPointer();
5207   for(int i=0;i<nbOfTuples;i++,pt++)
5208     {
5209       if(*pt>=0 && *pt<nbElemsIn)
5210         {
5211           int pos=indArrBg[*pt];
5212           if(pos>=0 && pos<nbOfTuples)
5213             tmp[pos]=i;
5214           else
5215             {
5216               std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value of new pos is " << pos << " ( indArrBg[" << *pt << "]) ! Should be in [0," << nbOfTuples << ") !";
5217               throw INTERP_KERNEL::Exception(oss.str().c_str());
5218             }
5219         }
5220       else
5221         {
5222           std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn << " !";
5223           throw INTERP_KERNEL::Exception(oss.str().c_str());
5224         }
5225     }
5226   return ret.retn();
5227 }
5228
5229 /*!
5230  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
5231  * from values of \a this array, which is supposed to contain a renumbering map in 
5232  * "Old to New" mode. The result array contains a renumbering map in "New to Old" mode.
5233  * To know how to use the renumbering maps see \ref numbering.
5234  *  \param [in] newNbOfElem - the number of tuples in the result array.
5235  *  \return DataArrayInt * - the new instance of DataArrayInt.
5236  *          The caller is to delete this result array using decrRef() as it is no more
5237  *          needed.
5238  * 
5239  *  \if ENABLE_EXAMPLES
5240  *  \ref cpp_mcdataarrayint_invertarrayo2n2n2o "Here is a C++ example".<br>
5241  *  \ref py_mcdataarrayint_invertarrayo2n2n2o  "Here is a Python example".
5242  *  \endif
5243  */
5244 DataArrayInt *DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const
5245 {
5246   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5247   ret->alloc(newNbOfElem,1);
5248   int nbOfOldNodes=getNumberOfTuples();
5249   const int *old2New=getConstPointer();
5250   int *pt=ret->getPointer();
5251   for(int i=0;i!=nbOfOldNodes;i++)
5252     {
5253       int newp(old2New[i]);
5254       if(newp!=-1)
5255         {
5256           if(newp>=0 && newp<newNbOfElem)
5257             pt[newp]=i;
5258           else
5259             {
5260               std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2O : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
5261               throw INTERP_KERNEL::Exception(oss.str().c_str());
5262             }
5263         }
5264     }
5265   return ret.retn();
5266 }
5267
5268 /*!
5269  * This method is similar to DataArrayInt::invertArrayO2N2N2O except that 
5270  * 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]
5271  */
5272 DataArrayInt *DataArrayInt::invertArrayO2N2N2OBis(int newNbOfElem) const
5273 {
5274   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5275   ret->alloc(newNbOfElem,1);
5276   int nbOfOldNodes=getNumberOfTuples();
5277   const int *old2New=getConstPointer();
5278   int *pt=ret->getPointer();
5279   for(int i=nbOfOldNodes-1;i>=0;i--)
5280     {
5281       int newp(old2New[i]);
5282       if(newp!=-1)
5283         {
5284           if(newp>=0 && newp<newNbOfElem)
5285             pt[newp]=i;
5286           else
5287             {
5288               std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2OBis : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
5289               throw INTERP_KERNEL::Exception(oss.str().c_str());
5290             }
5291         }
5292     }
5293   return ret.retn();
5294 }
5295
5296 /*!
5297  * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
5298  * from values of \a this array, which is supposed to contain a renumbering map in 
5299  * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
5300  * To know how to use the renumbering maps see \ref numbering.
5301  *  \param [in] newNbOfElem - the number of tuples in the result array.
5302  *  \return DataArrayInt * - the new instance of DataArrayInt.
5303  *          The caller is to delete this result array using decrRef() as it is no more
5304  *          needed.
5305  * 
5306  *  \if ENABLE_EXAMPLES
5307  *  \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
5308  *
5309  *  \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
5310  *  \endif
5311  */
5312 DataArrayInt *DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const
5313 {
5314   checkAllocated();
5315   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5316   ret->alloc(oldNbOfElem,1);
5317   const int *new2Old=getConstPointer();
5318   int *pt=ret->getPointer();
5319   std::fill(pt,pt+oldNbOfElem,-1);
5320   int nbOfNewElems=getNumberOfTuples();
5321   for(int i=0;i<nbOfNewElems;i++)
5322     {
5323       int v(new2Old[i]);
5324       if(v>=0 && v<oldNbOfElem)
5325         pt[v]=i;
5326       else
5327         {
5328           std::ostringstream oss; oss << "DataArrayInt::invertArrayN2O2O2N : in new id #" << i << " old value is " << v << " expected to be in [0," << oldNbOfElem << ") !";
5329           throw INTERP_KERNEL::Exception(oss.str().c_str());
5330         }
5331     }
5332   return ret.retn();
5333 }
5334
5335 /*!
5336  * Equivalent to DataArrayInt::isEqual except that if false the reason of
5337  * mismatch is given.
5338  * 
5339  * \param [in] other the instance to be compared with \a this
5340  * \param [out] reason In case of inequality returns the reason.
5341  * \sa DataArrayInt::isEqual
5342  */
5343 bool DataArrayInt::isEqualIfNotWhy(const DataArrayInt& other, std::string& reason) const
5344 {
5345   if(!areInfoEqualsIfNotWhy(other,reason))
5346     return false;
5347   return _mem.isEqual(other._mem,0,reason);
5348 }
5349
5350 /*!
5351  * Checks if \a this and another DataArrayInt are fully equal. For more info see
5352  * \ref MEDCouplingArrayBasicsCompare.
5353  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
5354  *  \return bool - \a true if the two arrays are equal, \a false else.
5355  */
5356 bool DataArrayInt::isEqual(const DataArrayInt& other) const
5357 {
5358   std::string tmp;
5359   return isEqualIfNotWhy(other,tmp);
5360 }
5361
5362 /*!
5363  * Checks if values of \a this and another DataArrayInt are equal. For more info see
5364  * \ref MEDCouplingArrayBasicsCompare.
5365  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
5366  *  \return bool - \a true if the values of two arrays are equal, \a false else.
5367  */
5368 bool DataArrayInt::isEqualWithoutConsideringStr(const DataArrayInt& other) const
5369 {
5370   std::string tmp;
5371   return _mem.isEqual(other._mem,0,tmp);
5372 }
5373
5374 /*!
5375  * Checks if values of \a this and another DataArrayInt are equal. Comparison is
5376  * performed on sorted value sequences.
5377  * For more info see\ref MEDCouplingArrayBasicsCompare.
5378  *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
5379  *  \return bool - \a true if the sorted values of two arrays are equal, \a false else.
5380  */
5381 bool DataArrayInt::isEqualWithoutConsideringStrAndOrder(const DataArrayInt& other) const
5382 {
5383   MCAuto<DataArrayInt> a=deepCopy();
5384   MCAuto<DataArrayInt> b=other.deepCopy();
5385   a->sort();
5386   b->sort();
5387   return a->isEqualWithoutConsideringStr(*b);
5388 }
5389
5390 /*!
5391  * This method compares content of input vector \a v and \a this.
5392  * 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.
5393  * For performance reasons \a this is expected to be sorted ascendingly. If not an exception will be thrown.
5394  *
5395  * \param [in] v - the vector of 'flags' to be compared with \a this.
5396  *
5397  * \throw If \a this is not sorted ascendingly.
5398  * \throw If \a this has not exactly one component.
5399  * \throw If \a this is not allocated.
5400  */
5401 bool DataArrayInt::isFittingWith(const std::vector<bool>& v) const
5402 {
5403   checkAllocated();
5404   if(getNumberOfComponents()!=1)
5405     throw INTERP_KERNEL::Exception("DataArrayInt::isFittingWith : number of components of this should be equal to one !");
5406   const int *w(begin()),*end2(end());
5407   int refVal=-std::numeric_limits<int>::max();
5408   int i=0;
5409   std::vector<bool>::const_iterator it(v.begin());
5410   for(;it!=v.end();it++,i++)
5411     {
5412       if(*it)
5413         {
5414           if(w!=end2)
5415             {
5416               if(*w++==i)
5417                 {
5418                   if(i>refVal)
5419                     refVal=i;
5420                   else
5421                     {
5422                       std::ostringstream oss; oss << "DataArrayInt::isFittingWith : At pos #" << std::distance(begin(),w-1) << " this is not sorted ascendingly !";
5423                       throw INTERP_KERNEL::Exception(oss.str().c_str());
5424                     }
5425                 }
5426               else
5427                 return false;
5428             }
5429           else
5430             return false;
5431         }
5432     }
5433   return w==end2;
5434 }
5435
5436 /*!
5437  * This method assumes that \a this has one component and is allocated. This method scans all tuples in \a this and for all tuple equal to \a val
5438  * put True to the corresponding entry in \a vec.
5439  * \a vec is expected to be with the same size than the number of tuples of \a this.
5440  *
5441  *  \sa DataArrayInt::switchOnTupleNotEqualTo.
5442  */
5443 void DataArrayInt::switchOnTupleEqualTo(int val, std::vector<bool>& vec) const
5444 {
5445   checkAllocated();
5446   if(getNumberOfComponents()!=1)
5447     throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleEqualTo : number of components of this should be equal to one !");
5448   int nbOfTuples(getNumberOfTuples());
5449   if(nbOfTuples!=(int)vec.size())
5450     throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleEqualTo : number of tuples of this should be equal to size of input vector of bool !");
5451   const int *pt(begin());
5452   for(int i=0;i<nbOfTuples;i++)
5453     if(pt[i]==val)
5454       vec[i]=true;
5455 }
5456
5457 /*!
5458  * 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
5459  * put True to the corresponding entry in \a vec.
5460  * \a vec is expected to be with the same size than the number of tuples of \a this.
5461  * 
5462  *  \sa DataArrayInt::switchOnTupleEqualTo.
5463  */
5464 void DataArrayInt::switchOnTupleNotEqualTo(int val, std::vector<bool>& vec) const
5465 {
5466   checkAllocated();
5467   if(getNumberOfComponents()!=1)
5468     throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleNotEqualTo : number of components of this should be equal to one !");
5469   int nbOfTuples(getNumberOfTuples());
5470   if(nbOfTuples!=(int)vec.size())
5471     throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleNotEqualTo : number of tuples of this should be equal to size of input vector of bool !");
5472   const int *pt(begin());
5473   for(int i=0;i<nbOfTuples;i++)
5474     if(pt[i]!=val)
5475       vec[i]=true;
5476 }
5477
5478 /*!
5479  * Computes for each tuple the sum of number of components values in the tuple and return it.
5480  * 
5481  * \return DataArrayInt * - the new instance of DataArrayInt containing the
5482  *          same number of tuples as \a this array and one component.
5483  *          The caller is to delete this result array using decrRef() as it is no more
5484  *          needed.
5485  *  \throw If \a this is not allocated.
5486  */
5487 DataArrayInt *DataArrayInt::sumPerTuple() const
5488 {
5489   checkAllocated();
5490   int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
5491   MCAuto<DataArrayInt> ret(DataArrayInt::New());
5492   ret->alloc(nbOfTuple,1);
5493   const int *src(getConstPointer());
5494   int *dest(ret->getPointer());
5495   for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
5496     *dest=std::accumulate(src,src+nbOfComp,0);
5497   return ret.retn();
5498 }
5499
5500 /*!
5501  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
5502  * If not an exception is thrown.
5503  *  \param [in] increasing - if \a true, the array values should be increasing.
5504  *  \throw If sequence of values is not strictly monotonic in agreement with \a
5505  *         increasing arg.
5506  *  \throw If \a this->getNumberOfComponents() != 1.
5507  *  \throw If \a this is not allocated.
5508  */
5509 void DataArrayInt::checkMonotonic(bool increasing) const
5510 {
5511   if(!isMonotonic(increasing))
5512     {
5513       if (increasing)
5514         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not INCREASING monotonic !");
5515       else
5516         throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not DECREASING monotonic !");
5517     }
5518 }
5519
5520 /*!
5521  * Checks that \a this array is consistently **increasing** or **decreasing** in value.
5522  *  \param [in] increasing - if \a true, array values should be increasing.
5523  *  \return bool - \a true if values change in accordance with \a increasing arg.
5524  *  \throw If \a this->getNumberOfComponents() != 1.
5525  *  \throw If \a this is not allocated.
5526  */
5527 bool DataArrayInt::isMonotonic(bool increasing) const
5528 {
5529   checkAllocated();
5530   if(getNumberOfComponents()!=1)
5531     throw INTERP_KERNEL::Exception("DataArrayInt::isMonotonic : only supported with 'this' array with ONE component !");
5532   int nbOfElements=getNumberOfTuples();
5533   const int *ptr=getConstPointer();
5534   if(nbOfElements==0)
5535     return true;
5536   int ref=ptr[0];
5537   if(increasing)
5538     {
5539       for(int i=1;i<nbOfElements;i++)
5540         {
5541           if(ptr[i]>=ref)
5542             ref=ptr[i];
5543           else
5544             return false;
5545         }
5546     }
5547   else
5548     {
5549       for(int i=1;i<nbOfElements;i++)
5550         {
5551           if(ptr[i]<=ref)
5552             ref=ptr[i];
5553           else
5554             return false;
5555         }
5556     }
5557   return true;
5558 }
5559
5560 /*!
5561  * This method check that array consistently INCREASING or DECREASING in value.
5562  */
5563 bool DataArrayInt::isStrictlyMonotonic(bool increasing) const
5564 {
5565   checkAllocated();
5566   if(getNumberOfComponents()!=1)
5567     throw INTERP_KERNEL::Exception("DataArrayInt::isStrictlyMonotonic : only supported with 'this' array with ONE component !");
5568   int nbOfElements=getNumberOfTuples();
5569   const int *ptr=getConstPointer();
5570   if(nbOfElements==0)
5571     return true;
5572   int ref=ptr[0];
5573   if(increasing)
5574     {
5575       for(int i=1;i<nbOfElements;i++)
5576         {
5577           if(ptr[i]>ref)
5578             ref=ptr[i];
5579           else
5580             return false;
5581         }
5582     }
5583   else
5584     {
5585       for(int i=1;i<nbOfElements;i++)
5586         {
5587           if(ptr[i]<ref)
5588             ref=ptr[i];
5589           else
5590             return false;
5591         }
5592     }
5593   return true;
5594 }
5595
5596 /*!
5597  * This method check that array consistently INCREASING or DECREASING in value.
5598  */
5599 void DataArrayInt::checkStrictlyMonotonic(bool increasing) const
5600 {
5601   if(!isStrictlyMonotonic(increasing))
5602     {
5603       if (increasing)
5604         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly INCREASING monotonic !");
5605       else
5606         throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly DECREASING monotonic !");
5607     }
5608 }
5609
5610 /*!
5611  * Creates a new one-dimensional DataArrayInt of the same size as \a this and a given
5612  * one-dimensional arrays that must be of the same length. The result array describes
5613  * correspondence between \a this and \a other arrays, so that 
5614  * <em> other.getIJ(i,0) == this->getIJ(ret->getIJ(i),0)</em>. If such a permutation is
5615  * not possible because some element in \a other is not in \a this, an exception is thrown.
5616  *  \param [in] other - an array to compute permutation to.
5617  *  \return DataArrayInt * - a new instance of DataArrayInt, which is a permutation array
5618  * from \a this to \a other. The caller is to delete this array using decrRef() as it is
5619  * no more needed.
5620  *  \throw If \a this->getNumberOfComponents() != 1.
5621  *  \throw If \a other->getNumberOfComponents() != 1.
5622  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples().
5623  *  \throw If \a other includes a value which is not in \a this array.
5624  * 
5625  *  \if ENABLE_EXAMPLES
5626  *  \ref cpp_mcdataarrayint_buildpermutationarr "Here is a C++ example".
5627  *
5628  *  \ref py_mcdataarrayint_buildpermutationarr "Here is a Python example".
5629  *  \endif
5630  */
5631 DataArrayInt *DataArrayInt::buildPermutationArr(const DataArrayInt& other) const
5632 {
5633   checkAllocated();
5634   if(getNumberOfComponents()!=1 || other.getNumberOfComponents()!=1)
5635     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' have to have exactly ONE component !");
5636   int nbTuple=getNumberOfTuples();
5637   other.checkAllocated();
5638   if(nbTuple!=other.getNumberOfTuples())
5639     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' must have the same number of tuple !");
5640   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5641   ret->alloc(nbTuple,1);
5642   ret->fillWithValue(-1);
5643   const int *pt=getConstPointer();
5644   std::map<int,int> mm;
5645   for(int i=0;i<nbTuple;i++)
5646     mm[pt[i]]=i;
5647   pt=other.getConstPointer();
5648   int *retToFill=ret->getPointer();
5649   for(int i=0;i<nbTuple;i++)
5650     {
5651       std::map<int,int>::const_iterator it=mm.find(pt[i]);
5652       if(it==mm.end())
5653         {
5654           std::ostringstream oss; oss << "DataArrayInt::buildPermutationArr : Arrays mismatch : element (" << pt[i] << ") in 'other' not findable in 'this' !";
5655           throw INTERP_KERNEL::Exception(oss.str().c_str());
5656         }
5657       retToFill[i]=(*it).second;
5658     }
5659   return ret.retn();
5660 }
5661
5662 /*!
5663  * Elements of \a partOfThis are expected to be included in \a this.
5664  * The returned array \a ret is so that this[ret]==partOfThis
5665  *
5666  * 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]
5667  * the return array will contain [3,2,5,7].
5668  *
5669  * \a this is expected to be a 1 compo allocated array.
5670  * \param [in] partOfThis - A 1 compo allocated array
5671  * \return - A newly allocated array to be dealed by caller having the same number of tuples than \a partOfThis.
5672  * \throw if two same element is present twice in \a this
5673  * \throw if an element in \a partOfThis is \b NOT in \a this.
5674  */
5675 DataArrayInt *DataArrayInt::indicesOfSubPart(const DataArrayInt& partOfThis) const
5676 {
5677   if(getNumberOfComponents()!=1 || partOfThis.getNumberOfComponents()!=1)
5678     throw INTERP_KERNEL::Exception("DataArrayInt::indicesOfSubPart : this and input array must be one component array !");
5679   checkAllocated(); partOfThis.checkAllocated();
5680   int thisNbTuples(getNumberOfTuples()),nbTuples(partOfThis.getNumberOfTuples());
5681   const int *thisPt(begin()),*pt(partOfThis.begin());
5682   MCAuto<DataArrayInt> ret(DataArrayInt::New());
5683   ret->alloc(nbTuples,1);
5684   int *retPt(ret->getPointer());
5685   std::map<int,int> m;
5686   for(int i=0;i<thisNbTuples;i++,thisPt++)
5687     m[*thisPt]=i;
5688   if(m.size()!=thisNbTuples)
5689     throw INTERP_KERNEL::Exception("DataArrayInt::indicesOfSubPart : some elements appears more than once !");
5690   for(int i=0;i<nbTuples;i++,retPt++,pt++)
5691     {
5692       std::map<int,int>::const_iterator it(m.find(*pt));
5693       if(it!=m.end())
5694         *retPt=(*it).second;
5695       else
5696         {
5697           std::ostringstream oss; oss << "DataArrayInt::indicesOfSubPart : At pos #" << i << " of input array value is " << *pt << " not in this !";
5698           throw INTERP_KERNEL::Exception(oss.str());
5699         }
5700     }
5701   return ret.retn();
5702 }
5703
5704 void DataArrayInt::aggregate(const DataArrayInt *other)
5705 {
5706   if(!other)
5707     throw INTERP_KERNEL::Exception("DataArrayInt::aggregate : null pointer !");
5708   if(getNumberOfComponents()!=other->getNumberOfComponents())
5709     throw INTERP_KERNEL::Exception("DataArrayInt::aggregate : mismatch number of components !");
5710   _mem.insertAtTheEnd(other->begin(),other->end());
5711 }
5712
5713 /*!
5714  * Returns a new DataArrayInt holding the same values as \a this array but differently
5715  * arranged in memory. If \a this array holds 2 components of 3 values:
5716  * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
5717  * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
5718  *  \warning Do not confuse this method with transpose()!
5719  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
5720  *          is to delete using decrRef() as it is no more needed.
5721  *  \throw If \a this is not allocated.
5722  */
5723 DataArrayInt *DataArrayInt::fromNoInterlace() const
5724 {
5725   checkAllocated();
5726   if(_mem.isNull())
5727     throw INTERP_KERNEL::Exception("DataArrayInt::fromNoInterlace : Not defined array !");
5728   int *tab=_mem.fromNoInterlace(getNumberOfComponents());
5729   DataArrayInt *ret=DataArrayInt::New();
5730   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
5731   return ret;
5732 }
5733
5734 /*!
5735  * Returns a new DataArrayInt holding the same values as \a this array but differently
5736  * arranged in memory. If \a this array holds 2 components of 3 values:
5737  * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
5738  * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
5739  *  \warning Do not confuse this method with transpose()!
5740  *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
5741  *          is to delete using decrRef() as it is no more needed.
5742  *  \throw If \a this is not allocated.
5743  */
5744 DataArrayInt *DataArrayInt::toNoInterlace() const
5745 {
5746   checkAllocated();
5747   if(_mem.isNull())
5748     throw INTERP_KERNEL::Exception("DataArrayInt::toNoInterlace : Not defined array !");
5749   int *tab=_mem.toNoInterlace(getNumberOfComponents());
5750   DataArrayInt *ret=DataArrayInt::New();
5751   ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
5752   return ret;
5753 }
5754
5755 /*!
5756  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode.
5757  * This map, if applied to \a this array, would make it sorted. For example, if
5758  * \a this array contents are [9,10,0,6,4,11,3,7] then the contents of the result array
5759  * are [5,6,0,3,2,7,1,4]; if this result array (\a res) is used as an argument in call
5760  * \a this->renumber(\a res) then the returned array contains [0,3,4,6,7,9,10,11].
5761  * This method is useful for renumbering (in MED file for example). For more info
5762  * on renumbering see \ref numbering.
5763  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5764  *          array using decrRef() as it is no more needed.
5765  *  \throw If \a this is not allocated.
5766  *  \throw If \a this->getNumberOfComponents() != 1.
5767  *  \throw If there are equal values in \a this array.
5768  */
5769 DataArrayInt *DataArrayInt::checkAndPreparePermutation() const
5770 {
5771   checkAllocated();
5772   if(getNumberOfComponents()!=1)
5773     throw INTERP_KERNEL::Exception("DataArrayInt::checkAndPreparePermutation : number of components must == 1 !");
5774   int nbTuples=getNumberOfTuples();
5775   const int *pt=getConstPointer();
5776   int *pt2=CheckAndPreparePermutation(pt,pt+nbTuples);
5777   DataArrayInt *ret=DataArrayInt::New();
5778   ret->useArray(pt2,true,C_DEALLOC,nbTuples,1);
5779   return ret;
5780 }
5781
5782 /*!
5783  * 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
5784  * input array \a ids2.
5785  * \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.
5786  * 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
5787  * inversely.
5788  * In case of success (no throw) : \c ids1->renumber(ret)->isEqual(ids2) where \a ret is the return of this method.
5789  *
5790  * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5791  *          array using decrRef() as it is no more needed.
5792  * \throw If either ids1 or ids2 is null not allocated or not with one components.
5793  * 
5794  */
5795 DataArrayInt *DataArrayInt::FindPermutationFromFirstToSecond(const DataArrayInt *ids1, const DataArrayInt *ids2)
5796 {
5797   if(!ids1 || !ids2)
5798     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be not null !");
5799   if(!ids1->isAllocated() || !ids2->isAllocated())
5800     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be allocated !");
5801   if(ids1->getNumberOfComponents()!=1 || ids2->getNumberOfComponents()!=1)
5802     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays have exactly one component !");
5803   if(ids1->getNumberOfTuples()!=ids2->getNumberOfTuples())
5804     {
5805       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 !";
5806       throw INTERP_KERNEL::Exception(oss.str().c_str());
5807     }
5808   MCAuto<DataArrayInt> p1(ids1->deepCopy());
5809   MCAuto<DataArrayInt> p2(ids2->deepCopy());
5810   p1->sort(true); p2->sort(true);
5811   if(!p1->isEqualWithoutConsideringStr(*p2))
5812     throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two arrays are not lying on same ids ! Impossible to find a permutation between the 2 arrays !");
5813   p1=ids1->checkAndPreparePermutation();
5814   p2=ids2->checkAndPreparePermutation();
5815   p2=p2->invertArrayO2N2N2O(p2->getNumberOfTuples());
5816   p2=p2->selectByTupleIdSafe(p1->begin(),p1->end());
5817   return p2.retn();
5818 }
5819
5820 /*!
5821  * Returns two arrays describing a surjective mapping from \a this set of values (\a A)
5822  * onto a set of values of size \a targetNb (\a B). The surjective function is 
5823  * \a B[ \a A[ i ]] = i. That is to say that for each \a id in [0,\a targetNb), where \a
5824  * targetNb < \a this->getNumberOfTuples(), there exists at least one tupleId (\a tid) so
5825  * that <em> this->getIJ( tid, 0 ) == id</em>. <br>
5826  * The first of out arrays returns indices of elements of \a this array, grouped by their
5827  * place in the set \a B. The second out array is the index of the first one; it shows how
5828  * many elements of \a A are mapped into each element of \a B. <br>
5829  * For more info on
5830  * mapping and its usage in renumbering see \ref numbering. <br>
5831  * \b Example:
5832  * - \a this: [0,3,2,3,2,2,1,2]
5833  * - \a targetNb: 4
5834  * - \a arr:  [0,  6,  2,4,5,7,  1,3]
5835  * - \a arrI: [0,1,2,6,8]
5836  *
5837  * This result means: <br>
5838  * the element of \a B 0 encounters within \a A once (\a arrI[ 0+1 ] - \a arrI[ 0 ]) and
5839  * its index within \a A is 0 ( \a arr[ 0:1 ] == \a arr[ \a arrI[ 0 ] : \a arrI[ 0+1 ]]);<br>
5840  * the element of \a B 2 encounters within \a A 4 times (\a arrI[ 2+1 ] - \a arrI[ 2 ]) and
5841  * its indices within \a A are [2,4,5,7] ( \a arr[ 2:6 ] == \a arr[ \a arrI[ 2 ] : 
5842  * \a arrI[ 2+1 ]]); <br> etc.
5843  *  \param [in] targetNb - the size of the set \a B. \a targetNb must be equal or more
5844  *         than the maximal value of \a A.
5845  *  \param [out] arr - a new instance of DataArrayInt returning indices of
5846  *         elements of \a this, grouped by their place in the set \a B. The caller is to delete
5847  *         this array using decrRef() as it is no more needed.
5848  *  \param [out] arrI - a new instance of DataArrayInt returning size of groups of equal
5849  *         elements of \a this. The caller is to delete this array using decrRef() as it
5850  *         is no more needed.
5851  *  \throw If \a this is not allocated.
5852  *  \throw If \a this->getNumberOfComponents() != 1.
5853  *  \throw If any value in \a this is more or equal to \a targetNb.
5854  */
5855 void DataArrayInt::changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, DataArrayInt *&arrI) const
5856 {
5857   checkAllocated();
5858   if(getNumberOfComponents()!=1)
5859     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : number of components must == 1 !");
5860   int nbOfTuples=getNumberOfTuples();
5861   MCAuto<DataArrayInt> ret(DataArrayInt::New());
5862   MCAuto<DataArrayInt> retI(DataArrayInt::New());
5863   retI->alloc(targetNb+1,1);
5864   const int *input=getConstPointer();
5865   std::vector< std::vector<int> > tmp(targetNb);
5866   for(int i=0;i<nbOfTuples;i++)
5867     {
5868       int tmp2=input[i];
5869       if(tmp2>=0 && tmp2<targetNb)
5870         tmp[tmp2].push_back(i);
5871       else
5872         {
5873           std::ostringstream oss; oss << "DataArrayInt::changeSurjectiveFormat : At pos " << i << " presence of element " << tmp2 << " ! should be in [0," << targetNb << ") !";
5874           throw INTERP_KERNEL::Exception(oss.str().c_str());
5875         }
5876     }
5877   int *retIPtr=retI->getPointer();
5878   *retIPtr=0;
5879   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++,retIPtr++)
5880     retIPtr[1]=retIPtr[0]+(int)((*it1).size());
5881   if(nbOfTuples!=retI->getIJ(targetNb,0))
5882     throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : big problem should never happen !");
5883   ret->alloc(nbOfTuples,1);
5884   int *retPtr=ret->getPointer();
5885   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++)
5886     retPtr=std::copy((*it1).begin(),(*it1).end(),retPtr);
5887   arr=ret.retn();
5888   arrI=retI.retn();
5889 }
5890
5891
5892 /*!
5893  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode computed
5894  * from a zip representation of a surjective format (returned e.g. by
5895  * \ref MEDCoupling::DataArrayDouble::findCommonTuples() "DataArrayDouble::findCommonTuples()"
5896  * for example). The result array minimizes the permutation. <br>
5897  * For more info on renumbering see \ref numbering. <br>
5898  * \b Example: <br>
5899  * - \a nbOfOldTuples: 10 
5900  * - \a arr          : [0,3, 5,7,9]
5901  * - \a arrIBg       : [0,2,5]
5902  * - \a newNbOfTuples: 7
5903  * - result array    : [0,1,2,0,3,4,5,4,6,4]
5904  *
5905  *  \param [in] nbOfOldTuples - number of tuples in the initial array \a arr.
5906  *  \param [in] arr - the array of tuple indices grouped by \a arrIBg array.
5907  *  \param [in] arrIBg - the array dividing all indices stored in \a arr into groups of
5908  *         (indices of) equal values. Its every element (except the last one) points to
5909  *         the first element of a group of equal values.
5910  *  \param [in] arrIEnd - specifies the end of \a arrIBg, so that the last element of \a
5911  *          arrIBg is \a arrIEnd[ -1 ].
5912  *  \param [out] newNbOfTuples - number of tuples after surjection application.
5913  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5914  *          array using decrRef() as it is no more needed.
5915  *  \throw If any value of \a arr breaks condition ( 0 <= \a arr[ i ] < \a nbOfOldTuples ).
5916  */
5917 DataArrayInt *DataArrayInt::ConvertIndexArrayToO2N(int nbOfOldTuples, const int *arr, const int *arrIBg, const int *arrIEnd, int &newNbOfTuples)
5918 {
5919   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5920   ret->alloc(nbOfOldTuples,1);
5921   int *pt=ret->getPointer();
5922   std::fill(pt,pt+nbOfOldTuples,-1);
5923   int nbOfGrps=((int)std::distance(arrIBg,arrIEnd))-1;
5924   const int *cIPtr=arrIBg;
5925   for(int i=0;i<nbOfGrps;i++)
5926     pt[arr[cIPtr[i]]]=-(i+2);
5927   int newNb=0;
5928   for(int iNode=0;iNode<nbOfOldTuples;iNode++)
5929     {
5930       if(pt[iNode]<0)
5931         {
5932           if(pt[iNode]==-1)
5933             pt[iNode]=newNb++;
5934           else
5935             {
5936               int grpId=-(pt[iNode]+2);
5937               for(int j=cIPtr[grpId];j<cIPtr[grpId+1];j++)
5938                 {
5939                   if(arr[j]>=0 && arr[j]<nbOfOldTuples)
5940                     pt[arr[j]]=newNb;
5941                   else
5942                     {
5943                       std::ostringstream oss; oss << "DataArrayInt::ConvertIndexArrayToO2N : With element #" << j << " value is " << arr[j] << " should be in [0," << nbOfOldTuples << ") !";
5944                       throw INTERP_KERNEL::Exception(oss.str().c_str());
5945                     }
5946                 }
5947               newNb++;
5948             }
5949         }
5950     }
5951   newNbOfTuples=newNb;
5952   return ret.retn();
5953 }
5954
5955 /*!
5956  * Returns a new DataArrayInt containing a renumbering map in "New to Old" mode,
5957  * which if applied to \a this array would make it sorted ascendingly.
5958  * For more info on renumbering see \ref numbering. <br>
5959  * \b Example: <br>
5960  * - \a this: [2,0,1,1,0,1,2,0,1,1,0,0]
5961  * - result: [10,0,5,6,1,7,11,2,8,9,3,4]
5962  * - after applying result to \a this: [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2] 
5963  *
5964  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5965  *          array using decrRef() as it is no more needed.
5966  *  \throw If \a this is not allocated.
5967  *  \throw If \a this->getNumberOfComponents() != 1.
5968  */
5969 DataArrayInt *DataArrayInt::buildPermArrPerLevel() const
5970 {
5971   checkAllocated();
5972   if(getNumberOfComponents()!=1)
5973     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermArrPerLevel : number of components must == 1 !");
5974   int nbOfTuples=getNumberOfTuples();
5975   const int *pt=getConstPointer();
5976   std::map<int,int> m;
5977   MCAuto<DataArrayInt> ret=DataArrayInt::New();
5978   ret->alloc(nbOfTuples,1);
5979   int *opt=ret->getPointer();
5980   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
5981     {
5982       int val=*pt;
5983       std::map<int,int>::iterator it=m.find(val);
5984       if(it!=m.end())
5985         {
5986           *opt=(*it).second;
5987           (*it).second++;
5988         }
5989       else
5990         {
5991           *opt=0;
5992           m.insert(std::pair<int,int>(val,1));
5993         }
5994     }
5995   int sum=0;
5996   for(std::map<int,int>::iterator it=m.begin();it!=m.end();it++)
5997     {
5998       int vt=(*it).second;
5999       (*it).second=sum;
6000       sum+=vt;
6001     }
6002   pt=getConstPointer();
6003   opt=ret->getPointer();
6004   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
6005     *opt+=m[*pt];
6006   //
6007   return ret.retn();
6008 }
6009
6010 /*!
6011  * Checks if \a this array has the given size, and if its contents is equal to an array filled with
6012  * iota(). This method is particularly useful for DataArrayInt instances that represent
6013  * a renumbering array, to check if there is a real need in renumbering.
6014  * This method checks than \a this can be considered as an identity mapping
6015  * of a set having \a sizeExpected elements into itself.
6016  *
6017  *  \param [in] sizeExpected - The number of elements expected.
6018  *  \return bool - \a true if \a this array contents == \a range( \a this->getNumberOfTuples())
6019  *  \throw If \a this is not allocated.
6020  *  \throw If \a this->getNumberOfComponents() != 1.
6021  */
6022 bool DataArrayInt::isIota(int sizeExpected) const
6023 {
6024   checkAllocated();
6025   if(getNumberOfComponents()!=1)
6026     return false;
6027   int nbOfTuples(getNumberOfTuples());
6028   if(nbOfTuples!=sizeExpected)
6029     return false;
6030   const int *pt=getConstPointer();
6031   for(int i=0;i<nbOfTuples;i++,pt++)
6032     if(*pt!=i)
6033       return false;
6034   return true;
6035 }
6036
6037 /*!
6038  * Checks if all values in \a this array are equal to \a val.
6039  *  \param [in] val - value to check equality of array values to.
6040  *  \return bool - \a true if all values are \a val.
6041  *  \throw If \a this is not allocated.
6042  *  \throw If \a this->getNumberOfComponents() != 1
6043  */
6044 bool DataArrayInt::isUniform(int val) const
6045 {
6046   checkAllocated();
6047   if(getNumberOfComponents()!=1)
6048     throw INTERP_KERNEL::Exception("DataArrayInt::isUniform : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
6049   int nbOfTuples=getNumberOfTuples();
6050   const int *w=getConstPointer();
6051   const int *end2=w+nbOfTuples;
6052   for(;w!=end2;w++)
6053     if(*w!=val)
6054       return false;
6055   return true;
6056 }
6057
6058 /*!
6059  * Checks if all values in \a this array are unique.
6060  *  \return bool - \a true if condition above is true
6061  *  \throw If \a this is not allocated.
6062  *  \throw If \a this->getNumberOfComponents() != 1
6063  */
6064 bool DataArrayInt::hasUniqueValues() const
6065 {
6066   checkAllocated();
6067   if(getNumberOfComponents()!=1)
6068     throw INTERP_KERNEL::Exception("DataArrayInt::hasOnlyUniqueValues: must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
6069   int nbOfTuples(getNumberOfTuples());
6070   std::set<int> s(begin(),end());  // in C++11, should use unordered_set (O(1) complexity)
6071   if (s.size() != nbOfTuples)
6072     return false;
6073   return true;
6074 }
6075
6076 /*!
6077  * Creates a new DataArrayDouble and assigns all (textual and numerical) data of \a this
6078  * array to the new one.
6079  *  \return DataArrayDouble * - the new instance of DataArrayInt.
6080  */
6081 DataArrayDouble *DataArrayInt::convertToDblArr() const
6082 {
6083   checkAllocated();
6084   DataArrayDouble *ret=DataArrayDouble::New();
6085   ret->alloc(getNumberOfTuples(),getNumberOfComponents());
6086   std::size_t nbOfVals=getNbOfElems();
6087   const int *src=getConstPointer();
6088   double *dest=ret->getPointer();
6089   std::copy(src,src+nbOfVals,dest);
6090   ret->copyStringInfoFrom(*this);
6091   return ret;
6092 }
6093
6094 /*!
6095  * Appends components of another array to components of \a this one, tuple by tuple.
6096  * So that the number of tuples of \a this array remains the same and the number of 
6097  * components increases.
6098  *  \param [in] other - the DataArrayInt to append to \a this one.
6099  *  \throw If \a this is not allocated.
6100  *  \throw If \a this and \a other arrays have different number of tuples.
6101  *
6102  *  \if ENABLE_EXAMPLES
6103  *  \ref cpp_mcdataarrayint_meldwith "Here is a C++ example".
6104  *
6105  *  \ref py_mcdataarrayint_meldwith "Here is a Python example".
6106  *  \endif
6107  */
6108 void DataArrayInt::meldWith(const DataArrayInt *other)
6109 {
6110   if(!other)
6111     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : DataArrayInt pointer in input is NULL !");
6112   checkAllocated();
6113   other->checkAllocated();
6114   int nbOfTuples=getNumberOfTuples();
6115   if(nbOfTuples!=other->getNumberOfTuples())
6116     throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : mismatch of number of tuples !");
6117   int nbOfComp1=getNumberOfComponents();
6118   int nbOfComp2=other->getNumberOfComponents();
6119   int *newArr=(int *)malloc(nbOfTuples*(nbOfComp1+nbOfComp2)*sizeof(int));
6120   int *w=newArr;
6121   const int *inp1=getConstPointer();
6122   const int *inp2=other->getConstPointer();
6123   for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
6124     {
6125       w=std::copy(inp1,inp1+nbOfComp1,w);
6126       w=std::copy(inp2,inp2+nbOfComp2,w);
6127     }
6128   useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
6129   std::vector<int> compIds(nbOfComp2);
6130   for(int i=0;i<nbOfComp2;i++)
6131     compIds[i]=nbOfComp1+i;
6132   copyPartOfStringInfoFrom2(compIds,*other);
6133 }
6134
6135 /*!
6136  * Copy all components in a specified order from another DataArrayInt.
6137  * The specified components become the first ones in \a this array.
6138  * Both numerical and textual data is copied. The number of tuples in \a this and
6139  * the other array can be different.
6140  *  \param [in] a - the array to copy data from.
6141  *  \param [in] compoIds - sequence of zero based indices of components, data of which is
6142  *              to be copied.
6143  *  \throw If \a a is NULL.
6144  *  \throw If \a compoIds.size() != \a a->getNumberOfComponents().
6145  *  \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
6146  *
6147  *  \if ENABLE_EXAMPLES
6148  *  \ref py_mcdataarrayint_setselectedcomponents "Here is a Python example".
6149  *  \endif
6150  */
6151 void DataArrayInt::setSelectedComponents(const DataArrayInt *a, const std::vector<int>& compoIds)
6152 {
6153   if(!a)
6154     throw INTERP_KERNEL::Exception("DataArrayInt::setSelectedComponents : input DataArrayInt is NULL !");
6155   checkAllocated();
6156   a->checkAllocated();
6157   copyPartOfStringInfoFrom2(compoIds,*a);
6158   std::size_t partOfCompoSz=compoIds.size();
6159   int nbOfCompo=getNumberOfComponents();
6160   int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
6161   const int *ac=a->getConstPointer();
6162   int *nc=getPointer();
6163   for(int i=0;i<nbOfTuples;i++)
6164     for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
6165       nc[nbOfCompo*i+compoIds[j]]=*ac;
6166 }
6167
6168 /*!
6169  * Assign pointer to one array to a pointer to another appay. Reference counter of
6170  * \a arrayToSet is incremented / decremented.
6171  *  \param [in] newArray - the pointer to array to assign to \a arrayToSet.
6172  *  \param [in,out] arrayToSet - the pointer to array to assign to.
6173  */
6174 void DataArrayInt::SetArrayIn(DataArrayInt *newArray, DataArrayInt* &arrayToSet)
6175 {
6176   if(newArray!=arrayToSet)
6177     {
6178       if(arrayToSet)
6179         arrayToSet->decrRef();
6180       arrayToSet=newArray;
6181       if(arrayToSet)
6182         arrayToSet->incrRef();
6183     }
6184 }
6185
6186 DataArrayIntIterator *DataArrayInt::iterator()
6187 {
6188   return new DataArrayIntIterator(this);
6189 }
6190
6191 /*!
6192  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to a
6193  * given one. The ids are sorted in the ascending order.
6194  *  \param [in] val - the value to find within \a this.
6195  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6196  *          array using decrRef() as it is no more needed.
6197  *  \throw If \a this is not allocated.
6198  *  \throw If \a this->getNumberOfComponents() != 1.
6199  *  \sa DataArrayInt::findIdsEqualTuple
6200  */
6201 DataArrayInt *DataArrayInt::findIdsEqual(int val) const
6202 {
6203   checkAllocated();
6204   if(getNumberOfComponents()!=1)
6205     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqual : the array must have only one component, you can call 'rearrange' method before !");
6206   const int *cptr(getConstPointer());
6207   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6208   int nbOfTuples=getNumberOfTuples();
6209   for(int i=0;i<nbOfTuples;i++,cptr++)
6210     if(*cptr==val)
6211       ret->pushBackSilent(i);
6212   return ret.retn();
6213 }
6214
6215 /*!
6216  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value \b not
6217  * equal to a given one. 
6218  *  \param [in] val - the value to ignore within \a this.
6219  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6220  *          array using decrRef() as it is no more needed.
6221  *  \throw If \a this is not allocated.
6222  *  \throw If \a this->getNumberOfComponents() != 1.
6223  */
6224 DataArrayInt *DataArrayInt::findIdsNotEqual(int val) const
6225 {
6226   checkAllocated();
6227   if(getNumberOfComponents()!=1)
6228     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotEqual : the array must have only one component, you can call 'rearrange' method before !");
6229   const int *cptr(getConstPointer());
6230   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6231   int nbOfTuples=getNumberOfTuples();
6232   for(int i=0;i<nbOfTuples;i++,cptr++)
6233     if(*cptr!=val)
6234       ret->pushBackSilent(i);
6235   return ret.retn();
6236 }
6237
6238 /*!
6239  * Creates a new DataArrayInt containing IDs (indices) of tuples holding tuple equal to those defined by [ \a tupleBg , \a tupleEnd )
6240  * This method is an extension of  DataArrayInt::findIdsEqual method.
6241  *
6242  *  \param [in] tupleBg - the begin (included) of the input tuple to find within \a this.
6243  *  \param [in] tupleEnd - the end (excluded) of the input tuple to find within \a this.
6244  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6245  *          array using decrRef() as it is no more needed.
6246  *  \throw If \a this is not allocated.
6247  *  \throw If \a this->getNumberOfComponents() != std::distance(tupleBg,tupleEnd).
6248  * \throw If \a this->getNumberOfComponents() is equal to 0.
6249  * \sa DataArrayInt::findIdsEqual
6250  */
6251 DataArrayInt *DataArrayInt::findIdsEqualTuple(const int *tupleBg, const int *tupleEnd) const
6252 {
6253   std::size_t nbOfCompoExp(std::distance(tupleBg,tupleEnd));
6254   checkAllocated();
6255   if(getNumberOfComponents()!=(int)nbOfCompoExp)
6256     {
6257       std::ostringstream oss; oss << "DataArrayInt::findIdsEqualTuple : mismatch of number of components. Input tuple has " << nbOfCompoExp << " whereas this array has " << getNumberOfComponents() << " components !";
6258       throw INTERP_KERNEL::Exception(oss.str().c_str());
6259     }
6260   if(nbOfCompoExp==0)
6261     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqualTuple : number of components should be > 0 !");
6262   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6263   const int *bg(begin()),*end2(end()),*work(begin());
6264   while(work!=end2)
6265     {
6266       work=std::search(work,end2,tupleBg,tupleEnd);
6267       if(work!=end2)
6268         {
6269           std::size_t pos(std::distance(bg,work));
6270           if(pos%nbOfCompoExp==0)
6271             ret->pushBackSilent(pos/nbOfCompoExp);
6272           work++;
6273         }
6274     }
6275   return ret.retn();
6276 }
6277
6278 /*!
6279  * Assigns \a newValue to all elements holding \a oldValue within \a this
6280  * one-dimensional array.
6281  *  \param [in] oldValue - the value to replace.
6282  *  \param [in] newValue - the value to assign.
6283  *  \return int - number of replacements performed.
6284  *  \throw If \a this is not allocated.
6285  *  \throw If \a this->getNumberOfComponents() != 1.
6286  */
6287 int DataArrayInt::changeValue(int oldValue, int newValue)
6288 {
6289   checkAllocated();
6290   if(getNumberOfComponents()!=1)
6291     throw INTERP_KERNEL::Exception("DataArrayInt::changeValue : the array must have only one component, you can call 'rearrange' method before !");
6292   if(oldValue==newValue)
6293     return 0;
6294   int *start(getPointer()),*end2(start+getNbOfElems());
6295   int ret(0);
6296   for(int *val=start;val!=end2;val++)
6297     {
6298       if(*val==oldValue)
6299         {
6300           *val=newValue;
6301           ret++;
6302         }
6303     }
6304   if(ret>0)
6305     declareAsNew();
6306   return ret;
6307 }
6308
6309 /*!
6310  * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to
6311  * one of given values.
6312  *  \param [in] valsBg - an array of values to find within \a this array.
6313  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
6314  *              the last value of \a valsBg is \a valsEnd[ -1 ].
6315  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6316  *          array using decrRef() as it is no more needed.
6317  *  \throw If \a this->getNumberOfComponents() != 1.
6318  */
6319 DataArrayInt *DataArrayInt::findIdsEqualList(const int *valsBg, const int *valsEnd) const
6320 {
6321   if(getNumberOfComponents()!=1)
6322     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqualList : the array must have only one component, you can call 'rearrange' method before !");
6323   std::set<int> vals2(valsBg,valsEnd);
6324   const int *cptr(getConstPointer());
6325   std::vector<int> res;
6326   int nbOfTuples(getNumberOfTuples());
6327   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6328   for(int i=0;i<nbOfTuples;i++,cptr++)
6329     if(vals2.find(*cptr)!=vals2.end())
6330       ret->pushBackSilent(i);
6331   return ret.retn();
6332 }
6333
6334 /*!
6335  * Creates a new DataArrayInt containing IDs (indices) of tuples holding values \b not
6336  * equal to any of given values.
6337  *  \param [in] valsBg - an array of values to ignore within \a this array.
6338  *  \param [in] valsEnd - specifies the end of the array \a valsBg, so that
6339  *              the last value of \a valsBg is \a valsEnd[ -1 ].
6340  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6341  *          array using decrRef() as it is no more needed.
6342  *  \throw If \a this->getNumberOfComponents() != 1.
6343  */
6344 DataArrayInt *DataArrayInt::findIdsNotEqualList(const int *valsBg, const int *valsEnd) const
6345 {
6346   if(getNumberOfComponents()!=1)
6347     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotEqualList : the array must have only one component, you can call 'rearrange' method before !");
6348   std::set<int> vals2(valsBg,valsEnd);
6349   const int *cptr=getConstPointer();
6350   std::vector<int> res;
6351   int nbOfTuples=getNumberOfTuples();
6352   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6353   for(int i=0;i<nbOfTuples;i++,cptr++)
6354     if(vals2.find(*cptr)==vals2.end())
6355       ret->pushBackSilent(i);
6356   return ret.retn();
6357 }
6358
6359 /*!
6360  * This method is an extension of DataArrayInt::findIdFirstEqual method because this method works for DataArrayInt with
6361  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
6362  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
6363  * If any the tuple id is returned. If not -1 is returned.
6364  * 
6365  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
6366  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
6367  *
6368  * \return tuple id where \b tupl is. -1 if no such tuple exists in \b this.
6369  * \sa DataArrayInt::findIdSequence, DataArrayInt::presenceOfTuple.
6370  */
6371 int DataArrayInt::findIdFirstEqualTuple(const std::vector<int>& tupl) const
6372 {
6373   checkAllocated();
6374   int nbOfCompo=getNumberOfComponents();
6375   if(nbOfCompo==0)
6376     throw INTERP_KERNEL::Exception("DataArrayInt::findIdFirstEqualTuple : 0 components in 'this' !");
6377   if(nbOfCompo!=(int)tupl.size())
6378     {
6379       std::ostringstream oss; oss << "DataArrayInt::findIdFirstEqualTuple : 'this' contains " << nbOfCompo << " components and searching for a tuple of length " << tupl.size() << " !";
6380       throw INTERP_KERNEL::Exception(oss.str().c_str());
6381     }
6382   const int *cptr=getConstPointer();
6383   std::size_t nbOfVals=getNbOfElems();
6384   for(const int *work=cptr;work!=cptr+nbOfVals;)
6385     {
6386       work=std::search(work,cptr+nbOfVals,tupl.begin(),tupl.end());
6387       if(work!=cptr+nbOfVals)
6388         {
6389           if(std::distance(cptr,work)%nbOfCompo!=0)
6390             work++;
6391           else
6392             return std::distance(cptr,work)/nbOfCompo;
6393         }
6394     }
6395   return -1;
6396 }
6397
6398 /*!
6399  * This method searches the sequence specified in input parameter \b vals in \b this.
6400  * This works only for DataArrayInt having number of components equal to one (if not an INTERP_KERNEL::Exception will be thrown).
6401  * This method differs from DataArrayInt::findIdFirstEqualTuple in that the position is internal raw data is not considered here contrary to DataArrayInt::findIdFirstEqualTuple.
6402  * \sa DataArrayInt::findIdFirstEqualTuple
6403  */
6404 int DataArrayInt::findIdSequence(const std::vector<int>& vals) const
6405 {
6406   checkAllocated();
6407   int nbOfCompo=getNumberOfComponents();
6408   if(nbOfCompo!=1)
6409     throw INTERP_KERNEL::Exception("DataArrayInt::findIdSequence : works only for DataArrayInt instance with one component !");
6410   const int *cptr=getConstPointer();
6411   std::size_t nbOfVals=getNbOfElems();
6412   const int *loc=std::search(cptr,cptr+nbOfVals,vals.begin(),vals.end());
6413   if(loc!=cptr+nbOfVals)
6414     return std::distance(cptr,loc);
6415   return -1;
6416 }
6417
6418 /*!
6419  * This method expects to be called when number of components of this is equal to one.
6420  * This method returns the tuple id, if it exists, of the first tuple equal to \b value.
6421  * If not any tuple contains \b value -1 is returned.
6422  * \sa DataArrayInt::presenceOfValue
6423  */
6424 int DataArrayInt::findIdFirstEqual(int value) const
6425 {
6426   checkAllocated();
6427   if(getNumberOfComponents()!=1)
6428     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
6429   const int *cptr=getConstPointer();
6430   int nbOfTuples=getNumberOfTuples();
6431   const int *ret=std::find(cptr,cptr+nbOfTuples,value);
6432   if(ret!=cptr+nbOfTuples)
6433     return std::distance(cptr,ret);
6434   return -1;
6435 }
6436
6437 /*!
6438  * This method expects to be called when number of components of this is equal to one.
6439  * This method returns the tuple id, if it exists, of the first tuple so that the value is contained in \b vals.
6440  * If not any tuple contains one of the values contained in 'vals' -1 is returned.
6441  * \sa DataArrayInt::presenceOfValue
6442  */
6443 int DataArrayInt::findIdFirstEqual(const std::vector<int>& vals) const
6444 {
6445   checkAllocated();
6446   if(getNumberOfComponents()!=1)
6447     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
6448   std::set<int> vals2(vals.begin(),vals.end());
6449   const int *cptr=getConstPointer();
6450   int nbOfTuples=getNumberOfTuples();
6451   for(const int *w=cptr;w!=cptr+nbOfTuples;w++)
6452     if(vals2.find(*w)!=vals2.end())
6453       return std::distance(cptr,w);
6454   return -1;
6455 }
6456
6457 /*!
6458  * This method returns the number of values in \a this that are equals to input parameter \a value.
6459  * This method only works for single component array.
6460  *
6461  * \return a value in [ 0, \c this->getNumberOfTuples() )
6462  *
6463  * \throw If \a this is not allocated
6464  *
6465  */
6466 int DataArrayInt::count(int value) const
6467 {
6468   int ret=0;
6469   checkAllocated();
6470   if(getNumberOfComponents()!=1)
6471     throw INTERP_KERNEL::Exception("DataArrayInt::count : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
6472   const int *vals=begin();
6473   int nbOfTuples=getNumberOfTuples();
6474   for(int i=0;i<nbOfTuples;i++,vals++)
6475     if(*vals==value)
6476       ret++;
6477   return ret;
6478 }
6479
6480 /*!
6481  * This method is an extension of DataArrayInt::presenceOfValue method because this method works for DataArrayInt with
6482  * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
6483  * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
6484  * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
6485  * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
6486  * \sa DataArrayInt::findIdFirstEqualTuple
6487  */
6488 bool DataArrayInt::presenceOfTuple(const std::vector<int>& tupl) const
6489 {
6490   return findIdFirstEqualTuple(tupl)!=-1;
6491 }
6492
6493
6494 /*!
6495  * Returns \a true if a given value is present within \a this one-dimensional array.
6496  *  \param [in] value - the value to find within \a this array.
6497  *  \return bool - \a true in case if \a value is present within \a this array.
6498  *  \throw If \a this is not allocated.
6499  *  \throw If \a this->getNumberOfComponents() != 1.
6500  *  \sa findIdFirstEqual()
6501  */
6502 bool DataArrayInt::presenceOfValue(int value) const
6503 {
6504   return findIdFirstEqual(value)!=-1;
6505 }
6506
6507 /*!
6508  * This method expects to be called when number of components of this is equal to one.
6509  * This method returns true if it exists a tuple so that the value is contained in \b vals.
6510  * If not any tuple contains one of the values contained in 'vals' false is returned.
6511  * \sa DataArrayInt::findIdFirstEqual
6512  */
6513 bool DataArrayInt::presenceOfValue(const std::vector<int>& vals) const
6514 {
6515   return findIdFirstEqual(vals)!=-1;
6516 }
6517
6518 /*!
6519  * Accumulates values of each component of \a this array.
6520  *  \param [out] res - an array of length \a this->getNumberOfComponents(), allocated 
6521  *         by the caller, that is filled by this method with sum value for each
6522  *         component.
6523  *  \throw If \a this is not allocated.
6524  */
6525 void DataArrayInt::accumulate(int *res) const
6526 {
6527   checkAllocated();
6528   const int *ptr=getConstPointer();
6529   int nbTuple=getNumberOfTuples();
6530   int nbComps=getNumberOfComponents();
6531   std::fill(res,res+nbComps,0);
6532   for(int i=0;i<nbTuple;i++)
6533     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<int>());
6534 }
6535
6536 int DataArrayInt::accumulate(int compId) const
6537 {
6538   checkAllocated();
6539   const int *ptr=getConstPointer();
6540   int nbTuple=getNumberOfTuples();
6541   int nbComps=getNumberOfComponents();
6542   if(compId<0 || compId>=nbComps)
6543     throw INTERP_KERNEL::Exception("DataArrayInt::accumulate : Invalid compId specified : No such nb of components !");
6544   int ret=0;
6545   for(int i=0;i<nbTuple;i++)
6546     ret+=ptr[i*nbComps+compId];
6547   return ret;
6548 }
6549
6550 /*!
6551  * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
6552  * The returned array will have same number of components than \a this and number of tuples equal to
6553  * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
6554  *
6555  * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
6556  *
6557  * \param [in] bgOfIndex - begin (included) of the input index array.
6558  * \param [in] endOfIndex - end (excluded) of the input index array.
6559  * \return DataArrayInt * - the new instance having the same number of components than \a this.
6560  * 
6561  * \throw If bgOfIndex or end is NULL.
6562  * \throw If input index array is not ascendingly sorted.
6563  * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
6564  * \throw If std::distance(bgOfIndex,endOfIndex)==0.
6565  */
6566 DataArrayInt *DataArrayInt::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
6567 {
6568   if(!bgOfIndex || !endOfIndex)
6569     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : input pointer NULL !");
6570   checkAllocated();
6571   int nbCompo=getNumberOfComponents();
6572   int nbOfTuples=getNumberOfTuples();
6573   int sz=(int)std::distance(bgOfIndex,endOfIndex);
6574   if(sz<1)
6575     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : invalid size of input index array !");
6576   sz--;
6577   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(sz,nbCompo);
6578   const int *w=bgOfIndex;
6579   if(*w<0 || *w>=nbOfTuples)
6580     throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
6581   const int *srcPt=begin()+(*w)*nbCompo;
6582   int *tmp=ret->getPointer();
6583   for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
6584     {
6585       std::fill(tmp,tmp+nbCompo,0);
6586       if(w[1]>=w[0])
6587         {
6588           for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
6589             {
6590               if(j>=0 && j<nbOfTuples)
6591                 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<int>());
6592               else
6593                 {
6594                   std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
6595                   throw INTERP_KERNEL::Exception(oss.str().c_str());
6596                 }
6597             }
6598         }
6599       else
6600         {
6601           std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
6602           throw INTERP_KERNEL::Exception(oss.str().c_str());
6603         }
6604     }
6605   ret->copyStringInfoFrom(*this);
6606   return ret.retn();
6607 }
6608
6609 /*!
6610  * Returns a new DataArrayInt by concatenating two given arrays, so that (1) the number
6611  * of tuples in the result array is <em> a1->getNumberOfTuples() + a2->getNumberOfTuples() -
6612  * offsetA2</em> and (2)
6613  * the number of component in the result array is same as that of each of given arrays.
6614  * First \a offsetA2 tuples of \a a2 are skipped and thus are missing from the result array.
6615  * Info on components is copied from the first of the given arrays. Number of components
6616  * in the given arrays must be the same.
6617  *  \param [in] a1 - an array to include in the result array.
6618  *  \param [in] a2 - another array to include in the result array.
6619  *  \param [in] offsetA2 - number of tuples of \a a2 to skip.
6620  *  \return DataArrayInt * - the new instance of DataArrayInt.
6621  *          The caller is to delete this result array using decrRef() as it is no more
6622  *          needed.
6623  *  \throw If either \a a1 or \a a2 is NULL.
6624  *  \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
6625  */
6626 DataArrayInt *DataArrayInt::Aggregate(const DataArrayInt *a1, const DataArrayInt *a2, int offsetA2)
6627 {
6628   if(!a1 || !a2)
6629     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input DataArrayInt instance is NULL !");
6630   int nbOfComp=a1->getNumberOfComponents();
6631   if(nbOfComp!=a2->getNumberOfComponents())
6632     throw INTERP_KERNEL::Exception("Nb of components mismatch for array Aggregation !");
6633   int nbOfTuple1=a1->getNumberOfTuples();
6634   int nbOfTuple2=a2->getNumberOfTuples();
6635   DataArrayInt *ret=DataArrayInt::New();
6636   ret->alloc(nbOfTuple1+nbOfTuple2-offsetA2,nbOfComp);
6637   int *pt=std::copy(a1->getConstPointer(),a1->getConstPointer()+nbOfTuple1*nbOfComp,ret->getPointer());
6638   std::copy(a2->getConstPointer()+offsetA2*nbOfComp,a2->getConstPointer()+nbOfTuple2*nbOfComp,pt);
6639   ret->copyStringInfoFrom(*a1);
6640   return ret;
6641 }
6642
6643 /*!
6644  * Returns a new DataArrayInt by concatenating all given arrays, so that (1) the number
6645  * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
6646  * the number of component in the result array is same as that of each of given arrays.
6647  * Info on components is copied from the first of the given arrays. Number of components
6648  * in the given arrays must be  the same.
6649  * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it
6650  * not the object itself.
6651  *  \param [in] arr - a sequence of arrays to include in the result array.
6652  *  \return DataArrayInt * - the new instance of DataArrayInt.
6653  *          The caller is to delete this result array using decrRef() as it is no more
6654  *          needed.
6655  *  \throw If all arrays within \a arr are NULL.
6656  *  \throw If getNumberOfComponents() of arrays within \a arr.
6657  */
6658 DataArrayInt *DataArrayInt::Aggregate(const std::vector<const DataArrayInt *>& arr)
6659 {
6660   std::vector<const DataArrayInt *> a;
6661   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
6662     if(*it4)
6663       a.push_back(*it4);
6664   if(a.empty())
6665     throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input list must be NON EMPTY !");
6666   std::vector<const DataArrayInt *>::const_iterator it=a.begin();
6667   int nbOfComp=(*it)->getNumberOfComponents();
6668   int nbt=(*it++)->getNumberOfTuples();
6669   for(int i=1;it!=a.end();it++,i++)
6670     {
6671       if((*it)->getNumberOfComponents()!=nbOfComp)
6672         throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : Nb of components mismatch for array aggregation !");
6673       nbt+=(*it)->getNumberOfTuples();
6674     }
6675   MCAuto<DataArrayInt> ret=DataArrayInt::New();
6676   ret->alloc(nbt,nbOfComp);
6677   int *pt=ret->getPointer();
6678   for(it=a.begin();it!=a.end();it++)
6679     pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
6680   ret->copyStringInfoFrom(*(a[0]));
6681   return ret.retn();
6682 }
6683
6684 /*!
6685  * This method takes as input a list of DataArrayInt instances \a arrs that represent each a packed index arrays.
6686  * A packed index array is an allocated array with one component, and at least one tuple. The first element
6687  * of each array in \a arrs must be 0. Each array in \a arrs is expected to be increasingly monotonic.
6688  * 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.
6689  * 
6690  * \return DataArrayInt * - a new object to be managed by the caller.
6691  */
6692 DataArrayInt *DataArrayInt::AggregateIndexes(const std::vector<const DataArrayInt *>& arrs)
6693 {
6694   int retSz=1;
6695   for(std::vector<const DataArrayInt *>::const_iterator it4=arrs.begin();it4!=arrs.end();it4++)
6696     {
6697       if(*it4)
6698         {
6699           (*it4)->checkAllocated();
6700           if((*it4)->getNumberOfComponents()!=1)
6701             {
6702               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of compo != 1 at pos " << std::distance(arrs.begin(),it4) << " !";
6703               throw INTERP_KERNEL::Exception(oss.str().c_str());
6704             }
6705           int nbTupl=(*it4)->getNumberOfTuples();
6706           if(nbTupl<1)
6707             {
6708               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of tuples < 1 at pos " << std::distance(arrs.begin(),it4) << " !";
6709               throw INTERP_KERNEL::Exception(oss.str().c_str());
6710             }
6711           if((*it4)->front()!=0)
6712             {
6713               std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with front value != 0 at pos " << std::distance(arrs.begin(),it4) << " !";
6714               throw INTERP_KERNEL::Exception(oss.str().c_str());
6715             }
6716           retSz+=nbTupl-1;
6717         }
6718       else
6719         {
6720           std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a null instance at pos " << std::distance(arrs.begin(),it4) << " !";
6721           throw INTERP_KERNEL::Exception(oss.str().c_str());
6722         }
6723     }
6724   if(arrs.empty())
6725     throw INTERP_KERNEL::Exception("DataArrayInt::AggregateIndexes : input list must be NON EMPTY !");
6726   MCAuto<DataArrayInt> ret=DataArrayInt::New();
6727   ret->alloc(retSz,1);
6728   int *pt=ret->getPointer(); *pt++=0;
6729   for(std::vector<const DataArrayInt *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
6730     pt=std::transform((*it)->begin()+1,(*it)->end(),pt,std::bind2nd(std::plus<int>(),pt[-1]));
6731   ret->copyStringInfoFrom(*(arrs[0]));
6732   return ret.retn();
6733 }
6734
6735 /*!
6736  * Returns in a single walk in \a this the min value and the max value in \a this.
6737  * \a this is expected to be single component array.
6738  *
6739  * \param [out] minValue - the min value in \a this.
6740  * \param [out] maxValue - the max value in \a this.
6741  *
6742  * \sa getMinValueInArray, getMinValue, getMaxValueInArray, getMaxValue
6743  */
6744 void DataArrayInt::getMinMaxValues(int& minValue, int& maxValue) const
6745 {
6746   checkAllocated();
6747   if(getNumberOfComponents()!=1)
6748     throw INTERP_KERNEL::Exception("DataArrayInt::getMinMaxValues : must be applied on DataArrayInt with only one component !");
6749   int nbTuples(getNumberOfTuples());
6750   const int *pt(begin());
6751   minValue=std::numeric_limits<int>::max(); maxValue=-std::numeric_limits<int>::max();
6752   for(int i=0;i<nbTuples;i++,pt++)
6753     {
6754       if(*pt<minValue)
6755         minValue=*pt;
6756       if(*pt>maxValue)
6757         maxValue=*pt;
6758     }
6759 }
6760
6761 /*!
6762  * Converts every value of \a this array to its absolute value.
6763  * \b WARNING this method is non const. If a new DataArrayInt instance should be built containing the result of abs DataArrayInt::computeAbs
6764  * should be called instead.
6765  *
6766  * \throw If \a this is not allocated.
6767  * \sa DataArrayInt::computeAbs
6768  */
6769 void DataArrayInt::abs()
6770 {
6771   checkAllocated();
6772   int *ptr(getPointer());
6773   std::size_t nbOfElems(getNbOfElems());
6774   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<int,int>(std::abs));
6775   declareAsNew();
6776 }
6777
6778 /*!
6779  * This method builds a new instance of \a this object containing the result of std::abs applied of all elements in \a this.
6780  * This method is a const method (that do not change any values in \a this) contrary to  DataArrayInt::abs method.
6781  *
6782  * \return DataArrayInt * - the new instance of DataArrayInt containing the
6783  *         same number of tuples and component as \a this array.
6784  *         The caller is to delete this result array using decrRef() as it is no more
6785  *         needed.
6786  * \throw If \a this is not allocated.
6787  * \sa DataArrayInt::abs
6788  */
6789 DataArrayInt *DataArrayInt::computeAbs() const
6790 {
6791   checkAllocated();
6792   DataArrayInt *newArr(DataArrayInt::New());
6793   int nbOfTuples(getNumberOfTuples());
6794   int nbOfComp(getNumberOfComponents());
6795   newArr->alloc(nbOfTuples,nbOfComp);
6796   std::transform(begin(),end(),newArr->getPointer(),std::ptr_fun<int,int>(std::abs));
6797   newArr->copyStringInfoFrom(*this);
6798   return newArr;
6799 }
6800
6801 /*!
6802  * Apply a liner function to a given component of \a this array, so that
6803  * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
6804  *  \param [in] a - the first coefficient of the function.
6805  *  \param [in] b - the second coefficient of the function.
6806  *  \param [in] compoId - the index of component to modify.
6807  *  \throw If \a this is not allocated.
6808  */
6809 void DataArrayInt::applyLin(int a, int b, int compoId)
6810 {
6811   checkAllocated();
6812   int *ptr=getPointer()+compoId;
6813   int nbOfComp=getNumberOfComponents();
6814   int nbOfTuple=getNumberOfTuples();
6815   for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
6816     *ptr=a*(*ptr)+b;
6817   declareAsNew();
6818 }
6819
6820 /*!
6821  * Apply a liner function to all elements of \a this array, so that
6822  * an element _x_ becomes \f$ a * x + b \f$.
6823  *  \param [in] a - the first coefficient of the function.
6824  *  \param [in] b - the second coefficient of the function.
6825  *  \throw If \a this is not allocated.
6826  */
6827 void DataArrayInt::applyLin(int a, int b)
6828 {
6829   checkAllocated();
6830   int *ptr=getPointer();
6831   std::size_t nbOfElems=getNbOfElems();
6832   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
6833     *ptr=a*(*ptr)+b;
6834   declareAsNew();
6835 }
6836
6837 /*!
6838  * Returns a full copy of \a this array except that sign of all elements is reversed.
6839  *  \return DataArrayInt * - the new instance of DataArrayInt containing the
6840  *          same number of tuples and component as \a this array.
6841  *          The caller is to delete this result array using decrRef() as it is no more
6842  *          needed.
6843  *  \throw If \a this is not allocated.
6844  */
6845 DataArrayInt *DataArrayInt::negate() const
6846 {
6847   checkAllocated();
6848   DataArrayInt *newArr=DataArrayInt::New();
6849   int nbOfTuples=getNumberOfTuples();
6850   int nbOfComp=getNumberOfComponents();
6851   newArr->alloc(nbOfTuples,nbOfComp);
6852   const int *cptr=getConstPointer();
6853   std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<int>());
6854   newArr->copyStringInfoFrom(*this);
6855   return newArr;
6856 }
6857
6858 /*!
6859  * Modify all elements of \a this array, so that
6860  * an element _x_ becomes \f$ numerator / x \f$.
6861  *  \warning If an exception is thrown because of presence of 0 element in \a this 
6862  *           array, all elements processed before detection of the zero element remain
6863  *           modified.
6864  *  \param [in] numerator - the numerator used to modify array elements.
6865  *  \throw If \a this is not allocated.
6866  *  \throw If there is an element equal to 0 in \a this array.
6867  */
6868 void DataArrayInt::applyInv(int numerator)
6869 {
6870   checkAllocated();
6871   int *ptr=getPointer();
6872   std::size_t nbOfElems=getNbOfElems();
6873   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
6874     {
6875       if(*ptr!=0)
6876         {
6877           *ptr=numerator/(*ptr);
6878         }
6879       else
6880         {
6881           std::ostringstream oss; oss << "DataArrayInt::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
6882           oss << " !";
6883           throw INTERP_KERNEL::Exception(oss.str().c_str());
6884         }
6885     }
6886   declareAsNew();
6887 }
6888
6889 /*!
6890  * Modify all elements of \a this array, so that
6891  * an element _x_ becomes \f$ x / val \f$.
6892  *  \param [in] val - the denominator used to modify array elements.
6893  *  \throw If \a this is not allocated.
6894  *  \throw If \a val == 0.
6895  */
6896 void DataArrayInt::applyDivideBy(int val)
6897 {
6898   if(val==0)
6899     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to divide by 0 !");
6900   checkAllocated();
6901   int *ptr=getPointer();
6902   std::size_t nbOfElems=getNbOfElems();
6903   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::divides<int>(),val));
6904   declareAsNew();
6905 }
6906
6907 /*!
6908  * Modify all elements of \a this array, so that
6909  * an element _x_ becomes  <em> x % val </em>.
6910  *  \param [in] val - the divisor used to modify array elements.
6911  *  \throw If \a this is not allocated.
6912  *  \throw If \a val <= 0.
6913  */
6914 void DataArrayInt::applyModulus(int val)
6915 {
6916   if(val<=0)
6917     throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to operate modulus on value <= 0 !");
6918   checkAllocated();
6919   int *ptr=getPointer();
6920   std::size_t nbOfElems=getNbOfElems();
6921   std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::modulus<int>(),val));
6922   declareAsNew();
6923 }
6924
6925 struct GreatEqual
6926 {
6927   GreatEqual(int v):_v(v) { }
6928   bool operator()(int v) const { return v>=_v; }
6929   int _v;
6930 };
6931
6932 struct GreaterThan
6933 {
6934   GreaterThan(int v):_v(v) { }
6935   bool operator()(int v) const { return v>_v; }
6936   int _v;
6937 };
6938
6939 struct LowerEqual
6940 {
6941   LowerEqual(int v):_v(v) { }
6942   bool operator()(int v) const { return v<=_v; }
6943   int _v;
6944 };
6945
6946 struct LowerThan
6947 {
6948   LowerThan(int v):_v(v) { }
6949   bool operator()(int v) const { return v<_v; }
6950   int _v;
6951 };
6952
6953 struct InRange
6954 {
6955   InRange(int a, int b):_a(a),_b(b) { }
6956   bool operator()(int v) const { return v>=_a || v<_b; }
6957   int _a,_b;
6958 };
6959
6960 /*!
6961  * This method works only on data array with one component.
6962  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
6963  * this[*id] in [\b vmin,\b vmax)
6964  * 
6965  * \param [in] vmin begin of range. This value is included in range (included).
6966  * \param [in] vmax end of range. This value is \b not included in range (excluded).
6967  * \return a newly allocated data array that the caller should deal with.
6968  *
6969  * \sa DataArrayInt::findIdsNotInRange , DataArrayInt::findIdsStricltyNegative
6970  */
6971 DataArrayInt *DataArrayInt::findIdsInRange(int vmin, int vmax) const
6972 {
6973   InRange ir(vmin,vmax);
6974   MCAuto<DataArrayInt> ret(findIdsAdv(ir));
6975   return ret.retn();
6976 }
6977
6978 struct NotInRange
6979 {
6980   NotInRange(int a, int b):_a(a),_b(b) { }
6981   bool operator()(int v) const { return v<_a || v>=_b; }
6982   int _a,_b;
6983 };
6984
6985 /*!
6986  * This method works only on data array with one component.
6987  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
6988  * this[*id] \b not in [\b vmin,\b vmax)
6989  * 
6990  * \param [in] vmin begin of range. This value is \b not included in range (excluded).
6991  * \param [in] vmax end of range. This value is included in range (included).
6992  * \return a newly allocated data array that the caller should deal with.
6993  * 
6994  * \sa DataArrayInt::findIdsInRange , DataArrayInt::findIdsStricltyNegative
6995  */
6996 DataArrayInt *DataArrayInt::findIdsNotInRange(int vmin, int vmax) const
6997 {
6998   NotInRange nir(vmin,vmax);
6999   MCAuto<DataArrayInt> ret(findIdsAdv(nir));
7000   return ret.retn();
7001 }
7002
7003 /*!
7004  * This method works only on data array with one component. This method returns a newly allocated array storing stored ascendantly of tuple ids in \a this so that this[id]<0.
7005  *
7006  * \return a newly allocated data array that the caller should deal with.
7007  * \sa DataArrayInt::findIdsInRange
7008  */
7009 DataArrayInt *DataArrayInt::findIdsStricltyNegative() const
7010 {
7011   LowerThan lt(0);
7012   MCAuto<DataArrayInt> ret(findIdsAdv(lt));
7013   return ret.retn();
7014 }
7015
7016 MCAuto<DataArrayInt> DataArrayInt::findIdsGreaterOrEqualTo(int val) const
7017 {
7018   GreatEqual ge(val);
7019   return findIdsAdv(ge);
7020 }
7021
7022 MCAuto<DataArrayInt> DataArrayInt::findIdsGreaterThan(int val) const
7023 {
7024   GreaterThan gt(val);
7025   return findIdsAdv(gt);
7026 }
7027
7028 MCAuto<DataArrayInt> DataArrayInt::findIdsLowerOrEqualTo(int val) const
7029 {
7030   LowerEqual le(val);
7031   return findIdsAdv(le);
7032 }
7033
7034 MCAuto<DataArrayInt> DataArrayInt::findIdsLowerThan(int val) const
7035 {
7036   LowerThan lt(val);
7037   return findIdsAdv(lt);
7038 }
7039
7040 /*!
7041  * This method works only on data array with one component.
7042  * 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.
7043  * 
7044  * \param [in] vmin begin of range. This value is included in range (included).
7045  * \param [in] vmax end of range. This value is \b not included in range (excluded).
7046  * \return if all ids in \a this are so that (*this)[i]==i for all i in [ 0, \c this->getNumberOfTuples() ). */
7047 bool DataArrayInt::checkAllIdsInRange(int vmin, int vmax) const
7048 {
7049   checkAllocated();
7050   if(getNumberOfComponents()!=1)
7051     throw INTERP_KERNEL::Exception("DataArrayInt::checkAllIdsInRange : this must have exactly one component !");
7052   int nbOfTuples=getNumberOfTuples();
7053   bool ret=true;
7054   const int *cptr=getConstPointer();
7055   for(int i=0;i<nbOfTuples;i++,cptr++)
7056     {
7057       if(*cptr>=vmin && *cptr<vmax)
7058         { ret=ret && *cptr==i; }
7059       else
7060         {
7061           std::ostringstream oss; oss << "DataArrayInt::checkAllIdsInRange : tuple #" << i << " has value " << *cptr << " should be in [" << vmin << "," << vmax << ") !";
7062           throw INTERP_KERNEL::Exception(oss.str().c_str());
7063         }
7064     }
7065   return ret;
7066 }
7067
7068 /*!
7069  * Modify all elements of \a this array, so that
7070  * an element _x_ becomes <em> val % x </em>.
7071  *  \warning If an exception is thrown because of presence of an element <= 0 in \a this 
7072  *           array, all elements processed before detection of the zero element remain
7073  *           modified.
7074  *  \param [in] val - the divident used to modify array elements.
7075  *  \throw If \a this is not allocated.
7076  *  \throw If there is an element equal to or less than 0 in \a this array.
7077  */
7078 void DataArrayInt::applyRModulus(int val)
7079 {
7080   checkAllocated();
7081   int *ptr=getPointer();
7082   std::size_t nbOfElems=getNbOfElems();
7083   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
7084     {
7085       if(*ptr>0)
7086         {
7087           *ptr=val%(*ptr);
7088         }
7089       else
7090         {
7091           std::ostringstream oss; oss << "DataArrayInt::applyRModulus : presence of value <=0 in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
7092           oss << " !";
7093           throw INTERP_KERNEL::Exception(oss.str().c_str());
7094         }
7095     }
7096   declareAsNew();
7097 }
7098
7099 /*!
7100  * Modify all elements of \a this array, so that
7101  * an element _x_ becomes <em> val ^ x </em>.
7102  *  \param [in] val - the value used to apply pow on all array elements.
7103  *  \throw If \a this is not allocated.
7104  *  \throw If \a val < 0.
7105  */
7106 void DataArrayInt::applyPow(int val)
7107 {
7108   checkAllocated();
7109   if(val<0)
7110     throw INTERP_KERNEL::Exception("DataArrayInt::applyPow : input pow in < 0 !");
7111   int *ptr=getPointer();
7112   std::size_t nbOfElems=getNbOfElems();
7113   if(val==0)
7114     {
7115       std::fill(ptr,ptr+nbOfElems,1);
7116       return ;
7117     }
7118   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
7119     {
7120       int tmp=1;
7121       for(int j=0;j<val;j++)
7122         tmp*=*ptr;
7123       *ptr=tmp;
7124     }
7125   declareAsNew();
7126 }
7127
7128 /*!
7129  * Modify all elements of \a this array, so that
7130  * an element _x_ becomes \f$ val ^ x \f$.
7131  *  \param [in] val - the value used to apply pow on all array elements.
7132  *  \throw If \a this is not allocated.
7133  *  \throw If there is an element < 0 in \a this array.
7134  *  \warning If an exception is thrown because of presence of 0 element in \a this 
7135  *           array, all elements processed before detection of the zero element remain
7136  *           modified.
7137  */
7138 void DataArrayInt::applyRPow(int val)
7139 {
7140   checkAllocated();
7141   int *ptr=getPointer();
7142   std::size_t nbOfElems=getNbOfElems();
7143   for(std::size_t i=0;i<nbOfElems;i++,ptr++)
7144     {
7145       if(*ptr>=0)
7146         {
7147           int tmp=1;
7148           for(int j=0;j<*ptr;j++)
7149             tmp*=val;
7150           *ptr=tmp;
7151         }
7152       else
7153         {
7154           std::ostringstream oss; oss << "DataArrayInt::applyRPow : presence of negative value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
7155           oss << " !";
7156           throw INTERP_KERNEL::Exception(oss.str().c_str());
7157         }
7158     }
7159   declareAsNew();
7160 }
7161
7162 /*!
7163  * Returns a new DataArrayInt by aggregating two given arrays, so that (1) the number
7164  * of components in the result array is a sum of the number of components of given arrays
7165  * and (2) the number of tuples in the result array is same as that of each of given
7166  * arrays. In other words the i-th tuple of result array includes all components of
7167  * i-th tuples of all given arrays.
7168  * Number of tuples in the given arrays must be the same.
7169  *  \param [in] a1 - an array to include in the result array.
7170  *  \param [in] a2 - another array to include in the result array.
7171  *  \return DataArrayInt * - the new instance of DataArrayInt.
7172  *          The caller is to delete this result array using decrRef() as it is no more
7173  *          needed.
7174  *  \throw If both \a a1 and \a a2 are NULL.
7175  *  \throw If any given array is not allocated.
7176  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
7177  */
7178 DataArrayInt *DataArrayInt::Meld(const DataArrayInt *a1, const DataArrayInt *a2)
7179 {
7180   std::vector<const DataArrayInt *> arr(2);
7181   arr[0]=a1; arr[1]=a2;
7182   return Meld(arr);
7183 }
7184
7185 /*!
7186  * Returns a new DataArrayInt by aggregating all given arrays, so that (1) the number
7187  * of components in the result array is a sum of the number of components of given arrays
7188  * and (2) the number of tuples in the result array is same as that of each of given
7189  * arrays. In other words the i-th tuple of result array includes all components of
7190  * i-th tuples of all given arrays.
7191  * Number of tuples in the given arrays must be  the same.
7192  *  \param [in] arr - a sequence of arrays to include in the result array.
7193  *  \return DataArrayInt * - the new instance of DataArrayInt.
7194  *          The caller is to delete this result array using decrRef() as it is no more
7195  *          needed.
7196  *  \throw If all arrays within \a arr are NULL.
7197  *  \throw If any given array is not allocated.
7198  *  \throw If getNumberOfTuples() of arrays within \a arr is different.
7199  */
7200 DataArrayInt *DataArrayInt::Meld(const std::vector<const DataArrayInt *>& arr)
7201 {
7202   std::vector<const DataArrayInt *> a;
7203   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
7204     if(*it4)
7205       a.push_back(*it4);
7206   if(a.empty())
7207     throw INTERP_KERNEL::Exception("DataArrayInt::Meld : array must be NON empty !");
7208   std::vector<const DataArrayInt *>::const_iterator it;
7209   for(it=a.begin();it!=a.end();it++)
7210     (*it)->checkAllocated();
7211   it=a.begin();
7212   int nbOfTuples=(*it)->getNumberOfTuples();
7213   std::vector<int> nbc(a.size());
7214   std::vector<const int *> pts(a.size());
7215   nbc[0]=(*it)->getNumberOfComponents();
7216   pts[0]=(*it++)->getConstPointer();
7217   for(int i=1;it!=a.end();it++,i++)
7218     {
7219       if(nbOfTuples!=(*it)->getNumberOfTuples())
7220         throw INTERP_KERNEL::Exception("DataArrayInt::meld : mismatch of number of tuples !");
7221       nbc[i]=(*it)->getNumberOfComponents();
7222       pts[i]=(*it)->getConstPointer();
7223     }
7224   int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
7225   DataArrayInt *ret=DataArrayInt::New();
7226   ret->alloc(nbOfTuples,totalNbOfComp);
7227   int *retPtr=ret->getPointer();
7228   for(int i=0;i<nbOfTuples;i++)
7229     for(int j=0;j<(int)a.size();j++)
7230       {
7231         retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
7232         pts[j]+=nbc[j];
7233       }
7234   int k=0;
7235   for(int i=0;i<(int)a.size();i++)
7236     for(int j=0;j<nbc[i];j++,k++)
7237       ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j));
7238   return ret;
7239 }
7240
7241 /*!
7242  * Returns a new DataArrayInt which is a minimal partition of elements of \a groups.
7243  * The i-th item of the result array is an ID of a set of elements belonging to a
7244  * unique set of groups, which the i-th element is a part of. This set of elements
7245  * belonging to a unique set of groups is called \a family, so the result array contains
7246  * IDs of families each element belongs to.
7247  *
7248  * \b Example: if we have two groups of elements: \a group1 [0,4] and \a group2 [ 0,1,2 ],
7249  * then there are 3 families:
7250  * - \a family1 (with ID 1) contains element [0] belonging to ( \a group1 + \a group2 ),
7251  * - \a family2 (with ID 2) contains elements [4] belonging to ( \a group1 ),
7252  * - \a family3 (with ID 3) contains element [1,2] belonging to ( \a group2 ), <br>
7253  * and the result array contains IDs of families [ 1,3,3,0,2 ]. <br> Note a family ID 0 which
7254  * stands for the element #3 which is in none of groups.
7255  *
7256  *  \param [in] groups - sequence of groups of element IDs.
7257  *  \param [in] newNb - total number of elements; it must be more than max ID of element
7258  *         in \a groups.
7259  *  \param [out] fidsOfGroups - IDs of families the elements of each group belong to.
7260  *  \return DataArrayInt * - a new instance of DataArrayInt containing IDs of families
7261  *         each element with ID from range [0, \a newNb ) belongs to. The caller is to
7262  *         delete this array using decrRef() as it is no more needed.
7263  *  \throw If any element ID in \a groups violates condition ( 0 <= ID < \a newNb ).
7264  */
7265 DataArrayInt *DataArrayInt::MakePartition(const std::vector<const DataArrayInt *>& groups, int newNb, std::vector< std::vector<int> >& fidsOfGroups)
7266 {
7267   std::vector<const DataArrayInt *> groups2;
7268   for(std::vector<const DataArrayInt *>::const_iterator it4=groups.begin();it4!=groups.end();it4++)
7269     if(*it4)
7270       groups2.push_back(*it4);
7271   MCAuto<DataArrayInt> ret=DataArrayInt::New();
7272   ret->alloc(newNb,1);
7273   int *retPtr=ret->getPointer();
7274   std::fill(retPtr,retPtr+newNb,0);
7275   int fid=1;
7276   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++)
7277     {
7278       const int *ptr=(*iter)->getConstPointer();
7279       std::size_t nbOfElem=(*iter)->getNbOfElems();
7280       int sfid=fid;
7281       for(int j=0;j<sfid;j++)
7282         {
7283           bool found=false;
7284           for(std::size_t i=0;i<nbOfElem;i++)
7285             {
7286               if(ptr[i]>=0 && ptr[i]<newNb)
7287                 {
7288                   if(retPtr[ptr[i]]==j)
7289                     {
7290                       retPtr[ptr[i]]=fid;
7291                       found=true;
7292                     }
7293                 }
7294               else
7295                 {
7296                   std::ostringstream oss; oss << "DataArrayInt::MakePartition : In group \"" << (*iter)->getName() << "\" in tuple #" << i << " value = " << ptr[i] << " ! Should be in [0," << newNb;
7297                   oss << ") !";
7298                   throw INTERP_KERNEL::Exception(oss.str().c_str());
7299                 }
7300             }
7301           if(found)
7302             fid++;
7303         }
7304     }
7305   fidsOfGroups.clear();
7306   fidsOfGroups.resize(groups2.size());
7307   int grId=0;
7308   for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++,grId++)
7309     {
7310       std::set<int> tmp;
7311       const int *ptr=(*iter)->getConstPointer();
7312       std::size_t nbOfElem=(*iter)->getNbOfElems();
7313       for(const int *p=ptr;p!=ptr+nbOfElem;p++)
7314         tmp.insert(retPtr[*p]);
7315       fidsOfGroups[grId].insert(fidsOfGroups[grId].end(),tmp.begin(),tmp.end());
7316     }
7317   return ret.retn();
7318 }
7319
7320 /*!
7321  * Returns a new DataArrayInt which contains all elements of given one-dimensional
7322  * arrays. The result array does not contain any duplicates and its values
7323  * are sorted in ascending order.
7324  *  \param [in] arr - sequence of DataArrayInt's to unite.
7325  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7326  *         array using decrRef() as it is no more needed.
7327  *  \throw If any \a arr[i] is not allocated.
7328  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
7329  */
7330 DataArrayInt *DataArrayInt::BuildUnion(const std::vector<const DataArrayInt *>& arr)
7331 {
7332   std::vector<const DataArrayInt *> a;
7333   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
7334     if(*it4)
7335       a.push_back(*it4);
7336   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
7337     {
7338       (*it)->checkAllocated();
7339       if((*it)->getNumberOfComponents()!=1)
7340         throw INTERP_KERNEL::Exception("DataArrayInt::BuildUnion : only single component allowed !");
7341     }
7342   //
7343   std::set<int> r;
7344   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
7345     {
7346       const int *pt=(*it)->getConstPointer();
7347       int nbOfTuples=(*it)->getNumberOfTuples();
7348       r.insert(pt,pt+nbOfTuples);
7349     }
7350   DataArrayInt *ret=DataArrayInt::New();
7351   ret->alloc((int)r.size(),1);
7352   std::copy(r.begin(),r.end(),ret->getPointer());
7353   return ret;
7354 }
7355
7356 /*!
7357  * Returns a new DataArrayInt which contains elements present in each of given one-dimensional
7358  * arrays. The result array does not contain any duplicates and its values
7359  * are sorted in ascending order.
7360  *  \param [in] arr - sequence of DataArrayInt's to intersect.
7361  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7362  *         array using decrRef() as it is no more needed.
7363  *  \throw If any \a arr[i] is not allocated.
7364  *  \throw If \a arr[i]->getNumberOfComponents() != 1.
7365  */
7366 DataArrayInt *DataArrayInt::BuildIntersection(const std::vector<const DataArrayInt *>& arr)
7367 {
7368   std::vector<const DataArrayInt *> a;
7369   for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
7370     if(*it4)
7371       a.push_back(*it4);
7372   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
7373     {
7374       (*it)->checkAllocated();
7375       if((*it)->getNumberOfComponents()!=1)
7376         throw INTERP_KERNEL::Exception("DataArrayInt::BuildIntersection : only single component allowed !");
7377     }
7378   //
7379   std::set<int> r;
7380   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
7381     {
7382       const int *pt=(*it)->getConstPointer();
7383       int nbOfTuples=(*it)->getNumberOfTuples();
7384       std::set<int> s1(pt,pt+nbOfTuples);
7385       if(it!=a.begin())
7386         {
7387           std::set<int> r2;
7388           std::set_intersection(r.begin(),r.end(),s1.begin(),s1.end(),inserter(r2,r2.end()));
7389           r=r2;
7390         }
7391       else
7392         r=s1;
7393     }
7394   DataArrayInt *ret(DataArrayInt::New());
7395   ret->alloc((int)r.size(),1);
7396   std::copy(r.begin(),r.end(),ret->getPointer());
7397   return ret;
7398 }
7399
7400 /// @cond INTERNAL
7401 namespace MEDCouplingImpl
7402 {
7403   class OpSwitchedOn
7404   {
7405   public:
7406     OpSwitchedOn(int *pt):_pt(pt),_cnt(0) { }
7407     void operator()(const bool& b) { if(b) *_pt++=_cnt; _cnt++; }
7408   private:
7409     int *_pt;
7410     int _cnt;
7411   };
7412
7413   class OpSwitchedOff
7414   {
7415   public:
7416     OpSwitchedOff(int *pt):_pt(pt),_cnt(0) { }
7417     void operator()(const bool& b) { if(!b) *_pt++=_cnt; _cnt++; }
7418   private:
7419     int *_pt;
7420     int _cnt;
7421   };
7422 }
7423 /// @endcond
7424
7425 /*!
7426  * This method returns the list of ids in ascending mode so that v[id]==true.
7427  */
7428 DataArrayInt *DataArrayInt::BuildListOfSwitchedOn(const std::vector<bool>& v)
7429 {
7430   int sz((int)std::count(v.begin(),v.end(),true));
7431   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
7432   std::for_each(v.begin(),v.end(),MEDCouplingImpl::OpSwitchedOn(ret->getPointer()));
7433   return ret.retn();
7434 }
7435
7436 /*!
7437  * This method returns the list of ids in ascending mode so that v[id]==false.
7438  */
7439 DataArrayInt *DataArrayInt::BuildListOfSwitchedOff(const std::vector<bool>& v)
7440 {
7441   int sz((int)std::count(v.begin(),v.end(),false));
7442   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
7443   std::for_each(v.begin(),v.end(),MEDCouplingImpl::OpSwitchedOff(ret->getPointer()));
7444   return ret.retn();
7445 }
7446
7447 /*!
7448  * This method allows to put a vector of vector of integer into a more compact data stucture (skyline). 
7449  * This method is not available into python because no available optimized data structure available to map std::vector< std::vector<int> >.
7450  *
7451  * \param [in] v the input data structure to be translate into skyline format.
7452  * \param [out] data the first element of the skyline format. The user is expected to deal with newly allocated array.
7453  * \param [out] dataIndex the second element of the skyline format.
7454  */
7455 void DataArrayInt::PutIntoToSkylineFrmt(const std::vector< std::vector<int> >& v, DataArrayInt *& data, DataArrayInt *& dataIndex)
7456 {
7457   int sz((int)v.size());
7458   MCAuto<DataArrayInt> ret0(DataArrayInt::New()),ret1(DataArrayInt::New());
7459   ret1->alloc(sz+1,1);
7460   int *pt(ret1->getPointer()); *pt=0;
7461   for(int i=0;i<sz;i++,pt++)
7462     pt[1]=pt[0]+(int)v[i].size();
7463   ret0->alloc(ret1->back(),1);
7464   pt=ret0->getPointer();
7465   for(int i=0;i<sz;i++)
7466     pt=std::copy(v[i].begin(),v[i].end(),pt);
7467   data=ret0.retn(); dataIndex=ret1.retn();
7468 }
7469
7470 /*!
7471  * Returns a new DataArrayInt which contains a complement of elements of \a this
7472  * one-dimensional array. I.e. the result array contains all elements from the range [0,
7473  * \a nbOfElement) not present in \a this array.
7474  *  \param [in] nbOfElement - maximal size of the result array.
7475  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7476  *         array using decrRef() as it is no more needed.
7477  *  \throw If \a this is not allocated.
7478  *  \throw If \a this->getNumberOfComponents() != 1.
7479  *  \throw If any element \a x of \a this array violates condition ( 0 <= \a x < \a
7480  *         nbOfElement ).
7481  */
7482 DataArrayInt *DataArrayInt::buildComplement(int nbOfElement) const
7483 {
7484   checkAllocated();
7485   if(getNumberOfComponents()!=1)
7486     throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : only single component allowed !");
7487   std::vector<bool> tmp(nbOfElement);
7488   const int *pt=getConstPointer();
7489   int nbOfTuples=getNumberOfTuples();
7490   for(const int *w=pt;w!=pt+nbOfTuples;w++)
7491     if(*w>=0 && *w<nbOfElement)
7492       tmp[*w]=true;
7493     else
7494       throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : an element is not in valid range : [0,nbOfElement) !");
7495   int nbOfRetVal=(int)std::count(tmp.begin(),tmp.end(),false);
7496   DataArrayInt *ret=DataArrayInt::New();
7497   ret->alloc(nbOfRetVal,1);
7498   int j=0;
7499   int *retPtr=ret->getPointer();
7500   for(int i=0;i<nbOfElement;i++)
7501     if(!tmp[i])
7502       retPtr[j++]=i;
7503   return ret;
7504 }
7505
7506 /*!
7507  * Returns a new DataArrayInt containing elements of \a this one-dimensional missing
7508  * from an \a other one-dimensional array.
7509  *  \param [in] other - a DataArrayInt containing elements not to include in the result array.
7510  *  \return DataArrayInt * - a new instance of DataArrayInt with one component. The
7511  *         caller is to delete this array using decrRef() as it is no more needed.
7512  *  \throw If \a other is NULL.
7513  *  \throw If \a other is not allocated.
7514  *  \throw If \a other->getNumberOfComponents() != 1.
7515  *  \throw If \a this is not allocated.
7516  *  \throw If \a this->getNumberOfComponents() != 1.
7517  *  \sa DataArrayInt::buildSubstractionOptimized()
7518  */
7519 DataArrayInt *DataArrayInt::buildSubstraction(const DataArrayInt *other) const
7520 {
7521   if(!other)
7522     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : DataArrayInt pointer in input is NULL !");
7523   checkAllocated();
7524   other->checkAllocated();
7525   if(getNumberOfComponents()!=1)
7526     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed !");
7527   if(other->getNumberOfComponents()!=1)
7528     throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed for other type !");
7529   const int *pt=getConstPointer();
7530   int nbOfTuples=getNumberOfTuples();
7531   std::set<int> s1(pt,pt+nbOfTuples);
7532   pt=other->getConstPointer();
7533   nbOfTuples=other->getNumberOfTuples();
7534   std::set<int> s2(pt,pt+nbOfTuples);
7535   std::vector<int> r;
7536   std::set_difference(s1.begin(),s1.end(),s2.begin(),s2.end(),std::back_insert_iterator< std::vector<int> >(r));
7537   DataArrayInt *ret=DataArrayInt::New();
7538   ret->alloc((int)r.size(),1);
7539   std::copy(r.begin(),r.end(),ret->getPointer());
7540   return ret;
7541 }
7542
7543 /*!
7544  * \a this is expected to have one component and to be sorted ascendingly (as for \a other).
7545  * \a other is expected to be a part of \a this. If not DataArrayInt::buildSubstraction should be called instead.
7546  * 
7547  * \param [in] other an array with one component and expected to be sorted ascendingly.
7548  * \ret list of ids in \a this but not in \a other.
7549  * \sa DataArrayInt::buildSubstraction
7550  */
7551 DataArrayInt *DataArrayInt::buildSubstractionOptimized(const DataArrayInt *other) const
7552 {
7553   static const char *MSG="DataArrayInt::buildSubstractionOptimized : only single component allowed !";
7554   if(!other) throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstractionOptimized : NULL input array !");
7555   checkAllocated(); other->checkAllocated();
7556   if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
7557   if(other->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
7558   const int *pt1Bg(begin()),*pt1End(end()),*pt2Bg(other->begin()),*pt2End(other->end());
7559   const int *work1(pt1Bg),*work2(pt2Bg);
7560   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
7561   for(;work1!=pt1End;work1++)
7562     {
7563       if(work2!=pt2End && *work1==*work2)
7564         work2++;
7565       else
7566         ret->pushBackSilent(*work1);
7567     }
7568   return ret.retn();
7569 }
7570
7571
7572 /*!
7573  * Returns a new DataArrayInt which contains all elements of \a this and a given
7574  * one-dimensional arrays. The result array does not contain any duplicates
7575  * and its values are sorted in ascending order.
7576  *  \param [in] other - an array to unite with \a this one.
7577  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7578  *         array using decrRef() as it is no more needed.
7579  *  \throw If \a this or \a other is not allocated.
7580  *  \throw If \a this->getNumberOfComponents() != 1.
7581  *  \throw If \a other->getNumberOfComponents() != 1.
7582  */
7583 DataArrayInt *DataArrayInt::buildUnion(const DataArrayInt *other) const
7584 {
7585   std::vector<const DataArrayInt *>arrs(2);
7586   arrs[0]=this; arrs[1]=other;
7587   return BuildUnion(arrs);
7588 }
7589
7590
7591 /*!
7592  * Returns a new DataArrayInt which contains elements present in both \a this and a given
7593  * one-dimensional arrays. The result array does not contain any duplicates
7594  * and its values are sorted in ascending order.
7595  *  \param [in] other - an array to intersect with \a this one.
7596  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7597  *         array using decrRef() as it is no more needed.
7598  *  \throw If \a this or \a other is not allocated.
7599  *  \throw If \a this->getNumberOfComponents() != 1.
7600  *  \throw If \a other->getNumberOfComponents() != 1.
7601  */
7602 DataArrayInt *DataArrayInt::buildIntersection(const DataArrayInt *other) const
7603 {
7604   std::vector<const DataArrayInt *>arrs(2);
7605   arrs[0]=this; arrs[1]=other;
7606   return BuildIntersection(arrs);
7607 }
7608
7609 /*!
7610  * This method can be applied on allocated with one component DataArrayInt instance.
7611  * This method is typically relevant for sorted arrays. All consecutive duplicated items in \a this will appear only once in returned DataArrayInt instance.
7612  * 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]
7613  * 
7614  * \return a newly allocated array that contain the result of the unique operation applied on \a this.
7615  * \throw if \a this is not allocated or if \a this has not exactly one component.
7616  * \sa DataArrayInt::buildUniqueNotSorted
7617  */
7618 DataArrayInt *DataArrayInt::buildUnique() const
7619 {
7620   checkAllocated();
7621   if(getNumberOfComponents()!=1)
7622     throw INTERP_KERNEL::Exception("DataArrayInt::buildUnique : only single component allowed !");
7623   int nbOfTuples=getNumberOfTuples();
7624   MCAuto<DataArrayInt> tmp=deepCopy();
7625   int *data=tmp->getPointer();
7626   int *last=std::unique(data,data+nbOfTuples);
7627   MCAuto<DataArrayInt> ret=DataArrayInt::New();
7628   ret->alloc(std::distance(data,last),1);
7629   std::copy(data,last,ret->getPointer());
7630   return ret.retn();
7631 }
7632
7633 /*!
7634  * This method can be applied on allocated with one component DataArrayInt instance.
7635  * This method keep elements only once by keeping the same order in \a this that is not expected to be sorted.
7636  *
7637  * \return a newly allocated array that contain the result of the unique operation applied on \a this.
7638  *
7639  * \throw if \a this is not allocated or if \a this has not exactly one component.
7640  *
7641  * \sa DataArrayInt::buildUnique
7642  */
7643 DataArrayInt *DataArrayInt::buildUniqueNotSorted() const
7644 {
7645   checkAllocated();
7646     if(getNumberOfComponents()!=1)
7647       throw INTERP_KERNEL::Exception("DataArrayInt::buildUniqueNotSorted : only single component allowed !");
7648   int minVal,maxVal;
7649   getMinMaxValues(minVal,maxVal);
7650   std::vector<bool> b(maxVal-minVal+1,false);
7651   const int *ptBg(begin()),*endBg(end());
7652   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
7653   for(const int *pt=ptBg;pt!=endBg;pt++)
7654     {
7655       if(!b[*pt-minVal])
7656         {
7657           ret->pushBackSilent(*pt);
7658           b[*pt-minVal]=true;
7659         }
7660     }
7661   ret->copyStringInfoFrom(*this);
7662   return ret.retn();
7663 }
7664
7665 /*!
7666  * Returns a new DataArrayInt which contains size of every of groups described by \a this
7667  * "index" array. Such "index" array is returned for example by 
7668  * \ref MEDCoupling::MEDCouplingUMesh::buildDescendingConnectivity
7669  * "MEDCouplingUMesh::buildDescendingConnectivity" and
7670  * \ref MEDCoupling::MEDCouplingUMesh::getNodalConnectivityIndex
7671  * "MEDCouplingUMesh::getNodalConnectivityIndex" etc.
7672  * This method preforms the reverse operation of DataArrayInt::computeOffsetsFull.
7673  *  \return DataArrayInt * - a new instance of DataArrayInt, whose number of tuples
7674  *          equals to \a this->getNumberOfComponents() - 1, and number of components is 1.
7675  *          The caller is to delete this array using decrRef() as it is no more needed. 
7676  *  \throw If \a this is not allocated.
7677  *  \throw If \a this->getNumberOfComponents() != 1.
7678  *  \throw If \a this->getNumberOfTuples() < 2.
7679  *
7680  *  \b Example: <br> 
7681  *         - this contains [1,3,6,7,7,9,15]
7682  *         - result array contains [2,3,1,0,2,6],
7683  *          where 2 = 3 - 1, 3 = 6 - 3, 1 = 7 - 6 etc.
7684  *
7685  * \sa DataArrayInt::computeOffsetsFull
7686  */
7687 DataArrayInt *DataArrayInt::deltaShiftIndex() const
7688 {
7689   checkAllocated();
7690   if(getNumberOfComponents()!=1)
7691     throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : only single component allowed !");
7692   int nbOfTuples=getNumberOfTuples();
7693   if(nbOfTuples<2)
7694     throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : 1 tuple at least must be present in 'this' !");
7695   const int *ptr=getConstPointer();
7696   DataArrayInt *ret=DataArrayInt::New();
7697   ret->alloc(nbOfTuples-1,1);
7698   int *out=ret->getPointer();
7699   std::transform(ptr+1,ptr+nbOfTuples,ptr,out,std::minus<int>());
7700   return ret;
7701 }
7702
7703 /*!
7704  * Modifies \a this one-dimensional array so that value of each element \a x
7705  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
7706  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number of tuples
7707  * and components remains the same.<br>
7708  * This method is useful for allToAllV in MPI with contiguous policy. This method
7709  * differs from computeOffsetsFull() in that the number of tuples is \b not changed by
7710  * this one.
7711  *  \throw If \a this is not allocated.
7712  *  \throw If \a this->getNumberOfComponents() != 1.
7713  *
7714  *  \b Example: <br>
7715  *          - Before \a this contains [3,5,1,2,0,8]
7716  *          - After \a this contains  [0,3,8,9,11,11]<br>
7717  *          Note that the last element 19 = 11 + 8 is missing because size of \a this
7718  *          array is retained and thus there is no space to store the last element.
7719  */
7720 void DataArrayInt::computeOffsets()
7721 {
7722   checkAllocated();
7723   if(getNumberOfComponents()!=1)
7724     throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets : only single component allowed !");
7725   int nbOfTuples=getNumberOfTuples();
7726   if(nbOfTuples==0)
7727     return ;
7728   int *work=getPointer();
7729   int tmp=work[0];
7730   work[0]=0;
7731   for(int i=1;i<nbOfTuples;i++)
7732     {
7733       int tmp2=work[i];
7734       work[i]=work[i-1]+tmp;
7735       tmp=tmp2;
7736     }
7737   declareAsNew();
7738 }
7739
7740
7741 /*!
7742  * Modifies \a this one-dimensional array so that value of each element \a x
7743  * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
7744  * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number
7745  * components remains the same and number of tuples is inceamented by one.<br>
7746  * This method is useful for allToAllV in MPI with contiguous policy. This method
7747  * differs from computeOffsets() in that the number of tuples is changed by this one.
7748  * This method preforms the reverse operation of DataArrayInt::deltaShiftIndex.
7749  *  \throw If \a this is not allocated.
7750  *  \throw If \a this->getNumberOfComponents() != 1.
7751  *
7752  *  \b Example: <br>
7753  *          - Before \a this contains [3,5,1,2,0,8]
7754  *          - After \a this contains  [0,3,8,9,11,11,19]<br>
7755  * \sa DataArrayInt::deltaShiftIndex
7756  */
7757 void DataArrayInt::computeOffsetsFull()
7758 {
7759   checkAllocated();
7760   if(getNumberOfComponents()!=1)
7761     throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsetsFull : only single component allowed !");
7762   int nbOfTuples=getNumberOfTuples();
7763   int *ret=(int *)malloc((nbOfTuples+1)*sizeof(int));
7764   const int *work=getConstPointer();
7765   ret[0]=0;
7766   for(int i=0;i<nbOfTuples;i++)
7767     ret[i+1]=work[i]+ret[i];
7768   useArray(ret,true,C_DEALLOC,nbOfTuples+1,1);
7769   declareAsNew();
7770 }
7771
7772 /*!
7773  * Returns two new DataArrayInt instances whose contents is computed from that of \a this and \a listOfIds arrays as follows.
7774  * \a this is expected to be an offset format ( as returned by DataArrayInt::computeOffsetsFull ) that is to say with one component
7775  * and ** sorted strictly increasingly **. \a listOfIds is expected to be sorted ascendingly (not strictly needed for \a listOfIds).
7776  * This methods searches in \a this, considered as a set of contiguous \c this->getNumberOfComponents() ranges, all ids in \a listOfIds
7777  * filling completely one of the ranges in \a this.
7778  *
7779  * \param [in] listOfIds a list of ids that has to be sorted ascendingly.
7780  * \param [out] rangeIdsFetched the range ids fetched
7781  * \param [out] idsInInputListThatFetch contains the list of ids in \a listOfIds that are \b fully included in a range in \a this. So
7782  *              \a idsInInputListThatFetch is a part of input \a listOfIds.
7783  *
7784  * \sa DataArrayInt::computeOffsetsFull
7785  *
7786  *  \b Example: <br>
7787  *          - \a this : [0,3,7,9,15,18]
7788  *          - \a listOfIds contains  [0,1,2,3,7,8,15,16,17]
7789  *          - \a rangeIdsFetched result array: [0,2,4]
7790  *          - \a idsInInputListThatFetch result array: [0,1,2,7,8,15,16,17]
7791  * In this example id 3 in input \a listOfIds is alone so it do not appear in output \a idsInInputListThatFetch.
7792  * <br>
7793  */
7794 void DataArrayInt::findIdsRangesInListOfIds(const DataArrayInt *listOfIds, DataArrayInt *& rangeIdsFetched, DataArrayInt *& idsInInputListThatFetch) const
7795 {
7796   if(!listOfIds)
7797     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : input list of ids is null !");
7798   listOfIds->checkAllocated(); checkAllocated();
7799   if(listOfIds->getNumberOfComponents()!=1)
7800     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : input list of ids must have exactly one component !");
7801   if(getNumberOfComponents()!=1)
7802     throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : this must have exactly one component !");
7803   MCAuto<DataArrayInt> ret0=DataArrayInt::New(); ret0->alloc(0,1);
7804   MCAuto<DataArrayInt> ret1=DataArrayInt::New(); ret1->alloc(0,1);
7805   const int *tupEnd(listOfIds->end()),*offBg(begin()),*offEnd(end()-1);
7806   const int *tupPtr(listOfIds->begin()),*offPtr(offBg);
7807   while(tupPtr!=tupEnd && offPtr!=offEnd)
7808     {
7809       if(*tupPtr==*offPtr)
7810         {
7811           int i=offPtr[0];
7812           while(i<offPtr[1] && *tupPtr==i && tupPtr!=tupEnd) { i++; tupPtr++; }
7813           if(i==offPtr[1])
7814             {
7815               ret0->pushBackSilent((int)std::distance(offBg,offPtr));
7816               ret1->pushBackValsSilent(tupPtr-(offPtr[1]-offPtr[0]),tupPtr);
7817               offPtr++;
7818             }
7819         }
7820       else
7821         { if(*tupPtr<*offPtr) tupPtr++; else offPtr++; }
7822     }
7823   rangeIdsFetched=ret0.retn();
7824   idsInInputListThatFetch=ret1.retn();
7825 }
7826
7827 /*!
7828  * Returns a new DataArrayInt whose contents is computed from that of \a this and \a
7829  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
7830  * "index" array of a "iota" array, thus, whose each element gives an index of a group
7831  * beginning within the "iota" array. And \a this is a one-dimensional array
7832  * considered as a selector of groups described by \a offsets to include into the result array.
7833  *  \throw If \a offsets is NULL.
7834  *  \throw If \a offsets is not allocated.
7835  *  \throw If \a offsets->getNumberOfComponents() != 1.
7836  *  \throw If \a offsets is not monotonically increasing.
7837  *  \throw If \a this is not allocated.
7838  *  \throw If \a this->getNumberOfComponents() != 1.
7839  *  \throw If any element of \a this is not a valid index for \a offsets array.
7840  *
7841  *  \b Example: <br>
7842  *          - \a this: [0,2,3]
7843  *          - \a offsets: [0,3,6,10,14,20]
7844  *          - result array: [0,1,2,6,7,8,9,10,11,12,13] == <br>
7845  *            \c range(0,3) + \c range(6,10) + \c range(10,14) ==<br>
7846  *            \c range( \a offsets[ \a this[0] ], offsets[ \a this[0]+1 ]) + 
7847  *            \c range( \a offsets[ \a this[1] ], offsets[ \a this[1]+1 ]) + 
7848  *            \c range( \a offsets[ \a this[2] ], offsets[ \a this[2]+1 ])
7849  */
7850 DataArrayInt *DataArrayInt::buildExplicitArrByRanges(const DataArrayInt *offsets) const
7851 {
7852   if(!offsets)
7853     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : DataArrayInt pointer in input is NULL !");
7854   checkAllocated();
7855   if(getNumberOfComponents()!=1)
7856     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : only single component allowed !");
7857   offsets->checkAllocated();
7858   if(offsets->getNumberOfComponents()!=1)
7859     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : input array should have only single component !");
7860   int othNbTuples=offsets->getNumberOfTuples()-1;
7861   int nbOfTuples=getNumberOfTuples();
7862   int retNbOftuples=0;
7863   const int *work=getConstPointer();
7864   const int *offPtr=offsets->getConstPointer();
7865   for(int i=0;i<nbOfTuples;i++)
7866     {
7867       int val=work[i];
7868       if(val>=0 && val<othNbTuples)
7869         {
7870           int delta=offPtr[val+1]-offPtr[val];
7871           if(delta>=0)
7872             retNbOftuples+=delta;
7873           else
7874             {
7875               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << val << " of offset array has a delta < 0 !";
7876               throw INTERP_KERNEL::Exception(oss.str().c_str());
7877             }
7878         }
7879       else
7880         {
7881           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << i << " in this contains " << val;
7882           oss << " whereas offsets array is of size " << othNbTuples+1 << " !";
7883           throw INTERP_KERNEL::Exception(oss.str().c_str());
7884         }
7885     }
7886   MCAuto<DataArrayInt> ret=DataArrayInt::New();
7887   ret->alloc(retNbOftuples,1);
7888   int *retPtr=ret->getPointer();
7889   for(int i=0;i<nbOfTuples;i++)
7890     {
7891       int val=work[i];
7892       int start=offPtr[val];
7893       int off=offPtr[val+1]-start;
7894       for(int j=0;j<off;j++,retPtr++)
7895         *retPtr=start+j;
7896     }
7897   return ret.retn();
7898 }
7899
7900 /*!
7901  * Returns a new DataArrayInt whose contents is computed using \a this that must be a 
7902  * scaled array (monotonically increasing).
7903 from that of \a this and \a
7904  * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
7905  * "index" array of a "iota" array, thus, whose each element gives an index of a group
7906  * beginning within the "iota" array. And \a this is a one-dimensional array
7907  * considered as a selector of groups described by \a offsets to include into the result array.
7908  *  \throw If \a  is NULL.
7909  *  \throw If \a this is not allocated.
7910  *  \throw If \a this->getNumberOfComponents() != 1.
7911  *  \throw If \a this->getNumberOfTuples() == 0.
7912  *  \throw If \a this is not monotonically increasing.
7913  *  \throw If any element of ids in ( \a bg \a stop \a step ) points outside the scale in \a this.
7914  *
7915  *  \b Example: <br>
7916  *          - \a bg , \a stop and \a step : (0,5,2)
7917  *          - \a this: [0,3,6,10,14,20]
7918  *          - result array: [0,0,0, 2,2,2,2, 4,4,4,4,4,4] == <br>
7919  */
7920 DataArrayInt *DataArrayInt::buildExplicitArrOfSliceOnScaledArr(int bg, int stop, int step) const
7921 {
7922   if(!isAllocated())
7923     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : not allocated array !");
7924   if(getNumberOfComponents()!=1)
7925     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of components is expected to be equal to one !");
7926   int nbOfTuples(getNumberOfTuples());
7927   if(nbOfTuples==0)
7928     throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of tuples must be != 0 !");
7929   const int *ids(begin());
7930   int nbOfEltsInSlc(GetNumberOfItemGivenBESRelative(bg,stop,step,"DataArrayInt::buildExplicitArrOfSliceOnScaledArr")),sz(0),pos(bg);
7931   for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
7932     {
7933       if(pos>=0 && pos<nbOfTuples-1)
7934         {
7935           int delta(ids[pos+1]-ids[pos]);
7936           sz+=delta;
7937           if(delta<0)
7938             {
7939               std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " and at this pos this is not monotonically increasing !";
7940               throw INTERP_KERNEL::Exception(oss.str().c_str());
7941             }          
7942         }
7943       else
7944         {
7945           std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " should be in [0," << nbOfTuples-1 << ") !";  
7946           throw INTERP_KERNEL::Exception(oss.str().c_str());
7947         }
7948     }
7949   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
7950   int *retPtr(ret->getPointer());
7951   pos=bg;
7952   for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
7953     {
7954       int delta(ids[pos+1]-ids[pos]);
7955       for(int j=0;j<delta;j++,retPtr++)
7956         *retPtr=pos;
7957     }
7958   return ret.retn();
7959 }
7960
7961 /*!
7962  * 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.
7963  * 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
7964  * in tuple **i** of returned DataArrayInt.
7965  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the first range.
7966  *
7967  * 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)]
7968  * The return DataArrayInt will contain : **[0,4,1,2,2,3]**
7969  * 
7970  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
7971  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
7972  * \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
7973  *        is thrown if no ranges in \a ranges contains value in \a this.
7974  * 
7975  * \sa DataArrayInt::findIdInRangeForEachTuple
7976  */
7977 DataArrayInt *DataArrayInt::findRangeIdForEachTuple(const DataArrayInt *ranges) const
7978 {
7979   if(!ranges)
7980     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : null input pointer !");
7981   if(ranges->getNumberOfComponents()!=2)
7982     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : input DataArrayInt instance should have 2 components !");
7983   checkAllocated();
7984   if(getNumberOfComponents()!=1)
7985     throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : this should have only one component !");
7986   int nbTuples=getNumberOfTuples();
7987   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
7988   int nbOfRanges=ranges->getNumberOfTuples();
7989   const int *rangesPtr=ranges->getConstPointer();
7990   int *retPtr=ret->getPointer();
7991   const int *inPtr=getConstPointer();
7992   for(int i=0;i<nbTuples;i++,retPtr++)
7993     {
7994       int val=inPtr[i];
7995       bool found=false;
7996       for(int j=0;j<nbOfRanges && !found;j++)
7997         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
7998           { *retPtr=j; found=true; }
7999       if(found)
8000         continue;
8001       else
8002         {
8003           std::ostringstream oss; oss << "DataArrayInt::findRangeIdForEachTuple : tuple #" << i << " not found by any ranges !";
8004           throw INTERP_KERNEL::Exception(oss.str().c_str());
8005         }
8006     }
8007   return ret.retn();
8008 }
8009
8010 /*!
8011  * 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.
8012  * 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
8013  * in tuple **i** of returned DataArrayInt.
8014  * If ranges overlapped (in theory it should not) this method do not detect it and always returns the sub position of the first range.
8015  *
8016  * 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)]
8017  * The return DataArrayInt will contain : **[1,2,4,0,2,2]**
8018  * This method is often called in pair with DataArrayInt::findRangeIdForEachTuple method.
8019  * 
8020  * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
8021  *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
8022  * \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
8023  *        is thrown if no ranges in \a ranges contains value in \a this.
8024  * \sa DataArrayInt::findRangeIdForEachTuple
8025  */
8026 DataArrayInt *DataArrayInt::findIdInRangeForEachTuple(const DataArrayInt *ranges) const
8027 {
8028   if(!ranges)
8029     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : null input pointer !");
8030   if(ranges->getNumberOfComponents()!=2)
8031     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : input DataArrayInt instance should have 2 components !");
8032   checkAllocated();
8033   if(getNumberOfComponents()!=1)
8034     throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : this should have only one component !");
8035   int nbTuples=getNumberOfTuples();
8036   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
8037   int nbOfRanges=ranges->getNumberOfTuples();
8038   const int *rangesPtr=ranges->getConstPointer();
8039   int *retPtr=ret->getPointer();
8040   const int *inPtr=getConstPointer();
8041   for(int i=0;i<nbTuples;i++,retPtr++)
8042     {
8043       int val=inPtr[i];
8044       bool found=false;
8045       for(int j=0;j<nbOfRanges && !found;j++)
8046         if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
8047           { *retPtr=val-rangesPtr[2*j]; found=true; }
8048       if(found)
8049         continue;
8050       else
8051         {
8052           std::ostringstream oss; oss << "DataArrayInt::findIdInRangeForEachTuple : tuple #" << i << " not found by any ranges !";
8053           throw INTERP_KERNEL::Exception(oss.str().c_str());
8054         }
8055     }
8056   return ret.retn();
8057 }
8058
8059 /*!
8060  * \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).
8061  * 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).
8062  * 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 !
8063  * If this method has correctly worked, \a this will be able to be considered as a linked list.
8064  * This method does nothing if number of tuples is lower of equal to 1.
8065  *
8066  * This method is useful for users having an unstructured mesh having only SEG2 to rearrange internaly the connectibity without any coordinates consideration.
8067  *
8068  * \sa MEDCouplingUMesh::orderConsecutiveCells1D, DataArrayInt::fromLinkedListOfPairToList
8069  */
8070 void DataArrayInt::sortEachPairToMakeALinkedList()
8071 {
8072   checkAllocated();
8073   if(getNumberOfComponents()!=2)
8074     throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : Only works on DataArrayInt instance with nb of components equal to 2 !");
8075   int nbOfTuples(getNumberOfTuples());
8076   if(nbOfTuples<=1)
8077     return ;
8078   int *conn(getPointer());
8079   for(int i=1;i<nbOfTuples;i++,conn+=2)
8080     {
8081       if(i>1)
8082         {
8083           if(conn[2]==conn[3])
8084             {
8085               std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " presence of a pair filled with same ids !";
8086               throw INTERP_KERNEL::Exception(oss.str().c_str());
8087             }
8088           if(conn[2]!=conn[1] && conn[3]==conn[1] && conn[2]!=conn[0])
8089             std::swap(conn[2],conn[3]);
8090           //not(conn[2]==conn[1] && conn[3]!=conn[1] && conn[3]!=conn[0])
8091           if(conn[2]!=conn[1] || conn[3]==conn[1] || conn[3]==conn[0])
8092             {
8093               std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " something is invalid !";
8094               throw INTERP_KERNEL::Exception(oss.str().c_str());
8095             }
8096         }
8097       else
8098         {
8099           if(conn[0]==conn[1] || conn[2]==conn[3])
8100             throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : In the 2 first tuples presence of a pair filled with same ids !");
8101           int tmp[4];
8102           std::set<int> s;
8103           s.insert(conn,conn+4);
8104           if(s.size()!=3)
8105             throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : This can't be considered as a linked list regarding 2 first tuples !");
8106           if(std::count(conn,conn+4,conn[0])==2)
8107             {
8108               tmp[0]=conn[1];
8109               tmp[1]=conn[0];
8110               tmp[2]=conn[0];
8111               if(conn[2]==conn[0])
8112                 { tmp[3]=conn[3]; }
8113               else
8114                 { tmp[3]=conn[2];}
8115               std::copy(tmp,tmp+4,conn);
8116             }
8117           else
8118             {//here we are sure to have (std::count(conn,conn+4,conn[1])==2)
8119               if(conn[1]==conn[3])
8120                 std::swap(conn[2],conn[3]);
8121             }
8122         }
8123     }
8124 }
8125
8126 /*!
8127  * \a this is expected to be a correctly linked list of pairs.
8128  * 
8129  * \sa DataArrayInt::sortEachPairToMakeALinkedList
8130  */
8131 MCAuto<DataArrayInt> DataArrayInt::fromLinkedListOfPairToList() const
8132 {
8133   checkAllocated();
8134   checkNbOfComps(2,"DataArrayInt::fromLinkedListOfPairToList : this is expected to have 2 components");
8135   int nbTuples(getNumberOfTuples());
8136   if(nbTuples<1)
8137     throw INTERP_KERNEL::Exception("DataArrayInt::fromLinkedListOfPairToList : no tuples in this ! Not a linked list !");
8138   MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbTuples+1,1);
8139   const int *thisPtr(begin());
8140   int *retPtr(ret->getPointer());
8141   retPtr[0]=thisPtr[0];
8142   for(int i=0;i<nbTuples;i++)
8143     {
8144       retPtr[i+1]=thisPtr[2*i+1];
8145       if(i<nbTuples-1)
8146         if(thisPtr[2*i+1]!=thisPtr[2*(i+1)+0])
8147           {
8148             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 ?";
8149             throw INTERP_KERNEL::Exception(oss.str());
8150           }
8151     }
8152   return ret;
8153 }
8154
8155 /*!
8156  * 
8157  * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayInt instance.
8158  *             \a nbTimes  should be at least equal to 1.
8159  * \return a newly allocated DataArrayInt having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
8160  * \throw if \a this is not allocated or if \a this has not number of components set to one or if \a nbTimes is lower than 1.
8161  */
8162 DataArrayInt *DataArrayInt::duplicateEachTupleNTimes(int nbTimes) const
8163 {
8164   checkAllocated();
8165   if(getNumberOfComponents()!=1)
8166     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : this should have only one component !");
8167   if(nbTimes<1)
8168     throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : nb times should be >= 1 !");
8169   int nbTuples=getNumberOfTuples();
8170   const int *inPtr=getConstPointer();
8171   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTimes*nbTuples,1);
8172   int *retPtr=ret->getPointer();
8173   for(int i=0;i<nbTuples;i++,inPtr++)
8174     {
8175       int val=*inPtr;
8176       for(int j=0;j<nbTimes;j++,retPtr++)
8177         *retPtr=val;
8178     }
8179   ret->copyStringInfoFrom(*this);
8180   return ret.retn();
8181 }
8182
8183 /*!
8184  * This method returns all different values found in \a this. This method throws if \a this has not been allocated.
8185  * But the number of components can be different from one.
8186  * \return a newly allocated array (that should be dealt by the caller) containing different values in \a this.
8187  */
8188 DataArrayInt *DataArrayInt::getDifferentValues() const
8189 {
8190   checkAllocated();
8191   std::set<int> ret;
8192   ret.insert(begin(),end());
8193   MCAuto<DataArrayInt> ret2=DataArrayInt::New(); ret2->alloc((int)ret.size(),1);
8194   std::copy(ret.begin(),ret.end(),ret2->getPointer());
8195   return ret2.retn();
8196 }
8197
8198 /*!
8199  * This method is a refinement of DataArrayInt::getDifferentValues because it returns not only different values in \a this but also, for each of
8200  * them it tells which tuple id have this id.
8201  * This method works only on arrays with one component (if it is not the case call DataArrayInt::rearrange(1) ).
8202  * This method returns two arrays having same size.
8203  * 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.
8204  * 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]]
8205  */
8206 std::vector<DataArrayInt *> DataArrayInt::partitionByDifferentValues(std::vector<int>& differentIds) const
8207 {
8208   checkAllocated();
8209   if(getNumberOfComponents()!=1)
8210     throw INTERP_KERNEL::Exception("DataArrayInt::partitionByDifferentValues : this should have only one component !");
8211   int id=0;
8212   std::map<int,int> m,m2,m3;
8213   for(const int *w=begin();w!=end();w++)
8214     m[*w]++;
8215   differentIds.resize(m.size());
8216   std::vector<DataArrayInt *> ret(m.size());
8217   std::vector<int *> retPtr(m.size());
8218   for(std::map<int,int>::const_iterator it=m.begin();it!=m.end();it++,id++)
8219     {
8220       m2[(*it).first]=id;
8221       ret[id]=DataArrayInt::New();
8222       ret[id]->alloc((*it).second,1);
8223       retPtr[id]=ret[id]->getPointer();
8224       differentIds[id]=(*it).first;
8225     }
8226   id=0;
8227   for(const int *w=begin();w!=end();w++,id++)
8228     {
8229       retPtr[m2[*w]][m3[*w]++]=id;
8230     }
8231   return ret;
8232 }
8233
8234 /*!
8235  * This method split ids in [0, \c this->getNumberOfTuples() ) using \a this array as a field of weight (>=0 each).
8236  * The aim of this method is to return a set of \a nbOfSlices chunk of contiguous ids as balanced as possible.
8237  *
8238  * \param [in] nbOfSlices - number of slices expected.
8239  * \return - a vector having a size equal to \a nbOfSlices giving the start (included) and the stop (excluded) of each chunks.
8240  * 
8241  * \sa DataArray::GetSlice
8242  * \throw If \a this is not allocated or not with exactly one component.
8243  * \throw If an element in \a this if < 0.
8244  */
8245 std::vector< std::pair<int,int> > DataArrayInt::splitInBalancedSlices(int nbOfSlices) const
8246 {
8247   if(!isAllocated() || getNumberOfComponents()!=1)
8248     throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : this array should have number of components equal to one and must be allocated !");
8249   if(nbOfSlices<=0)
8250     throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : number of slices must be >= 1 !");
8251   int sum(accumulate(0)),nbOfTuples(getNumberOfTuples());
8252   int sumPerSlc(sum/nbOfSlices),pos(0);
8253   const int *w(begin());
8254   std::vector< std::pair<int,int> > ret(nbOfSlices);
8255   for(int i=0;i<nbOfSlices;i++)
8256     {
8257       std::pair<int,int> p(pos,-1);
8258       int locSum(0);
8259       while(locSum<sumPerSlc && pos<nbOfTuples) { pos++; locSum+=*w++; }
8260       if(i!=nbOfSlices-1)
8261         p.second=pos;
8262       else
8263         p.second=nbOfTuples;
8264       ret[i]=p;
8265     }
8266   return ret;
8267 }
8268
8269 /*!
8270  * Returns a new DataArrayInt that is a sum of two given arrays. There are 3
8271  * valid cases.
8272  * 1.  The arrays have same number of tuples and components. Then each value of
8273  *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
8274  *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
8275  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
8276  *   component. Then
8277  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
8278  * 3.  The arrays have same number of components and one array, say _a2_, has one
8279  *   tuple. Then
8280  *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
8281  *
8282  * Info on components is copied either from the first array (in the first case) or from
8283  * the array with maximal number of elements (getNbOfElems()).
8284  *  \param [in] a1 - an array to sum up.
8285  *  \param [in] a2 - another array to sum up.
8286  *  \return DataArrayInt * - the new instance of DataArrayInt.
8287  *          The caller is to delete this result array using decrRef() as it is no more
8288  *          needed.
8289  *  \throw If either \a a1 or \a a2 is NULL.
8290  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
8291  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
8292  *         none of them has number of tuples or components equal to 1.
8293  */
8294 DataArrayInt *DataArrayInt::Add(const DataArrayInt *a1, const DataArrayInt *a2)
8295 {
8296   if(!a1 || !a2)
8297     throw INTERP_KERNEL::Exception("DataArrayInt::Add : input DataArrayInt instance is NULL !");
8298   int nbOfTuple=a1->getNumberOfTuples();
8299   int nbOfTuple2=a2->getNumberOfTuples();
8300   int nbOfComp=a1->getNumberOfComponents();
8301   int nbOfComp2=a2->getNumberOfComponents();
8302   MCAuto<DataArrayInt> ret=0;
8303   if(nbOfTuple==nbOfTuple2)
8304     {
8305       if(nbOfComp==nbOfComp2)
8306         {
8307           ret=DataArrayInt::New();
8308           ret->alloc(nbOfTuple,nbOfComp);
8309           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<int>());
8310           ret->copyStringInfoFrom(*a1);
8311         }
8312       else
8313         {
8314           int nbOfCompMin,nbOfCompMax;
8315           const DataArrayInt *aMin, *aMax;
8316           if(nbOfComp>nbOfComp2)
8317             {
8318               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
8319               aMin=a2; aMax=a1;
8320             }
8321           else
8322             {
8323               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
8324               aMin=a1; aMax=a2;
8325             }
8326           if(nbOfCompMin==1)
8327             {
8328               ret=DataArrayInt::New();
8329               ret->alloc(nbOfTuple,nbOfCompMax);
8330               const int *aMinPtr=aMin->getConstPointer();
8331               const int *aMaxPtr=aMax->getConstPointer();
8332               int *res=ret->getPointer();
8333               for(int i=0;i<nbOfTuple;i++)
8334                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<int>(),aMinPtr[i]));
8335               ret->copyStringInfoFrom(*aMax);
8336             }
8337           else
8338             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
8339         }
8340     }
8341   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
8342     {
8343       if(nbOfComp==nbOfComp2)
8344         {
8345           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
8346           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
8347           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
8348           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
8349           ret=DataArrayInt::New();
8350           ret->alloc(nbOfTupleMax,nbOfComp);
8351           int *res=ret->getPointer();
8352           for(int i=0;i<nbOfTupleMax;i++)
8353             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<int>());
8354           ret->copyStringInfoFrom(*aMax);
8355         }
8356       else
8357         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
8358     }
8359   else
8360     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
8361   return ret.retn();
8362 }
8363
8364 /*!
8365  * Adds values of another DataArrayInt to values of \a this one. There are 3
8366  * valid cases.
8367  * 1.  The arrays have same number of tuples and components. Then each value of
8368  *   \a other array is added to the corresponding value of \a this array, i.e.:
8369  *   _a_ [ i, j ] += _other_ [ i, j ].
8370  * 2.  The arrays have same number of tuples and \a other array has one component. Then
8371  *   _a_ [ i, j ] += _other_ [ i, 0 ].
8372  * 3.  The arrays have same number of components and \a other array has one tuple. Then
8373  *   _a_ [ i, j ] += _a2_ [ 0, j ].
8374  *
8375  *  \param [in] other - an array to add to \a this one.
8376  *  \throw If \a other is NULL.
8377  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
8378  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
8379  *         \a other has number of both tuples and components not equal to 1.
8380  */
8381 void DataArrayInt::addEqual(const DataArrayInt *other)
8382 {
8383   if(!other)
8384     throw INTERP_KERNEL::Exception("DataArrayInt::addEqual : input DataArrayInt instance is NULL !");
8385   const char *msg="Nb of tuples mismatch for DataArrayInt::addEqual  !";
8386   checkAllocated(); other->checkAllocated();
8387   int nbOfTuple=getNumberOfTuples();
8388   int nbOfTuple2=other->getNumberOfTuples();
8389   int nbOfComp=getNumberOfComponents();
8390   int nbOfComp2=other->getNumberOfComponents();
8391   if(nbOfTuple==nbOfTuple2)
8392     {
8393       if(nbOfComp==nbOfComp2)
8394         {
8395           std::transform(begin(),end(),other->begin(),getPointer(),std::plus<int>());
8396         }
8397       else if(nbOfComp2==1)
8398         {
8399           int *ptr=getPointer();
8400           const int *ptrc=other->getConstPointer();
8401           for(int i=0;i<nbOfTuple;i++)
8402             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<int>(),*ptrc++));
8403         }
8404       else
8405         throw INTERP_KERNEL::Exception(msg);
8406     }
8407   else if(nbOfTuple2==1)
8408     {
8409       if(nbOfComp2==nbOfComp)
8410         {
8411           int *ptr=getPointer();
8412           const int *ptrc=other->getConstPointer();
8413           for(int i=0;i<nbOfTuple;i++)
8414             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<int>());
8415         }
8416       else
8417         throw INTERP_KERNEL::Exception(msg);
8418     }
8419   else
8420     throw INTERP_KERNEL::Exception(msg);
8421   declareAsNew();
8422 }
8423
8424 /*!
8425  * Returns a new DataArrayInt that is a subtraction of two given arrays. There are 3
8426  * valid cases.
8427  * 1.  The arrays have same number of tuples and components. Then each value of
8428  *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
8429  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
8430  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
8431  *   component. Then
8432  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
8433  * 3.  The arrays have same number of components and one array, say _a2_, has one
8434  *   tuple. Then
8435  *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
8436  *
8437  * Info on components is copied either from the first array (in the first case) or from
8438  * the array with maximal number of elements (getNbOfElems()).
8439  *  \param [in] a1 - an array to subtract from.
8440  *  \param [in] a2 - an array to subtract.
8441  *  \return DataArrayInt * - the new instance of DataArrayInt.
8442  *          The caller is to delete this result array using decrRef() as it is no more
8443  *          needed.
8444  *  \throw If either \a a1 or \a a2 is NULL.
8445  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
8446  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
8447  *         none of them has number of tuples or components equal to 1.
8448  */
8449 DataArrayInt *DataArrayInt::Substract(const DataArrayInt *a1, const DataArrayInt *a2)
8450 {
8451   if(!a1 || !a2)
8452     throw INTERP_KERNEL::Exception("DataArrayInt::Substract : input DataArrayInt instance is NULL !");
8453   int nbOfTuple1=a1->getNumberOfTuples();
8454   int nbOfTuple2=a2->getNumberOfTuples();
8455   int nbOfComp1=a1->getNumberOfComponents();
8456   int nbOfComp2=a2->getNumberOfComponents();
8457   if(nbOfTuple2==nbOfTuple1)
8458     {
8459       if(nbOfComp1==nbOfComp2)
8460         {
8461           MCAuto<DataArrayInt> ret=DataArrayInt::New();
8462           ret->alloc(nbOfTuple2,nbOfComp1);
8463           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<int>());
8464           ret->copyStringInfoFrom(*a1);
8465           return ret.retn();
8466         }
8467       else if(nbOfComp2==1)
8468         {
8469           MCAuto<DataArrayInt> ret=DataArrayInt::New();
8470           ret->alloc(nbOfTuple1,nbOfComp1);
8471           const int *a2Ptr=a2->getConstPointer();
8472           const int *a1Ptr=a1->getConstPointer();
8473           int *res=ret->getPointer();
8474           for(int i=0;i<nbOfTuple1;i++)
8475             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<int>(),a2Ptr[i]));
8476           ret->copyStringInfoFrom(*a1);
8477           return ret.retn();
8478         }
8479       else
8480         {
8481           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
8482           return 0;
8483         }
8484     }
8485   else if(nbOfTuple2==1)
8486     {
8487       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
8488       MCAuto<DataArrayInt> ret=DataArrayInt::New();
8489       ret->alloc(nbOfTuple1,nbOfComp1);
8490       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
8491       int *pt=ret->getPointer();
8492       for(int i=0;i<nbOfTuple1;i++)
8493         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<int>());
8494       ret->copyStringInfoFrom(*a1);
8495       return ret.retn();
8496     }
8497   else
8498     {
8499       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
8500       return 0;
8501     }
8502 }
8503
8504 /*!
8505  * Subtract values of another DataArrayInt from values of \a this one. There are 3
8506  * valid cases.
8507  * 1.  The arrays have same number of tuples and components. Then each value of
8508  *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
8509  *   _a_ [ i, j ] -= _other_ [ i, j ].
8510  * 2.  The arrays have same number of tuples and \a other array has one component. Then
8511  *   _a_ [ i, j ] -= _other_ [ i, 0 ].
8512  * 3.  The arrays have same number of components and \a other array has one tuple. Then
8513  *   _a_ [ i, j ] -= _a2_ [ 0, j ].
8514  *
8515  *  \param [in] other - an array to subtract from \a this one.
8516  *  \throw If \a other is NULL.
8517  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
8518  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
8519  *         \a other has number of both tuples and components not equal to 1.
8520  */
8521 void DataArrayInt::substractEqual(const DataArrayInt *other)
8522 {
8523   if(!other)
8524     throw INTERP_KERNEL::Exception("DataArrayInt::substractEqual : input DataArrayInt instance is NULL !");
8525   const char *msg="Nb of tuples mismatch for DataArrayInt::substractEqual  !";
8526   checkAllocated(); other->checkAllocated();
8527   int nbOfTuple=getNumberOfTuples();
8528   int nbOfTuple2=other->getNumberOfTuples();
8529   int nbOfComp=getNumberOfComponents();
8530   int nbOfComp2=other->getNumberOfComponents();
8531   if(nbOfTuple==nbOfTuple2)
8532     {
8533       if(nbOfComp==nbOfComp2)
8534         {
8535           std::transform(begin(),end(),other->begin(),getPointer(),std::minus<int>());
8536         }
8537       else if(nbOfComp2==1)
8538         {
8539           int *ptr=getPointer();
8540           const int *ptrc=other->getConstPointer();
8541           for(int i=0;i<nbOfTuple;i++)
8542             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<int>(),*ptrc++));
8543         }
8544       else
8545         throw INTERP_KERNEL::Exception(msg);
8546     }
8547   else if(nbOfTuple2==1)
8548     {
8549       int *ptr=getPointer();
8550       const int *ptrc=other->getConstPointer();
8551       for(int i=0;i<nbOfTuple;i++)
8552         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<int>());
8553     }
8554   else
8555     throw INTERP_KERNEL::Exception(msg);
8556   declareAsNew();
8557 }
8558
8559 /*!
8560  * Returns a new DataArrayInt that is a product of two given arrays. There are 3
8561  * valid cases.
8562  * 1.  The arrays have same number of tuples and components. Then each value of
8563  *   the result array (_a_) is a product of the corresponding values of \a a1 and
8564  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
8565  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
8566  *   component. Then
8567  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
8568  * 3.  The arrays have same number of components and one array, say _a2_, has one
8569  *   tuple. Then
8570  *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
8571  *
8572  * Info on components is copied either from the first array (in the first case) or from
8573  * the array with maximal number of elements (getNbOfElems()).
8574  *  \param [in] a1 - a factor array.
8575  *  \param [in] a2 - another factor array.
8576  *  \return DataArrayInt * - the new instance of DataArrayInt.
8577  *          The caller is to delete this result array using decrRef() as it is no more
8578  *          needed.
8579  *  \throw If either \a a1 or \a a2 is NULL.
8580  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
8581  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
8582  *         none of them has number of tuples or components equal to 1.
8583  */
8584 DataArrayInt *DataArrayInt::Multiply(const DataArrayInt *a1, const DataArrayInt *a2)
8585 {
8586   if(!a1 || !a2)
8587     throw INTERP_KERNEL::Exception("DataArrayInt::Multiply : input DataArrayInt instance is NULL !");
8588   int nbOfTuple=a1->getNumberOfTuples();
8589   int nbOfTuple2=a2->getNumberOfTuples();
8590   int nbOfComp=a1->getNumberOfComponents();
8591   int nbOfComp2=a2->getNumberOfComponents();
8592   MCAuto<DataArrayInt> ret=0;
8593   if(nbOfTuple==nbOfTuple2)
8594     {
8595       if(nbOfComp==nbOfComp2)
8596         {
8597           ret=DataArrayInt::New();
8598           ret->alloc(nbOfTuple,nbOfComp);
8599           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<int>());
8600           ret->copyStringInfoFrom(*a1);
8601         }
8602       else
8603         {
8604           int nbOfCompMin,nbOfCompMax;
8605           const DataArrayInt *aMin, *aMax;
8606           if(nbOfComp>nbOfComp2)
8607             {
8608               nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
8609               aMin=a2; aMax=a1;
8610             }
8611           else
8612             {
8613               nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
8614               aMin=a1; aMax=a2;
8615             }
8616           if(nbOfCompMin==1)
8617             {
8618               ret=DataArrayInt::New();
8619               ret->alloc(nbOfTuple,nbOfCompMax);
8620               const int *aMinPtr=aMin->getConstPointer();
8621               const int *aMaxPtr=aMax->getConstPointer();
8622               int *res=ret->getPointer();
8623               for(int i=0;i<nbOfTuple;i++)
8624                 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<int>(),aMinPtr[i]));
8625               ret->copyStringInfoFrom(*aMax);
8626             }
8627           else
8628             throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
8629         }
8630     }
8631   else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
8632     {
8633       if(nbOfComp==nbOfComp2)
8634         {
8635           int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
8636           const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
8637           const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
8638           const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
8639           ret=DataArrayInt::New();
8640           ret->alloc(nbOfTupleMax,nbOfComp);
8641           int *res=ret->getPointer();
8642           for(int i=0;i<nbOfTupleMax;i++)
8643             res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<int>());
8644           ret->copyStringInfoFrom(*aMax);
8645         }
8646       else
8647         throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
8648     }
8649   else
8650     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
8651   return ret.retn();
8652 }
8653
8654
8655 /*!
8656  * Multiply values of another DataArrayInt to values of \a this one. There are 3
8657  * valid cases.
8658  * 1.  The arrays have same number of tuples and components. Then each value of
8659  *   \a other array is multiplied to the corresponding value of \a this array, i.e.:
8660  *   _a_ [ i, j ] *= _other_ [ i, j ].
8661  * 2.  The arrays have same number of tuples and \a other array has one component. Then
8662  *   _a_ [ i, j ] *= _other_ [ i, 0 ].
8663  * 3.  The arrays have same number of components and \a other array has one tuple. Then
8664  *   _a_ [ i, j ] *= _a2_ [ 0, j ].
8665  *
8666  *  \param [in] other - an array to multiply to \a this one.
8667  *  \throw If \a other is NULL.
8668  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
8669  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
8670  *         \a other has number of both tuples and components not equal to 1.
8671  */
8672 void DataArrayInt::multiplyEqual(const DataArrayInt *other)
8673 {
8674   if(!other)
8675     throw INTERP_KERNEL::Exception("DataArrayInt::multiplyEqual : input DataArrayInt instance is NULL !");
8676   const char *msg="Nb of tuples mismatch for DataArrayInt::multiplyEqual !";
8677   checkAllocated(); other->checkAllocated();
8678   int nbOfTuple=getNumberOfTuples();
8679   int nbOfTuple2=other->getNumberOfTuples();
8680   int nbOfComp=getNumberOfComponents();
8681   int nbOfComp2=other->getNumberOfComponents();
8682   if(nbOfTuple==nbOfTuple2)
8683     {
8684       if(nbOfComp==nbOfComp2)
8685         {
8686           std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<int>());
8687         }
8688       else if(nbOfComp2==1)
8689         {
8690           int *ptr=getPointer();
8691           const int *ptrc=other->getConstPointer();
8692           for(int i=0;i<nbOfTuple;i++)
8693             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<int>(),*ptrc++));    
8694         }
8695       else
8696         throw INTERP_KERNEL::Exception(msg);
8697     }
8698   else if(nbOfTuple2==1)
8699     {
8700       if(nbOfComp2==nbOfComp)
8701         {
8702           int *ptr=getPointer();
8703           const int *ptrc=other->getConstPointer();
8704           for(int i=0;i<nbOfTuple;i++)
8705             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<int>());
8706         }
8707       else
8708         throw INTERP_KERNEL::Exception(msg);
8709     }
8710   else
8711     throw INTERP_KERNEL::Exception(msg);
8712   declareAsNew();
8713 }
8714
8715
8716 /*!
8717  * Returns a new DataArrayInt that is a division of two given arrays. There are 3
8718  * valid cases.
8719  * 1.  The arrays have same number of tuples and components. Then each value of
8720  *   the result array (_a_) is a division of the corresponding values of \a a1 and
8721  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
8722  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
8723  *   component. Then
8724  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
8725  * 3.  The arrays have same number of components and one array, say _a2_, has one
8726  *   tuple. Then
8727  *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
8728  *
8729  * Info on components is copied either from the first array (in the first case) or from
8730  * the array with maximal number of elements (getNbOfElems()).
8731  *  \warning No check of division by zero is performed!
8732  *  \param [in] a1 - a numerator array.
8733  *  \param [in] a2 - a denominator array.
8734  *  \return DataArrayInt * - the new instance of DataArrayInt.
8735  *          The caller is to delete this result array using decrRef() as it is no more
8736  *          needed.
8737  *  \throw If either \a a1 or \a a2 is NULL.
8738  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
8739  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
8740  *         none of them has number of tuples or components equal to 1.
8741  */
8742 DataArrayInt *DataArrayInt::Divide(const DataArrayInt *a1, const DataArrayInt *a2)
8743 {
8744   if(!a1 || !a2)
8745     throw INTERP_KERNEL::Exception("DataArrayInt::Divide : input DataArrayInt instance is NULL !");
8746   int nbOfTuple1=a1->getNumberOfTuples();
8747   int nbOfTuple2=a2->getNumberOfTuples();
8748   int nbOfComp1=a1->getNumberOfComponents();
8749   int nbOfComp2=a2->getNumberOfComponents();
8750   if(nbOfTuple2==nbOfTuple1)
8751     {
8752       if(nbOfComp1==nbOfComp2)
8753         {
8754           MCAuto<DataArrayInt> ret=DataArrayInt::New();
8755           ret->alloc(nbOfTuple2,nbOfComp1);
8756           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<int>());
8757           ret->copyStringInfoFrom(*a1);
8758           return ret.retn();
8759         }
8760       else if(nbOfComp2==1)
8761         {
8762           MCAuto<DataArrayInt> ret=DataArrayInt::New();
8763           ret->alloc(nbOfTuple1,nbOfComp1);
8764           const int *a2Ptr=a2->getConstPointer();
8765           const int *a1Ptr=a1->getConstPointer();
8766           int *res=ret->getPointer();
8767           for(int i=0;i<nbOfTuple1;i++)
8768             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<int>(),a2Ptr[i]));
8769           ret->copyStringInfoFrom(*a1);
8770           return ret.retn();
8771         }
8772       else
8773         {
8774           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
8775           return 0;
8776         }
8777     }
8778   else if(nbOfTuple2==1)
8779     {
8780       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
8781       MCAuto<DataArrayInt> ret=DataArrayInt::New();
8782       ret->alloc(nbOfTuple1,nbOfComp1);
8783       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
8784       int *pt=ret->getPointer();
8785       for(int i=0;i<nbOfTuple1;i++)
8786         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<int>());
8787       ret->copyStringInfoFrom(*a1);
8788       return ret.retn();
8789     }
8790   else
8791     {
8792       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
8793       return 0;
8794     }
8795 }
8796
8797 /*!
8798  * Divide values of \a this array by values of another DataArrayInt. There are 3
8799  * valid cases.
8800  * 1.  The arrays have same number of tuples and components. Then each value of
8801  *    \a this array is divided by the corresponding value of \a other one, i.e.:
8802  *   _a_ [ i, j ] /= _other_ [ i, j ].
8803  * 2.  The arrays have same number of tuples and \a other array has one component. Then
8804  *   _a_ [ i, j ] /= _other_ [ i, 0 ].
8805  * 3.  The arrays have same number of components and \a other array has one tuple. Then
8806  *   _a_ [ i, j ] /= _a2_ [ 0, j ].
8807  *
8808  *  \warning No check of division by zero is performed!
8809  *  \param [in] other - an array to divide \a this one by.
8810  *  \throw If \a other is NULL.
8811  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
8812  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
8813  *         \a other has number of both tuples and components not equal to 1.
8814  */
8815 void DataArrayInt::divideEqual(const DataArrayInt *other)
8816 {
8817   if(!other)
8818     throw INTERP_KERNEL::Exception("DataArrayInt::divideEqual : input DataArrayInt instance is NULL !");
8819   const char *msg="Nb of tuples mismatch for DataArrayInt::divideEqual !";
8820   checkAllocated(); other->checkAllocated();
8821   int nbOfTuple=getNumberOfTuples();
8822   int nbOfTuple2=other->getNumberOfTuples();
8823   int nbOfComp=getNumberOfComponents();
8824   int nbOfComp2=other->getNumberOfComponents();
8825   if(nbOfTuple==nbOfTuple2)
8826     {
8827       if(nbOfComp==nbOfComp2)
8828         {
8829           std::transform(begin(),end(),other->begin(),getPointer(),std::divides<int>());
8830         }
8831       else if(nbOfComp2==1)
8832         {
8833           int *ptr=getPointer();
8834           const int *ptrc=other->getConstPointer();
8835           for(int i=0;i<nbOfTuple;i++)
8836             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<int>(),*ptrc++));
8837         }
8838       else
8839         throw INTERP_KERNEL::Exception(msg);
8840     }
8841   else if(nbOfTuple2==1)
8842     {
8843       if(nbOfComp2==nbOfComp)
8844         {
8845           int *ptr=getPointer();
8846           const int *ptrc=other->getConstPointer();
8847           for(int i=0;i<nbOfTuple;i++)
8848             std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<int>());
8849         }
8850       else
8851         throw INTERP_KERNEL::Exception(msg);
8852     }
8853   else
8854     throw INTERP_KERNEL::Exception(msg);
8855   declareAsNew();
8856 }
8857
8858
8859 /*!
8860  * Returns a new DataArrayInt that is a modulus of two given arrays. There are 3
8861  * valid cases.
8862  * 1.  The arrays have same number of tuples and components. Then each value of
8863  *   the result array (_a_) is a division of the corresponding values of \a a1 and
8864  *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, j ].
8865  * 2.  The arrays have same number of tuples and one array, say _a2_, has one
8866  *   component. Then
8867  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, 0 ].
8868  * 3.  The arrays have same number of components and one array, say _a2_, has one
8869  *   tuple. Then
8870  *   _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ 0, j ].
8871  *
8872  * Info on components is copied either from the first array (in the first case) or from
8873  * the array with maximal number of elements (getNbOfElems()).
8874  *  \warning No check of division by zero is performed!
8875  *  \param [in] a1 - a dividend array.
8876  *  \param [in] a2 - a divisor array.
8877  *  \return DataArrayInt * - the new instance of DataArrayInt.
8878  *          The caller is to delete this result array using decrRef() as it is no more
8879  *          needed.
8880  *  \throw If either \a a1 or \a a2 is NULL.
8881  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
8882  *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
8883  *         none of them has number of tuples or components equal to 1.
8884  */
8885 DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt *a2)
8886 {
8887   if(!a1 || !a2)
8888     throw INTERP_KERNEL::Exception("DataArrayInt::Modulus : input DataArrayInt instance is NULL !");
8889   int nbOfTuple1=a1->getNumberOfTuples();
8890   int nbOfTuple2=a2->getNumberOfTuples();
8891   int nbOfComp1=a1->getNumberOfComponents();
8892   int nbOfComp2=a2->getNumberOfComponents();
8893   if(nbOfTuple2==nbOfTuple1)
8894     {
8895       if(nbOfComp1==nbOfComp2)
8896         {
8897           MCAuto<DataArrayInt> ret=DataArrayInt::New();
8898           ret->alloc(nbOfTuple2,nbOfComp1);
8899           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::modulus<int>());
8900           ret->copyStringInfoFrom(*a1);
8901           return ret.retn();
8902         }
8903       else if(nbOfComp2==1)
8904         {
8905           MCAuto<DataArrayInt> ret=DataArrayInt::New();
8906           ret->alloc(nbOfTuple1,nbOfComp1);
8907           const int *a2Ptr=a2->getConstPointer();
8908           const int *a1Ptr=a1->getConstPointer();
8909           int *res=ret->getPointer();
8910           for(int i=0;i<nbOfTuple1;i++)
8911             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::modulus<int>(),a2Ptr[i]));
8912           ret->copyStringInfoFrom(*a1);
8913           return ret.retn();
8914         }
8915       else
8916         {
8917           a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
8918           return 0;
8919         }
8920     }
8921   else if(nbOfTuple2==1)
8922     {
8923       a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
8924       MCAuto<DataArrayInt> ret=DataArrayInt::New();
8925       ret->alloc(nbOfTuple1,nbOfComp1);
8926       const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
8927       int *pt=ret->getPointer();
8928       for(int i=0;i<nbOfTuple1;i++)
8929         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::modulus<int>());
8930       ret->copyStringInfoFrom(*a1);
8931       return ret.retn();
8932     }
8933   else
8934     {
8935       a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Modulus !");//will always throw an exception
8936       return 0;
8937     }
8938 }
8939
8940 /*!
8941  * Modify \a this array so that each value becomes a modulus of division of this value by
8942  * a value of another DataArrayInt. There are 3 valid cases.
8943  * 1.  The arrays have same number of tuples and components. Then each value of
8944  *    \a this array is divided by the corresponding value of \a other one, i.e.:
8945  *   _a_ [ i, j ] %= _other_ [ i, j ].
8946  * 2.  The arrays have same number of tuples and \a other array has one component. Then
8947  *   _a_ [ i, j ] %= _other_ [ i, 0 ].
8948  * 3.  The arrays have same number of components and \a other array has one tuple. Then
8949  *   _a_ [ i, j ] %= _a2_ [ 0, j ].
8950  *
8951  *  \warning No check of division by zero is performed!
8952  *  \param [in] other - a divisor array.
8953  *  \throw If \a other is NULL.
8954  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
8955  *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
8956  *         \a other has number of both tuples and components not equal to 1.
8957  */
8958 void DataArrayInt::modulusEqual(const DataArrayInt *other)
8959 {
8960   if(!other)
8961     throw INTERP_KERNEL::Exception("DataArrayInt::modulusEqual : input DataArrayInt instance is NULL !");
8962   const char *msg="Nb of tuples mismatch for DataArrayInt::modulusEqual !";
8963   checkAllocated(); other->checkAllocated();
8964   int nbOfTuple=getNumberOfTuples();
8965   int nbOfTuple2=other->getNumberOfTuples();
8966   int nbOfComp=getNumberOfComponents();
8967   int nbOfComp2=other->getNumberOfComponents();
8968   if(nbOfTuple==nbOfTuple2)
8969     {
8970       if(nbOfComp==nbOfComp2)
8971         {
8972           std::transform(begin(),end(),other->begin(),getPointer(),std::modulus<int>());
8973         }
8974       else if(nbOfComp2==1)
8975         {
8976           if(nbOfComp2==nbOfComp)
8977             {
8978               int *ptr=getPointer();
8979               const int *ptrc=other->getConstPointer();
8980               for(int i=0;i<nbOfTuple;i++)
8981                 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::modulus<int>(),*ptrc++));
8982             }
8983           else
8984             throw INTERP_KERNEL::Exception(msg);
8985         }
8986       else
8987         throw INTERP_KERNEL::Exception(msg);
8988     }
8989   else if(nbOfTuple2==1)
8990     {
8991       int *ptr=getPointer();
8992       const int *ptrc=other->getConstPointer();
8993       for(int i=0;i<nbOfTuple;i++)
8994         std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::modulus<int>());
8995     }
8996   else
8997     throw INTERP_KERNEL::Exception(msg);
8998   declareAsNew();
8999 }
9000
9001 /*!
9002  * Returns a new DataArrayInt that is the result of pow of two given arrays. There are 3
9003  * valid cases.
9004  *
9005  *  \param [in] a1 - an array to pow up.
9006  *  \param [in] a2 - another array to sum up.
9007  *  \return DataArrayInt * - the new instance of DataArrayInt.
9008  *          The caller is to delete this result array using decrRef() as it is no more
9009  *          needed.
9010  *  \throw If either \a a1 or \a a2 is NULL.
9011  *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
9012  *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
9013  *  \throw If there is a negative value in \a a2.
9014  */
9015 DataArrayInt *DataArrayInt::Pow(const DataArrayInt *a1, const DataArrayInt *a2)
9016 {
9017   if(!a1 || !a2)
9018     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : at least one of input instances is null !");
9019   int nbOfTuple=a1->getNumberOfTuples();
9020   int nbOfTuple2=a2->getNumberOfTuples();
9021   int nbOfComp=a1->getNumberOfComponents();
9022   int nbOfComp2=a2->getNumberOfComponents();
9023   if(nbOfTuple!=nbOfTuple2)
9024     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of tuples mismatches !");
9025   if(nbOfComp!=1 || nbOfComp2!=1)
9026     throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of components of both arrays must be equal to 1 !");
9027   MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuple,1);
9028   const int *ptr1(a1->begin()),*ptr2(a2->begin());
9029   int *ptr=ret->getPointer();
9030   for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
9031     {
9032       if(*ptr2>=0)
9033         {
9034           int tmp=1;
9035           for(int j=0;j<*ptr2;j++)
9036             tmp*=*ptr1;
9037           *ptr=tmp;
9038         }
9039       else
9040         {
9041           std::ostringstream oss; oss << "DataArrayInt::Pow : on tuple #" << i << " of a2 value is < 0 (" << *ptr2 << ") !";
9042           throw INTERP_KERNEL::Exception(oss.str().c_str());
9043         }
9044     }
9045   return ret.retn();
9046 }
9047
9048 /*!
9049  * Apply pow on values of another DataArrayInt to values of \a this one.
9050  *
9051  *  \param [in] other - an array to pow to \a this one.
9052  *  \throw If \a other is NULL.
9053  *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
9054  *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
9055  *  \throw If there is a negative value in \a other.
9056  */
9057 void DataArrayInt::powEqual(const DataArrayInt *other)
9058 {
9059   if(!other)
9060     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : input instance is null !");
9061   int nbOfTuple=getNumberOfTuples();
9062   int nbOfTuple2=other->getNumberOfTuples();
9063   int nbOfComp=getNumberOfComponents();
9064   int nbOfComp2=other->getNumberOfComponents();
9065   if(nbOfTuple!=nbOfTuple2)
9066     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of tuples mismatches !");
9067   if(nbOfComp!=1 || nbOfComp2!=1)
9068     throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of components of both arrays must be equal to 1 !");
9069   int *ptr=getPointer();
9070   const int *ptrc=other->begin();
9071   for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
9072     {
9073       if(*ptrc>=0)
9074         {
9075           int tmp=1;
9076           for(int j=0;j<*ptrc;j++)
9077             tmp*=*ptr;
9078           *ptr=tmp;
9079         }
9080       else
9081         {
9082           std::ostringstream oss; oss << "DataArrayInt::powEqual : on tuple #" << i << " of other value is < 0 (" << *ptrc << ") !";
9083           throw INTERP_KERNEL::Exception(oss.str().c_str());
9084         }
9085     }
9086   declareAsNew();
9087 }
9088
9089 /*!
9090  * Returns a C array which is a renumbering map in "Old to New" mode for the input array.
9091  * This map, if applied to \a start array, would make it sorted. For example, if
9092  * \a start array contents are [9,10,0,6,4,11,3,7] then the contents of the result array is
9093  * [5,6,0,3,2,7,1,4].
9094  *  \param [in] start - pointer to the first element of the array for which the
9095  *         permutation map is computed.
9096  *  \param [in] end - pointer specifying the end of the array \a start, so that
9097  *         the last value of \a start is \a end[ -1 ].
9098  *  \return int * - the result permutation array that the caller is to delete as it is no
9099  *         more needed.
9100  *  \throw If there are equal values in the input array.
9101  */
9102 int *DataArrayInt::CheckAndPreparePermutation(const int *start, const int *end)
9103 {
9104   std::size_t sz=std::distance(start,end);
9105   int *ret=(int *)malloc(sz*sizeof(int));
9106   int *work=new int[sz];
9107   std::copy(start,end,work);
9108   std::sort(work,work+sz);
9109   if(std::unique(work,work+sz)!=work+sz)
9110     {
9111       delete [] work;
9112       free(ret);
9113       throw INTERP_KERNEL::Exception("Some elements are equals in the specified array !");
9114     }
9115   std::map<int,int> m;
9116   for(int *workPt=work;workPt!=work+sz;workPt++)
9117     m[*workPt]=(int)std::distance(work,workPt);
9118   int *iter2=ret;
9119   for(const int *iter=start;iter!=end;iter++,iter2++)
9120     *iter2=m[*iter];
9121   delete [] work;
9122   return ret;
9123 }
9124
9125 /*!
9126  * Returns a new DataArrayInt containing an arithmetic progression
9127  * that is equal to the sequence returned by Python \c range(\a begin,\a  end,\a  step )
9128  * function.
9129  *  \param [in] begin - the start value of the result sequence.
9130  *  \param [in] end - limiting value, so that every value of the result array is less than
9131  *              \a end.
9132  *  \param [in] step - specifies the increment or decrement.
9133  *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9134  *          array using decrRef() as it is no more needed.
9135  *  \throw If \a step == 0.
9136  *  \throw If \a end < \a begin && \a step > 0.
9137  *  \throw If \a end > \a begin && \a step < 0.
9138  */
9139 DataArrayInt *DataArrayInt::Range(int begin, int end, int step)
9140 {
9141   int nbOfTuples=GetNumberOfItemGivenBESRelative(begin,end,step,"DataArrayInt::Range");
9142   MCAuto<DataArrayInt> ret=DataArrayInt::New();
9143   ret->alloc(nbOfTuples,1);
9144   int *ptr=ret->getPointer();
9145   if(step>0)
9146     {
9147       for(int i=begin;i<end;i+=step,ptr++)
9148         *ptr=i;
9149     }
9150   else
9151     {
9152       for(int i=begin;i>end;i+=step,ptr++)
9153         *ptr=i;
9154     }
9155   return ret.retn();
9156 }
9157
9158 /*!
9159  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
9160  * Server side.
9161  */
9162 void DataArrayInt::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
9163 {
9164   tinyInfo.resize(2);
9165   if(isAllocated())
9166     {
9167       tinyInfo[0]=getNumberOfTuples();
9168       tinyInfo[1]=getNumberOfComponents();
9169     }
9170   else
9171     {
9172       tinyInfo[0]=-1;
9173       tinyInfo[1]=-1;
9174     }
9175 }
9176
9177 /*!
9178  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
9179  * Server side.
9180  */
9181 void DataArrayInt::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
9182 {
9183   if(isAllocated())
9184     {
9185       int nbOfCompo=getNumberOfComponents();
9186       tinyInfo.resize(nbOfCompo+1);
9187       tinyInfo[0]=getName();
9188       for(int i=0;i<nbOfCompo;i++)
9189         tinyInfo[i+1]=getInfoOnComponent(i);
9190     }
9191   else
9192     {
9193       tinyInfo.resize(1);
9194       tinyInfo[0]=getName();
9195     }
9196 }
9197
9198 /*!
9199  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
9200  * This method returns if a feeding is needed.
9201  */
9202 bool DataArrayInt::resizeForUnserialization(const std::vector<int>& tinyInfoI)
9203 {
9204   int nbOfTuple=tinyInfoI[0];
9205   int nbOfComp=tinyInfoI[1];
9206   if(nbOfTuple!=-1 || nbOfComp!=-1)
9207     {
9208       alloc(nbOfTuple,nbOfComp);
9209       return true;
9210     }
9211   return false;
9212 }
9213
9214 /*!
9215  * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
9216  * This method returns if a feeding is needed.
9217  */
9218 void DataArrayInt::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
9219 {
9220   setName(tinyInfoS[0]);
9221   if(isAllocated())
9222     {
9223       int nbOfCompo=tinyInfoI[1];
9224       for(int i=0;i<nbOfCompo;i++)
9225         setInfoOnComponent(i,tinyInfoS[i+1]);
9226     }
9227 }
9228
9229 DataArrayIntIterator::DataArrayIntIterator(DataArrayInt *da):_da(da),_pt(0),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
9230 {
9231   if(_da)
9232     {
9233       _da->incrRef();
9234       if(_da->isAllocated())
9235         {
9236           _nb_comp=da->getNumberOfComponents();
9237           _nb_tuple=da->getNumberOfTuples();
9238           _pt=da->getPointer();
9239         }
9240     }
9241 }
9242
9243 DataArrayIntIterator::~DataArrayIntIterator()
9244 {
9245   if(_da)
9246     _da->decrRef();
9247 }
9248
9249 DataArrayIntTuple *DataArrayIntIterator::nextt()
9250 {
9251   if(_tuple_id<_nb_tuple)
9252     {
9253       _tuple_id++;
9254       DataArrayIntTuple *ret=new DataArrayIntTuple(_pt,_nb_comp);
9255       _pt+=_nb_comp;
9256       return ret;
9257     }
9258   else
9259     return 0;
9260 }
9261
9262 DataArrayIntTuple::DataArrayIntTuple(int *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
9263 {
9264 }
9265
9266 std::string DataArrayIntTuple::repr() const
9267 {
9268   std::ostringstream oss; oss << "(";
9269   for(int i=0;i<_nb_of_compo-1;i++)
9270     oss << _pt[i] << ", ";
9271   oss << _pt[_nb_of_compo-1] << ")";
9272   return oss.str();
9273 }
9274
9275 int DataArrayIntTuple::intValue() const
9276 {
9277   if(_nb_of_compo==1)
9278     return *_pt;
9279   throw INTERP_KERNEL::Exception("DataArrayIntTuple::intValue : DataArrayIntTuple instance has not exactly 1 component -> Not possible to convert it into an integer !");
9280 }
9281
9282 /*!
9283  * This method returns a newly allocated instance the caller should dealed with by a MEDCoupling::DataArrayInt::decrRef.
9284  * This method performs \b no copy of data. The content is only referenced using MEDCoupling::DataArrayInt::useArray with ownership set to \b false.
9285  * 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
9286  * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
9287  */
9288 DataArrayInt *DataArrayIntTuple::buildDAInt(int nbOfTuples, int nbOfCompo) const
9289 {
9290   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
9291     {
9292       DataArrayInt *ret=DataArrayInt::New();
9293       ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
9294       return ret;
9295     }
9296   else
9297     {
9298       std::ostringstream oss; oss << "DataArrayIntTuple::buildDAInt : unable to build a requested DataArrayInt instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
9299       oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
9300       throw INTERP_KERNEL::Exception(oss.str().c_str());
9301     }
9302 }