1 // Copyright (C) 2007-2016 CEA/DEN, EDF R&D
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.
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.
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
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 // Author : Anthony Geay (EDF R&D)
21 #include "MEDCouplingMemArray.txx"
24 #include "GenMathFormulae.hxx"
25 #include "InterpKernelAutoPtr.hxx"
26 #include "InterpKernelExprParser.hxx"
28 #include "InterpKernelAutoPtr.hxx"
29 #include "InterpKernelGeo2DEdgeArcCircle.hxx"
30 #include "InterpKernelAutoPtr.hxx"
31 #include "InterpKernelGeo2DNode.hxx"
32 #include "InterpKernelGeo2DEdgeLin.hxx"
41 typedef double (*MYFUNCPTR)(double);
43 using namespace MEDCoupling;
45 template class MEDCoupling::MemArray<int>;
46 template class MEDCoupling::MemArray<double>;
47 template class MEDCoupling::DataArrayTemplate<int>;
48 template class MEDCoupling::DataArrayTemplate<double>;
49 template class MEDCoupling::DataArrayTemplateClassic<int>;
50 template class MEDCoupling::DataArrayTemplateClassic<double>;
51 template class MEDCoupling::DataArrayTemplateFP<double>;
52 template class MEDCoupling::DataArrayIterator<double>;
53 template class MEDCoupling::DataArrayIterator<int>;
54 template class MEDCoupling::DataArrayDiscrete<Int32>;
55 template class MEDCoupling::DataArrayDiscreteSigned<Int32>;
57 // [ABN] : Newest Intel compilers need this:
58 template Traits<Int32>::ArrayType* MEDCoupling::DataArrayTuple<Int32>::buildDA(int, int) const;
59 template Traits<double>::ArrayType* MEDCoupling::DataArrayTuple<double>::buildDA(int, int) const;
60 template Traits<float>::ArrayType* MEDCoupling::DataArrayTuple<float>::buildDA(int, int) const;
63 template<int SPACEDIM>
64 void DataArrayDouble::findCommonTuplesAlg(const double *bbox, int nbNodes, int limitNodeId, double prec, DataArrayInt *c, DataArrayInt *cI) const
66 const double *coordsPtr=getConstPointer();
67 BBTreePts<SPACEDIM,int> myTree(bbox,0,0,nbNodes,prec);
68 std::vector<bool> isDone(nbNodes);
69 for(int i=0;i<nbNodes;i++)
73 std::vector<int> intersectingElems;
74 myTree.getElementsAroundPoint(coordsPtr+i*SPACEDIM,intersectingElems);
75 if(intersectingElems.size()>1)
77 std::vector<int> commonNodes;
78 for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
82 commonNodes.push_back(*it);
85 if(!commonNodes.empty())
87 cI->pushBackSilent(cI->back()+(int)commonNodes.size()+1);
89 c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
96 template<int SPACEDIM>
97 void DataArrayDouble::FindTupleIdsNearTuplesAlg(const BBTreePts<SPACEDIM,int>& myTree, const double *pos, int nbOfTuples, double eps,
98 DataArrayInt *c, DataArrayInt *cI)
100 for(int i=0;i<nbOfTuples;i++)
102 std::vector<int> intersectingElems;
103 myTree.getElementsAroundPoint(pos+i*SPACEDIM,intersectingElems);
104 std::vector<int> commonNodes;
105 for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
106 commonNodes.push_back(*it);
107 cI->pushBackSilent(cI->back()+(int)commonNodes.size());
108 c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
112 template<int SPACEDIM>
113 void DataArrayDouble::FindClosestTupleIdAlg(const BBTreePts<SPACEDIM,int>& myTree, double dist, const double *pos, int nbOfTuples, const double *thisPt, int thisNbOfTuples, int *res)
115 double distOpt(dist);
116 const double *p(pos);
118 for(int i=0;i<nbOfTuples;i++,p+=SPACEDIM,r++)
123 double ret=myTree.getElementsAroundPoint2(p,distOpt,elem);
124 if(ret!=std::numeric_limits<double>::max())
126 distOpt=std::max(ret,1e-4);
131 { distOpt=2*distOpt; continue; }
136 int DataArray::EffectiveCircPerm(int nbOfShift, int nbOfTuples)
139 throw INTERP_KERNEL::Exception("DataArray::EffectiveCircPerm : number of tuples is expected to be > 0 !");
142 return nbOfShift%nbOfTuples;
148 return nbOfTuples-tmp;
152 std::size_t DataArray::getHeapMemorySizeWithoutChildren() const
154 std::size_t sz1=_name.capacity();
155 std::size_t sz2=_info_on_compo.capacity();
157 for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
158 sz3+=(*it).capacity();
162 std::vector<const BigMemoryObject *> DataArray::getDirectChildrenWithNull() const
164 return std::vector<const BigMemoryObject *>();
168 * Sets the attribute \a _name of \a this array.
169 * See \ref MEDCouplingArrayBasicsName "DataArrays infos" for more information.
170 * \param [in] name - new array name
172 void DataArray::setName(const std::string& name)
178 * Copies textual data from an \a other DataArray. The copied data are
179 * - the name attribute,
180 * - the information of components.
182 * For more information on these data see \ref MEDCouplingArrayBasicsName "DataArrays infos".
184 * \param [in] other - another instance of DataArray to copy the textual data from.
185 * \throw If number of components of \a this array differs from that of the \a other.
187 void DataArray::copyStringInfoFrom(const DataArray& other)
189 if(_info_on_compo.size()!=other._info_on_compo.size())
190 throw INTERP_KERNEL::Exception("Size of arrays mismatches on copyStringInfoFrom !");
192 _info_on_compo=other._info_on_compo;
195 void DataArray::copyPartOfStringInfoFrom(const DataArray& other, const std::vector<int>& compoIds)
197 int nbOfCompoOth=other.getNumberOfComponents();
198 std::size_t newNbOfCompo=compoIds.size();
199 for(std::size_t i=0;i<newNbOfCompo;i++)
200 if(compoIds[i]>=nbOfCompoOth || compoIds[i]<0)
202 std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompoOth << ")";
203 throw INTERP_KERNEL::Exception(oss.str().c_str());
205 for(std::size_t i=0;i<newNbOfCompo;i++)
206 setInfoOnComponent((int)i,other.getInfoOnComponent(compoIds[i]));
209 void DataArray::copyPartOfStringInfoFrom2(const std::vector<int>& compoIds, const DataArray& other)
211 std::size_t nbOfCompo(getNumberOfComponents());
212 std::size_t partOfCompoToSet=compoIds.size();
213 if(partOfCompoToSet!=other.getNumberOfComponents())
214 throw INTERP_KERNEL::Exception("Given compoIds has not the same size as number of components of given array !");
215 for(std::size_t i=0;i<partOfCompoToSet;i++)
216 if(compoIds[i]>=(int)nbOfCompo || compoIds[i]<0)
218 std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompo << ")";
219 throw INTERP_KERNEL::Exception(oss.str().c_str());
221 for(std::size_t i=0;i<partOfCompoToSet;i++)
222 setInfoOnComponent(compoIds[i],other.getInfoOnComponent((int)i));
225 bool DataArray::areInfoEqualsIfNotWhy(const DataArray& other, std::string& reason) const
227 std::ostringstream oss;
228 if(_name!=other._name)
230 oss << "Names DataArray mismatch : this name=\"" << _name << " other name=\"" << other._name << "\" !";
234 if(_info_on_compo!=other._info_on_compo)
236 oss << "Components DataArray mismatch : \nThis components=";
237 for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
238 oss << "\"" << *it << "\",";
239 oss << "\nOther components=";
240 for(std::vector<std::string>::const_iterator it=other._info_on_compo.begin();it!=other._info_on_compo.end();it++)
241 oss << "\"" << *it << "\",";
249 * Compares textual information of \a this DataArray with that of an \a other one.
250 * The compared data are
251 * - the name attribute,
252 * - the information of components.
254 * For more information on these data see \ref MEDCouplingArrayBasicsName "DataArrays infos".
255 * \param [in] other - another instance of DataArray to compare the textual data of.
256 * \return bool - \a true if the textual information is same, \a false else.
258 bool DataArray::areInfoEquals(const DataArray& other) const
261 return areInfoEqualsIfNotWhy(other,tmp);
264 void DataArray::reprWithoutNameStream(std::ostream& stream) const
266 stream << "Number of components : "<< getNumberOfComponents() << "\n";
267 stream << "Info of these components : ";
268 for(std::vector<std::string>::const_iterator iter=_info_on_compo.begin();iter!=_info_on_compo.end();iter++)
269 stream << "\"" << *iter << "\" ";
273 std::string DataArray::cppRepr(const std::string& varName) const
275 std::ostringstream ret;
276 reprCppStream(varName,ret);
281 * Sets information on all components. To know more on format of this information
282 * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
283 * \param [in] info - a vector of strings.
284 * \throw If size of \a info differs from the number of components of \a this.
286 void DataArray::setInfoOnComponents(const std::vector<std::string>& info)
288 if(getNumberOfComponents()!=info.size())
290 std::ostringstream oss; oss << "DataArray::setInfoOnComponents : input is of size " << info.size() << " whereas number of components is equal to " << getNumberOfComponents() << " !";
291 throw INTERP_KERNEL::Exception(oss.str().c_str());
297 * This method is only a dispatcher towards DataArrayDouble::setPartOfValues3, DataArrayInt::setPartOfValues3, DataArrayChar::setPartOfValues3 depending on the true
298 * type of \a this and \a aBase.
300 * \throw If \a aBase and \a this do not have the same type.
302 * \sa DataArrayDouble::setPartOfValues3, DataArrayInt::setPartOfValues3, DataArrayChar::setPartOfValues3.
304 void DataArray::setPartOfValuesBase3(const DataArray *aBase, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
307 throw INTERP_KERNEL::Exception("DataArray::setPartOfValuesBase3 : input aBase object is NULL !");
308 DataArrayDouble *this1(dynamic_cast<DataArrayDouble *>(this));
309 DataArrayInt *this2(dynamic_cast<DataArrayInt *>(this));
310 DataArrayChar *this3(dynamic_cast<DataArrayChar *>(this));
311 const DataArrayDouble *a1(dynamic_cast<const DataArrayDouble *>(aBase));
312 const DataArrayInt *a2(dynamic_cast<const DataArrayInt *>(aBase));
313 const DataArrayChar *a3(dynamic_cast<const DataArrayChar *>(aBase));
316 this1->setPartOfValues3(a1,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
321 this2->setPartOfValues3(a2,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
326 this3->setPartOfValues3(a3,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
329 throw INTERP_KERNEL::Exception("DataArray::setPartOfValuesBase3 : input aBase object and this do not have the same type !");
332 std::vector<std::string> DataArray::getVarsOnComponent() const
334 int nbOfCompo=(int)_info_on_compo.size();
335 std::vector<std::string> ret(nbOfCompo);
336 for(int i=0;i<nbOfCompo;i++)
337 ret[i]=getVarOnComponent(i);
341 std::vector<std::string> DataArray::getUnitsOnComponent() const
343 int nbOfCompo=(int)_info_on_compo.size();
344 std::vector<std::string> ret(nbOfCompo);
345 for(int i=0;i<nbOfCompo;i++)
346 ret[i]=getUnitOnComponent(i);
351 * Returns information on a component specified by an index.
352 * To know more on format of this information
353 * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
354 * \param [in] i - the index (zero based) of the component of interest.
355 * \return std::string - a string containing the information on \a i-th component.
356 * \throw If \a i is not a valid component index.
358 std::string DataArray::getInfoOnComponent(int i) const
360 if(i<(int)_info_on_compo.size() && i>=0)
361 return _info_on_compo[i];
364 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();
365 throw INTERP_KERNEL::Exception(oss.str().c_str());
370 * Returns the var part of the full information of the \a i-th component.
371 * For example, if \c getInfoOnComponent(0) returns "SIGXY [N/m^2]", then
372 * \c getVarOnComponent(0) returns "SIGXY".
373 * If a unit part of information is not detected by presence of
374 * two square brackets, then the full information is returned.
375 * To read more about the component information format, see
376 * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
377 * \param [in] i - the index (zero based) of the component of interest.
378 * \return std::string - a string containing the var information, or the full info.
379 * \throw If \a i is not a valid component index.
381 std::string DataArray::getVarOnComponent(int i) const
383 if(i<(int)_info_on_compo.size() && i>=0)
385 return GetVarNameFromInfo(_info_on_compo[i]);
389 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();
390 throw INTERP_KERNEL::Exception(oss.str().c_str());
395 * Returns the unit part of the full information of the \a i-th component.
396 * For example, if \c getInfoOnComponent(0) returns "SIGXY [ N/m^2]", then
397 * \c getUnitOnComponent(0) returns " N/m^2".
398 * If a unit part of information is not detected by presence of
399 * two square brackets, then an empty string is returned.
400 * To read more about the component information format, see
401 * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
402 * \param [in] i - the index (zero based) of the component of interest.
403 * \return std::string - a string containing the unit information, if any, or "".
404 * \throw If \a i is not a valid component index.
406 std::string DataArray::getUnitOnComponent(int i) const
408 if(i<(int)_info_on_compo.size() && i>=0)
410 return GetUnitFromInfo(_info_on_compo[i]);
414 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();
415 throw INTERP_KERNEL::Exception(oss.str().c_str());
420 * Returns the var part of the full component information.
421 * For example, if \a info == "SIGXY [N/m^2]", then this method returns "SIGXY".
422 * If a unit part of information is not detected by presence of
423 * two square brackets, then the whole \a info is returned.
424 * To read more about the component information format, see
425 * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
426 * \param [in] info - the full component information.
427 * \return std::string - a string containing only var information, or the \a info.
429 std::string DataArray::GetVarNameFromInfo(const std::string& info)
431 std::size_t p1=info.find_last_of('[');
432 std::size_t p2=info.find_last_of(']');
433 if(p1==std::string::npos || p2==std::string::npos)
438 return std::string();
439 std::size_t p3=info.find_last_not_of(' ',p1-1);
440 return info.substr(0,p3+1);
444 * Returns the unit part of the full component information.
445 * For example, if \a info == "SIGXY [ N/m^2]", then this method returns " N/m^2".
446 * If a unit part of information is not detected by presence of
447 * two square brackets, then an empty string is returned.
448 * To read more about the component information format, see
449 * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
450 * \param [in] info - the full component information.
451 * \return std::string - a string containing only unit information, if any, or "".
453 std::string DataArray::GetUnitFromInfo(const std::string& info)
455 std::size_t p1=info.find_last_of('[');
456 std::size_t p2=info.find_last_of(']');
457 if(p1==std::string::npos || p2==std::string::npos)
458 return std::string();
460 return std::string();
461 return info.substr(p1+1,p2-p1-1);
465 * This method put in info format the result of the merge of \a var and \a unit.
466 * The standard format for that is "var [unit]".
467 * Inversely you can retrieve the var part or the unit part of info string using resp. GetVarNameFromInfo and GetUnitFromInfo.
469 std::string DataArray::BuildInfoFromVarAndUnit(const std::string& var, const std::string& unit)
471 std::ostringstream oss;
472 oss << var << " [" << unit << "]";
476 std::string DataArray::GetAxisTypeRepr(MEDCouplingAxisType at)
481 return std::string("AX_CART");
483 return std::string("AX_CYL");
485 return std::string("AX_SPHER");
487 throw INTERP_KERNEL::Exception("DataArray::GetAxisTypeRepr : unrecognized axis type enum !");
492 * Returns a new DataArray by concatenating all given arrays, so that (1) the number
493 * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
494 * the number of component in the result array is same as that of each of given arrays.
495 * Info on components is copied from the first of the given arrays. Number of components
496 * in the given arrays must be the same.
497 * \param [in] arrs - a sequence of arrays to include in the result array. All arrays must have the same type.
498 * \return DataArray * - the new instance of DataArray (that can be either DataArrayInt, DataArrayDouble, DataArrayChar).
499 * The caller is to delete this result array using decrRef() as it is no more
501 * \throw If all arrays within \a arrs are NULL.
502 * \throw If all not null arrays in \a arrs have not the same type.
503 * \throw If getNumberOfComponents() of arrays within \a arrs.
505 DataArray *DataArray::Aggregate(const std::vector<const DataArray *>& arrs)
507 std::vector<const DataArray *> arr2;
508 for(std::vector<const DataArray *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
512 throw INTERP_KERNEL::Exception("DataArray::Aggregate : only null instance in input vector !");
513 std::vector<const DataArrayDouble *> arrd;
514 std::vector<const DataArrayInt *> arri;
515 std::vector<const DataArrayChar *> arrc;
516 for(std::vector<const DataArray *>::const_iterator it=arr2.begin();it!=arr2.end();it++)
518 const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(*it);
520 { arrd.push_back(a); continue; }
521 const DataArrayInt *b=dynamic_cast<const DataArrayInt *>(*it);
523 { arri.push_back(b); continue; }
524 const DataArrayChar *c=dynamic_cast<const DataArrayChar *>(*it);
526 { arrc.push_back(c); continue; }
527 throw INTERP_KERNEL::Exception("DataArray::Aggregate : presence of not null instance in inuput that is not in [DataArrayDouble, DataArrayInt, DataArrayChar] !");
529 if(arr2.size()==arrd.size())
530 return DataArrayDouble::Aggregate(arrd);
531 if(arr2.size()==arri.size())
532 return DataArrayInt::Aggregate(arri);
533 if(arr2.size()==arrc.size())
534 return DataArrayChar::Aggregate(arrc);
535 throw INTERP_KERNEL::Exception("DataArray::Aggregate : all input arrays must have the same type !");
539 * Sets information on a component specified by an index.
540 * To know more on format of this information
541 * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
542 * \warning Don't pass NULL as \a info!
543 * \param [in] i - the index (zero based) of the component of interest.
544 * \param [in] info - the string containing the information.
545 * \throw If \a i is not a valid component index.
547 void DataArray::setInfoOnComponent(int i, const std::string& info)
549 if(i<(int)_info_on_compo.size() && i>=0)
550 _info_on_compo[i]=info;
553 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();
554 throw INTERP_KERNEL::Exception(oss.str().c_str());
559 * Sets information on all components. This method can change number of components
560 * at certain conditions; if the conditions are not respected, an exception is thrown.
561 * The number of components can be changed in \a this only if \a this is not allocated.
562 * The condition of number of components must not be changed.
564 * To know more on format of the component information see
565 * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
566 * \param [in] info - a vector of component infos.
567 * \throw If \a this->getNumberOfComponents() != \a info.size() && \a this->isAllocated()
569 void DataArray::setInfoAndChangeNbOfCompo(const std::vector<std::string>& info)
571 if(getNumberOfComponents()!=info.size())
577 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 !";
578 throw INTERP_KERNEL::Exception(oss.str().c_str());
585 void DataArray::checkNbOfTuples(int nbOfTuples, const std::string& msg) const
587 if((int)getNumberOfTuples()!=nbOfTuples)
589 std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " << nbOfTuples << " having " << getNumberOfTuples() << " !";
590 throw INTERP_KERNEL::Exception(oss.str().c_str());
594 void DataArray::checkNbOfComps(int nbOfCompo, const std::string& msg) const
596 if((int)getNumberOfComponents()!=nbOfCompo)
598 std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << nbOfCompo << " having " << getNumberOfComponents() << " !";
599 throw INTERP_KERNEL::Exception(oss.str().c_str());
603 void DataArray::checkNbOfElems(std::size_t nbOfElems, const std::string& msg) const
605 if(getNbOfElems()!=nbOfElems)
607 std::ostringstream oss; oss << msg << " : mismatch number of elems : Expected " << nbOfElems << " having " << getNbOfElems() << " !";
608 throw INTERP_KERNEL::Exception(oss.str().c_str());
612 void DataArray::checkNbOfTuplesAndComp(const DataArray& other, const std::string& msg) const
614 if(getNumberOfTuples()!=other.getNumberOfTuples())
616 std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " << other.getNumberOfTuples() << " having " << getNumberOfTuples() << " !";
617 throw INTERP_KERNEL::Exception(oss.str().c_str());
619 if(getNumberOfComponents()!=other.getNumberOfComponents())
621 std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << other.getNumberOfComponents() << " having " << getNumberOfComponents() << " !";
622 throw INTERP_KERNEL::Exception(oss.str().c_str());
626 void DataArray::checkNbOfTuplesAndComp(int nbOfTuples, int nbOfCompo, const std::string& msg) const
628 checkNbOfTuples(nbOfTuples,msg);
629 checkNbOfComps(nbOfCompo,msg);
633 * Simply this method checks that \b value is in [0,\b ref).
635 void DataArray::CheckValueInRange(int ref, int value, const std::string& msg)
637 if(value<0 || value>=ref)
639 std::ostringstream oss; oss << "DataArray::CheckValueInRange : " << msg << " ! Expected in range [0," << ref << "[ having " << value << " !";
640 throw INTERP_KERNEL::Exception(oss.str().c_str());
645 * This method checks that [\b start, \b end) is compliant with ref length \b value.
646 * typically start in [0,\b value) and end in [0,\b value). If value==start and start==end, it is supported.
648 void DataArray::CheckValueInRangeEx(int value, int start, int end, const std::string& msg)
650 if(start<0 || start>=value)
652 if(value!=start || end!=start)
654 std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg << " ! Expected start " << start << " of input range, in [0," << value << "[ !";
655 throw INTERP_KERNEL::Exception(oss.str().c_str());
658 if(end<0 || end>value)
660 std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg << " ! Expected end " << end << " of input range, in [0," << value << "] !";
661 throw INTERP_KERNEL::Exception(oss.str().c_str());
665 void DataArray::CheckClosingParInRange(int ref, int value, const std::string& msg)
667 if(value<0 || value>ref)
669 std::ostringstream oss; oss << "DataArray::CheckClosingParInRange : " << msg << " ! Expected input range in [0," << ref << "] having closing open parenthesis " << value << " !";
670 throw INTERP_KERNEL::Exception(oss.str().c_str());
675 * 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,
676 * typically it is a whole slice of tuples of DataArray or cells, nodes of a mesh...
678 * The input \a sliceId should be an id in [0, \a nbOfSlices) that specifies the slice of work.
680 * \param [in] start - the start of the input slice of the whole work to perform split into slices.
681 * \param [in] stop - the stop of the input slice of the whole work to perform split into slices.
682 * \param [in] step - the step (that can be <0) of the input slice of the whole work to perform split into slices.
683 * \param [in] sliceId - the slice id considered
684 * \param [in] nbOfSlices - the number of slices (typically the number of cores on which the work is expected to be sliced)
685 * \param [out] startSlice - the start of the slice considered
686 * \param [out] stopSlice - the stop of the slice consided
688 * \throw If \a step == 0
689 * \throw If \a nbOfSlices not > 0
690 * \throw If \a sliceId not in [0,nbOfSlices)
692 void DataArray::GetSlice(int start, int stop, int step, int sliceId, int nbOfSlices, int& startSlice, int& stopSlice)
696 std::ostringstream oss; oss << "DataArray::GetSlice : nbOfSlices (" << nbOfSlices << ") must be > 0 !";
697 throw INTERP_KERNEL::Exception(oss.str().c_str());
699 if(sliceId<0 || sliceId>=nbOfSlices)
701 std::ostringstream oss; oss << "DataArray::GetSlice : sliceId (" << nbOfSlices << ") must be in [0 , nbOfSlices (" << nbOfSlices << ") ) !";
702 throw INTERP_KERNEL::Exception(oss.str().c_str());
704 int nbElems=GetNumberOfItemGivenBESRelative(start,stop,step,"DataArray::GetSlice");
705 int minNbOfElemsPerSlice=nbElems/nbOfSlices;
706 startSlice=start+minNbOfElemsPerSlice*step*sliceId;
707 if(sliceId<nbOfSlices-1)
708 stopSlice=start+minNbOfElemsPerSlice*step*(sliceId+1);
713 int DataArray::GetNumberOfItemGivenBES(int begin, int end, int step, const std::string& msg)
717 std::ostringstream oss; oss << msg << " : end before begin !";
718 throw INTERP_KERNEL::Exception(oss.str().c_str());
724 std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
725 throw INTERP_KERNEL::Exception(oss.str().c_str());
727 return (end-1-begin)/step+1;
730 int DataArray::GetNumberOfItemGivenBESRelative(int begin, int end, int step, const std::string& msg)
733 throw INTERP_KERNEL::Exception("DataArray::GetNumberOfItemGivenBES : step=0 is not allowed !");
734 if(end<begin && step>0)
736 std::ostringstream oss; oss << msg << " : end before begin whereas step is positive !";
737 throw INTERP_KERNEL::Exception(oss.str().c_str());
739 if(begin<end && step<0)
741 std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
742 throw INTERP_KERNEL::Exception(oss.str().c_str());
745 return (std::max(begin,end)-1-std::min(begin,end))/std::abs(step)+1;
750 int DataArray::GetPosOfItemGivenBESRelativeNoThrow(int value, int begin, int end, int step)
756 if(begin<=value && value<end)
758 if((value-begin)%step==0)
759 return (value-begin)/step;
768 if(begin>=value && value>end)
770 if((begin-value)%(-step)==0)
771 return (begin-value)/(-step);
784 * Returns a new instance of DataArrayDouble. The caller is to delete this array
785 * using decrRef() as it is no more needed.
787 DataArrayDouble *DataArrayDouble::New()
789 return new DataArrayDouble;
793 * Returns the only one value in \a this, if and only if number of elements
794 * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
795 * \return double - the sole value stored in \a this array.
796 * \throw If at least one of conditions stated above is not fulfilled.
798 double DataArrayDouble::doubleValue() const
802 if(getNbOfElems()==1)
804 return *getConstPointer();
807 throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is allocated but number of elements is not equal to 1 !");
810 throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is not allocated !");
814 * Returns a full copy of \a this. For more info on copying data arrays see
815 * \ref MEDCouplingArrayBasicsCopyDeep.
816 * \return DataArrayDouble * - a new instance of DataArrayDouble. The caller is to
817 * delete this array using decrRef() as it is no more needed.
819 DataArrayDouble *DataArrayDouble::deepCopy() const
821 return new DataArrayDouble(*this);
825 * Checks that \a this array is consistently **increasing** or **decreasing** in value,
826 * with at least absolute difference value of |\a eps| at each step.
827 * If not an exception is thrown.
828 * \param [in] increasing - if \a true, the array values should be increasing.
829 * \param [in] eps - minimal absolute difference between the neighbor values at which
830 * the values are considered different.
831 * \throw If sequence of values is not strictly monotonic in agreement with \a
833 * \throw If \a this->getNumberOfComponents() != 1.
834 * \throw If \a this is not allocated.
836 void DataArrayDouble::checkMonotonic(bool increasing, double eps) const
838 if(!isMonotonic(increasing,eps))
841 throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not INCREASING monotonic !");
843 throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not DECREASING monotonic !");
848 * Checks that \a this array is consistently **increasing** or **decreasing** in value,
849 * with at least absolute difference value of |\a eps| at each step.
850 * \param [in] increasing - if \a true, array values should be increasing.
851 * \param [in] eps - minimal absolute difference between the neighbor values at which
852 * the values are considered different.
853 * \return bool - \a true if values change in accordance with \a increasing arg.
854 * \throw If \a this->getNumberOfComponents() != 1.
855 * \throw If \a this is not allocated.
857 bool DataArrayDouble::isMonotonic(bool increasing, double eps) const
860 if(getNumberOfComponents()!=1)
861 throw INTERP_KERNEL::Exception("DataArrayDouble::isMonotonic : only supported with 'this' array with ONE component !");
862 int nbOfElements=getNumberOfTuples();
863 const double *ptr=getConstPointer();
867 double absEps=fabs(eps);
870 for(int i=1;i<nbOfElements;i++)
872 if(ptr[i]<(ref+absEps))
880 for(int i=1;i<nbOfElements;i++)
882 if(ptr[i]>(ref-absEps))
891 * Returns a textual and human readable representation of \a this instance of
892 * DataArrayDouble. This text is shown when a DataArrayDouble is printed in Python.
893 * \return std::string - text describing \a this DataArrayDouble.
895 * \sa reprNotTooLong, reprZip
897 std::string DataArrayDouble::repr() const
899 std::ostringstream ret;
904 std::string DataArrayDouble::reprZip() const
906 std::ostringstream ret;
911 void DataArrayDouble::writeVTK(std::ostream& ofs, int indent, const std::string& nameInFile, DataArrayByte *byteArr) const
913 static const char SPACE[4]={' ',' ',' ',' '};
915 std::string idt(indent,' ');
917 ofs << idt << "<DataArray type=\"Float32\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
919 bool areAllEmpty(true);
920 for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
924 for(std::size_t i=0;i<_info_on_compo.size();i++)
925 ofs << " ComponentName" << i << "=\"" << _info_on_compo[i] << "\"";
929 ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
930 INTERP_KERNEL::AutoPtr<float> tmp(new float[getNbOfElems()]);
932 // to make Visual C++ happy : instead of std::copy(begin(),end(),(float *)tmp);
933 for(const double *src=begin();src!=end();src++,pt++)
935 const char *data(reinterpret_cast<const char *>((float *)tmp));
936 std::size_t sz(getNbOfElems()*sizeof(float));
937 byteArr->insertAtTheEnd(data,data+sz);
938 byteArr->insertAtTheEnd(SPACE,SPACE+4);
942 ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
943 std::copy(begin(),end(),std::ostream_iterator<double>(ofs," "));
945 ofs << std::endl << idt << "</DataArray>\n";
948 void DataArrayDouble::reprCppStream(const std::string& varName, std::ostream& stream) const
950 int nbTuples(getNumberOfTuples()),nbComp(getNumberOfComponents());
951 const double *data(getConstPointer());
952 stream.precision(17);
953 stream << "DataArrayDouble *" << varName << "=DataArrayDouble::New();" << std::endl;
954 if(nbTuples*nbComp>=1)
956 stream << "const double " << varName << "Data[" << nbTuples*nbComp << "]={";
957 std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<double>(stream,","));
958 stream << data[nbTuples*nbComp-1] << "};" << std::endl;
959 stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
962 stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
963 stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
967 * Method that gives a quick overvien of \a this for python.
969 void DataArrayDouble::reprQuickOverview(std::ostream& stream) const
971 static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
972 stream << "DataArrayDouble C++ instance at " << this << ". ";
975 int nbOfCompo=(int)_info_on_compo.size();
978 int nbOfTuples=getNumberOfTuples();
979 stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
980 reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
983 stream << "Number of components : 0.";
986 stream << "*** No data allocated ****";
989 void DataArrayDouble::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
991 const double *data=begin();
992 int nbOfTuples=getNumberOfTuples();
993 int nbOfCompo=(int)_info_on_compo.size();
994 std::ostringstream oss2; oss2 << "[";
996 std::string oss2Str(oss2.str());
997 bool isFinished=true;
998 for(int i=0;i<nbOfTuples && isFinished;i++)
1003 for(int j=0;j<nbOfCompo;j++,data++)
1006 if(j!=nbOfCompo-1) oss2 << ", ";
1012 if(i!=nbOfTuples-1) oss2 << ", ";
1013 std::string oss3Str(oss2.str());
1014 if(oss3Str.length()<maxNbOfByteInRepr)
1026 * Equivalent to DataArrayDouble::isEqual except that if false the reason of
1027 * mismatch is given.
1029 * \param [in] other the instance to be compared with \a this
1030 * \param [in] prec the precision to compare numeric data of the arrays.
1031 * \param [out] reason In case of inequality returns the reason.
1032 * \sa DataArrayDouble::isEqual
1034 bool DataArrayDouble::isEqualIfNotWhy(const DataArrayDouble& other, double prec, std::string& reason) const
1036 if(!areInfoEqualsIfNotWhy(other,reason))
1038 return _mem.isEqual(other._mem,prec,reason);
1042 * Checks if \a this and another DataArrayDouble are fully equal. For more info see
1043 * \ref MEDCouplingArrayBasicsCompare.
1044 * \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1045 * \param [in] prec - precision value to compare numeric data of the arrays.
1046 * \return bool - \a true if the two arrays are equal, \a false else.
1048 bool DataArrayDouble::isEqual(const DataArrayDouble& other, double prec) const
1051 return isEqualIfNotWhy(other,prec,tmp);
1055 * Checks if values of \a this and another DataArrayDouble are equal. For more info see
1056 * \ref MEDCouplingArrayBasicsCompare.
1057 * \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1058 * \param [in] prec - precision value to compare numeric data of the arrays.
1059 * \return bool - \a true if the values of two arrays are equal, \a false else.
1061 bool DataArrayDouble::isEqualWithoutConsideringStr(const DataArrayDouble& other, double prec) const
1064 return _mem.isEqual(other._mem,prec,tmp);
1068 * This method checks that all tuples in \a other are in \a this.
1069 * If true, the output param \a tupleIds contains the tuples ids of \a this that correspond to tupes in \a this.
1070 * 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.
1072 * \param [in] other - the array having the same number of components than \a this.
1073 * \param [out] tupleIds - the tuple ids containing the same number of tuples than \a other has.
1074 * \sa DataArrayDouble::findCommonTuples
1076 bool DataArrayDouble::areIncludedInMe(const DataArrayDouble *other, double prec, DataArrayInt *&tupleIds) const
1079 throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : input array is NULL !");
1080 checkAllocated(); other->checkAllocated();
1081 if(getNumberOfComponents()!=other->getNumberOfComponents())
1082 throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : the number of components does not match !");
1083 MCAuto<DataArrayDouble> a=DataArrayDouble::Aggregate(this,other);
1084 DataArrayInt *c=0,*ci=0;
1085 a->findCommonTuples(prec,getNumberOfTuples(),c,ci);
1086 MCAuto<DataArrayInt> cSafe(c),ciSafe(ci);
1087 int newNbOfTuples=-1;
1088 MCAuto<DataArrayInt> ids=DataArrayInt::ConvertIndexArrayToO2N(a->getNumberOfTuples(),c->begin(),ci->begin(),ci->end(),newNbOfTuples);
1089 MCAuto<DataArrayInt> ret1=ids->selectByTupleIdSafeSlice(getNumberOfTuples(),a->getNumberOfTuples(),1);
1090 tupleIds=ret1.retn();
1091 return newNbOfTuples==getNumberOfTuples();
1095 * Searches for tuples coincident within \a prec tolerance. Each tuple is considered
1096 * as coordinates of a point in getNumberOfComponents()-dimensional space. The
1097 * distance separating two points is computed with the infinite norm.
1099 * Indices of coincident tuples are stored in output arrays.
1100 * A pair of arrays (\a comm, \a commIndex) is called "Surjective Format 2".
1102 * This method is typically used by MEDCouplingPointSet::findCommonNodes() and
1103 * MEDCouplingUMesh::mergeNodes().
1104 * \param [in] prec - minimal absolute distance between two tuples (infinite norm) at which they are
1105 * considered not coincident.
1106 * \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
1107 * tuples have id strictly lower than \a limitTupleId then they are not returned.
1108 * \param [out] comm - the array holding ids (== indices) of coincident tuples.
1109 * \a comm->getNumberOfComponents() == 1.
1110 * \a comm->getNumberOfTuples() == \a commIndex->back().
1111 * \param [out] commIndex - the array dividing all indices stored in \a comm into
1112 * groups of (indices of) coincident tuples. Its every value is a tuple
1113 * index where a next group of tuples begins. For example the second
1114 * group of tuples in \a comm is described by following range of indices:
1115 * [ \a commIndex[1], \a commIndex[2] ). \a commIndex->getNumberOfTuples()-1
1116 * gives the number of groups of coincident tuples.
1117 * \throw If \a this is not allocated.
1118 * \throw If the number of components is not in [1,2,3,4].
1120 * \if ENABLE_EXAMPLES
1121 * \ref cpp_mcdataarraydouble_findcommontuples "Here is a C++ example".
1123 * \ref py_mcdataarraydouble_findcommontuples "Here is a Python example".
1125 * \sa DataArrayInt::ConvertIndexArrayToO2N(), DataArrayDouble::areIncludedInMe
1127 void DataArrayDouble::findCommonTuples(double prec, int limitTupleId, DataArrayInt *&comm, DataArrayInt *&commIndex) const
1130 int nbOfCompo=getNumberOfComponents();
1131 if ((nbOfCompo<1) || (nbOfCompo>4)) //test before work
1132 throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : Unexpected spacedim of coords. Must be 1, 2, 3 or 4.");
1134 int nbOfTuples=getNumberOfTuples();
1136 MCAuto<DataArrayInt> c(DataArrayInt::New()),cI(DataArrayInt::New()); c->alloc(0,1); cI->pushBackSilent(0);
1140 findCommonTuplesAlg<4>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1143 findCommonTuplesAlg<3>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1146 findCommonTuplesAlg<2>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1149 findCommonTuplesAlg<1>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1152 throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : nb of components managed are 1,2,3 and 4 ! not implemented for other number of components !");
1155 commIndex=cI.retn();
1159 * This methods returns the minimal distance between the two set of points \a this and \a other.
1160 * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
1161 * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
1163 * \param [out] thisTupleId the tuple id in \a this corresponding to the returned minimal distance
1164 * \param [out] otherTupleId the tuple id in \a other corresponding to the returned minimal distance
1165 * \return the minimal distance between the two set of points \a this and \a other.
1166 * \sa DataArrayDouble::findClosestTupleId
1168 double DataArrayDouble::minimalDistanceTo(const DataArrayDouble *other, int& thisTupleId, int& otherTupleId) const
1170 MCAuto<DataArrayInt> part1=findClosestTupleId(other);
1171 int nbOfCompo(getNumberOfComponents());
1172 int otherNbTuples(other->getNumberOfTuples());
1173 const double *thisPt(begin()),*otherPt(other->begin());
1174 const int *part1Pt(part1->begin());
1175 double ret=std::numeric_limits<double>::max();
1176 for(int i=0;i<otherNbTuples;i++,part1Pt++,otherPt+=nbOfCompo)
1179 for(int j=0;j<nbOfCompo;j++)
1180 tmp+=(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j])*(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j]);
1182 { ret=tmp; thisTupleId=*part1Pt; otherTupleId=i; }
1188 * This methods returns for each tuple in \a other which tuple in \a this is the closest.
1189 * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
1190 * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
1192 * \return a newly allocated (new object to be dealt by the caller) DataArrayInt having \c other->getNumberOfTuples() tuples and one components.
1193 * \sa DataArrayDouble::minimalDistanceTo
1195 DataArrayInt *DataArrayDouble::findClosestTupleId(const DataArrayDouble *other) const
1198 throw INTERP_KERNEL::Exception("DataArrayDouble::findClosestTupleId : other instance is NULL !");
1199 checkAllocated(); other->checkAllocated();
1200 std::size_t nbOfCompo(getNumberOfComponents());
1201 if(nbOfCompo!=other->getNumberOfComponents())
1203 std::ostringstream oss; oss << "DataArrayDouble::findClosestTupleId : number of components in this is " << nbOfCompo;
1204 oss << ", whereas number of components in other is " << other->getNumberOfComponents() << "! Should be equal !";
1205 throw INTERP_KERNEL::Exception(oss.str().c_str());
1207 int nbOfTuples=other->getNumberOfTuples();
1208 int thisNbOfTuples=getNumberOfTuples();
1209 MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuples,1);
1211 getMinMaxPerComponent(bounds);
1216 double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2])),zDelta(fabs(bounds[5]-bounds[4]));
1217 double delta=std::max(xDelta,yDelta); delta=std::max(delta,zDelta);
1218 double characSize=pow((delta*delta*delta)/((double)thisNbOfTuples),1./3.);
1219 BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1220 FindClosestTupleIdAlg<3>(myTree,3.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1225 double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2]));
1226 double delta=std::max(xDelta,yDelta);
1227 double characSize=sqrt(delta/(double)thisNbOfTuples);
1228 BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1229 FindClosestTupleIdAlg<2>(myTree,2.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1234 double characSize=fabs(bounds[1]-bounds[0])/thisNbOfTuples;
1235 BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1236 FindClosestTupleIdAlg<1>(myTree,1.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1240 throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for findClosestTupleId. Must be 1, 2 or 3.");
1246 * This method expects that \a this and \a otherBBoxFrmt arrays are bounding box arrays ( as the output of MEDCouplingPointSet::getBoundingBoxForBBTree method ).
1247 * 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
1248 * how many bounding boxes in \a otherBBoxFrmt.
1249 * So, this method expects that \a this and \a otherBBoxFrmt have the same number of components.
1251 * \param [in] otherBBoxFrmt - It is an array .
1252 * \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.
1253 * \sa MEDCouplingPointSet::getBoundingBoxForBBTree
1254 * \throw If \a this and \a otherBBoxFrmt have not the same number of components.
1255 * \throw If \a this and \a otherBBoxFrmt number of components is not even (BBox format).
1257 DataArrayInt *DataArrayDouble::computeNbOfInteractionsWith(const DataArrayDouble *otherBBoxFrmt, double eps) const
1260 throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : input array is NULL !");
1261 if(!isAllocated() || !otherBBoxFrmt->isAllocated())
1262 throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : this and input array must be allocated !");
1263 std::size_t nbOfComp(getNumberOfComponents()),nbOfTuples(getNumberOfTuples());
1264 if(nbOfComp!=otherBBoxFrmt->getNumberOfComponents())
1266 std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : this number of components (" << nbOfComp << ") must be equal to the number of components of input array (" << otherBBoxFrmt->getNumberOfComponents() << ") !";
1267 throw INTERP_KERNEL::Exception(oss.str().c_str());
1271 std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : Number of components (" << nbOfComp << ") is not even ! It should be to be compatible with bbox format !";
1272 throw INTERP_KERNEL::Exception(oss.str().c_str());
1274 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbOfTuples,1);
1275 const double *thisBBPtr(begin());
1276 int *retPtr(ret->getPointer());
1281 BBTree<3,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
1282 for(std::size_t i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
1283 *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
1288 BBTree<2,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
1289 for(std::size_t i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
1290 *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
1295 BBTree<1,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
1296 for(std::size_t i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
1297 *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
1301 throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : space dimension supported are [1,2,3] !");
1308 * Returns a copy of \a this array by excluding coincident tuples. Each tuple is
1309 * considered as coordinates of a point in getNumberOfComponents()-dimensional
1310 * space. The distance between tuples is computed using norm2. If several tuples are
1311 * not far each from other than \a prec, only one of them remains in the result
1312 * array. The order of tuples in the result array is same as in \a this one except
1313 * that coincident tuples are excluded.
1314 * \param [in] prec - minimal absolute distance between two tuples at which they are
1315 * considered not coincident.
1316 * \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
1317 * tuples have id strictly lower than \a limitTupleId then they are not excluded.
1318 * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1319 * is to delete using decrRef() as it is no more needed.
1320 * \throw If \a this is not allocated.
1321 * \throw If the number of components is not in [1,2,3,4].
1323 * \if ENABLE_EXAMPLES
1324 * \ref py_mcdataarraydouble_getdifferentvalues "Here is a Python example".
1327 DataArrayDouble *DataArrayDouble::getDifferentValues(double prec, int limitTupleId) const
1330 DataArrayInt *c0=0,*cI0=0;
1331 findCommonTuples(prec,limitTupleId,c0,cI0);
1332 MCAuto<DataArrayInt> c(c0),cI(cI0);
1333 int newNbOfTuples=-1;
1334 MCAuto<DataArrayInt> o2n=DataArrayInt::ConvertIndexArrayToO2N(getNumberOfTuples(),c0->begin(),cI0->begin(),cI0->end(),newNbOfTuples);
1335 return renumberAndReduce(o2n->getConstPointer(),newNbOfTuples);
1339 * Copy all components in a specified order from another DataArrayDouble.
1340 * Both numerical and textual data is copied. The number of tuples in \a this and
1341 * the other array can be different.
1342 * \param [in] a - the array to copy data from.
1343 * \param [in] compoIds - sequence of zero based indices of components, data of which is
1345 * \throw If \a a is NULL.
1346 * \throw If \a compoIds.size() != \a a->getNumberOfComponents().
1347 * \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
1349 * \if ENABLE_EXAMPLES
1350 * \ref py_mcdataarraydouble_setselectedcomponents "Here is a Python example".
1353 void DataArrayDouble::setSelectedComponents(const DataArrayDouble *a, const std::vector<int>& compoIds)
1356 throw INTERP_KERNEL::Exception("DataArrayDouble::setSelectedComponents : input DataArrayDouble is NULL !");
1358 copyPartOfStringInfoFrom2(compoIds,*a);
1359 std::size_t partOfCompoSz=compoIds.size();
1360 int nbOfCompo=getNumberOfComponents();
1361 int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
1362 const double *ac=a->getConstPointer();
1363 double *nc=getPointer();
1364 for(int i=0;i<nbOfTuples;i++)
1365 for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
1366 nc[nbOfCompo*i+compoIds[j]]=*ac;
1370 * Checks if 0.0 value is present in \a this array. If it is the case, an exception
1372 * \throw If zero is found in \a this array.
1374 void DataArrayDouble::checkNoNullValues() const
1376 const double *tmp=getConstPointer();
1377 std::size_t nbOfElems=getNbOfElems();
1378 const double *where=std::find(tmp,tmp+nbOfElems,0.);
1379 if(where!=tmp+nbOfElems)
1380 throw INTERP_KERNEL::Exception("A value 0.0 have been detected !");
1384 * Computes minimal and maximal value in each component. An output array is filled
1385 * with \c 2 * \a this->getNumberOfComponents() values, so the caller is to allocate
1386 * enough memory before calling this method.
1387 * \param [out] bounds - array of size at least 2 *\a this->getNumberOfComponents().
1388 * It is filled as follows:<br>
1389 * \a bounds[0] = \c min_of_component_0 <br>
1390 * \a bounds[1] = \c max_of_component_0 <br>
1391 * \a bounds[2] = \c min_of_component_1 <br>
1392 * \a bounds[3] = \c max_of_component_1 <br>
1395 void DataArrayDouble::getMinMaxPerComponent(double *bounds) const
1398 int dim=getNumberOfComponents();
1399 for (int idim=0; idim<dim; idim++)
1401 bounds[idim*2]=std::numeric_limits<double>::max();
1402 bounds[idim*2+1]=-std::numeric_limits<double>::max();
1404 const double *ptr=getConstPointer();
1405 int nbOfTuples=getNumberOfTuples();
1406 for(int i=0;i<nbOfTuples;i++)
1408 for(int idim=0;idim<dim;idim++)
1410 if(bounds[idim*2]>ptr[i*dim+idim])
1412 bounds[idim*2]=ptr[i*dim+idim];
1414 if(bounds[idim*2+1]<ptr[i*dim+idim])
1416 bounds[idim*2+1]=ptr[i*dim+idim];
1423 * This method retrieves a newly allocated DataArrayDouble instance having same number of tuples than \a this and twice number of components than \a this
1424 * to store both the min and max per component of each tuples.
1425 * \param [in] epsilon the width of the bbox (identical in each direction) - 0.0 by default
1427 * \return a newly created DataArrayDouble instance having \c this->getNumberOfTuples() tuples and 2 * \c this->getNumberOfComponent() components
1429 * \throw If \a this is not allocated yet.
1431 DataArrayDouble *DataArrayDouble::computeBBoxPerTuple(double epsilon) const
1434 const double *dataPtr=getConstPointer();
1435 int nbOfCompo=getNumberOfComponents();
1436 int nbTuples=getNumberOfTuples();
1437 MCAuto<DataArrayDouble> bbox=DataArrayDouble::New();
1438 bbox->alloc(nbTuples,2*nbOfCompo);
1439 double *bboxPtr=bbox->getPointer();
1440 for(int i=0;i<nbTuples;i++)
1442 for(int j=0;j<nbOfCompo;j++)
1444 bboxPtr[2*nbOfCompo*i+2*j]=dataPtr[nbOfCompo*i+j]-epsilon;
1445 bboxPtr[2*nbOfCompo*i+2*j+1]=dataPtr[nbOfCompo*i+j]+epsilon;
1452 * For each tuples **t** in \a other, this method retrieves tuples in \a this that are equal to **t**.
1453 * Two tuples are considered equal if the euclidian distance between the two tuples is lower than \a eps.
1455 * \param [in] other a DataArrayDouble having same number of components than \a this.
1456 * \param [in] eps absolute precision representing distance (using infinite norm) between 2 tuples behind which 2 tuples are considered equal.
1457 * \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.
1458 * \a cI allows to extract information in \a c.
1459 * \param [out] cI is an indirection array that allows to extract the data contained in \a c.
1461 * \throw In case of:
1462 * - \a this is not allocated
1463 * - \a other is not allocated or null
1464 * - \a this and \a other do not have the same number of components
1465 * - if number of components of \a this is not in [1,2,3]
1467 * \sa MEDCouplingPointSet::getNodeIdsNearPoints, DataArrayDouble::getDifferentValues
1469 void DataArrayDouble::computeTupleIdsNearTuples(const DataArrayDouble *other, double eps, DataArrayInt *& c, DataArrayInt *& cI) const
1472 throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : input pointer other is null !");
1474 other->checkAllocated();
1475 int nbOfCompo=getNumberOfComponents();
1476 int otherNbOfCompo=other->getNumberOfComponents();
1477 if(nbOfCompo!=otherNbOfCompo)
1478 throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : number of components should be equal between this and other !");
1479 int nbOfTuplesOther=other->getNumberOfTuples();
1480 MCAuto<DataArrayInt> cArr(DataArrayInt::New()),cIArr(DataArrayInt::New()); cArr->alloc(0,1); cIArr->pushBackSilent(0);
1485 BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
1486 FindTupleIdsNearTuplesAlg<3>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
1491 BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
1492 FindTupleIdsNearTuplesAlg<2>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
1497 BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
1498 FindTupleIdsNearTuplesAlg<1>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
1502 throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for computeTupleIdsNearTuples. Must be 1, 2 or 3.");
1504 c=cArr.retn(); cI=cIArr.retn();
1508 * 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
1509 * around origin of 'radius' 1.
1511 * \param [in] eps absolute epsilon. under that value of delta between max and min no scale is performed.
1513 void DataArrayDouble::recenterForMaxPrecision(double eps)
1516 int dim=getNumberOfComponents();
1517 std::vector<double> bounds(2*dim);
1518 getMinMaxPerComponent(&bounds[0]);
1519 for(int i=0;i<dim;i++)
1521 double delta=bounds[2*i+1]-bounds[2*i];
1522 double offset=(bounds[2*i]+bounds[2*i+1])/2.;
1524 applyLin(1./delta,-offset/delta,i);
1526 applyLin(1.,-offset,i);
1531 * Returns the maximal value and all its locations within \a this one-dimensional array.
1532 * \param [out] tupleIds - a new instance of DataArrayInt containing indices of
1533 * tuples holding the maximal value. The caller is to delete it using
1534 * decrRef() as it is no more needed.
1535 * \return double - the maximal value among all values of \a this array.
1536 * \throw If \a this->getNumberOfComponents() != 1
1537 * \throw If \a this->getNumberOfTuples() < 1
1539 double DataArrayDouble::getMaxValue2(DataArrayInt*& tupleIds) const
1543 double ret=getMaxValue(tmp);
1544 tupleIds=findIdsInRange(ret,ret);
1549 * Returns the minimal value and all its locations within \a this one-dimensional array.
1550 * \param [out] tupleIds - a new instance of DataArrayInt containing indices of
1551 * tuples holding the minimal value. The caller is to delete it using
1552 * decrRef() as it is no more needed.
1553 * \return double - the minimal value among all values of \a this array.
1554 * \throw If \a this->getNumberOfComponents() != 1
1555 * \throw If \a this->getNumberOfTuples() < 1
1557 double DataArrayDouble::getMinValue2(DataArrayInt*& tupleIds) const
1561 double ret=getMinValue(tmp);
1562 tupleIds=findIdsInRange(ret,ret);
1567 * 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.
1568 * This method only works for single component array.
1570 * \return a value in [ 0, \c this->getNumberOfTuples() )
1572 * \throw If \a this is not allocated
1575 int DataArrayDouble::count(double value, double eps) const
1579 if(getNumberOfComponents()!=1)
1580 throw INTERP_KERNEL::Exception("DataArrayDouble::count : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
1581 const double *vals=begin();
1582 int nbOfTuples=getNumberOfTuples();
1583 for(int i=0;i<nbOfTuples;i++,vals++)
1584 if(fabs(*vals-value)<=eps)
1590 * Returns the average value of \a this one-dimensional array.
1591 * \return double - the average value over all values of \a this array.
1592 * \throw If \a this->getNumberOfComponents() != 1
1593 * \throw If \a this->getNumberOfTuples() < 1
1595 double DataArrayDouble::getAverageValue() const
1597 if(getNumberOfComponents()!=1)
1598 throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
1599 int nbOfTuples=getNumberOfTuples();
1601 throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : array exists but number of tuples must be > 0 !");
1602 const double *vals=getConstPointer();
1603 double ret=std::accumulate(vals,vals+nbOfTuples,0.);
1604 return ret/nbOfTuples;
1608 * Returns the Euclidean norm of the vector defined by \a this array.
1609 * \return double - the value of the Euclidean norm, i.e.
1610 * the square root of the inner product of vector.
1611 * \throw If \a this is not allocated.
1613 double DataArrayDouble::norm2() const
1617 std::size_t nbOfElems=getNbOfElems();
1618 const double *pt=getConstPointer();
1619 for(std::size_t i=0;i<nbOfElems;i++,pt++)
1625 * Returns the maximum norm of the vector defined by \a this array.
1626 * This method works even if the number of components is different from one.
1627 * If the number of elements in \a this is 0, -1. is returned.
1628 * \return double - the value of the maximum norm, i.e.
1629 * the maximal absolute value among values of \a this array (whatever its number of components).
1630 * \throw If \a this is not allocated.
1632 double DataArrayDouble::normMax() const
1636 std::size_t nbOfElems(getNbOfElems());
1637 const double *pt(getConstPointer());
1638 for(std::size_t i=0;i<nbOfElems;i++,pt++)
1640 double val(std::abs(*pt));
1648 * Returns the maximum norm of for each component of \a this array.
1649 * If the number of elements in \a this is 0, -1. is returned.
1650 * \param [out] res - pointer to an array of result values, of size at least \a
1651 * this->getNumberOfComponents(), that is to be allocated by the caller.
1652 * \throw If \a this is not allocated.
1654 void DataArrayDouble::normMaxPerComponent(double * res) const
1657 std::size_t nbOfTuples(getNumberOfTuples());
1658 int nbOfCompos(getNumberOfComponents());
1659 std::fill(res, res+nbOfCompos, -1.0);
1660 const double *pt(getConstPointer());
1661 for(std::size_t i=0;i<nbOfTuples;i++)
1662 for (int j=0; j<nbOfCompos; j++, pt++)
1664 double val(std::abs(*pt));
1672 * Returns the minimum norm (absolute value) of the vector defined by \a this array.
1673 * This method works even if the number of components is different from one.
1674 * If the number of elements in \a this is 0, std::numeric_limits<double>::max() is returned.
1675 * \return double - the value of the minimum norm, i.e.
1676 * the minimal absolute value among values of \a this array (whatever its number of components).
1677 * \throw If \a this is not allocated.
1679 double DataArrayDouble::normMin() const
1682 double ret(std::numeric_limits<double>::max());
1683 std::size_t nbOfElems(getNbOfElems());
1684 const double *pt(getConstPointer());
1685 for(std::size_t i=0;i<nbOfElems;i++,pt++)
1687 double val(std::abs(*pt));
1695 * Accumulates values of each component of \a this array.
1696 * \param [out] res - an array of length \a this->getNumberOfComponents(), allocated
1697 * by the caller, that is filled by this method with sum value for each
1699 * \throw If \a this is not allocated.
1701 void DataArrayDouble::accumulate(double *res) const
1704 const double *ptr=getConstPointer();
1705 int nbTuple=getNumberOfTuples();
1706 int nbComps=getNumberOfComponents();
1707 std::fill(res,res+nbComps,0.);
1708 for(int i=0;i<nbTuple;i++)
1709 std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<double>());
1713 * This method returns the min distance from an external tuple defined by [ \a tupleBg , \a tupleEnd ) to \a this and
1714 * the first tuple in \a this that matches the returned distance. If there is no tuples in \a this an exception will be thrown.
1717 * \a this is expected to be allocated and expected to have a number of components equal to the distance from \a tupleBg to
1718 * \a tupleEnd. If not an exception will be thrown.
1720 * \param [in] tupleBg start pointer (included) of input external tuple
1721 * \param [in] tupleEnd end pointer (not included) of input external tuple
1722 * \param [out] tupleId the tuple id in \a this that matches the min of distance between \a this and input external tuple
1723 * \return the min distance.
1724 * \sa MEDCouplingUMesh::distanceToPoint
1726 double DataArrayDouble::distanceToTuple(const double *tupleBg, const double *tupleEnd, int& tupleId) const
1729 int nbTuple=getNumberOfTuples();
1730 int nbComps=getNumberOfComponents();
1731 if(nbComps!=(int)std::distance(tupleBg,tupleEnd))
1732 { 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()); }
1734 throw INTERP_KERNEL::Exception("DataArrayDouble::distanceToTuple : no tuple in this ! No distance to compute !");
1735 double ret0=std::numeric_limits<double>::max();
1737 const double *work=getConstPointer();
1738 for(int i=0;i<nbTuple;i++)
1741 for(int j=0;j<nbComps;j++,work++)
1742 val+=(*work-tupleBg[j])*((*work-tupleBg[j]));
1746 { ret0=val; tupleId=i; }
1752 * Accumulate values of the given component of \a this array.
1753 * \param [in] compId - the index of the component of interest.
1754 * \return double - a sum value of \a compId-th component.
1755 * \throw If \a this is not allocated.
1756 * \throw If \a the condition ( 0 <= \a compId < \a this->getNumberOfComponents() ) is
1759 double DataArrayDouble::accumulate(int compId) const
1762 const double *ptr=getConstPointer();
1763 int nbTuple=getNumberOfTuples();
1764 int nbComps=getNumberOfComponents();
1765 if(compId<0 || compId>=nbComps)
1766 throw INTERP_KERNEL::Exception("DataArrayDouble::accumulate : Invalid compId specified : No such nb of components !");
1768 for(int i=0;i<nbTuple;i++)
1769 ret+=ptr[i*nbComps+compId];
1774 * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
1775 * The returned array will have same number of components than \a this and number of tuples equal to
1776 * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
1778 * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
1779 * 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.
1781 * \param [in] bgOfIndex - begin (included) of the input index array.
1782 * \param [in] endOfIndex - end (excluded) of the input index array.
1783 * \return DataArrayDouble * - the new instance having the same number of components than \a this.
1785 * \throw If bgOfIndex or end is NULL.
1786 * \throw If input index array is not ascendingly sorted.
1787 * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
1788 * \throw If std::distance(bgOfIndex,endOfIndex)==0.
1790 DataArrayDouble *DataArrayDouble::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
1792 if(!bgOfIndex || !endOfIndex)
1793 throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : input pointer NULL !");
1795 int nbCompo=getNumberOfComponents();
1796 int nbOfTuples=getNumberOfTuples();
1797 int sz=(int)std::distance(bgOfIndex,endOfIndex);
1799 throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : invalid size of input index array !");
1801 MCAuto<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(sz,nbCompo);
1802 const int *w=bgOfIndex;
1803 if(*w<0 || *w>=nbOfTuples)
1804 throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
1805 const double *srcPt=begin()+(*w)*nbCompo;
1806 double *tmp=ret->getPointer();
1807 for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
1809 std::fill(tmp,tmp+nbCompo,0.);
1812 for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
1814 if(j>=0 && j<nbOfTuples)
1815 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<double>());
1818 std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
1819 throw INTERP_KERNEL::Exception(oss.str().c_str());
1825 std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
1826 throw INTERP_KERNEL::Exception(oss.str().c_str());
1829 ret->copyStringInfoFrom(*this);
1834 * 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.
1835 * This method expects that \a this as only one component. The returned array will have \a this->getNumberOfTuples()+1 tuple with also one component.
1836 * The ith element of returned array is equal to the sum of elements in \a this with rank strictly lower than i.
1838 * \return DataArrayDouble - A newly built array containing cum sum of \a this.
1840 MCAuto<DataArrayDouble> DataArrayDouble::cumSum() const
1843 checkNbOfComps(1,"DataArrayDouble::cumSum : this is expected to be single component");
1844 int nbOfTuple(getNumberOfTuples());
1845 MCAuto<DataArrayDouble> ret(DataArrayDouble::New()); ret->alloc(nbOfTuple+1,1);
1846 double *ptr(ret->getPointer());
1848 const double *thisPtr(begin());
1849 for(int i=0;i<nbOfTuple;i++)
1850 ptr[i+1]=ptr[i]+thisPtr[i];
1855 * Converts each 2D point defined by the tuple of \a this array from the Polar to the
1856 * Cartesian coordinate system. The two components of the tuple of \a this array are
1857 * considered to contain (1) radius and (2) angle of the point in the Polar CS.
1858 * \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
1859 * contains X and Y coordinates of the point in the Cartesian CS. The caller
1860 * is to delete this array using decrRef() as it is no more needed. The array
1861 * does not contain any textual info on components.
1862 * \throw If \a this->getNumberOfComponents() != 2.
1863 * \sa fromCartToPolar
1865 DataArrayDouble *DataArrayDouble::fromPolarToCart() const
1868 int nbOfComp(getNumberOfComponents());
1870 throw INTERP_KERNEL::Exception("DataArrayDouble::fromPolarToCart : must be an array with exactly 2 components !");
1871 int nbOfTuple(getNumberOfTuples());
1872 DataArrayDouble *ret(DataArrayDouble::New());
1873 ret->alloc(nbOfTuple,2);
1874 double *w(ret->getPointer());
1875 const double *wIn(getConstPointer());
1876 for(int i=0;i<nbOfTuple;i++,w+=2,wIn+=2)
1878 w[0]=wIn[0]*cos(wIn[1]);
1879 w[1]=wIn[0]*sin(wIn[1]);
1885 * Converts each 3D point defined by the tuple of \a this array from the Cylindrical to
1886 * the Cartesian coordinate system. The three components of the tuple of \a this array
1887 * are considered to contain (1) radius, (2) azimuth and (3) altitude of the point in
1888 * the Cylindrical CS.
1889 * \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
1890 * contains X, Y and Z coordinates of the point in the Cartesian CS. The info
1891 * on the third component is copied from \a this array. The caller
1892 * is to delete this array using decrRef() as it is no more needed.
1893 * \throw If \a this->getNumberOfComponents() != 3.
1896 DataArrayDouble *DataArrayDouble::fromCylToCart() const
1899 int nbOfComp(getNumberOfComponents());
1901 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCylToCart : must be an array with exactly 3 components !");
1902 int nbOfTuple(getNumberOfTuples());
1903 DataArrayDouble *ret(DataArrayDouble::New());
1904 ret->alloc(getNumberOfTuples(),3);
1905 double *w(ret->getPointer());
1906 const double *wIn(getConstPointer());
1907 for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
1909 w[0]=wIn[0]*cos(wIn[1]);
1910 w[1]=wIn[0]*sin(wIn[1]);
1913 ret->setInfoOnComponent(2,getInfoOnComponent(2));
1918 * Converts each 3D point defined by the tuple of \a this array from the Spherical to
1919 * the Cartesian coordinate system. The three components of the tuple of \a this array
1920 * are considered to contain (1) radius, (2) polar angle and (3) azimuthal angle of the
1921 * point in the Cylindrical CS.
1922 * \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
1923 * contains X, Y and Z coordinates of the point in the Cartesian CS. The info
1924 * on the third component is copied from \a this array. The caller
1925 * is to delete this array using decrRef() as it is no more needed.
1926 * \throw If \a this->getNumberOfComponents() != 3.
1927 * \sa fromCartToSpher
1929 DataArrayDouble *DataArrayDouble::fromSpherToCart() const
1932 int nbOfComp(getNumberOfComponents());
1934 throw INTERP_KERNEL::Exception("DataArrayDouble::fromSpherToCart : must be an array with exactly 3 components !");
1935 int nbOfTuple(getNumberOfTuples());
1936 DataArrayDouble *ret(DataArrayDouble::New());
1937 ret->alloc(getNumberOfTuples(),3);
1938 double *w(ret->getPointer());
1939 const double *wIn(getConstPointer());
1940 for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
1942 w[0]=wIn[0]*cos(wIn[2])*sin(wIn[1]);
1943 w[1]=wIn[0]*sin(wIn[2])*sin(wIn[1]);
1944 w[2]=wIn[0]*cos(wIn[1]);
1950 * 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.
1951 * 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.
1952 * If \a at equals to AX_CYL the returned array will be the result of operation cylindric to cartesian of \a this...
1954 * \param [in] atOfThis - The axis type of \a this.
1955 * \return DataArrayDouble * - the new instance of DataArrayDouble (that must be dealed by caller) containing the result of the cartesianizification of \a this.
1957 DataArrayDouble *DataArrayDouble::cartesianize(MEDCouplingAxisType atOfThis) const
1960 int nbOfComp(getNumberOfComponents());
1961 MCAuto<DataArrayDouble> ret;
1969 ret=fromCylToCart();
1974 ret=fromPolarToCart();
1978 throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : For AX_CYL, number of components must be in [2,3] !");
1982 ret=fromSpherToCart();
1987 ret=fromPolarToCart();
1991 throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : For AX_CYL, number of components must be in [2,3] !");
1993 throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : not recognized axis type ! Only AX_CART, AX_CYL and AX_SPHER supported !");
1995 ret->copyStringInfoFrom(*this);
2000 * This method returns a newly created array to be deallocated that contains the result of conversion from cartesian to polar.
2001 * This method expects that \a this has exactly 2 components.
2002 * \sa fromPolarToCart
2004 DataArrayDouble *DataArrayDouble::fromCartToPolar() const
2006 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2008 int nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2010 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToPolar : must be an array with exactly 2 components !");
2011 ret->alloc(nbTuples,2);
2012 double *retPtr(ret->getPointer());
2013 const double *ptr(begin());
2014 for(int i=0;i<nbTuples;i++,ptr+=2,retPtr+=2)
2016 retPtr[0]=sqrt(ptr[0]*ptr[0]+ptr[1]*ptr[1]);
2017 retPtr[1]=atan2(ptr[1],ptr[0]);
2023 * This method returns a newly created array to be deallocated that contains the result of conversion from cartesian to cylindrical.
2024 * This method expects that \a this has exactly 3 components.
2027 DataArrayDouble *DataArrayDouble::fromCartToCyl() const
2029 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2031 int nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2033 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCyl : must be an array with exactly 3 components !");
2034 ret->alloc(nbTuples,3);
2035 double *retPtr(ret->getPointer());
2036 const double *ptr(begin());
2037 for(int i=0;i<nbTuples;i++,ptr+=3,retPtr+=3)
2039 retPtr[0]=sqrt(ptr[0]*ptr[0]+ptr[1]*ptr[1]);
2040 retPtr[1]=atan2(ptr[1],ptr[0]);
2047 * This method returns a newly created array to be deallocated that contains the result of conversion from cartesian to spherical coordinates.
2048 * \sa fromSpherToCart
2050 DataArrayDouble *DataArrayDouble::fromCartToSpher() const
2052 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2054 int nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2056 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToSpher : must be an array with exactly 3 components !");
2057 ret->alloc(nbTuples,3);
2058 double *retPtr(ret->getPointer());
2059 const double *ptr(begin());
2060 for(int i=0;i<nbTuples;i++,ptr+=3,retPtr+=3)
2062 retPtr[0]=sqrt(ptr[0]*ptr[0]+ptr[1]*ptr[1]+ptr[2]*ptr[2]);
2063 retPtr[1]=acos(ptr[2]/retPtr[0]);
2064 retPtr[2]=atan2(ptr[1],ptr[0]);
2070 * 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.
2071 * This method expects that \a this has exactly 3 components.
2072 * \sa MEDCouplingFieldDouble::computeVectorFieldCyl
2074 DataArrayDouble *DataArrayDouble::fromCartToCylGiven(const DataArrayDouble *coords, const double center[3], const double vect[3]) const
2077 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : input coords are NULL !");
2078 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2079 checkAllocated(); coords->checkAllocated();
2080 std::size_t nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2082 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : must be an array with exactly 3 components !");
2083 if(coords->getNumberOfComponents()!=3)
2084 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : coords array must have exactly 3 components !");
2085 if(coords->getNumberOfTuples()!=nbTuples)
2086 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : coords array must have the same number of tuples !");
2087 ret->alloc(nbTuples,nbOfComp);
2088 double magOfVect(sqrt(vect[0]*vect[0]+vect[1]*vect[1]+vect[2]*vect[2]));
2090 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : magnitude of vect is too low !");
2091 double Ur[3],Uteta[3],Uz[3],*retPtr(ret->getPointer());
2092 const double *coo(coords->begin()),*vectField(begin());
2093 std::transform(vect,vect+3,Uz,std::bind2nd(std::multiplies<double>(),1./magOfVect));
2094 for(int i=0;i<nbTuples;i++,vectField+=3,retPtr+=3,coo+=3)
2096 std::transform(coo,coo+3,center,Ur,std::minus<double>());
2097 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];
2098 double magOfTeta(sqrt(Uteta[0]*Uteta[0]+Uteta[1]*Uteta[1]+Uteta[2]*Uteta[2]));
2099 std::transform(Uteta,Uteta+3,Uteta,std::bind2nd(std::multiplies<double>(),1./magOfTeta));
2100 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];
2101 retPtr[0]=Ur[0]*vectField[0]+Ur[1]*vectField[1]+Ur[2]*vectField[2];
2102 retPtr[1]=Uteta[0]*vectField[0]+Uteta[1]*vectField[1]+Uteta[2]*vectField[2];
2103 retPtr[2]=Uz[0]*vectField[0]+Uz[1]*vectField[1]+Uz[2]*vectField[2];
2105 ret->copyStringInfoFrom(*this);
2110 * Computes the doubly contracted product of every tensor defined by the tuple of \a this
2111 * array containing 6 components.
2112 * \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
2113 * is calculated from the tuple <em>(t)</em> of \a this array as follows:
2114 * \f$ t[0]^2+t[1]^2+t[2]^2+2*t[3]^2+2*t[4]^2+2*t[5]^2\f$.
2115 * The caller is to delete this result array using decrRef() as it is no more needed.
2116 * \throw If \a this->getNumberOfComponents() != 6.
2118 DataArrayDouble *DataArrayDouble::doublyContractedProduct() const
2121 int nbOfComp(getNumberOfComponents());
2123 throw INTERP_KERNEL::Exception("DataArrayDouble::doublyContractedProduct : must be an array with exactly 6 components !");
2124 DataArrayDouble *ret=DataArrayDouble::New();
2125 int nbOfTuple=getNumberOfTuples();
2126 ret->alloc(nbOfTuple,1);
2127 const double *src=getConstPointer();
2128 double *dest=ret->getPointer();
2129 for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
2130 *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];
2135 * Computes the determinant of every square matrix defined by the tuple of \a this
2136 * array, which contains either 4, 6 or 9 components. The case of 6 components
2137 * corresponds to that of the upper triangular matrix.
2138 * \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
2139 * is the determinant of matrix of the corresponding tuple of \a this array.
2140 * The caller is to delete this result array using decrRef() as it is no more
2142 * \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2144 DataArrayDouble *DataArrayDouble::determinant() const
2147 DataArrayDouble *ret=DataArrayDouble::New();
2148 int nbOfTuple=getNumberOfTuples();
2149 ret->alloc(nbOfTuple,1);
2150 const double *src=getConstPointer();
2151 double *dest=ret->getPointer();
2152 switch(getNumberOfComponents())
2155 for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
2156 *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];
2159 for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
2160 *dest=src[0]*src[3]-src[1]*src[2];
2163 for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
2164 *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];
2168 throw INTERP_KERNEL::Exception("DataArrayDouble::determinant : Invalid number of components ! must be in 4,6,9 !");
2173 * Computes 3 eigenvalues of every upper triangular matrix defined by the tuple of
2174 * \a this array, which contains 6 components.
2175 * \return DataArrayDouble * - the new instance of DataArrayDouble containing 3
2176 * components, whose each tuple contains the eigenvalues of the matrix of
2177 * corresponding tuple of \a this array.
2178 * The caller is to delete this result array using decrRef() as it is no more
2180 * \throw If \a this->getNumberOfComponents() != 6.
2182 DataArrayDouble *DataArrayDouble::eigenValues() const
2185 int nbOfComp=getNumberOfComponents();
2187 throw INTERP_KERNEL::Exception("DataArrayDouble::eigenValues : must be an array with exactly 6 components !");
2188 DataArrayDouble *ret=DataArrayDouble::New();
2189 int nbOfTuple=getNumberOfTuples();
2190 ret->alloc(nbOfTuple,3);
2191 const double *src=getConstPointer();
2192 double *dest=ret->getPointer();
2193 for(int i=0;i<nbOfTuple;i++,dest+=3,src+=6)
2194 INTERP_KERNEL::computeEigenValues6(src,dest);
2199 * Computes 3 eigenvectors of every upper triangular matrix defined by the tuple of
2200 * \a this array, which contains 6 components.
2201 * \return DataArrayDouble * - the new instance of DataArrayDouble containing 9
2202 * components, whose each tuple contains 3 eigenvectors of the matrix of
2203 * corresponding tuple of \a this array.
2204 * The caller is to delete this result array using decrRef() as it is no more
2206 * \throw If \a this->getNumberOfComponents() != 6.
2208 DataArrayDouble *DataArrayDouble::eigenVectors() const
2211 int nbOfComp=getNumberOfComponents();
2213 throw INTERP_KERNEL::Exception("DataArrayDouble::eigenVectors : must be an array with exactly 6 components !");
2214 DataArrayDouble *ret=DataArrayDouble::New();
2215 int nbOfTuple=getNumberOfTuples();
2216 ret->alloc(nbOfTuple,9);
2217 const double *src=getConstPointer();
2218 double *dest=ret->getPointer();
2219 for(int i=0;i<nbOfTuple;i++,src+=6)
2222 INTERP_KERNEL::computeEigenValues6(src,tmp);
2223 for(int j=0;j<3;j++,dest+=3)
2224 INTERP_KERNEL::computeEigenVectorForEigenValue6(src,tmp[j],1e-12,dest);
2230 * Computes the inverse matrix of every matrix defined by the tuple of \a this
2231 * array, which contains either 4, 6 or 9 components. The case of 6 components
2232 * corresponds to that of the upper triangular matrix.
2233 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2234 * same number of components as \a this one, whose each tuple is the inverse
2235 * matrix of the matrix of corresponding tuple of \a this array.
2236 * The caller is to delete this result array using decrRef() as it is no more
2238 * \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2240 DataArrayDouble *DataArrayDouble::inverse() const
2243 int nbOfComp=getNumberOfComponents();
2244 if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
2245 throw INTERP_KERNEL::Exception("DataArrayDouble::inversion : must be an array with 4,6 or 9 components !");
2246 DataArrayDouble *ret=DataArrayDouble::New();
2247 int nbOfTuple=getNumberOfTuples();
2248 ret->alloc(nbOfTuple,nbOfComp);
2249 const double *src=getConstPointer();
2250 double *dest=ret->getPointer();
2252 for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
2254 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];
2255 dest[0]=(src[1]*src[2]-src[4]*src[4])/det;
2256 dest[1]=(src[0]*src[2]-src[5]*src[5])/det;
2257 dest[2]=(src[0]*src[1]-src[3]*src[3])/det;
2258 dest[3]=(src[5]*src[4]-src[3]*src[2])/det;
2259 dest[4]=(src[5]*src[3]-src[0]*src[4])/det;
2260 dest[5]=(src[3]*src[4]-src[1]*src[5])/det;
2262 else if(nbOfComp==4)
2263 for(int i=0;i<nbOfTuple;i++,dest+=4,src+=4)
2265 double det=src[0]*src[3]-src[1]*src[2];
2267 dest[1]=-src[1]/det;
2268 dest[2]=-src[2]/det;
2272 for(int i=0;i<nbOfTuple;i++,dest+=9,src+=9)
2274 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];
2275 dest[0]=(src[4]*src[8]-src[7]*src[5])/det;
2276 dest[1]=(src[7]*src[2]-src[1]*src[8])/det;
2277 dest[2]=(src[1]*src[5]-src[4]*src[2])/det;
2278 dest[3]=(src[6]*src[5]-src[3]*src[8])/det;
2279 dest[4]=(src[0]*src[8]-src[6]*src[2])/det;
2280 dest[5]=(src[2]*src[3]-src[0]*src[5])/det;
2281 dest[6]=(src[3]*src[7]-src[6]*src[4])/det;
2282 dest[7]=(src[6]*src[1]-src[0]*src[7])/det;
2283 dest[8]=(src[0]*src[4]-src[1]*src[3])/det;
2289 * Computes the trace of every matrix defined by the tuple of \a this
2290 * array, which contains either 4, 6 or 9 components. The case of 6 components
2291 * corresponds to that of the upper triangular matrix.
2292 * \return DataArrayDouble * - the new instance of DataArrayDouble containing
2293 * 1 component, whose each tuple is the trace of
2294 * the matrix of corresponding tuple of \a this array.
2295 * The caller is to delete this result array using decrRef() as it is no more
2297 * \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2299 DataArrayDouble *DataArrayDouble::trace() const
2302 int nbOfComp=getNumberOfComponents();
2303 if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
2304 throw INTERP_KERNEL::Exception("DataArrayDouble::trace : must be an array with 4,6 or 9 components !");
2305 DataArrayDouble *ret=DataArrayDouble::New();
2306 int nbOfTuple=getNumberOfTuples();
2307 ret->alloc(nbOfTuple,1);
2308 const double *src=getConstPointer();
2309 double *dest=ret->getPointer();
2311 for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
2312 *dest=src[0]+src[1]+src[2];
2313 else if(nbOfComp==4)
2314 for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
2315 *dest=src[0]+src[3];
2317 for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
2318 *dest=src[0]+src[4]+src[8];
2323 * Computes the stress deviator tensor of every stress tensor defined by the tuple of
2324 * \a this array, which contains 6 components.
2325 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2326 * same number of components and tuples as \a this array.
2327 * The caller is to delete this result array using decrRef() as it is no more
2329 * \throw If \a this->getNumberOfComponents() != 6.
2331 DataArrayDouble *DataArrayDouble::deviator() const
2334 int nbOfComp=getNumberOfComponents();
2336 throw INTERP_KERNEL::Exception("DataArrayDouble::deviator : must be an array with exactly 6 components !");
2337 DataArrayDouble *ret=DataArrayDouble::New();
2338 int nbOfTuple=getNumberOfTuples();
2339 ret->alloc(nbOfTuple,6);
2340 const double *src=getConstPointer();
2341 double *dest=ret->getPointer();
2342 for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
2344 double tr=(src[0]+src[1]+src[2])/3.;
2356 * Computes the magnitude of every vector defined by the tuple of
2358 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2359 * same number of tuples as \a this array and one component.
2360 * The caller is to delete this result array using decrRef() as it is no more
2362 * \throw If \a this is not allocated.
2364 DataArrayDouble *DataArrayDouble::magnitude() const
2367 int nbOfComp=getNumberOfComponents();
2368 DataArrayDouble *ret=DataArrayDouble::New();
2369 int nbOfTuple=getNumberOfTuples();
2370 ret->alloc(nbOfTuple,1);
2371 const double *src=getConstPointer();
2372 double *dest=ret->getPointer();
2373 for(int i=0;i<nbOfTuple;i++,dest++)
2376 for(int j=0;j<nbOfComp;j++,src++)
2384 * Computes the maximal value within every tuple of \a this array.
2385 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2386 * same number of tuples as \a this array and one component.
2387 * The caller is to delete this result array using decrRef() as it is no more
2389 * \throw If \a this is not allocated.
2390 * \sa DataArrayDouble::maxPerTupleWithCompoId
2392 DataArrayDouble *DataArrayDouble::maxPerTuple() const
2395 int nbOfComp=getNumberOfComponents();
2396 MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
2397 int nbOfTuple=getNumberOfTuples();
2398 ret->alloc(nbOfTuple,1);
2399 const double *src=getConstPointer();
2400 double *dest=ret->getPointer();
2401 for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
2402 *dest=*std::max_element(src,src+nbOfComp);
2407 * Computes the maximal value within every tuple of \a this array and it returns the first component
2408 * id for each tuple that corresponds to the maximal value within the tuple.
2410 * \param [out] compoIdOfMaxPerTuple - the new new instance of DataArrayInt containing the
2411 * same number of tuples and only one component.
2412 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2413 * same number of tuples as \a this array and one component.
2414 * The caller is to delete this result array using decrRef() as it is no more
2416 * \throw If \a this is not allocated.
2417 * \sa DataArrayDouble::maxPerTuple
2419 DataArrayDouble *DataArrayDouble::maxPerTupleWithCompoId(DataArrayInt* &compoIdOfMaxPerTuple) const
2422 int nbOfComp=getNumberOfComponents();
2423 MCAuto<DataArrayDouble> ret0=DataArrayDouble::New();
2424 MCAuto<DataArrayInt> ret1=DataArrayInt::New();
2425 int nbOfTuple=getNumberOfTuples();
2426 ret0->alloc(nbOfTuple,1); ret1->alloc(nbOfTuple,1);
2427 const double *src=getConstPointer();
2428 double *dest=ret0->getPointer(); int *dest1=ret1->getPointer();
2429 for(int i=0;i<nbOfTuple;i++,dest++,dest1++,src+=nbOfComp)
2431 const double *loc=std::max_element(src,src+nbOfComp);
2433 *dest1=(int)std::distance(src,loc);
2435 compoIdOfMaxPerTuple=ret1.retn();
2440 * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c this->getNumberOfTuples() tuples.
2441 * \n This returned array contains the euclidian distance for each tuple in \a this.
2442 * \n So the returned array can be seen as a dense symmetrical matrix whose diagonal elements are equal to 0.
2443 * \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)
2445 * \warning use this method with care because it can leads to big amount of consumed memory !
2447 * \return A newly allocated (huge) MEDCoupling::DataArrayDouble instance that the caller should deal with.
2449 * \throw If \a this is not allocated.
2451 * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrixWith
2453 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrix() const
2456 int nbOfComp=getNumberOfComponents();
2457 int nbOfTuples=getNumberOfTuples();
2458 const double *inData=getConstPointer();
2459 MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
2460 ret->alloc(nbOfTuples*nbOfTuples,1);
2461 double *outData=ret->getPointer();
2462 for(int i=0;i<nbOfTuples;i++)
2464 outData[i*nbOfTuples+i]=0.;
2465 for(int j=i+1;j<nbOfTuples;j++)
2468 for(int k=0;k<nbOfComp;k++)
2469 { double delta=inData[i*nbOfComp+k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
2471 outData[i*nbOfTuples+j]=dist;
2472 outData[j*nbOfTuples+i]=dist;
2479 * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c other->getNumberOfTuples() tuples.
2480 * \n This returned array contains the euclidian distance for each tuple in \a other with each tuple in \a this.
2481 * \n So the returned array can be seen as a dense rectangular matrix with \c other->getNumberOfTuples() rows and \c this->getNumberOfTuples() columns.
2482 * \n Output rectangular matrix is sorted along rows.
2483 * \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)
2485 * \warning use this method with care because it can leads to big amount of consumed memory !
2487 * \param [in] other DataArrayDouble instance having same number of components than \a this.
2488 * \return A newly allocated (huge) MEDCoupling::DataArrayDouble instance that the caller should deal with.
2490 * \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.
2492 * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrix
2494 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrixWith(const DataArrayDouble *other) const
2497 throw INTERP_KERNEL::Exception("DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : input parameter is null !");
2499 other->checkAllocated();
2500 int nbOfComp=getNumberOfComponents();
2501 int otherNbOfComp=other->getNumberOfComponents();
2502 if(nbOfComp!=otherNbOfComp)
2504 std::ostringstream oss; oss << "DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : this nb of compo=" << nbOfComp << " and other nb of compo=" << otherNbOfComp << ". It should match !";
2505 throw INTERP_KERNEL::Exception(oss.str().c_str());
2507 int nbOfTuples=getNumberOfTuples();
2508 int otherNbOfTuples=other->getNumberOfTuples();
2509 const double *inData=getConstPointer();
2510 const double *inDataOther=other->getConstPointer();
2511 MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
2512 ret->alloc(otherNbOfTuples*nbOfTuples,1);
2513 double *outData=ret->getPointer();
2514 for(int i=0;i<otherNbOfTuples;i++,inDataOther+=nbOfComp)
2516 for(int j=0;j<nbOfTuples;j++)
2519 for(int k=0;k<nbOfComp;k++)
2520 { double delta=inDataOther[k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
2522 outData[i*nbOfTuples+j]=dist;
2529 * This method expects that \a this stores 3 tuples containing 2 components each.
2530 * Each of this tuples represent a point into 2D space.
2531 * This method tries to find an arc of circle starting from first point (tuple) to 2nd and middle point (tuple) along 3nd and last point (tuple).
2532 * If such arc of circle exists, the corresponding center, radius of circle is returned. And additionnaly the length of arc expressed with an \a ang output variable in ]0,2*pi[.
2534 * \throw If \a this is not allocated.
2535 * \throw If \a this has not 3 tuples of 2 components
2536 * \throw If tuples/points in \a this are aligned
2538 void DataArrayDouble::asArcOfCircle(double center[2], double& radius, double& ang) const
2541 INTERP_KERNEL::QuadraticPlanarPrecision arcPrec(1e-14);
2542 if(getNumberOfTuples()!=3 && getNumberOfComponents()!=2)
2543 throw INTERP_KERNEL::Exception("DataArrayDouble::asArcCircle : this method expects");
2544 const double *pt(begin());
2545 MCAuto<INTERP_KERNEL::Node> n0(new INTERP_KERNEL::Node(pt[0],pt[1])),n1(new INTERP_KERNEL::Node(pt[2],pt[3])),n2(new INTERP_KERNEL::Node(pt[4],pt[5]));
2547 INTERP_KERNEL::AutoCppPtr<INTERP_KERNEL::EdgeLin> e1(new INTERP_KERNEL::EdgeLin(n0,n2)),e2(new INTERP_KERNEL::EdgeLin(n2,n1));
2548 INTERP_KERNEL::SegSegIntersector inters(*e1,*e2);
2549 bool colinearity(inters.areColinears());
2551 throw INTERP_KERNEL::Exception("DataArrayDouble::asArcOfCircle : 3 points in this have been detected as colinear !");
2553 INTERP_KERNEL::AutoCppPtr<INTERP_KERNEL::EdgeArcCircle> ret(new INTERP_KERNEL::EdgeArcCircle(n0,n2,n1));
2554 const double *c(ret->getCenter());
2555 center[0]=c[0]; center[1]=c[1];
2556 radius=ret->getRadius();
2557 ang=ret->getAngle();
2561 * Sorts value within every tuple of \a this array.
2562 * \param [in] asc - if \a true, the values are sorted in ascending order, else,
2563 * in descending order.
2564 * \throw If \a this is not allocated.
2566 void DataArrayDouble::sortPerTuple(bool asc)
2569 double *pt=getPointer();
2570 int nbOfTuple=getNumberOfTuples();
2571 int nbOfComp=getNumberOfComponents();
2573 for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
2574 std::sort(pt,pt+nbOfComp);
2576 for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
2577 std::sort(pt,pt+nbOfComp,std::greater<double>());
2582 * Modify all elements of \a this array, so that
2583 * an element _x_ becomes \f$ numerator / x \f$.
2584 * \warning If an exception is thrown because of presence of 0.0 element in \a this
2585 * array, all elements processed before detection of the zero element remain
2587 * \param [in] numerator - the numerator used to modify array elements.
2588 * \throw If \a this is not allocated.
2589 * \throw If there is an element equal to 0.0 in \a this array.
2591 void DataArrayDouble::applyInv(double numerator)
2594 double *ptr=getPointer();
2595 std::size_t nbOfElems=getNbOfElems();
2596 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2598 if(std::abs(*ptr)>std::numeric_limits<double>::min())
2600 *ptr=numerator/(*ptr);
2604 std::ostringstream oss; oss << "DataArrayDouble::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
2606 throw INTERP_KERNEL::Exception(oss.str().c_str());
2613 * Modify all elements of \a this array, so that
2614 * an element _x_ becomes <em> val ^ x </em>. Contrary to DataArrayInt::applyPow
2615 * all values in \a this have to be >= 0 if val is \b not integer.
2616 * \param [in] val - the value used to apply pow on all array elements.
2617 * \throw If \a this is not allocated.
2618 * \warning If an exception is thrown because of presence of 0 element in \a this
2619 * array and \a val is \b not integer, all elements processed before detection of the zero element remain
2622 void DataArrayDouble::applyPow(double val)
2625 double *ptr=getPointer();
2626 std::size_t nbOfElems=getNbOfElems();
2628 bool isInt=((double)val2)==val;
2631 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2637 std::ostringstream oss; oss << "DataArrayDouble::applyPow (double) : At elem # " << i << " value is " << *ptr << " ! must be >=0. !";
2638 throw INTERP_KERNEL::Exception(oss.str().c_str());
2644 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2645 *ptr=pow(*ptr,val2);
2651 * Modify all elements of \a this array, so that
2652 * an element _x_ becomes \f$ val ^ x \f$.
2653 * \param [in] val - the value used to apply pow on all array elements.
2654 * \throw If \a this is not allocated.
2655 * \throw If \a val < 0.
2656 * \warning If an exception is thrown because of presence of 0 element in \a this
2657 * array, all elements processed before detection of the zero element remain
2660 void DataArrayDouble::applyRPow(double val)
2664 throw INTERP_KERNEL::Exception("DataArrayDouble::applyRPow : the input value has to be >= 0 !");
2665 double *ptr=getPointer();
2666 std::size_t nbOfElems=getNbOfElems();
2667 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2673 * Returns a new DataArrayDouble created from \a this one by applying \a
2674 * FunctionToEvaluate to every tuple of \a this array. Textual data is not copied.
2675 * For more info see \ref MEDCouplingArrayApplyFunc
2676 * \param [in] nbOfComp - number of components in the result array.
2677 * \param [in] func - the \a FunctionToEvaluate declared as
2678 * \c bool (*\a func)(\c const \c double *\a pos, \c double *\a res),
2679 * where \a pos points to the first component of a tuple of \a this array
2680 * and \a res points to the first component of a tuple of the result array.
2681 * Note that length (number of components) of \a pos can differ from
2683 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2684 * same number of tuples as \a this array.
2685 * The caller is to delete this result array using decrRef() as it is no more
2687 * \throw If \a this is not allocated.
2688 * \throw If \a func returns \a false.
2690 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, FunctionToEvaluate func) const
2693 DataArrayDouble *newArr=DataArrayDouble::New();
2694 int nbOfTuples=getNumberOfTuples();
2695 int oldNbOfComp=getNumberOfComponents();
2696 newArr->alloc(nbOfTuples,nbOfComp);
2697 const double *ptr=getConstPointer();
2698 double *ptrToFill=newArr->getPointer();
2699 for(int i=0;i<nbOfTuples;i++)
2701 if(!func(ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp))
2703 std::ostringstream oss; oss << "For tuple # " << i << " with value (";
2704 std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
2705 oss << ") : Evaluation of function failed !";
2707 throw INTERP_KERNEL::Exception(oss.str().c_str());
2714 * Returns a new DataArrayDouble created from \a this one by applying a function to every
2715 * tuple of \a this array. Textual data is not copied.
2716 * For more info see \ref MEDCouplingArrayApplyFunc1.
2717 * \param [in] nbOfComp - number of components in the result array.
2718 * \param [in] func - the expression defining how to transform a tuple of \a this array.
2719 * Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
2720 * \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
2721 * If false the computation is carried on without any notification. When false the evaluation is a little faster.
2722 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2723 * same number of tuples as \a this array and \a nbOfComp components.
2724 * The caller is to delete this result array using decrRef() as it is no more
2726 * \throw If \a this is not allocated.
2727 * \throw If computing \a func fails.
2729 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, const std::string& func, bool isSafe) const
2731 INTERP_KERNEL::ExprParser expr(func);
2733 std::set<std::string> vars;
2734 expr.getTrueSetOfVars(vars);
2735 std::vector<std::string> varsV(vars.begin(),vars.end());
2736 return applyFuncNamedCompo(nbOfComp,varsV,func,isSafe);
2740 * Returns a new DataArrayDouble created from \a this one by applying a function to every
2741 * tuple of \a this array. Textual data is not copied. This method works by tuples (whatever its size).
2742 * If \a this is a one component array, call applyFuncOnThis instead that performs the same work faster.
2744 * For more info see \ref MEDCouplingArrayApplyFunc0.
2745 * \param [in] func - the expression defining how to transform a tuple of \a this array.
2746 * Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
2747 * \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
2748 * If false the computation is carried on without any notification. When false the evaluation is a little faster.
2749 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2750 * same number of tuples and components as \a this array.
2751 * The caller is to delete this result array using decrRef() as it is no more
2753 * \sa applyFuncOnThis
2754 * \throw If \a this is not allocated.
2755 * \throw If computing \a func fails.
2757 DataArrayDouble *DataArrayDouble::applyFunc(const std::string& func, bool isSafe) const
2759 int nbOfComp(getNumberOfComponents());
2761 throw INTERP_KERNEL::Exception("DataArrayDouble::applyFunc : output number of component must be > 0 !");
2763 int nbOfTuples(getNumberOfTuples());
2764 MCAuto<DataArrayDouble> newArr(DataArrayDouble::New());
2765 newArr->alloc(nbOfTuples,nbOfComp);
2766 INTERP_KERNEL::ExprParser expr(func);
2768 std::set<std::string> vars;
2769 expr.getTrueSetOfVars(vars);
2770 if((int)vars.size()>1)
2772 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 : ";
2773 std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
2774 throw INTERP_KERNEL::Exception(oss.str().c_str());
2778 expr.prepareFastEvaluator();
2779 newArr->rearrange(1);
2780 newArr->fillWithValue(expr.evaluateDouble());
2781 newArr->rearrange(nbOfComp);
2782 return newArr.retn();
2784 std::vector<std::string> vars2(vars.begin(),vars.end());
2785 double buff,*ptrToFill(newArr->getPointer());
2786 const double *ptr(begin());
2787 std::vector<double> stck;
2788 expr.prepareExprEvaluationDouble(vars2,1,1,0,&buff,&buff+1);
2789 expr.prepareFastEvaluator();
2792 for(int i=0;i<nbOfTuples;i++)
2794 for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
2797 expr.evaluateDoubleInternal(stck);
2798 *ptrToFill=stck.back();
2805 for(int i=0;i<nbOfTuples;i++)
2807 for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
2812 expr.evaluateDoubleInternalSafe(stck);
2814 catch(INTERP_KERNEL::Exception& e)
2816 std::ostringstream oss; oss << "For tuple # " << i << " component # " << iComp << " with value (";
2818 oss << ") : Evaluation of function failed !" << e.what();
2819 throw INTERP_KERNEL::Exception(oss.str().c_str());
2821 *ptrToFill=stck.back();
2826 return newArr.retn();
2830 * This method is a non const method that modify the array in \a this.
2831 * This method only works on one component array. It means that function \a func must
2832 * contain at most one variable.
2833 * This method is a specialization of applyFunc method with one parameter on one component array.
2835 * \param [in] func - the expression defining how to transform a tuple of \a this array.
2836 * Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
2837 * \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
2838 * If false the computation is carried on without any notification. When false the evaluation is a little faster.
2842 void DataArrayDouble::applyFuncOnThis(const std::string& func, bool isSafe)
2844 int nbOfComp(getNumberOfComponents());
2846 throw INTERP_KERNEL::Exception("DataArrayDouble::applyFuncOnThis : output number of component must be > 0 !");
2848 int nbOfTuples(getNumberOfTuples());
2849 INTERP_KERNEL::ExprParser expr(func);
2851 std::set<std::string> vars;
2852 expr.getTrueSetOfVars(vars);
2853 if((int)vars.size()>1)
2855 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 : ";
2856 std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
2857 throw INTERP_KERNEL::Exception(oss.str().c_str());
2861 expr.prepareFastEvaluator();
2862 std::vector<std::string> compInfo(getInfoOnComponents());
2864 fillWithValue(expr.evaluateDouble());
2865 rearrange(nbOfComp);
2866 setInfoOnComponents(compInfo);
2869 std::vector<std::string> vars2(vars.begin(),vars.end());
2870 double buff,*ptrToFill(getPointer());
2871 const double *ptr(begin());
2872 std::vector<double> stck;
2873 expr.prepareExprEvaluationDouble(vars2,1,1,0,&buff,&buff+1);
2874 expr.prepareFastEvaluator();
2877 for(int i=0;i<nbOfTuples;i++)
2879 for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
2882 expr.evaluateDoubleInternal(stck);
2883 *ptrToFill=stck.back();
2890 for(int i=0;i<nbOfTuples;i++)
2892 for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
2897 expr.evaluateDoubleInternalSafe(stck);
2899 catch(INTERP_KERNEL::Exception& e)
2901 std::ostringstream oss; oss << "For tuple # " << i << " component # " << iComp << " with value (";
2903 oss << ") : Evaluation of function failed !" << e.what();
2904 throw INTERP_KERNEL::Exception(oss.str().c_str());
2906 *ptrToFill=stck.back();
2914 * Returns a new DataArrayDouble created from \a this one by applying a function to every
2915 * tuple of \a this array. Textual data is not copied.
2916 * For more info see \ref MEDCouplingArrayApplyFunc2.
2917 * \param [in] nbOfComp - number of components in the result array.
2918 * \param [in] func - the expression defining how to transform a tuple of \a this array.
2919 * Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
2920 * \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
2921 * If false the computation is carried on without any notification. When false the evaluation is a little faster.
2922 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2923 * same number of tuples as \a this array.
2924 * The caller is to delete this result array using decrRef() as it is no more
2926 * \throw If \a this is not allocated.
2927 * \throw If \a func contains vars that are not in \a this->getInfoOnComponent().
2928 * \throw If computing \a func fails.
2930 DataArrayDouble *DataArrayDouble::applyFuncCompo(int nbOfComp, const std::string& func, bool isSafe) const
2932 return applyFuncNamedCompo(nbOfComp,getVarsOnComponent(),func,isSafe);
2936 * Returns a new DataArrayDouble created from \a this one by applying a function to every
2937 * tuple of \a this array. Textual data is not copied.
2938 * For more info see \ref MEDCouplingArrayApplyFunc3.
2939 * \param [in] nbOfComp - number of components in the result array.
2940 * \param [in] varsOrder - sequence of vars defining their order.
2941 * \param [in] func - the expression defining how to transform a tuple of \a this array.
2942 * Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
2943 * \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
2944 * If false the computation is carried on without any notification. When false the evaluation is a little faster.
2945 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2946 * same number of tuples as \a this array.
2947 * The caller is to delete this result array using decrRef() as it is no more
2949 * \throw If \a this is not allocated.
2950 * \throw If \a func contains vars not in \a varsOrder.
2951 * \throw If computing \a func fails.
2953 DataArrayDouble *DataArrayDouble::applyFuncNamedCompo(int nbOfComp, const std::vector<std::string>& varsOrder, const std::string& func, bool isSafe) const
2956 throw INTERP_KERNEL::Exception("DataArrayDouble::applyFuncNamedCompo : output number of component must be > 0 !");
2957 std::vector<std::string> varsOrder2(varsOrder);
2958 int oldNbOfComp(getNumberOfComponents());
2959 for(int i=(int)varsOrder.size();i<oldNbOfComp;i++)
2960 varsOrder2.push_back(std::string());
2962 int nbOfTuples(getNumberOfTuples());
2963 INTERP_KERNEL::ExprParser expr(func);
2965 std::set<std::string> vars;
2966 expr.getTrueSetOfVars(vars);
2967 if((int)vars.size()>oldNbOfComp)
2969 std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
2970 oss << vars.size() << " variables : ";
2971 std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
2972 throw INTERP_KERNEL::Exception(oss.str().c_str());
2974 MCAuto<DataArrayDouble> newArr(DataArrayDouble::New());
2975 newArr->alloc(nbOfTuples,nbOfComp);
2976 INTERP_KERNEL::AutoPtr<double> buff(new double[oldNbOfComp]);
2977 double *buffPtr(buff),*ptrToFill;
2978 std::vector<double> stck;
2979 for(int iComp=0;iComp<nbOfComp;iComp++)
2981 expr.prepareExprEvaluationDouble(varsOrder2,oldNbOfComp,nbOfComp,iComp,buffPtr,buffPtr+oldNbOfComp);
2982 expr.prepareFastEvaluator();
2983 const double *ptr(getConstPointer());
2984 ptrToFill=newArr->getPointer()+iComp;
2987 for(int i=0;i<nbOfTuples;i++,ptrToFill+=nbOfComp,ptr+=oldNbOfComp)
2989 std::copy(ptr,ptr+oldNbOfComp,buffPtr);
2990 expr.evaluateDoubleInternal(stck);
2991 *ptrToFill=stck.back();
2997 for(int i=0;i<nbOfTuples;i++,ptrToFill+=nbOfComp,ptr+=oldNbOfComp)
2999 std::copy(ptr,ptr+oldNbOfComp,buffPtr);
3002 expr.evaluateDoubleInternalSafe(stck);
3003 *ptrToFill=stck.back();
3006 catch(INTERP_KERNEL::Exception& e)
3008 std::ostringstream oss; oss << "For tuple # " << i << " with value (";
3009 std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
3010 oss << ") : Evaluation of function failed !" << e.what();
3011 throw INTERP_KERNEL::Exception(oss.str().c_str());
3016 return newArr.retn();
3019 void DataArrayDouble::applyFuncFast32(const std::string& func)
3022 INTERP_KERNEL::ExprParser expr(func);
3024 char *funcStr=expr.compileX86();
3026 *((void **)&funcPtr)=funcStr;//he he...
3028 double *ptr=getPointer();
3029 int nbOfComp=getNumberOfComponents();
3030 int nbOfTuples=getNumberOfTuples();
3031 int nbOfElems=nbOfTuples*nbOfComp;
3032 for(int i=0;i<nbOfElems;i++,ptr++)
3037 void DataArrayDouble::applyFuncFast64(const std::string& func)
3040 INTERP_KERNEL::ExprParser expr(func);
3042 char *funcStr=expr.compileX86_64();
3044 *((void **)&funcPtr)=funcStr;//he he...
3046 double *ptr=getPointer();
3047 int nbOfComp=getNumberOfComponents();
3048 int nbOfTuples=getNumberOfTuples();
3049 int nbOfElems=nbOfTuples*nbOfComp;
3050 for(int i=0;i<nbOfElems;i++,ptr++)
3056 * \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.
3058 MCAuto<DataArrayDouble> DataArrayDouble::symmetry3DPlane(const double point[3], const double normalVector[3]) const
3061 if(getNumberOfComponents()!=3)
3062 throw INTERP_KERNEL::Exception("DataArrayDouble::symmetry3DPlane : this is excepted to have 3 components !");
3063 int nbTuples(getNumberOfTuples());
3064 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
3065 ret->alloc(nbTuples,3);
3066 Symmetry3DPlane(point,normalVector,nbTuples,begin(),ret->getPointer());
3070 DataArrayDoubleIterator *DataArrayDouble::iterator()
3072 return new DataArrayDoubleIterator(this);
3076 * Returns a new DataArrayInt containing indices of tuples of \a this one-dimensional
3077 * array whose values are within a given range. Textual data is not copied.
3078 * \param [in] vmin - a lowest acceptable value (included).
3079 * \param [in] vmax - a greatest acceptable value (included).
3080 * \return DataArrayInt * - the new instance of DataArrayInt.
3081 * The caller is to delete this result array using decrRef() as it is no more
3083 * \throw If \a this->getNumberOfComponents() != 1.
3085 * \sa DataArrayDouble::findIdsNotInRange
3087 * \if ENABLE_EXAMPLES
3088 * \ref cpp_mcdataarraydouble_getidsinrange "Here is a C++ example".<br>
3089 * \ref py_mcdataarraydouble_getidsinrange "Here is a Python example".
3092 DataArrayInt *DataArrayDouble::findIdsInRange(double vmin, double vmax) const
3095 if(getNumberOfComponents()!=1)
3096 throw INTERP_KERNEL::Exception("DataArrayDouble::findIdsInRange : this must have exactly one component !");
3097 const double *cptr(begin());
3098 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
3099 int nbOfTuples(getNumberOfTuples());
3100 for(int i=0;i<nbOfTuples;i++,cptr++)
3101 if(*cptr>=vmin && *cptr<=vmax)
3102 ret->pushBackSilent(i);
3107 * Returns a new DataArrayInt containing indices of tuples of \a this one-dimensional
3108 * array whose values are not within a given range. Textual data is not copied.
3109 * \param [in] vmin - a lowest not acceptable value (excluded).
3110 * \param [in] vmax - a greatest not acceptable value (excluded).
3111 * \return DataArrayInt * - the new instance of DataArrayInt.
3112 * The caller is to delete this result array using decrRef() as it is no more
3114 * \throw If \a this->getNumberOfComponents() != 1.
3116 * \sa DataArrayDouble::findIdsInRange
3118 DataArrayInt *DataArrayDouble::findIdsNotInRange(double vmin, double vmax) const
3121 if(getNumberOfComponents()!=1)
3122 throw INTERP_KERNEL::Exception("DataArrayDouble::findIdsNotInRange : this must have exactly one component !");
3123 const double *cptr(begin());
3124 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
3125 int nbOfTuples(getNumberOfTuples());
3126 for(int i=0;i<nbOfTuples;i++,cptr++)
3127 if(*cptr<vmin || *cptr>vmax)
3128 ret->pushBackSilent(i);
3133 * Returns a new DataArrayDouble by concatenating two given arrays, so that (1) the number
3134 * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
3135 * the number of component in the result array is same as that of each of given arrays.
3136 * Info on components is copied from the first of the given arrays. Number of components
3137 * in the given arrays must be the same.
3138 * \param [in] a1 - an array to include in the result array.
3139 * \param [in] a2 - another array to include in the result array.
3140 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3141 * The caller is to delete this result array using decrRef() as it is no more
3143 * \throw If both \a a1 and \a a2 are NULL.
3144 * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
3146 DataArrayDouble *DataArrayDouble::Aggregate(const DataArrayDouble *a1, const DataArrayDouble *a2)
3148 std::vector<const DataArrayDouble *> tmp(2);
3149 tmp[0]=a1; tmp[1]=a2;
3150 return Aggregate(tmp);
3154 * Returns a new DataArrayDouble by concatenating all given arrays, so that (1) the number
3155 * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
3156 * the number of component in the result array is same as that of each of given arrays.
3157 * Info on components is copied from the first of the given arrays. Number of components
3158 * in the given arrays must be the same.
3159 * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it
3160 * not the object itself.
3161 * \param [in] arr - a sequence of arrays to include in the result array.
3162 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3163 * The caller is to delete this result array using decrRef() as it is no more
3165 * \throw If all arrays within \a arr are NULL.
3166 * \throw If getNumberOfComponents() of arrays within \a arr.
3168 DataArrayDouble *DataArrayDouble::Aggregate(const std::vector<const DataArrayDouble *>& arr)
3170 std::vector<const DataArrayDouble *> a;
3171 for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
3175 throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : input list must contain at least one NON EMPTY DataArrayDouble !");
3176 std::vector<const DataArrayDouble *>::const_iterator it=a.begin();
3177 std::size_t nbOfComp((*it)->getNumberOfComponents());
3178 int nbt=(*it++)->getNumberOfTuples();
3179 for(int i=1;it!=a.end();it++,i++)
3181 if((*it)->getNumberOfComponents()!=nbOfComp)
3182 throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : Nb of components mismatch for array aggregation !");
3183 nbt+=(*it)->getNumberOfTuples();
3185 MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
3186 ret->alloc(nbt,nbOfComp);
3187 double *pt=ret->getPointer();
3188 for(it=a.begin();it!=a.end();it++)
3189 pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
3190 ret->copyStringInfoFrom(*(a[0]));
3195 * Returns a new DataArrayDouble containing a dot product of two given arrays, so that
3196 * the i-th tuple of the result array is a sum of products of j-th components of i-th
3197 * tuples of given arrays (\f$ a_i = \sum_{j=1}^n a1_j * a2_j \f$).
3198 * Info on components and name is copied from the first of the given arrays.
3199 * Number of tuples and components in the given arrays must be the same.
3200 * \param [in] a1 - a given array.
3201 * \param [in] a2 - another given array.
3202 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3203 * The caller is to delete this result array using decrRef() as it is no more
3205 * \throw If either \a a1 or \a a2 is NULL.
3206 * \throw If any given array is not allocated.
3207 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3208 * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
3210 DataArrayDouble *DataArrayDouble::Dot(const DataArrayDouble *a1, const DataArrayDouble *a2)
3213 throw INTERP_KERNEL::Exception("DataArrayDouble::Dot : input DataArrayDouble instance is NULL !");
3214 a1->checkAllocated();
3215 a2->checkAllocated();
3216 std::size_t nbOfComp(a1->getNumberOfComponents());
3217 if(nbOfComp!=a2->getNumberOfComponents())
3218 throw INTERP_KERNEL::Exception("Nb of components mismatch for array Dot !");
3219 std::size_t nbOfTuple(a1->getNumberOfTuples());
3220 if(nbOfTuple!=a2->getNumberOfTuples())
3221 throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Dot !");
3222 DataArrayDouble *ret=DataArrayDouble::New();
3223 ret->alloc(nbOfTuple,1);
3224 double *retPtr=ret->getPointer();
3225 const double *a1Ptr=a1->begin(),*a2Ptr(a2->begin());
3226 for(std::size_t i=0;i<nbOfTuple;i++)
3229 for(std::size_t j=0;j<nbOfComp;j++)
3230 sum+=a1Ptr[i*nbOfComp+j]*a2Ptr[i*nbOfComp+j];
3233 ret->setInfoOnComponent(0,a1->getInfoOnComponent(0));
3234 ret->setName(a1->getName());
3239 * Returns a new DataArrayDouble containing a cross product of two given arrays, so that
3240 * the i-th tuple of the result array contains 3 components of a vector which is a cross
3241 * product of two vectors defined by the i-th tuples of given arrays.
3242 * Info on components is copied from the first of the given arrays.
3243 * Number of tuples in the given arrays must be the same.
3244 * Number of components in the given arrays must be 3.
3245 * \param [in] a1 - a given array.
3246 * \param [in] a2 - another given array.
3247 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3248 * The caller is to delete this result array using decrRef() as it is no more
3250 * \throw If either \a a1 or \a a2 is NULL.
3251 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3252 * \throw If \a a1->getNumberOfComponents() != 3
3253 * \throw If \a a2->getNumberOfComponents() != 3
3255 DataArrayDouble *DataArrayDouble::CrossProduct(const DataArrayDouble *a1, const DataArrayDouble *a2)
3258 throw INTERP_KERNEL::Exception("DataArrayDouble::CrossProduct : input DataArrayDouble instance is NULL !");
3259 std::size_t nbOfComp(a1->getNumberOfComponents());
3260 if(nbOfComp!=a2->getNumberOfComponents())
3261 throw INTERP_KERNEL::Exception("Nb of components mismatch for array crossProduct !");
3263 throw INTERP_KERNEL::Exception("Nb of components must be equal to 3 for array crossProduct !");
3264 std::size_t nbOfTuple(a1->getNumberOfTuples());
3265 if(nbOfTuple!=a2->getNumberOfTuples())
3266 throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array crossProduct !");
3267 DataArrayDouble *ret=DataArrayDouble::New();
3268 ret->alloc(nbOfTuple,3);
3269 double *retPtr=ret->getPointer();
3270 const double *a1Ptr(a1->begin()),*a2Ptr(a2->begin());
3271 for(std::size_t i=0;i<nbOfTuple;i++)
3273 retPtr[3*i]=a1Ptr[3*i+1]*a2Ptr[3*i+2]-a1Ptr[3*i+2]*a2Ptr[3*i+1];
3274 retPtr[3*i+1]=a1Ptr[3*i+2]*a2Ptr[3*i]-a1Ptr[3*i]*a2Ptr[3*i+2];
3275 retPtr[3*i+2]=a1Ptr[3*i]*a2Ptr[3*i+1]-a1Ptr[3*i+1]*a2Ptr[3*i];
3277 ret->copyStringInfoFrom(*a1);
3282 * Returns a new DataArrayDouble containing maximal values of two given arrays.
3283 * Info on components is copied from the first of the given arrays.
3284 * Number of tuples and components in the given arrays must be the same.
3285 * \param [in] a1 - an array to compare values with another one.
3286 * \param [in] a2 - another array to compare values with the first one.
3287 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3288 * The caller is to delete this result array using decrRef() as it is no more
3290 * \throw If either \a a1 or \a a2 is NULL.
3291 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3292 * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
3294 DataArrayDouble *DataArrayDouble::Max(const DataArrayDouble *a1, const DataArrayDouble *a2)
3297 throw INTERP_KERNEL::Exception("DataArrayDouble::Max : input DataArrayDouble instance is NULL !");
3298 std::size_t nbOfComp(a1->getNumberOfComponents());
3299 if(nbOfComp!=a2->getNumberOfComponents())
3300 throw INTERP_KERNEL::Exception("Nb of components mismatch for array Max !");
3301 std::size_t nbOfTuple(a1->getNumberOfTuples());
3302 if(nbOfTuple!=a2->getNumberOfTuples())
3303 throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Max !");
3304 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
3305 ret->alloc(nbOfTuple,nbOfComp);
3306 double *retPtr(ret->getPointer());
3307 const double *a1Ptr(a1->begin()),*a2Ptr(a2->begin());
3308 std::size_t nbElem(nbOfTuple*nbOfComp);
3309 for(std::size_t i=0;i<nbElem;i++)
3310 retPtr[i]=std::max(a1Ptr[i],a2Ptr[i]);
3311 ret->copyStringInfoFrom(*a1);
3316 * Returns a new DataArrayDouble containing minimal values of two given arrays.
3317 * Info on components is copied from the first of the given arrays.
3318 * Number of tuples and components in the given arrays must be the same.
3319 * \param [in] a1 - an array to compare values with another one.
3320 * \param [in] a2 - another array to compare values with the first one.
3321 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3322 * The caller is to delete this result array using decrRef() as it is no more
3324 * \throw If either \a a1 or \a a2 is NULL.
3325 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3326 * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
3328 DataArrayDouble *DataArrayDouble::Min(const DataArrayDouble *a1, const DataArrayDouble *a2)
3331 throw INTERP_KERNEL::Exception("DataArrayDouble::Min : input DataArrayDouble instance is NULL !");
3332 std::size_t nbOfComp(a1->getNumberOfComponents());
3333 if(nbOfComp!=a2->getNumberOfComponents())
3334 throw INTERP_KERNEL::Exception("Nb of components mismatch for array min !");
3335 std::size_t nbOfTuple(a1->getNumberOfTuples());
3336 if(nbOfTuple!=a2->getNumberOfTuples())
3337 throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array min !");
3338 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
3339 ret->alloc(nbOfTuple,nbOfComp);
3340 double *retPtr(ret->getPointer());
3341 const double *a1Ptr(a1->begin()),*a2Ptr(a2->begin());
3342 std::size_t nbElem(nbOfTuple*nbOfComp);
3343 for(std::size_t i=0;i<nbElem;i++)
3344 retPtr[i]=std::min(a1Ptr[i],a2Ptr[i]);
3345 ret->copyStringInfoFrom(*a1);
3350 * Returns a new DataArrayDouble that is the result of pow of two given arrays. There are 3
3353 * \param [in] a1 - an array to pow up.
3354 * \param [in] a2 - another array to sum up.
3355 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3356 * The caller is to delete this result array using decrRef() as it is no more
3358 * \throw If either \a a1 or \a a2 is NULL.
3359 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3360 * \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
3361 * \throw If there is a negative value in \a a1.
3363 DataArrayDouble *DataArrayDouble::Pow(const DataArrayDouble *a1, const DataArrayDouble *a2)
3366 throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : at least one of input instances is null !");
3367 int nbOfTuple=a1->getNumberOfTuples();
3368 int nbOfTuple2=a2->getNumberOfTuples();
3369 int nbOfComp=a1->getNumberOfComponents();
3370 int nbOfComp2=a2->getNumberOfComponents();
3371 if(nbOfTuple!=nbOfTuple2)
3372 throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of tuples mismatches !");
3373 if(nbOfComp!=1 || nbOfComp2!=1)
3374 throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of components of both arrays must be equal to 1 !");
3375 MCAuto<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbOfTuple,1);
3376 const double *ptr1(a1->begin()),*ptr2(a2->begin());
3377 double *ptr=ret->getPointer();
3378 for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
3382 *ptr=pow(*ptr1,*ptr2);
3386 std::ostringstream oss; oss << "DataArrayDouble::Pow : on tuple #" << i << " of a1 value is < 0 (" << *ptr1 << ") !";
3387 throw INTERP_KERNEL::Exception(oss.str().c_str());
3394 * Apply pow on values of another DataArrayDouble to values of \a this one.
3396 * \param [in] other - an array to pow to \a this one.
3397 * \throw If \a other is NULL.
3398 * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
3399 * \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
3400 * \throw If there is a negative value in \a this.
3402 void DataArrayDouble::powEqual(const DataArrayDouble *other)
3405 throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : input instance is null !");
3406 int nbOfTuple=getNumberOfTuples();
3407 int nbOfTuple2=other->getNumberOfTuples();
3408 int nbOfComp=getNumberOfComponents();
3409 int nbOfComp2=other->getNumberOfComponents();
3410 if(nbOfTuple!=nbOfTuple2)
3411 throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of tuples mismatches !");
3412 if(nbOfComp!=1 || nbOfComp2!=1)
3413 throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of components of both arrays must be equal to 1 !");
3414 double *ptr=getPointer();
3415 const double *ptrc=other->begin();
3416 for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
3419 *ptr=pow(*ptr,*ptrc);
3422 std::ostringstream oss; oss << "DataArrayDouble::powEqual : on tuple #" << i << " of this value is < 0 (" << *ptr << ") !";
3423 throw INTERP_KERNEL::Exception(oss.str().c_str());
3430 * This method is \b NOT wrapped into python because it can be useful only for performance reasons in C++ context.
3431 * All values in \a this must be 0. or 1. within eps error. 0 means false, 1 means true.
3432 * If an another value than 0 or 1 appear (within eps precision) an INTERP_KERNEL::Exception will be thrown.
3434 * \throw if \a this is not allocated.
3435 * \throw if \a this has not exactly one component.
3437 std::vector<bool> DataArrayDouble::toVectorOfBool(double eps) const
3440 if(getNumberOfComponents()!=1)
3441 throw INTERP_KERNEL::Exception("DataArrayDouble::toVectorOfBool : must be applied on single component array !");
3442 int nbt(getNumberOfTuples());
3443 std::vector<bool> ret(nbt);
3444 const double *pt(begin());
3445 for(int i=0;i<nbt;i++)
3449 else if(fabs(pt[i]-1.)<eps)
3453 std::ostringstream oss; oss << "DataArrayDouble::toVectorOfBool : the tuple #" << i << " has value " << pt[i] << " is invalid ! must be 0. or 1. !";
3454 throw INTERP_KERNEL::Exception(oss.str().c_str());
3461 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
3464 void DataArrayDouble::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
3469 tinyInfo[0]=getNumberOfTuples();
3470 tinyInfo[1]=getNumberOfComponents();
3480 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
3483 void DataArrayDouble::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
3487 int nbOfCompo=getNumberOfComponents();
3488 tinyInfo.resize(nbOfCompo+1);
3489 tinyInfo[0]=getName();
3490 for(int i=0;i<nbOfCompo;i++)
3491 tinyInfo[i+1]=getInfoOnComponent(i);
3496 tinyInfo[0]=getName();
3501 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
3502 * This method returns if a feeding is needed.
3504 bool DataArrayDouble::resizeForUnserialization(const std::vector<int>& tinyInfoI)
3506 int nbOfTuple=tinyInfoI[0];
3507 int nbOfComp=tinyInfoI[1];
3508 if(nbOfTuple!=-1 || nbOfComp!=-1)
3510 alloc(nbOfTuple,nbOfComp);
3517 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
3519 void DataArrayDouble::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
3521 setName(tinyInfoS[0]);
3524 int nbOfCompo=getNumberOfComponents();
3525 for(int i=0;i<nbOfCompo;i++)
3526 setInfoOnComponent(i,tinyInfoS[i+1]);
3531 * Low static method that operates 3D rotation of 'nbNodes' 3D nodes whose coordinates are arranged in \a coordsIn
3532 * around an axe ( \a center, \a vect) and with angle \a angle.
3534 void DataArrayDouble::Rotate3DAlg(const double *center, const double *vect, double angle, int nbNodes, const double *coordsIn, double *coordsOut)
3536 if(!center || !vect)
3537 throw INTERP_KERNEL::Exception("DataArrayDouble::Rotate3DAlg : null vector in input !");
3538 double sina(sin(angle));
3539 double cosa(cos(angle));
3540 double vectorNorm[3];
3542 double matrixTmp[9];
3543 double norm(sqrt(vect[0]*vect[0]+vect[1]*vect[1]+vect[2]*vect[2]));
3544 if(norm<std::numeric_limits<double>::min())
3545 throw INTERP_KERNEL::Exception("DataArrayDouble::Rotate3DAlg : magnitude of input vector is too close of 0. !");
3546 std::transform(vect,vect+3,vectorNorm,std::bind2nd(std::multiplies<double>(),1/norm));
3547 //rotation matrix computation
3548 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;
3549 matrixTmp[0]=vectorNorm[0]*vectorNorm[0]; matrixTmp[1]=vectorNorm[0]*vectorNorm[1]; matrixTmp[2]=vectorNorm[0]*vectorNorm[2];
3550 matrixTmp[3]=vectorNorm[1]*vectorNorm[0]; matrixTmp[4]=vectorNorm[1]*vectorNorm[1]; matrixTmp[5]=vectorNorm[1]*vectorNorm[2];
3551 matrixTmp[6]=vectorNorm[2]*vectorNorm[0]; matrixTmp[7]=vectorNorm[2]*vectorNorm[1]; matrixTmp[8]=vectorNorm[2]*vectorNorm[2];
3552 std::transform(matrixTmp,matrixTmp+9,matrixTmp,std::bind2nd(std::multiplies<double>(),1-cosa));
3553 std::transform(matrix,matrix+9,matrixTmp,matrix,std::plus<double>());
3554 matrixTmp[0]=0.; matrixTmp[1]=-vectorNorm[2]; matrixTmp[2]=vectorNorm[1];
3555 matrixTmp[3]=vectorNorm[2]; matrixTmp[4]=0.; matrixTmp[5]=-vectorNorm[0];
3556 matrixTmp[6]=-vectorNorm[1]; matrixTmp[7]=vectorNorm[0]; matrixTmp[8]=0.;
3557 std::transform(matrixTmp,matrixTmp+9,matrixTmp,std::bind2nd(std::multiplies<double>(),sina));
3558 std::transform(matrix,matrix+9,matrixTmp,matrix,std::plus<double>());
3559 //rotation matrix computed.
3561 for(int i=0; i<nbNodes; i++)
3563 std::transform(coordsIn+i*3,coordsIn+(i+1)*3,center,tmp,std::minus<double>());
3564 coordsOut[i*3]=matrix[0]*tmp[0]+matrix[1]*tmp[1]+matrix[2]*tmp[2]+center[0];
3565 coordsOut[i*3+1]=matrix[3]*tmp[0]+matrix[4]*tmp[1]+matrix[5]*tmp[2]+center[1];
3566 coordsOut[i*3+2]=matrix[6]*tmp[0]+matrix[7]*tmp[1]+matrix[8]*tmp[2]+center[2];
3570 void DataArrayDouble::Symmetry3DPlane(const double point[3], const double normalVector[3], int nbNodes, const double *coordsIn, double *coordsOut)
3572 double matrix[9],matrix2[9],matrix3[9];
3573 double vect[3],crossVect[3];
3574 INTERP_KERNEL::orthogonalVect3(normalVector,vect);
3575 crossVect[0]=normalVector[1]*vect[2]-normalVector[2]*vect[1];
3576 crossVect[1]=normalVector[2]*vect[0]-normalVector[0]*vect[2];
3577 crossVect[2]=normalVector[0]*vect[1]-normalVector[1]*vect[0];
3578 double nv(INTERP_KERNEL::norm<3>(vect)),ni(INTERP_KERNEL::norm<3>(normalVector)),nc(INTERP_KERNEL::norm<3>(crossVect));
3579 matrix[0]=vect[0]/nv; matrix[1]=crossVect[0]/nc; matrix[2]=-normalVector[0]/ni;
3580 matrix[3]=vect[1]/nv; matrix[4]=crossVect[1]/nc; matrix[5]=-normalVector[1]/ni;
3581 matrix[6]=vect[2]/nv; matrix[7]=crossVect[2]/nc; matrix[8]=-normalVector[2]/ni;
3582 matrix2[0]=vect[0]/nv; matrix2[1]=vect[1]/nv; matrix2[2]=vect[2]/nv;
3583 matrix2[3]=crossVect[0]/nc; matrix2[4]=crossVect[1]/nc; matrix2[5]=crossVect[2]/nc;
3584 matrix2[6]=normalVector[0]/ni; matrix2[7]=normalVector[1]/ni; matrix2[8]=normalVector[2]/ni;
3585 for(int i=0;i<3;i++)
3586 for(int j=0;j<3;j++)
3589 for(int k=0;k<3;k++)
3590 val+=matrix[3*i+k]*matrix2[3*k+j];
3593 //rotation matrix computed.
3595 for(int i=0; i<nbNodes; i++)
3597 std::transform(coordsIn+i*3,coordsIn+(i+1)*3,point,tmp,std::minus<double>());
3598 coordsOut[i*3]=matrix3[0]*tmp[0]+matrix3[1]*tmp[1]+matrix3[2]*tmp[2]+point[0];
3599 coordsOut[i*3+1]=matrix3[3]*tmp[0]+matrix3[4]*tmp[1]+matrix3[5]*tmp[2]+point[1];
3600 coordsOut[i*3+2]=matrix3[6]*tmp[0]+matrix3[7]*tmp[1]+matrix3[8]*tmp[2]+point[2];
3604 void DataArrayDouble::GiveBaseForPlane(const double normalVector[3], double baseOfPlane[9])
3606 double vect[3],crossVect[3];
3607 INTERP_KERNEL::orthogonalVect3(normalVector,vect);
3608 crossVect[0]=normalVector[1]*vect[2]-normalVector[2]*vect[1];
3609 crossVect[1]=normalVector[2]*vect[0]-normalVector[0]*vect[2];
3610 crossVect[2]=normalVector[0]*vect[1]-normalVector[1]*vect[0];
3611 double nv(INTERP_KERNEL::norm<3>(vect)),ni(INTERP_KERNEL::norm<3>(normalVector)),nc(INTERP_KERNEL::norm<3>(crossVect));
3612 baseOfPlane[0]=vect[0]/nv; baseOfPlane[1]=vect[1]/nv; baseOfPlane[2]=vect[2]/nv;
3613 baseOfPlane[3]=crossVect[0]/nc; baseOfPlane[4]=crossVect[1]/nc; baseOfPlane[5]=crossVect[2]/nc;
3614 baseOfPlane[6]=normalVector[0]/ni; baseOfPlane[7]=normalVector[1]/ni; baseOfPlane[8]=normalVector[2]/ni;
3618 * Low static method that operates 3D rotation of \a nbNodes 3D nodes whose coordinates are arranged in \a coords
3619 * around the center point \a center and with angle \a angle.
3621 void DataArrayDouble::Rotate2DAlg(const double *center, double angle, int nbNodes, const double *coordsIn, double *coordsOut)
3623 double cosa=cos(angle);
3624 double sina=sin(angle);
3626 matrix[0]=cosa; matrix[1]=-sina; matrix[2]=sina; matrix[3]=cosa;
3628 for(int i=0; i<nbNodes; i++)
3630 std::transform(coordsIn+i*2,coordsIn+(i+1)*2,center,tmp,std::minus<double>());
3631 coordsOut[i*2]=matrix[0]*tmp[0]+matrix[1]*tmp[1]+center[0];
3632 coordsOut[i*2+1]=matrix[2]*tmp[0]+matrix[3]*tmp[1]+center[1];
3636 DataArrayDoubleIterator::DataArrayDoubleIterator(DataArrayDouble *da):DataArrayIterator<double>(da)
3640 DataArrayDoubleTuple::DataArrayDoubleTuple(double *pt, int nbOfComp):DataArrayTuple<double>(pt,nbOfComp)
3645 std::string DataArrayDoubleTuple::repr() const
3647 std::ostringstream oss; oss.precision(17); oss << "(";
3648 for(int i=0;i<_nb_of_compo-1;i++)
3649 oss << _pt[i] << ", ";
3650 oss << _pt[_nb_of_compo-1] << ")";
3654 double DataArrayDoubleTuple::doubleValue() const
3656 return this->zeValue();
3660 * This method returns a newly allocated instance the caller should dealed with by a MEDCoupling::DataArrayDouble::decrRef.
3661 * This method performs \b no copy of data. The content is only referenced using MEDCoupling::DataArrayDouble::useArray with ownership set to \b false.
3662 * 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
3663 * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
3665 DataArrayDouble *DataArrayDoubleTuple::buildDADouble(int nbOfTuples, int nbOfCompo) const
3667 return this->buildDA(nbOfTuples,nbOfCompo);
3671 * Returns a new instance of DataArrayInt. The caller is to delete this array
3672 * using decrRef() as it is no more needed.
3674 DataArrayInt *DataArrayInt::New()
3676 return new DataArrayInt;
3680 * Returns the only one value in \a this, if and only if number of elements
3681 * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
3682 * \return double - the sole value stored in \a this array.
3683 * \throw If at least one of conditions stated above is not fulfilled.
3685 int DataArrayInt::intValue() const
3689 if(getNbOfElems()==1)
3691 return *getConstPointer();
3694 throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is allocated but number of elements is not equal to 1 !");
3697 throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is not allocated !");
3701 * Returns an integer value characterizing \a this array, which is useful for a quick
3702 * comparison of many instances of DataArrayInt.
3703 * \return int - the hash value.
3704 * \throw If \a this is not allocated.
3706 int DataArrayInt::getHashCode() const
3709 std::size_t nbOfElems=getNbOfElems();
3710 int ret=nbOfElems*65536;
3715 const int *pt=begin();
3716 for(std::size_t i=0;i<nbOfElems;i+=delta)
3717 ret0+=pt[i] & 0x1FFF;
3722 * Returns a full copy of \a this. For more info on copying data arrays see
3723 * \ref MEDCouplingArrayBasicsCopyDeep.
3724 * \return DataArrayInt * - a new instance of DataArrayInt.
3726 DataArrayInt32 *DataArrayInt32::deepCopy() const
3728 return new DataArrayInt32(*this);
3732 * Returns a textual and human readable representation of \a this instance of
3733 * DataArrayInt. This text is shown when a DataArrayInt is printed in Python.
3734 * \return std::string - text describing \a this DataArrayInt.
3736 * \sa reprNotTooLong, reprZip
3738 std::string DataArrayInt::repr() const
3740 std::ostringstream ret;
3745 std::string DataArrayInt::reprZip() const
3747 std::ostringstream ret;
3752 void DataArrayInt::writeVTK(std::ostream& ofs, int indent, const std::string& type, const std::string& nameInFile, DataArrayByte *byteArr) const
3754 static const char SPACE[4]={' ',' ',' ',' '};
3756 std::string idt(indent,' ');
3757 ofs << idt << "<DataArray type=\"" << type << "\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
3760 ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
3761 if(std::string(type)=="Int32")
3763 const char *data(reinterpret_cast<const char *>(begin()));
3764 std::size_t sz(getNbOfElems()*sizeof(int));
3765 byteArr->insertAtTheEnd(data,data+sz);
3766 byteArr->insertAtTheEnd(SPACE,SPACE+4);
3768 else if(std::string(type)=="Int8")
3770 INTERP_KERNEL::AutoPtr<char> tmp(new char[getNbOfElems()]);
3771 std::copy(begin(),end(),(char *)tmp);
3772 byteArr->insertAtTheEnd((char *)tmp,(char *)tmp+getNbOfElems());
3773 byteArr->insertAtTheEnd(SPACE,SPACE+4);
3775 else if(std::string(type)=="UInt8")
3777 INTERP_KERNEL::AutoPtr<unsigned char> tmp(new unsigned char[getNbOfElems()]);
3778 std::copy(begin(),end(),(unsigned char *)tmp);
3779 byteArr->insertAtTheEnd((unsigned char *)tmp,(unsigned char *)tmp+getNbOfElems());
3780 byteArr->insertAtTheEnd(SPACE,SPACE+4);
3783 throw INTERP_KERNEL::Exception("DataArrayInt::writeVTK : Only Int32, Int8 and UInt8 supported !");
3787 ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
3788 std::copy(begin(),end(),std::ostream_iterator<int>(ofs," "));
3790 ofs << std::endl << idt << "</DataArray>\n";
3793 void DataArrayInt::reprCppStream(const std::string& varName, std::ostream& stream) const
3795 int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
3796 const int *data=getConstPointer();
3797 stream << "DataArrayInt *" << varName << "=DataArrayInt::New();" << std::endl;
3798 if(nbTuples*nbComp>=1)
3800 stream << "const int " << varName << "Data[" << nbTuples*nbComp << "]={";
3801 std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<int>(stream,","));
3802 stream << data[nbTuples*nbComp-1] << "};" << std::endl;
3803 stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
3806 stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
3807 stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
3811 * Method that gives a quick overvien of \a this for python.
3813 void DataArrayInt::reprQuickOverview(std::ostream& stream) const
3815 static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
3816 stream << "DataArrayInt C++ instance at " << this << ". ";
3819 int nbOfCompo=(int)_info_on_compo.size();
3822 int nbOfTuples=getNumberOfTuples();
3823 stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
3824 reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
3827 stream << "Number of components : 0.";
3830 stream << "*** No data allocated ****";
3833 void DataArrayInt::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
3835 const int *data=begin();
3836 int nbOfTuples=getNumberOfTuples();
3837 int nbOfCompo=(int)_info_on_compo.size();
3838 std::ostringstream oss2; oss2 << "[";
3839 std::string oss2Str(oss2.str());
3840 bool isFinished=true;
3841 for(int i=0;i<nbOfTuples && isFinished;i++)
3846 for(int j=0;j<nbOfCompo;j++,data++)
3849 if(j!=nbOfCompo-1) oss2 << ", ";
3855 if(i!=nbOfTuples-1) oss2 << ", ";
3856 std::string oss3Str(oss2.str());
3857 if(oss3Str.length()<maxNbOfByteInRepr)
3869 * Computes distribution of values of \a this one-dimensional array between given value
3870 * ranges (casts). This method is typically useful for entity number splitting by types,
3872 * \warning The values contained in \a arrBg should be sorted ascendently. No
3873 * check of this is be done. If not, the result is not warranted.
3874 * \param [in] arrBg - the array of ascending values defining the value ranges. The i-th
3875 * value of \a arrBg (\a arrBg[ i ]) gives the lowest value of the i-th range,
3876 * and the greatest value of the i-th range equals to \a arrBg[ i+1 ] - 1. \a
3877 * arrBg containing \a n values defines \a n-1 ranges. The last value of \a arrBg
3878 * should be more than every value in \a this array.
3879 * \param [in] arrEnd - specifies the end of the array \a arrBg, so that
3880 * the last value of \a arrBg is \a arrEnd[ -1 ].
3881 * \param [out] castArr - a new instance of DataArrayInt, of same size as \a this array
3882 * (same number of tuples and components), the caller is to delete
3883 * using decrRef() as it is no more needed.
3884 * This array contains indices of ranges for every value of \a this array. I.e.
3885 * the i-th value of \a castArr gives the index of range the i-th value of \a this
3886 * belongs to. Or, in other words, this parameter contains for each tuple in \a
3887 * this in which cast it holds.
3888 * \param [out] rankInsideCast - a new instance of DataArrayInt, of same size as \a this
3889 * array, the caller is to delete using decrRef() as it is no more needed.
3890 * This array contains ranks of values of \a this array within ranges
3891 * they belongs to. I.e. the i-th value of \a rankInsideCast gives the rank of
3892 * the i-th value of \a this array within the \a castArr[ i ]-th range, to which
3893 * the i-th value of \a this belongs to. Or, in other words, this param contains
3894 * for each tuple its rank inside its cast. The rank is computed as difference
3895 * between the value and the lowest value of range.
3896 * \param [out] castsPresent - a new instance of DataArrayInt, containing indices of
3897 * ranges (casts) to which at least one value of \a this array belongs.
3898 * Or, in other words, this param contains the casts that \a this contains.
3899 * The caller is to delete this array using decrRef() as it is no more needed.
3901 * \b Example: If \a this contains [6,5,0,3,2,7,8,1,4] and \a arrBg contains [0,4,9] then
3902 * the output of this method will be :
3903 * - \a castArr : [1,1,0,0,0,1,1,0,1]
3904 * - \a rankInsideCast: [2,1,0,3,2,3,4,1,0]
3905 * - \a castsPresent : [0,1]
3907 * I.e. values of \a this array belong to 2 ranges: #0 and #1. Value 6 belongs to the
3908 * range #1 and its rank within this range is 2; etc.
3910 * \throw If \a this->getNumberOfComponents() != 1.
3911 * \throw If \a arrEnd - arrBg < 2.
3912 * \throw If any value of \a this is not less than \a arrEnd[-1].
3914 void DataArrayInt::splitByValueRange(const int *arrBg, const int *arrEnd,
3915 DataArrayInt *& castArr, DataArrayInt *& rankInsideCast, DataArrayInt *& castsPresent) const
3918 if(getNumberOfComponents()!=1)
3919 throw INTERP_KERNEL::Exception("Call splitByValueRange method on DataArrayInt with only one component, you can call 'rearrange' method before !");
3920 int nbOfTuples=getNumberOfTuples();
3921 std::size_t nbOfCast=std::distance(arrBg,arrEnd);
3923 throw INTERP_KERNEL::Exception("DataArrayInt::splitByValueRange : The input array giving the cast range values should be of size >=2 !");
3925 const int *work=getConstPointer();
3926 typedef std::reverse_iterator<const int *> rintstart;
3927 rintstart bg(arrEnd);//OK no problem because size of 'arr' is greater or equal 2
3928 rintstart end2(arrBg);
3929 MCAuto<DataArrayInt> ret1=DataArrayInt::New();
3930 MCAuto<DataArrayInt> ret2=DataArrayInt::New();
3931 MCAuto<DataArrayInt> ret3=DataArrayInt::New();
3932 ret1->alloc(nbOfTuples,1);
3933 ret2->alloc(nbOfTuples,1);
3934 int *ret1Ptr=ret1->getPointer();
3935 int *ret2Ptr=ret2->getPointer();
3936 std::set<std::size_t> castsDetected;
3937 for(int i=0;i<nbOfTuples;i++)
3939 rintstart res=std::find_if(bg,end2,std::bind2nd(std::less_equal<int>(), work[i]));
3940 std::size_t pos=std::distance(bg,res);
3941 std::size_t pos2=nbOfCast-pos;
3944 ret1Ptr[i]=(int)pos2;
3945 ret2Ptr[i]=work[i]-arrBg[pos2];
3946 castsDetected.insert(pos2);
3950 std::ostringstream oss; oss << "DataArrayInt::splitByValueRange : At rank #" << i << " the value is " << work[i] << " should be in [0," << *bg << ") !";
3951 throw INTERP_KERNEL::Exception(oss.str().c_str());
3954 ret3->alloc((int)castsDetected.size(),1);
3955 std::copy(castsDetected.begin(),castsDetected.end(),ret3->getPointer());
3956 castArr=ret1.retn();
3957 rankInsideCast=ret2.retn();
3958 castsPresent=ret3.retn();
3962 * 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 ).
3963 * 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 ).
3964 * This method works only if \a this is allocated and single component. If not an exception will be thrown.
3966 * \param [out] strt - the start of the range (included) if true is returned.
3967 * \param [out] sttoopp - the end of the range (not included) if true is returned.
3968 * \param [out] stteepp - the step of the range if true is returned.
3969 * \return the verdict of the check.
3971 * \sa DataArray::GetNumberOfItemGivenBES
3973 bool DataArrayInt::isRange(int& strt, int& sttoopp, int& stteepp) const
3976 if(getNumberOfComponents()!=1)
3977 throw INTERP_KERNEL::Exception("DataArrayInt::isRange : this must be single component array !");
3978 int nbTuples(getNumberOfTuples());
3980 { strt=0; sttoopp=0; stteepp=1; return true; }
3981 const int *pt(begin());
3984 { sttoopp=strt+1; stteepp=1; return true; }
3985 strt=*pt; sttoopp=pt[nbTuples-1];
3991 int a(sttoopp-1-strt),tmp(strt);
3992 if(a%(nbTuples-1)!=0)
3994 stteepp=a/(nbTuples-1);
3995 for(int i=0;i<nbTuples;i++,tmp+=stteepp)
4003 int a(strt-sttoopp-1),tmp(strt);
4004 if(a%(nbTuples-1)!=0)
4006 stteepp=-(a/(nbTuples-1));
4007 for(int i=0;i<nbTuples;i++,tmp+=stteepp)
4016 * Modifies in place \a this one-dimensional array so that each value \a v = \a indArrBg[ \a v ],
4017 * i.e. a current value is used as in index to get a new value from \a indArrBg.
4018 * \param [in] indArrBg - pointer to the first element of array of new values to assign
4020 * \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
4021 * the last value of \a indArrBg is \a indArrEnd[ -1 ].
4022 * \throw If \a this->getNumberOfComponents() != 1
4023 * \throw If any value of \a this can't be used as a valid index for
4024 * [\a indArrBg, \a indArrEnd).
4026 * \sa changeValue, findIdForEach
4028 void DataArrayInt::transformWithIndArr(const int *indArrBg, const int *indArrEnd)
4030 this->checkAllocated();
4031 if(this->getNumberOfComponents()!=1)
4032 throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
4033 int nbElemsIn((int)std::distance(indArrBg,indArrEnd)),nbOfTuples(getNumberOfTuples()),*pt(getPointer());
4034 for(int i=0;i<nbOfTuples;i++,pt++)
4036 if(*pt>=0 && *pt<nbElemsIn)
4040 std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " of this value is " << *pt << ", should be in [0," << nbElemsIn << ") !";
4041 throw INTERP_KERNEL::Exception(oss.str());
4044 this->declareAsNew();
4047 void DataArrayInt::transformWithIndArr(const MapKeyVal<int>& m)
4049 this->checkAllocated();
4050 if(this->getNumberOfComponents()!=1)
4051 throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
4052 const std::map<int,int>& dat(m.data());
4053 int nbOfTuples(getNumberOfTuples()),*pt(getPointer());
4054 for(int i=0;i<nbOfTuples;i++,pt++)
4056 std::map<int,int>::const_iterator it(dat.find(*pt));
4061 std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " of this value is " << *pt << " not in map !";
4062 throw INTERP_KERNEL::Exception(oss.str());
4065 this->declareAsNew();
4069 * Creates a one-dimensional DataArrayInt (\a res) whose contents are computed from
4070 * values of \a this (\a a) and the given (\a indArr) arrays as follows:
4071 * \a res[ \a indArr[ \a a[ i ]]] = i. I.e. for each value in place i \a v = \a a[ i ],
4072 * new value in place \a indArr[ \a v ] is i.
4073 * \param [in] indArrBg - the array holding indices within the result array to assign
4074 * indices of values of \a this array pointing to values of \a indArrBg.
4075 * \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
4076 * the last value of \a indArrBg is \a indArrEnd[ -1 ].
4077 * \return DataArrayInt * - the new instance of DataArrayInt.
4078 * The caller is to delete this result array using decrRef() as it is no more
4080 * \throw If \a this->getNumberOfComponents() != 1.
4081 * \throw If any value of \a this array is not a valid index for \a indArrBg array.
4082 * \throw If any value of \a indArrBg is not a valid index for \a this array.
4084 DataArrayInt *DataArrayInt::transformWithIndArrR(const int *indArrBg, const int *indArrEnd) const
4087 if(getNumberOfComponents()!=1)
4088 throw INTERP_KERNEL::Exception("Call transformWithIndArrR method on DataArrayInt with only one component, you can call 'rearrange' method before !");
4089 int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
4090 int nbOfTuples=getNumberOfTuples();
4091 const int *pt=getConstPointer();
4092 MCAuto<DataArrayInt> ret=DataArrayInt::New();
4093 ret->alloc(nbOfTuples,1);
4094 ret->fillWithValue(-1);
4095 int *tmp=ret->getPointer();
4096 for(int i=0;i<nbOfTuples;i++,pt++)
4098 if(*pt>=0 && *pt<nbElemsIn)
4100 int pos=indArrBg[*pt];
4101 if(pos>=0 && pos<nbOfTuples)
4105 std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value of new pos is " << pos << " ( indArrBg[" << *pt << "]) ! Should be in [0," << nbOfTuples << ") !";
4106 throw INTERP_KERNEL::Exception(oss.str().c_str());
4111 std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn << " !";
4112 throw INTERP_KERNEL::Exception(oss.str().c_str());
4119 * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
4120 * from values of \a this array, which is supposed to contain a renumbering map in
4121 * "Old to New" mode. The result array contains a renumbering map in "New to Old" mode.
4122 * To know how to use the renumbering maps see \ref numbering.
4123 * \param [in] newNbOfElem - the number of tuples in the result array.
4124 * \return DataArrayInt * - the new instance of DataArrayInt.
4125 * The caller is to delete this result array using decrRef() as it is no more
4128 * \if ENABLE_EXAMPLES
4129 * \ref cpp_mcdataarrayint_invertarrayo2n2n2o "Here is a C++ example".<br>
4130 * \ref py_mcdataarrayint_invertarrayo2n2n2o "Here is a Python example".
4133 DataArrayInt *DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const
4135 MCAuto<DataArrayInt> ret(DataArrayInt::New());
4136 ret->alloc(newNbOfElem,1);
4137 int nbOfOldNodes(this->getNumberOfTuples());
4138 const int *old2New(begin());
4139 int *pt(ret->getPointer());
4140 for(int i=0;i!=nbOfOldNodes;i++)
4142 int newp(old2New[i]);
4145 if(newp>=0 && newp<newNbOfElem)
4149 std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2O : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
4150 throw INTERP_KERNEL::Exception(oss.str().c_str());
4158 * This method is similar to DataArrayInt::invertArrayO2N2N2O except that
4159 * 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]
4161 DataArrayInt *DataArrayInt::invertArrayO2N2N2OBis(int newNbOfElem) const
4163 MCAuto<DataArrayInt> ret=DataArrayInt::New();
4164 ret->alloc(newNbOfElem,1);
4165 int nbOfOldNodes=getNumberOfTuples();
4166 const int *old2New=getConstPointer();
4167 int *pt=ret->getPointer();
4168 for(int i=nbOfOldNodes-1;i>=0;i--)
4170 int newp(old2New[i]);
4173 if(newp>=0 && newp<newNbOfElem)
4177 std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2OBis : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
4178 throw INTERP_KERNEL::Exception(oss.str().c_str());
4186 * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
4187 * from values of \a this array, which is supposed to contain a renumbering map in
4188 * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
4189 * To know how to use the renumbering maps see \ref numbering.
4190 * \param [in] newNbOfElem - the number of tuples in the result array.
4191 * \return DataArrayInt * - the new instance of DataArrayInt.
4192 * The caller is to delete this result array using decrRef() as it is no more
4195 * \if ENABLE_EXAMPLES
4196 * \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
4198 * \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
4199 * \sa invertArrayN2O2O2NOptimized
4202 DataArrayInt *DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const
4205 MCAuto<DataArrayInt> ret=DataArrayInt::New();
4206 ret->alloc(oldNbOfElem,1);
4207 const int *new2Old=getConstPointer();
4208 int *pt=ret->getPointer();
4209 std::fill(pt,pt+oldNbOfElem,-1);
4210 int nbOfNewElems=getNumberOfTuples();
4211 for(int i=0;i<nbOfNewElems;i++)
4214 if(v>=0 && v<oldNbOfElem)
4218 std::ostringstream oss; oss << "DataArrayInt::invertArrayN2O2O2N : in new id #" << i << " old value is " << v << " expected to be in [0," << oldNbOfElem << ") !";
4219 throw INTERP_KERNEL::Exception(oss.str().c_str());
4226 * Creates a map, whose contents are computed
4227 * from values of \a this array, which is supposed to contain a renumbering map in
4228 * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
4229 * To know how to use the renumbering maps see \ref numbering.
4230 * \param [in] newNbOfElem - the number of tuples in the result array.
4231 * \return MapII - the new instance of Map.
4233 * \if ENABLE_EXAMPLES
4234 * \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
4236 * \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
4237 * \sa invertArrayN2O2O2N, giveN2OOptimized, MEDCouplingPointSet::renumberNodesInConn
4240 MCAuto< MapKeyVal<int> > DataArrayInt32::invertArrayN2O2O2NOptimized() const
4243 if(getNumberOfComponents()!=1)
4244 throw INTERP_KERNEL::Exception("DataArrayInt32::invertArrayN2O2O2NOptimized : single component expected !");
4245 MCAuto< MapKeyVal<int> > ret(MapKeyVal<int>::New());
4246 std::map<int,int>& m(ret->data());
4247 const int *new2Old(begin());
4248 std::size_t nbOfNewElems(this->getNumberOfTuples());
4249 for(std::size_t i=0;i<nbOfNewElems;i++)
4258 * Creates a map, whose contents are computed
4259 * from values of \a this array, which is supposed to contain a renumbering map in
4260 * "New to Old" mode. The result array contains a renumbering map in "New to Old" mode as C++ map for performance reasons.
4262 * \sa invertArrayN2O2O2NOptimized, MEDCouplingPointSet::renumberNodesInConn
4264 MCAuto< MapKeyVal<int> > DataArrayInt32::giveN2OOptimized() const
4267 if(getNumberOfComponents()!=1)
4268 throw INTERP_KERNEL::Exception("DataArrayInt32::giveN2OOptimized : single component expected !");
4269 MCAuto< MapKeyVal<int> > ret(MapKeyVal<int>::New());
4270 std::map<int,int>& m(ret->data());
4271 const int *new2Old(begin());
4272 std::size_t nbOfNewElems(this->getNumberOfTuples());
4273 for(std::size_t i=0;i<nbOfNewElems;i++)
4282 * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode.
4283 * This map, if applied to \a this array, would make it sorted. For example, if
4284 * \a this array contents are [9,10,0,6,4,11,3,7] then the contents of the result array
4285 * are [5,6,0,3,2,7,1,4]; if this result array (\a res) is used as an argument in call
4286 * \a this->renumber(\a res) then the returned array contains [0,3,4,6,7,9,10,11].
4287 * This method is useful for renumbering (in MED file for example). For more info
4288 * on renumbering see \ref numbering.
4289 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4290 * array using decrRef() as it is no more needed.
4291 * \throw If \a this is not allocated.
4292 * \throw If \a this->getNumberOfComponents() != 1.
4293 * \throw If there are equal values in \a this array.
4295 DataArrayInt *DataArrayInt::checkAndPreparePermutation() const
4298 if(getNumberOfComponents()!=1)
4299 throw INTERP_KERNEL::Exception("DataArrayInt::checkAndPreparePermutation : number of components must == 1 !");
4300 int nbTuples=getNumberOfTuples();
4301 const int *pt=getConstPointer();
4302 int *pt2=CheckAndPreparePermutation(pt,pt+nbTuples);
4303 DataArrayInt *ret=DataArrayInt::New();
4304 ret->useArray(pt2,true,C_DEALLOC,nbTuples,1);
4309 * This method tries to find the permutation to apply to the first input \a ids1 to obtain the same array (without considering strings information) the second
4310 * input array \a ids2.
4311 * \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.
4312 * 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
4314 * In case of success both assertion will be true (no throw) :
4315 * \c ids1->renumber(ret)->isEqual(ids2) where \a ret is the return of this method.
4316 * \c ret->transformWithIndArr(ids2)->isEqual(ids1)
4319 * - \a ids1 : [3,1,103,4,6,10,-7,205]
4320 * - \a ids2 : [-7,1,205,10,6,3,103,4]
4321 * - \a return is : [5,1,6,7,4,3,0,2] because ids2[5]==ids1[0], ids2[1]==ids1[1], ids2[6]==ids1[2]...
4323 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4324 * array using decrRef() as it is no more needed.
4325 * \throw If either ids1 or ids2 is null not allocated or not with one components.
4327 * \sa DataArrayInt32::findIdForEach
4329 DataArrayInt *DataArrayInt::FindPermutationFromFirstToSecond(const DataArrayInt *ids1, const DataArrayInt *ids2)
4332 throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be not null !");
4333 if(!ids1->isAllocated() || !ids2->isAllocated())
4334 throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be allocated !");
4335 if(ids1->getNumberOfComponents()!=1 || ids2->getNumberOfComponents()!=1)
4336 throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays have exactly one component !");
4337 if(ids1->getNumberOfTuples()!=ids2->getNumberOfTuples())
4339 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 !";
4340 throw INTERP_KERNEL::Exception(oss.str().c_str());
4342 MCAuto<DataArrayInt> p1(ids1->deepCopy());
4343 MCAuto<DataArrayInt> p2(ids2->deepCopy());
4344 p1->sort(true); p2->sort(true);
4345 if(!p1->isEqualWithoutConsideringStr(*p2))
4346 throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two arrays are not lying on same ids ! Impossible to find a permutation between the 2 arrays !");
4347 p1=ids1->checkAndPreparePermutation();
4348 p2=ids2->checkAndPreparePermutation();
4349 p2=p2->invertArrayO2N2N2O(p2->getNumberOfTuples());
4350 p2=p2->selectByTupleIdSafe(p1->begin(),p1->end());
4355 * Returns two arrays describing a surjective mapping from \a this set of values (\a A)
4356 * onto a set of values of size \a targetNb (\a B). The surjective function is
4357 * \a B[ \a A[ i ]] = i. That is to say that for each \a id in [0,\a targetNb), where \a
4358 * targetNb < \a this->getNumberOfTuples(), there exists at least one tupleId (\a tid) so
4359 * that <em> this->getIJ( tid, 0 ) == id</em>. <br>
4360 * The first of out arrays returns indices of elements of \a this array, grouped by their
4361 * place in the set \a B. The second out array is the index of the first one; it shows how
4362 * many elements of \a A are mapped into each element of \a B. <br>
4364 * mapping and its usage in renumbering see \ref numbering. <br>
4366 * - \a this: [0,3,2,3,2,2,1,2]
4368 * - \a arr: [0, 6, 2,4,5,7, 1,3]
4369 * - \a arrI: [0,1,2,6,8]
4371 * This result means: <br>
4372 * the element of \a B 0 encounters within \a A once (\a arrI[ 0+1 ] - \a arrI[ 0 ]) and
4373 * its index within \a A is 0 ( \a arr[ 0:1 ] == \a arr[ \a arrI[ 0 ] : \a arrI[ 0+1 ]]);<br>
4374 * the element of \a B 2 encounters within \a A 4 times (\a arrI[ 2+1 ] - \a arrI[ 2 ]) and
4375 * its indices within \a A are [2,4,5,7] ( \a arr[ 2:6 ] == \a arr[ \a arrI[ 2 ] :
4376 * \a arrI[ 2+1 ]]); <br> etc.
4377 * \param [in] targetNb - the size of the set \a B. \a targetNb must be equal or more
4378 * than the maximal value of \a A.
4379 * \param [out] arr - a new instance of DataArrayInt returning indices of
4380 * elements of \a this, grouped by their place in the set \a B. The caller is to delete
4381 * this array using decrRef() as it is no more needed.
4382 * \param [out] arrI - a new instance of DataArrayInt returning size of groups of equal
4383 * elements of \a this. The caller is to delete this array using decrRef() as it
4384 * is no more needed.
4385 * \throw If \a this is not allocated.
4386 * \throw If \a this->getNumberOfComponents() != 1.
4387 * \throw If any value in \a this is more or equal to \a targetNb.
4389 void DataArrayInt::changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, DataArrayInt *&arrI) const
4392 if(getNumberOfComponents()!=1)
4393 throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : number of components must == 1 !");
4394 int nbOfTuples=getNumberOfTuples();
4395 MCAuto<DataArrayInt> ret(DataArrayInt::New());
4396 MCAuto<DataArrayInt> retI(DataArrayInt::New());
4397 retI->alloc(targetNb+1,1);
4398 const int *input=getConstPointer();
4399 std::vector< std::vector<int> > tmp(targetNb);
4400 for(int i=0;i<nbOfTuples;i++)
4403 if(tmp2>=0 && tmp2<targetNb)
4404 tmp[tmp2].push_back(i);
4407 std::ostringstream oss; oss << "DataArrayInt::changeSurjectiveFormat : At pos " << i << " presence of element " << tmp2 << " ! should be in [0," << targetNb << ") !";
4408 throw INTERP_KERNEL::Exception(oss.str().c_str());
4411 int *retIPtr=retI->getPointer();
4413 for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++,retIPtr++)
4414 retIPtr[1]=retIPtr[0]+(int)((*it1).size());
4415 if(nbOfTuples!=retI->getIJ(targetNb,0))
4416 throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : big problem should never happen !");
4417 ret->alloc(nbOfTuples,1);
4418 int *retPtr=ret->getPointer();
4419 for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++)
4420 retPtr=std::copy((*it1).begin(),(*it1).end(),retPtr);
4427 * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode computed
4428 * from a zip representation of a surjective format (returned e.g. by
4429 * \ref MEDCoupling::DataArrayDouble::findCommonTuples() "DataArrayDouble::findCommonTuples()"
4430 * for example). The result array minimizes the permutation. <br>
4431 * For more info on renumbering see \ref numbering. <br>
4433 * - \a nbOfOldTuples: 10
4434 * - \a arr : [0,3, 5,7,9]
4435 * - \a arrIBg : [0,2,5]
4436 * - \a newNbOfTuples: 7
4437 * - result array : [0,1,2,0,3,4,5,4,6,4]
4439 * \param [in] nbOfOldTuples - number of tuples in the initial array \a arr.
4440 * \param [in] arr - the array of tuple indices grouped by \a arrIBg array.
4441 * \param [in] arrIBg - the array dividing all indices stored in \a arr into groups of
4442 * (indices of) equal values. Its every element (except the last one) points to
4443 * the first element of a group of equal values.
4444 * \param [in] arrIEnd - specifies the end of \a arrIBg, so that the last element of \a
4445 * arrIBg is \a arrIEnd[ -1 ].
4446 * \param [out] newNbOfTuples - number of tuples after surjection application.
4447 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4448 * array using decrRef() as it is no more needed.
4449 * \throw If any value of \a arr breaks condition ( 0 <= \a arr[ i ] < \a nbOfOldTuples ).
4451 DataArrayInt *DataArrayInt::ConvertIndexArrayToO2N(int nbOfOldTuples, const int *arr, const int *arrIBg, const int *arrIEnd, int &newNbOfTuples)
4453 MCAuto<DataArrayInt> ret=DataArrayInt::New();
4454 ret->alloc(nbOfOldTuples,1);
4455 int *pt=ret->getPointer();
4456 std::fill(pt,pt+nbOfOldTuples,-1);
4457 int nbOfGrps=((int)std::distance(arrIBg,arrIEnd))-1;
4458 const int *cIPtr=arrIBg;
4459 for(int i=0;i<nbOfGrps;i++)
4460 pt[arr[cIPtr[i]]]=-(i+2);
4462 for(int iNode=0;iNode<nbOfOldTuples;iNode++)
4470 int grpId=-(pt[iNode]+2);
4471 for(int j=cIPtr[grpId];j<cIPtr[grpId+1];j++)
4473 if(arr[j]>=0 && arr[j]<nbOfOldTuples)
4477 std::ostringstream oss; oss << "DataArrayInt::ConvertIndexArrayToO2N : With element #" << j << " value is " << arr[j] << " should be in [0," << nbOfOldTuples << ") !";
4478 throw INTERP_KERNEL::Exception(oss.str().c_str());
4485 newNbOfTuples=newNb;
4490 * Returns a new DataArrayInt containing a renumbering map in "New to Old" mode,
4491 * which if applied to \a this array would make it sorted ascendingly.
4492 * For more info on renumbering see \ref numbering. <br>
4494 * - \a this: [2,0,1,1,0,1,2,0,1,1,0,0]
4495 * - result: [10,0,5,6,1,7,11,2,8,9,3,4]
4496 * - after applying result to \a this: [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2]
4498 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4499 * array using decrRef() as it is no more needed.
4500 * \throw If \a this is not allocated.
4501 * \throw If \a this->getNumberOfComponents() != 1.
4503 DataArrayInt *DataArrayInt::buildPermArrPerLevel() const
4506 if(getNumberOfComponents()!=1)
4507 throw INTERP_KERNEL::Exception("DataArrayInt::buildPermArrPerLevel : number of components must == 1 !");
4508 int nbOfTuples=getNumberOfTuples();
4509 const int *pt=getConstPointer();
4510 std::map<int,int> m;
4511 MCAuto<DataArrayInt> ret=DataArrayInt::New();
4512 ret->alloc(nbOfTuples,1);
4513 int *opt=ret->getPointer();
4514 for(int i=0;i<nbOfTuples;i++,pt++,opt++)
4517 std::map<int,int>::iterator it=m.find(val);
4526 m.insert(std::pair<int,int>(val,1));
4530 for(std::map<int,int>::iterator it=m.begin();it!=m.end();it++)
4532 int vt=(*it).second;
4536 pt=getConstPointer();
4537 opt=ret->getPointer();
4538 for(int i=0;i<nbOfTuples;i++,pt++,opt++)
4545 * Checks if \a this array has the given size, and if its contents is equal to an array filled with
4546 * iota(). This method is particularly useful for DataArrayInt instances that represent
4547 * a renumbering array, to check if there is a real need in renumbering.
4548 * This method checks than \a this can be considered as an identity mapping
4549 * of a set having \a sizeExpected elements into itself.
4551 * \param [in] sizeExpected - The number of elements expected.
4552 * \return bool - \a true if \a this array contents == \a range( \a this->getNumberOfTuples())
4553 * \throw If \a this is not allocated.
4554 * \throw If \a this->getNumberOfComponents() != 1.
4556 bool DataArrayInt::isIota(int sizeExpected) const
4559 if(getNumberOfComponents()!=1)
4561 int nbOfTuples(getNumberOfTuples());
4562 if(nbOfTuples!=sizeExpected)
4564 const int *pt=getConstPointer();
4565 for(int i=0;i<nbOfTuples;i++,pt++)
4572 * Checks if all values in \a this array are equal to \a val.
4573 * \param [in] val - value to check equality of array values to.
4574 * \return bool - \a true if all values are \a val.
4575 * \throw If \a this is not allocated.
4576 * \throw If \a this->getNumberOfComponents() != 1
4577 * \sa DataArrayInt::checkUniformAndGuess
4579 bool DataArrayInt::isUniform(int val) const
4582 if(getNumberOfComponents()!=1)
4583 throw INTERP_KERNEL::Exception("DataArrayInt::isUniform : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
4584 const int *w(begin()),*end2(end());
4592 * This method checks that \a this is uniform. If not and exception will be thrown.
4593 * In case of uniformity the corresponding value is returned.
4595 * \return int - the unique value contained in this
4596 * \throw If \a this is not allocated.
4597 * \throw If \a this->getNumberOfComponents() != 1
4598 * \throw If \a this is not uniform.
4599 * \sa DataArrayInt::isUniform
4601 int DataArrayInt::checkUniformAndGuess() const
4604 if(getNumberOfComponents()!=1)
4605 throw INTERP_KERNEL::Exception("DataArrayInt::checkUniformAndGuess : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
4607 throw INTERP_KERNEL::Exception("DataArrayInt::checkUniformAndGuess : this is empty !");
4608 const int *w(begin()),*end2(end());
4612 throw INTERP_KERNEL::Exception("DataArrayInt::checkUniformAndGuess : this is not uniform !");
4617 * Checks if all values in \a this array are unique.
4618 * \return bool - \a true if condition above is true
4619 * \throw If \a this is not allocated.
4620 * \throw If \a this->getNumberOfComponents() != 1
4622 bool DataArrayInt::hasUniqueValues() const
4625 if(getNumberOfComponents()!=1)
4626 throw INTERP_KERNEL::Exception("DataArrayInt::hasOnlyUniqueValues: must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
4627 std::size_t nbOfTuples(getNumberOfTuples());
4628 std::set<int> s(begin(),end()); // in C++11, should use unordered_set (O(1) complexity)
4629 if (s.size() != nbOfTuples)
4635 * Copy all components in a specified order from another DataArrayInt.
4636 * The specified components become the first ones in \a this array.
4637 * Both numerical and textual data is copied. The number of tuples in \a this and
4638 * the other array can be different.
4639 * \param [in] a - the array to copy data from.
4640 * \param [in] compoIds - sequence of zero based indices of components, data of which is
4642 * \throw If \a a is NULL.
4643 * \throw If \a compoIds.size() != \a a->getNumberOfComponents().
4644 * \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
4646 * \if ENABLE_EXAMPLES
4647 * \ref py_mcdataarrayint_setselectedcomponents "Here is a Python example".
4650 void DataArrayInt::setSelectedComponents(const DataArrayInt *a, const std::vector<int>& compoIds)
4653 throw INTERP_KERNEL::Exception("DataArrayInt::setSelectedComponents : input DataArrayInt is NULL !");
4655 a->checkAllocated();
4656 copyPartOfStringInfoFrom2(compoIds,*a);
4657 std::size_t partOfCompoSz=compoIds.size();
4658 int nbOfCompo=getNumberOfComponents();
4659 int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
4660 const int *ac=a->getConstPointer();
4661 int *nc=getPointer();
4662 for(int i=0;i<nbOfTuples;i++)
4663 for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
4664 nc[nbOfCompo*i+compoIds[j]]=*ac;
4667 DataArrayIntIterator *DataArrayInt::iterator()
4669 return new DataArrayIntIterator(this);
4673 * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to a
4674 * given one. The ids are sorted in the ascending order.
4675 * \param [in] val - the value to find within \a this.
4676 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4677 * array using decrRef() as it is no more needed.
4678 * \throw If \a this is not allocated.
4679 * \throw If \a this->getNumberOfComponents() != 1.
4680 * \sa DataArrayInt::findIdsEqualTuple
4682 DataArrayInt *DataArrayInt::findIdsEqual(int val) const
4685 if(getNumberOfComponents()!=1)
4686 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqual : the array must have only one component, you can call 'rearrange' method before !");
4687 const int *cptr(getConstPointer());
4688 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4689 int nbOfTuples=getNumberOfTuples();
4690 for(int i=0;i<nbOfTuples;i++,cptr++)
4692 ret->pushBackSilent(i);
4697 * Creates a new DataArrayInt containing IDs (indices) of tuples holding value \b not
4698 * equal to a given one.
4699 * \param [in] val - the value to ignore within \a this.
4700 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4701 * array using decrRef() as it is no more needed.
4702 * \throw If \a this is not allocated.
4703 * \throw If \a this->getNumberOfComponents() != 1.
4705 DataArrayInt *DataArrayInt::findIdsNotEqual(int val) const
4708 if(getNumberOfComponents()!=1)
4709 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotEqual : the array must have only one component, you can call 'rearrange' method before !");
4710 const int *cptr(getConstPointer());
4711 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4712 int nbOfTuples=getNumberOfTuples();
4713 for(int i=0;i<nbOfTuples;i++,cptr++)
4715 ret->pushBackSilent(i);
4720 * Creates a new DataArrayInt containing IDs (indices) of tuples holding tuple equal to those defined by [ \a tupleBg , \a tupleEnd )
4721 * This method is an extension of DataArrayInt::findIdsEqual method.
4723 * \param [in] tupleBg - the begin (included) of the input tuple to find within \a this.
4724 * \param [in] tupleEnd - the end (excluded) of the input tuple to find within \a this.
4725 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4726 * array using decrRef() as it is no more needed.
4727 * \throw If \a this is not allocated.
4728 * \throw If \a this->getNumberOfComponents() != std::distance(tupleBg,tupleEnd).
4729 * \throw If \a this->getNumberOfComponents() is equal to 0.
4730 * \sa DataArrayInt::findIdsEqual
4732 DataArrayInt *DataArrayInt::findIdsEqualTuple(const int *tupleBg, const int *tupleEnd) const
4734 std::size_t nbOfCompoExp(std::distance(tupleBg,tupleEnd));
4736 if(getNumberOfComponents()!=nbOfCompoExp)
4738 std::ostringstream oss; oss << "DataArrayInt::findIdsEqualTuple : mismatch of number of components. Input tuple has " << nbOfCompoExp << " whereas this array has " << getNumberOfComponents() << " components !";
4739 throw INTERP_KERNEL::Exception(oss.str().c_str());
4742 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqualTuple : number of components should be > 0 !");
4743 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4744 const int *bg(begin()),*end2(end()),*work(begin());
4747 work=std::search(work,end2,tupleBg,tupleEnd);
4750 std::size_t pos(std::distance(bg,work));
4751 if(pos%nbOfCompoExp==0)
4752 ret->pushBackSilent(pos/nbOfCompoExp);
4760 * This method finds for each element \a ELT in [valsBg,valsEnd) elements in \a this equal to it. Associated to ELT
4761 * this method will return the tuple id of last element found. If there is no element in \a this equal to ELT
4762 * an exception will be thrown.
4764 * In case of success this[ret]==vals. Samely ret->transformWithIndArr(this->begin(),this->end())==vals.
4765 * Where \a vals is the [valsBg,valsEnd) array and \a ret the array returned by this method.
4766 * This method can be seen as an extension of FindPermutationFromFirstToSecond.
4769 * - \a this: [17,27,2,10,-4,3,12,27,16]
4770 * - \a val : [3,16,-4,27,17]
4771 * - result: [5,8,4,7,0]
4773 * \return - An array of size std::distance(valsBg,valsEnd)
4775 * \sa DataArrayInt32::FindPermutationFromFirstToSecond
4777 MCAuto<DataArrayInt32> DataArrayInt32::findIdForEach(const int *valsBg, const int *valsEnd) const
4779 MCAuto<DataArrayInt32> ret(DataArrayInt32::New());
4780 std::size_t nbOfTuplesOut(std::distance(valsBg,valsEnd));
4781 ret->alloc(nbOfTuplesOut,1);
4782 MCAuto< MapKeyVal<int> > zeMap(invertArrayN2O2O2NOptimized());
4783 const std::map<int,int>& dat(zeMap->data());
4784 int *ptToFeed(ret->getPointer());
4785 for(const int *pt=valsBg;pt!=valsEnd;pt++)
4787 std::map<int,int>::const_iterator it(dat.find(*pt));
4789 *ptToFeed++=(*it).second;
4792 std::ostringstream oss; oss << "DataArrayInt32::findIdForEach : error for element at place " << std::distance(valsBg,pt);
4793 oss << " of input array value is " << *pt << " which is not in this !";
4794 throw INTERP_KERNEL::Exception(oss.str());
4801 * Assigns \a newValue to all elements holding \a oldValue within \a this
4802 * one-dimensional array.
4803 * \param [in] oldValue - the value to replace.
4804 * \param [in] newValue - the value to assign.
4805 * \return int - number of replacements performed.
4806 * \throw If \a this is not allocated.
4807 * \throw If \a this->getNumberOfComponents() != 1.
4809 int DataArrayInt::changeValue(int oldValue, int newValue)
4812 if(getNumberOfComponents()!=1)
4813 throw INTERP_KERNEL::Exception("DataArrayInt::changeValue : the array must have only one component, you can call 'rearrange' method before !");
4814 if(oldValue==newValue)
4816 int *start(getPointer()),*end2(start+getNbOfElems());
4818 for(int *val=start;val!=end2;val++)
4832 * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to
4833 * one of given values.
4834 * \param [in] valsBg - an array of values to find within \a this array.
4835 * \param [in] valsEnd - specifies the end of the array \a valsBg, so that
4836 * the last value of \a valsBg is \a valsEnd[ -1 ].
4837 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4838 * array using decrRef() as it is no more needed.
4839 * \throw If \a this->getNumberOfComponents() != 1.
4841 DataArrayInt *DataArrayInt::findIdsEqualList(const int *valsBg, const int *valsEnd) const
4843 if(getNumberOfComponents()!=1)
4844 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqualList : the array must have only one component, you can call 'rearrange' method before !");
4845 std::set<int> vals2(valsBg,valsEnd);
4846 const int *cptr(getConstPointer());
4847 std::vector<int> res;
4848 int nbOfTuples(getNumberOfTuples());
4849 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4850 for(int i=0;i<nbOfTuples;i++,cptr++)
4851 if(vals2.find(*cptr)!=vals2.end())
4852 ret->pushBackSilent(i);
4857 * Creates a new DataArrayInt containing IDs (indices) of tuples holding values \b not
4858 * equal to any of given values.
4859 * \param [in] valsBg - an array of values to ignore within \a this array.
4860 * \param [in] valsEnd - specifies the end of the array \a valsBg, so that
4861 * the last value of \a valsBg is \a valsEnd[ -1 ].
4862 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4863 * array using decrRef() as it is no more needed.
4864 * \throw If \a this->getNumberOfComponents() != 1.
4866 DataArrayInt *DataArrayInt::findIdsNotEqualList(const int *valsBg, const int *valsEnd) const
4868 if(getNumberOfComponents()!=1)
4869 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotEqualList : the array must have only one component, you can call 'rearrange' method before !");
4870 std::set<int> vals2(valsBg,valsEnd);
4871 const int *cptr=getConstPointer();
4872 std::vector<int> res;
4873 int nbOfTuples=getNumberOfTuples();
4874 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4875 for(int i=0;i<nbOfTuples;i++,cptr++)
4876 if(vals2.find(*cptr)==vals2.end())
4877 ret->pushBackSilent(i);
4882 * This method is an extension of DataArrayInt::findIdFirstEqual method because this method works for DataArrayInt with
4883 * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
4884 * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
4885 * If any the tuple id is returned. If not -1 is returned.
4887 * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
4888 * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
4890 * \return tuple id where \b tupl is. -1 if no such tuple exists in \b this.
4891 * \sa DataArrayInt::findIdSequence, DataArrayInt::presenceOfTuple.
4893 int DataArrayInt::findIdFirstEqualTuple(const std::vector<int>& tupl) const
4896 int nbOfCompo=getNumberOfComponents();
4898 throw INTERP_KERNEL::Exception("DataArrayInt::findIdFirstEqualTuple : 0 components in 'this' !");
4899 if(nbOfCompo!=(int)tupl.size())
4901 std::ostringstream oss; oss << "DataArrayInt::findIdFirstEqualTuple : 'this' contains " << nbOfCompo << " components and searching for a tuple of length " << tupl.size() << " !";
4902 throw INTERP_KERNEL::Exception(oss.str().c_str());
4904 const int *cptr=getConstPointer();
4905 std::size_t nbOfVals=getNbOfElems();
4906 for(const int *work=cptr;work!=cptr+nbOfVals;)
4908 work=std::search(work,cptr+nbOfVals,tupl.begin(),tupl.end());
4909 if(work!=cptr+nbOfVals)
4911 if(std::distance(cptr,work)%nbOfCompo!=0)
4914 return std::distance(cptr,work)/nbOfCompo;
4921 * This method searches the sequence specified in input parameter \b vals in \b this.
4922 * This works only for DataArrayInt having number of components equal to one (if not an INTERP_KERNEL::Exception will be thrown).
4923 * This method differs from DataArrayInt::findIdFirstEqualTuple in that the position is internal raw data is not considered here contrary to DataArrayInt::findIdFirstEqualTuple.
4924 * \sa DataArrayInt::findIdFirstEqualTuple
4926 int DataArrayInt::findIdSequence(const std::vector<int>& vals) const
4929 int nbOfCompo=getNumberOfComponents();
4931 throw INTERP_KERNEL::Exception("DataArrayInt::findIdSequence : works only for DataArrayInt instance with one component !");
4932 const int *cptr=getConstPointer();
4933 std::size_t nbOfVals=getNbOfElems();
4934 const int *loc=std::search(cptr,cptr+nbOfVals,vals.begin(),vals.end());
4935 if(loc!=cptr+nbOfVals)
4936 return std::distance(cptr,loc);
4941 * This method expects to be called when number of components of this is equal to one.
4942 * This method returns the tuple id, if it exists, of the first tuple equal to \b value.
4943 * If not any tuple contains \b value -1 is returned.
4944 * \sa DataArrayInt::presenceOfValue
4946 int DataArrayInt::findIdFirstEqual(int value) const
4949 if(getNumberOfComponents()!=1)
4950 throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
4951 const int *cptr=getConstPointer();
4952 int nbOfTuples=getNumberOfTuples();
4953 const int *ret=std::find(cptr,cptr+nbOfTuples,value);
4954 if(ret!=cptr+nbOfTuples)
4955 return std::distance(cptr,ret);
4960 * This method expects to be called when number of components of this is equal to one.
4961 * This method returns the tuple id, if it exists, of the first tuple so that the value is contained in \b vals.
4962 * If not any tuple contains one of the values contained in 'vals' -1 is returned.
4963 * \sa DataArrayInt::presenceOfValue
4965 int DataArrayInt::findIdFirstEqual(const std::vector<int>& vals) const
4968 if(getNumberOfComponents()!=1)
4969 throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
4970 std::set<int> vals2(vals.begin(),vals.end());
4971 const int *cptr=getConstPointer();
4972 int nbOfTuples=getNumberOfTuples();
4973 for(const int *w=cptr;w!=cptr+nbOfTuples;w++)
4974 if(vals2.find(*w)!=vals2.end())
4975 return std::distance(cptr,w);
4980 * This method returns the number of values in \a this that are equals to input parameter \a value.
4981 * This method only works for single component array.
4983 * \return a value in [ 0, \c this->getNumberOfTuples() )
4985 * \throw If \a this is not allocated
4988 int DataArrayInt::count(int value) const
4992 if(getNumberOfComponents()!=1)
4993 throw INTERP_KERNEL::Exception("DataArrayInt::count : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
4994 const int *vals=begin();
4995 int nbOfTuples=getNumberOfTuples();
4996 for(int i=0;i<nbOfTuples;i++,vals++)
5003 * This method is an extension of DataArrayInt::presenceOfValue method because this method works for DataArrayInt with
5004 * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
5005 * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
5006 * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
5007 * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
5008 * \sa DataArrayInt::findIdFirstEqualTuple
5010 bool DataArrayInt::presenceOfTuple(const std::vector<int>& tupl) const
5012 return findIdFirstEqualTuple(tupl)!=-1;
5017 * Returns \a true if a given value is present within \a this one-dimensional array.
5018 * \param [in] value - the value to find within \a this array.
5019 * \return bool - \a true in case if \a value is present within \a this array.
5020 * \throw If \a this is not allocated.
5021 * \throw If \a this->getNumberOfComponents() != 1.
5022 * \sa findIdFirstEqual()
5024 bool DataArrayInt::presenceOfValue(int value) const
5026 return findIdFirstEqual(value)!=-1;
5030 * This method expects to be called when number of components of this is equal to one.
5031 * This method returns true if it exists a tuple so that the value is contained in \b vals.
5032 * If not any tuple contains one of the values contained in 'vals' false is returned.
5033 * \sa DataArrayInt::findIdFirstEqual
5035 bool DataArrayInt::presenceOfValue(const std::vector<int>& vals) const
5037 return findIdFirstEqual(vals)!=-1;
5041 * Accumulates values of each component of \a this array.
5042 * \param [out] res - an array of length \a this->getNumberOfComponents(), allocated
5043 * by the caller, that is filled by this method with sum value for each
5045 * \throw If \a this is not allocated.
5047 void DataArrayInt::accumulate(int *res) const
5050 const int *ptr=getConstPointer();
5051 int nbTuple=getNumberOfTuples();
5052 int nbComps=getNumberOfComponents();
5053 std::fill(res,res+nbComps,0);
5054 for(int i=0;i<nbTuple;i++)
5055 std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<int>());
5058 int DataArrayInt::accumulate(int compId) const
5061 const int *ptr=getConstPointer();
5062 int nbTuple=getNumberOfTuples();
5063 int nbComps=getNumberOfComponents();
5064 if(compId<0 || compId>=nbComps)
5065 throw INTERP_KERNEL::Exception("DataArrayInt::accumulate : Invalid compId specified : No such nb of components !");
5067 for(int i=0;i<nbTuple;i++)
5068 ret+=ptr[i*nbComps+compId];
5073 * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
5074 * The returned array will have same number of components than \a this and number of tuples equal to
5075 * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
5077 * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
5079 * \param [in] bgOfIndex - begin (included) of the input index array.
5080 * \param [in] endOfIndex - end (excluded) of the input index array.
5081 * \return DataArrayInt * - the new instance having the same number of components than \a this.
5083 * \throw If bgOfIndex or end is NULL.
5084 * \throw If input index array is not ascendingly sorted.
5085 * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
5086 * \throw If std::distance(bgOfIndex,endOfIndex)==0.
5088 DataArrayInt *DataArrayInt::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
5090 if(!bgOfIndex || !endOfIndex)
5091 throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : input pointer NULL !");
5093 int nbCompo=getNumberOfComponents();
5094 int nbOfTuples=getNumberOfTuples();
5095 int sz=(int)std::distance(bgOfIndex,endOfIndex);
5097 throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : invalid size of input index array !");
5099 MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(sz,nbCompo);
5100 const int *w=bgOfIndex;
5101 if(*w<0 || *w>=nbOfTuples)
5102 throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
5103 const int *srcPt=begin()+(*w)*nbCompo;
5104 int *tmp=ret->getPointer();
5105 for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
5107 std::fill(tmp,tmp+nbCompo,0);
5110 for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
5112 if(j>=0 && j<nbOfTuples)
5113 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<int>());
5116 std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
5117 throw INTERP_KERNEL::Exception(oss.str().c_str());
5123 std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
5124 throw INTERP_KERNEL::Exception(oss.str().c_str());
5127 ret->copyStringInfoFrom(*this);
5132 * Returns a new DataArrayInt by concatenating two given arrays, so that (1) the number
5133 * of tuples in the result array is <em> a1->getNumberOfTuples() + a2->getNumberOfTuples() -
5134 * offsetA2</em> and (2)
5135 * the number of component in the result array is same as that of each of given arrays.
5136 * First \a offsetA2 tuples of \a a2 are skipped and thus are missing from the result array.
5137 * Info on components is copied from the first of the given arrays. Number of components
5138 * in the given arrays must be the same.
5139 * \param [in] a1 - an array to include in the result array.
5140 * \param [in] a2 - another array to include in the result array.
5141 * \param [in] offsetA2 - number of tuples of \a a2 to skip.
5142 * \return DataArrayInt * - the new instance of DataArrayInt.
5143 * The caller is to delete this result array using decrRef() as it is no more
5145 * \throw If either \a a1 or \a a2 is NULL.
5146 * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
5148 DataArrayInt *DataArrayInt::Aggregate(const DataArrayInt *a1, const DataArrayInt *a2, int offsetA2)
5151 throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input DataArrayInt instance is NULL !");
5152 std::size_t nbOfComp(a1->getNumberOfComponents());
5153 if(nbOfComp!=a2->getNumberOfComponents())
5154 throw INTERP_KERNEL::Exception("Nb of components mismatch for array Aggregation !");
5155 std::size_t nbOfTuple1(a1->getNumberOfTuples()),nbOfTuple2(a2->getNumberOfTuples());
5156 MCAuto<DataArrayInt> ret(DataArrayInt::New());
5157 ret->alloc(nbOfTuple1+nbOfTuple2-offsetA2,nbOfComp);
5158 int *pt=std::copy(a1->begin(),a1->end(),ret->getPointer());
5159 std::copy(a2->getConstPointer()+offsetA2*nbOfComp,a2->getConstPointer()+nbOfTuple2*nbOfComp,pt);
5160 ret->copyStringInfoFrom(*a1);
5165 * Returns a new DataArrayInt by concatenating all given arrays, so that (1) the number
5166 * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
5167 * the number of component in the result array is same as that of each of given arrays.
5168 * Info on components is copied from the first of the given arrays. Number of components
5169 * in the given arrays must be the same.
5170 * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it
5171 * not the object itself.
5172 * \param [in] arr - a sequence of arrays to include in the result array.
5173 * \return DataArrayInt * - the new instance of DataArrayInt.
5174 * The caller is to delete this result array using decrRef() as it is no more
5176 * \throw If all arrays within \a arr are NULL.
5177 * \throw If getNumberOfComponents() of arrays within \a arr.
5179 DataArrayInt *DataArrayInt::Aggregate(const std::vector<const DataArrayInt *>& arr)
5181 std::vector<const DataArrayInt *> a;
5182 for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
5186 throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input list must be NON EMPTY !");
5187 std::vector<const DataArrayInt *>::const_iterator it=a.begin();
5188 std::size_t nbOfComp((*it)->getNumberOfComponents()),nbt((*it++)->getNumberOfTuples());
5189 for(int i=1;it!=a.end();it++,i++)
5191 if((*it)->getNumberOfComponents()!=nbOfComp)
5192 throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : Nb of components mismatch for array aggregation !");
5193 nbt+=(*it)->getNumberOfTuples();
5195 MCAuto<DataArrayInt> ret=DataArrayInt::New();
5196 ret->alloc(nbt,nbOfComp);
5197 int *pt=ret->getPointer();
5198 for(it=a.begin();it!=a.end();it++)
5199 pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
5200 ret->copyStringInfoFrom(*(a[0]));
5205 * This method takes as input a list of DataArrayInt instances \a arrs that represent each a packed index arrays.
5206 * A packed index array is an allocated array with one component, and at least one tuple. The first element
5207 * of each array in \a arrs must be 0. Each array in \a arrs is expected to be increasingly monotonic.
5208 * 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.
5210 * \return DataArrayInt * - a new object to be managed by the caller.
5212 DataArrayInt *DataArrayInt::AggregateIndexes(const std::vector<const DataArrayInt *>& arrs)
5215 for(std::vector<const DataArrayInt *>::const_iterator it4=arrs.begin();it4!=arrs.end();it4++)
5219 (*it4)->checkAllocated();
5220 if((*it4)->getNumberOfComponents()!=1)
5222 std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of compo != 1 at pos " << std::distance(arrs.begin(),it4) << " !";
5223 throw INTERP_KERNEL::Exception(oss.str().c_str());
5225 int nbTupl=(*it4)->getNumberOfTuples();
5228 std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of tuples < 1 at pos " << std::distance(arrs.begin(),it4) << " !";
5229 throw INTERP_KERNEL::Exception(oss.str().c_str());
5231 if((*it4)->front()!=0)
5233 std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with front value != 0 at pos " << std::distance(arrs.begin(),it4) << " !";
5234 throw INTERP_KERNEL::Exception(oss.str().c_str());
5240 std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a null instance at pos " << std::distance(arrs.begin(),it4) << " !";
5241 throw INTERP_KERNEL::Exception(oss.str().c_str());
5245 throw INTERP_KERNEL::Exception("DataArrayInt::AggregateIndexes : input list must be NON EMPTY !");
5246 MCAuto<DataArrayInt> ret=DataArrayInt::New();
5247 ret->alloc(retSz,1);
5248 int *pt=ret->getPointer(); *pt++=0;
5249 for(std::vector<const DataArrayInt *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
5250 pt=std::transform((*it)->begin()+1,(*it)->end(),pt,std::bind2nd(std::plus<int>(),pt[-1]));
5251 ret->copyStringInfoFrom(*(arrs[0]));
5256 * Returns in a single walk in \a this the min value and the max value in \a this.
5257 * \a this is expected to be single component array.
5259 * \param [out] minValue - the min value in \a this.
5260 * \param [out] maxValue - the max value in \a this.
5262 * \sa getMinValueInArray, getMinValue, getMaxValueInArray, getMaxValue
5264 void DataArrayInt::getMinMaxValues(int& minValue, int& maxValue) const
5267 if(getNumberOfComponents()!=1)
5268 throw INTERP_KERNEL::Exception("DataArrayInt::getMinMaxValues : must be applied on DataArrayInt with only one component !");
5269 int nbTuples(getNumberOfTuples());
5270 const int *pt(begin());
5271 minValue=std::numeric_limits<int>::max(); maxValue=-std::numeric_limits<int>::max();
5272 for(int i=0;i<nbTuples;i++,pt++)
5282 * Modify all elements of \a this array, so that
5283 * an element _x_ becomes \f$ numerator / x \f$.
5284 * \warning If an exception is thrown because of presence of 0 element in \a this
5285 * array, all elements processed before detection of the zero element remain
5287 * \param [in] numerator - the numerator used to modify array elements.
5288 * \throw If \a this is not allocated.
5289 * \throw If there is an element equal to 0 in \a this array.
5291 void DataArrayInt::applyInv(int numerator)
5294 int *ptr=getPointer();
5295 std::size_t nbOfElems=getNbOfElems();
5296 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
5300 *ptr=numerator/(*ptr);
5304 std::ostringstream oss; oss << "DataArrayInt::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
5306 throw INTERP_KERNEL::Exception(oss.str().c_str());
5313 * Modify all elements of \a this array, so that
5314 * an element _x_ becomes \f$ x / val \f$.
5315 * \param [in] val - the denominator used to modify array elements.
5316 * \throw If \a this is not allocated.
5317 * \throw If \a val == 0.
5319 void DataArrayInt::applyDivideBy(int val)
5322 throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to divide by 0 !");
5324 int *ptr=getPointer();
5325 std::size_t nbOfElems=getNbOfElems();
5326 std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::divides<int>(),val));
5331 * Modify all elements of \a this array, so that
5332 * an element _x_ becomes <em> x % val </em>.
5333 * \param [in] val - the divisor used to modify array elements.
5334 * \throw If \a this is not allocated.
5335 * \throw If \a val <= 0.
5337 void DataArrayInt::applyModulus(int val)
5340 throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to operate modulus on value <= 0 !");
5342 int *ptr=getPointer();
5343 std::size_t nbOfElems=getNbOfElems();
5344 std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::modulus<int>(),val));
5349 * This method works only on data array with one component.
5350 * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
5351 * this[*id] in [\b vmin,\b vmax)
5353 * \param [in] vmin begin of range. This value is included in range (included).
5354 * \param [in] vmax end of range. This value is \b not included in range (excluded).
5355 * \return a newly allocated data array that the caller should deal with.
5357 * \sa DataArrayInt::findIdsNotInRange , DataArrayInt::findIdsStricltyNegative
5359 DataArrayInt *DataArrayInt::findIdsInRange(int vmin, int vmax) const
5361 InRange<int> ir(vmin,vmax);
5362 MCAuto<DataArrayInt> ret(findIdsAdv(ir));
5367 * This method works only on data array with one component.
5368 * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
5369 * this[*id] \b not in [\b vmin,\b vmax)
5371 * \param [in] vmin begin of range. This value is \b not included in range (excluded).
5372 * \param [in] vmax end of range. This value is included in range (included).
5373 * \return a newly allocated data array that the caller should deal with.
5375 * \sa DataArrayInt::findIdsInRange , DataArrayInt::findIdsStricltyNegative
5377 DataArrayInt *DataArrayInt::findIdsNotInRange(int vmin, int vmax) const
5379 NotInRange<int> nir(vmin,vmax);
5380 MCAuto<DataArrayInt> ret(findIdsAdv(nir));
5385 * This method works only on data array with one component.
5386 * 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.
5388 * \param [in] vmin begin of range. This value is included in range (included).
5389 * \param [in] vmax end of range. This value is \b not included in range (excluded).
5390 * \return if all ids in \a this are so that (*this)[i]==i for all i in [ 0, \c this->getNumberOfTuples() ). */
5391 bool DataArrayInt::checkAllIdsInRange(int vmin, int vmax) const
5394 if(getNumberOfComponents()!=1)
5395 throw INTERP_KERNEL::Exception("DataArrayInt::checkAllIdsInRange : this must have exactly one component !");
5396 int nbOfTuples=getNumberOfTuples();
5398 const int *cptr=getConstPointer();
5399 for(int i=0;i<nbOfTuples;i++,cptr++)
5401 if(*cptr>=vmin && *cptr<vmax)
5402 { ret=ret && *cptr==i; }
5405 std::ostringstream oss; oss << "DataArrayInt::checkAllIdsInRange : tuple #" << i << " has value " << *cptr << " should be in [" << vmin << "," << vmax << ") !";
5406 throw INTERP_KERNEL::Exception(oss.str().c_str());
5413 * Modify all elements of \a this array, so that
5414 * an element _x_ becomes <em> val % x </em>.
5415 * \warning If an exception is thrown because of presence of an element <= 0 in \a this
5416 * array, all elements processed before detection of the zero element remain
5418 * \param [in] val - the divident used to modify array elements.
5419 * \throw If \a this is not allocated.
5420 * \throw If there is an element equal to or less than 0 in \a this array.
5422 void DataArrayInt::applyRModulus(int val)
5425 int *ptr=getPointer();
5426 std::size_t nbOfElems=getNbOfElems();
5427 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
5435 std::ostringstream oss; oss << "DataArrayInt::applyRModulus : presence of value <=0 in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
5437 throw INTERP_KERNEL::Exception(oss.str().c_str());
5444 * Modify all elements of \a this array, so that
5445 * an element _x_ becomes <em> val ^ x </em>.
5446 * \param [in] val - the value used to apply pow on all array elements.
5447 * \throw If \a this is not allocated.
5448 * \throw If \a val < 0.
5450 void DataArrayInt::applyPow(int val)
5454 throw INTERP_KERNEL::Exception("DataArrayInt::applyPow : input pow in < 0 !");
5455 int *ptr=getPointer();
5456 std::size_t nbOfElems=getNbOfElems();
5459 std::fill(ptr,ptr+nbOfElems,1);
5462 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
5465 for(int j=0;j<val;j++)
5473 * Modify all elements of \a this array, so that
5474 * an element _x_ becomes \f$ val ^ x \f$.
5475 * \param [in] val - the value used to apply pow on all array elements.
5476 * \throw If \a this is not allocated.
5477 * \throw If there is an element < 0 in \a this array.
5478 * \warning If an exception is thrown because of presence of 0 element in \a this
5479 * array, all elements processed before detection of the zero element remain
5482 void DataArrayInt::applyRPow(int val)
5485 int *ptr=getPointer();
5486 std::size_t nbOfElems=getNbOfElems();
5487 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
5492 for(int j=0;j<*ptr;j++)
5498 std::ostringstream oss; oss << "DataArrayInt::applyRPow : presence of negative value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
5500 throw INTERP_KERNEL::Exception(oss.str().c_str());
5507 * Returns a new DataArrayInt which is a minimal partition of elements of \a groups.
5508 * The i-th item of the result array is an ID of a set of elements belonging to a
5509 * unique set of groups, which the i-th element is a part of. This set of elements
5510 * belonging to a unique set of groups is called \a family, so the result array contains
5511 * IDs of families each element belongs to.
5513 * \b Example: if we have two groups of elements: \a group1 [0,4] and \a group2 [ 0,1,2 ],
5514 * then there are 3 families:
5515 * - \a family1 (with ID 1) contains element [0] belonging to ( \a group1 + \a group2 ),
5516 * - \a family2 (with ID 2) contains elements [4] belonging to ( \a group1 ),
5517 * - \a family3 (with ID 3) contains element [1,2] belonging to ( \a group2 ), <br>
5518 * and the result array contains IDs of families [ 1,3,3,0,2 ]. <br> Note a family ID 0 which
5519 * stands for the element #3 which is in none of groups.
5521 * \param [in] groups - sequence of groups of element IDs.
5522 * \param [in] newNb - total number of elements; it must be more than max ID of element
5524 * \param [out] fidsOfGroups - IDs of families the elements of each group belong to.
5525 * \return DataArrayInt * - a new instance of DataArrayInt containing IDs of families
5526 * each element with ID from range [0, \a newNb ) belongs to. The caller is to
5527 * delete this array using decrRef() as it is no more needed.
5528 * \throw If any element ID in \a groups violates condition ( 0 <= ID < \a newNb ).
5530 DataArrayInt *DataArrayInt::MakePartition(const std::vector<const DataArrayInt *>& groups, int newNb, std::vector< std::vector<int> >& fidsOfGroups)
5532 std::vector<const DataArrayInt *> groups2;
5533 for(std::vector<const DataArrayInt *>::const_iterator it4=groups.begin();it4!=groups.end();it4++)
5535 groups2.push_back(*it4);
5536 MCAuto<DataArrayInt> ret=DataArrayInt::New();
5537 ret->alloc(newNb,1);
5538 int *retPtr=ret->getPointer();
5539 std::fill(retPtr,retPtr+newNb,0);
5541 for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++)
5543 const int *ptr=(*iter)->getConstPointer();
5544 std::size_t nbOfElem=(*iter)->getNbOfElems();
5546 for(int j=0;j<sfid;j++)
5549 for(std::size_t i=0;i<nbOfElem;i++)
5551 if(ptr[i]>=0 && ptr[i]<newNb)
5553 if(retPtr[ptr[i]]==j)
5561 std::ostringstream oss; oss << "DataArrayInt::MakePartition : In group \"" << (*iter)->getName() << "\" in tuple #" << i << " value = " << ptr[i] << " ! Should be in [0," << newNb;
5563 throw INTERP_KERNEL::Exception(oss.str().c_str());
5570 fidsOfGroups.clear();
5571 fidsOfGroups.resize(groups2.size());
5573 for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++,grId++)
5576 const int *ptr=(*iter)->getConstPointer();
5577 std::size_t nbOfElem=(*iter)->getNbOfElems();
5578 for(const int *p=ptr;p!=ptr+nbOfElem;p++)
5579 tmp.insert(retPtr[*p]);
5580 fidsOfGroups[grId].insert(fidsOfGroups[grId].end(),tmp.begin(),tmp.end());
5586 * Returns a new DataArrayInt which contains all elements of given one-dimensional
5587 * arrays. The result array does not contain any duplicates and its values
5588 * are sorted in ascending order.
5589 * \param [in] arr - sequence of DataArrayInt's to unite.
5590 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5591 * array using decrRef() as it is no more needed.
5592 * \throw If any \a arr[i] is not allocated.
5593 * \throw If \a arr[i]->getNumberOfComponents() != 1.
5595 DataArrayInt *DataArrayInt::BuildUnion(const std::vector<const DataArrayInt *>& arr)
5597 std::vector<const DataArrayInt *> a;
5598 for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
5601 for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
5603 (*it)->checkAllocated();
5604 if((*it)->getNumberOfComponents()!=1)
5605 throw INTERP_KERNEL::Exception("DataArrayInt::BuildUnion : only single component allowed !");
5609 for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
5611 const int *pt=(*it)->getConstPointer();
5612 int nbOfTuples=(*it)->getNumberOfTuples();
5613 r.insert(pt,pt+nbOfTuples);
5615 DataArrayInt *ret=DataArrayInt::New();
5616 ret->alloc((int)r.size(),1);
5617 std::copy(r.begin(),r.end(),ret->getPointer());
5622 * Returns a new DataArrayInt which contains elements present in each of given one-dimensional
5623 * arrays. The result array does not contain any duplicates and its values
5624 * are sorted in ascending order.
5625 * \param [in] arr - sequence of DataArrayInt's to intersect.
5626 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5627 * array using decrRef() as it is no more needed.
5628 * \throw If any \a arr[i] is not allocated.
5629 * \throw If \a arr[i]->getNumberOfComponents() != 1.
5631 DataArrayInt *DataArrayInt::BuildIntersection(const std::vector<const DataArrayInt *>& arr)
5633 std::vector<const DataArrayInt *> a;
5634 for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
5637 for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
5639 (*it)->checkAllocated();
5640 if((*it)->getNumberOfComponents()!=1)
5641 throw INTERP_KERNEL::Exception("DataArrayInt::BuildIntersection : only single component allowed !");
5645 for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
5647 const int *pt=(*it)->getConstPointer();
5648 int nbOfTuples=(*it)->getNumberOfTuples();
5649 std::set<int> s1(pt,pt+nbOfTuples);
5653 std::set_intersection(r.begin(),r.end(),s1.begin(),s1.end(),inserter(r2,r2.end()));
5659 DataArrayInt *ret(DataArrayInt::New());
5660 ret->alloc((int)r.size(),1);
5661 std::copy(r.begin(),r.end(),ret->getPointer());
5666 namespace MEDCouplingImpl
5671 OpSwitchedOn(int *pt):_pt(pt),_cnt(0) { }
5672 void operator()(const bool& b) { if(b) *_pt++=_cnt; _cnt++; }
5681 OpSwitchedOff(int *pt):_pt(pt),_cnt(0) { }
5682 void operator()(const bool& b) { if(!b) *_pt++=_cnt; _cnt++; }
5691 * This method returns the list of ids in ascending mode so that v[id]==true.
5693 DataArrayInt *DataArrayInt::BuildListOfSwitchedOn(const std::vector<bool>& v)
5695 int sz((int)std::count(v.begin(),v.end(),true));
5696 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
5697 std::for_each(v.begin(),v.end(),MEDCouplingImpl::OpSwitchedOn(ret->getPointer()));
5702 * This method returns the list of ids in ascending mode so that v[id]==false.
5704 DataArrayInt *DataArrayInt::BuildListOfSwitchedOff(const std::vector<bool>& v)
5706 int sz((int)std::count(v.begin(),v.end(),false));
5707 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
5708 std::for_each(v.begin(),v.end(),MEDCouplingImpl::OpSwitchedOff(ret->getPointer()));
5713 * This method allows to put a vector of vector of integer into a more compact data structure (skyline).
5714 * This method is not available into python because no available optimized data structure available to map std::vector< std::vector<int> >.
5716 * \param [in] v the input data structure to be translate into skyline format.
5717 * \param [out] data the first element of the skyline format. The user is expected to deal with newly allocated array.
5718 * \param [out] dataIndex the second element of the skyline format.
5720 void DataArrayInt::PutIntoToSkylineFrmt(const std::vector< std::vector<int> >& v, DataArrayInt *& data, DataArrayInt *& dataIndex)
5722 int sz((int)v.size());
5723 MCAuto<DataArrayInt> ret0(DataArrayInt::New()),ret1(DataArrayInt::New());
5724 ret1->alloc(sz+1,1);
5725 int *pt(ret1->getPointer()); *pt=0;
5726 for(int i=0;i<sz;i++,pt++)
5727 pt[1]=pt[0]+(int)v[i].size();
5728 ret0->alloc(ret1->back(),1);
5729 pt=ret0->getPointer();
5730 for(int i=0;i<sz;i++)
5731 pt=std::copy(v[i].begin(),v[i].end(),pt);
5732 data=ret0.retn(); dataIndex=ret1.retn();
5736 * Returns a new DataArrayInt which contains a complement of elements of \a this
5737 * one-dimensional array. I.e. the result array contains all elements from the range [0,
5738 * \a nbOfElement) not present in \a this array.
5739 * \param [in] nbOfElement - maximal size of the result array.
5740 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5741 * array using decrRef() as it is no more needed.
5742 * \throw If \a this is not allocated.
5743 * \throw If \a this->getNumberOfComponents() != 1.
5744 * \throw If any element \a x of \a this array violates condition ( 0 <= \a x < \a
5747 DataArrayInt *DataArrayInt::buildComplement(int nbOfElement) const
5750 if(getNumberOfComponents()!=1)
5751 throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : only single component allowed !");
5752 std::vector<bool> tmp(nbOfElement);
5753 const int *pt=getConstPointer();
5754 int nbOfTuples=getNumberOfTuples();
5755 for(const int *w=pt;w!=pt+nbOfTuples;w++)
5756 if(*w>=0 && *w<nbOfElement)
5759 throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : an element is not in valid range : [0,nbOfElement) !");
5760 int nbOfRetVal=(int)std::count(tmp.begin(),tmp.end(),false);
5761 DataArrayInt *ret=DataArrayInt::New();
5762 ret->alloc(nbOfRetVal,1);
5764 int *retPtr=ret->getPointer();
5765 for(int i=0;i<nbOfElement;i++)
5772 * Returns a new DataArrayInt containing elements of \a this one-dimensional missing
5773 * from an \a other one-dimensional array.
5774 * \param [in] other - a DataArrayInt containing elements not to include in the result array.
5775 * \return DataArrayInt * - a new instance of DataArrayInt with one component. The
5776 * caller is to delete this array using decrRef() as it is no more needed.
5777 * \throw If \a other is NULL.
5778 * \throw If \a other is not allocated.
5779 * \throw If \a other->getNumberOfComponents() != 1.
5780 * \throw If \a this is not allocated.
5781 * \throw If \a this->getNumberOfComponents() != 1.
5782 * \sa DataArrayInt::buildSubstractionOptimized()
5784 DataArrayInt *DataArrayInt::buildSubstraction(const DataArrayInt *other) const
5787 throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : DataArrayInt pointer in input is NULL !");
5789 other->checkAllocated();
5790 if(getNumberOfComponents()!=1)
5791 throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed !");
5792 if(other->getNumberOfComponents()!=1)
5793 throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed for other type !");
5794 const int *pt=getConstPointer();
5795 int nbOfTuples=getNumberOfTuples();
5796 std::set<int> s1(pt,pt+nbOfTuples);
5797 pt=other->getConstPointer();
5798 nbOfTuples=other->getNumberOfTuples();
5799 std::set<int> s2(pt,pt+nbOfTuples);
5801 std::set_difference(s1.begin(),s1.end(),s2.begin(),s2.end(),std::back_insert_iterator< std::vector<int> >(r));
5802 DataArrayInt *ret=DataArrayInt::New();
5803 ret->alloc((int)r.size(),1);
5804 std::copy(r.begin(),r.end(),ret->getPointer());
5809 * \a this is expected to have one component and to be sorted ascendingly (as for \a other).
5810 * \a other is expected to be a part of \a this. If not DataArrayInt::buildSubstraction should be called instead.
5812 * \param [in] other an array with one component and expected to be sorted ascendingly.
5813 * \ret list of ids in \a this but not in \a other.
5814 * \sa DataArrayInt::buildSubstraction
5816 DataArrayInt *DataArrayInt::buildSubstractionOptimized(const DataArrayInt *other) const
5818 static const char *MSG="DataArrayInt::buildSubstractionOptimized : only single component allowed !";
5819 if(!other) throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstractionOptimized : NULL input array !");
5820 checkAllocated(); other->checkAllocated();
5821 if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
5822 if(other->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
5823 const int *pt1Bg(begin()),*pt1End(end()),*pt2Bg(other->begin()),*pt2End(other->end());
5824 const int *work1(pt1Bg),*work2(pt2Bg);
5825 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
5826 for(;work1!=pt1End;work1++)
5828 if(work2!=pt2End && *work1==*work2)
5831 ret->pushBackSilent(*work1);
5838 * Returns a new DataArrayInt which contains all elements of \a this and a given
5839 * one-dimensional arrays. The result array does not contain any duplicates
5840 * and its values are sorted in ascending order.
5841 * \param [in] other - an array to unite with \a this one.
5842 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5843 * array using decrRef() as it is no more needed.
5844 * \throw If \a this or \a other is not allocated.
5845 * \throw If \a this->getNumberOfComponents() != 1.
5846 * \throw If \a other->getNumberOfComponents() != 1.
5848 DataArrayInt *DataArrayInt::buildUnion(const DataArrayInt *other) const
5850 std::vector<const DataArrayInt *>arrs(2);
5851 arrs[0]=this; arrs[1]=other;
5852 return BuildUnion(arrs);
5857 * Returns a new DataArrayInt which contains elements present in both \a this and a given
5858 * one-dimensional arrays. The result array does not contain any duplicates
5859 * and its values are sorted in ascending order.
5860 * \param [in] other - an array to intersect with \a this one.
5861 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5862 * array using decrRef() as it is no more needed.
5863 * \throw If \a this or \a other is not allocated.
5864 * \throw If \a this->getNumberOfComponents() != 1.
5865 * \throw If \a other->getNumberOfComponents() != 1.
5867 DataArrayInt *DataArrayInt::buildIntersection(const DataArrayInt *other) const
5869 std::vector<const DataArrayInt *>arrs(2);
5870 arrs[0]=this; arrs[1]=other;
5871 return BuildIntersection(arrs);
5875 * This method can be applied on allocated with one component DataArrayInt instance.
5876 * This method is typically relevant for sorted arrays. All consecutive duplicated items in \a this will appear only once in returned DataArrayInt instance.
5877 * 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]
5879 * \return a newly allocated array that contain the result of the unique operation applied on \a this.
5880 * \throw if \a this is not allocated or if \a this has not exactly one component.
5881 * \sa DataArrayInt::buildUniqueNotSorted
5883 DataArrayInt *DataArrayInt::buildUnique() const
5886 if(getNumberOfComponents()!=1)
5887 throw INTERP_KERNEL::Exception("DataArrayInt::buildUnique : only single component allowed !");
5888 int nbOfTuples=getNumberOfTuples();
5889 MCAuto<DataArrayInt> tmp=deepCopy();
5890 int *data=tmp->getPointer();
5891 int *last=std::unique(data,data+nbOfTuples);
5892 MCAuto<DataArrayInt> ret=DataArrayInt::New();
5893 ret->alloc(std::distance(data,last),1);
5894 std::copy(data,last,ret->getPointer());
5899 * This method can be applied on allocated with one component DataArrayInt instance.
5900 * This method keep elements only once by keeping the same order in \a this that is not expected to be sorted.
5902 * \return a newly allocated array that contain the result of the unique operation applied on \a this.
5904 * \throw if \a this is not allocated or if \a this has not exactly one component.
5906 * \sa DataArrayInt::buildUnique
5908 DataArrayInt *DataArrayInt::buildUniqueNotSorted() const
5911 if(getNumberOfComponents()!=1)
5912 throw INTERP_KERNEL::Exception("DataArrayInt::buildUniqueNotSorted : only single component allowed !");
5914 getMinMaxValues(minVal,maxVal);
5915 std::vector<bool> b(maxVal-minVal+1,false);
5916 const int *ptBg(begin()),*endBg(end());
5917 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
5918 for(const int *pt=ptBg;pt!=endBg;pt++)
5922 ret->pushBackSilent(*pt);
5926 ret->copyStringInfoFrom(*this);
5931 * Returns a new DataArrayInt which contains size of every of groups described by \a this
5932 * "index" array. Such "index" array is returned for example by
5933 * \ref MEDCoupling::MEDCouplingUMesh::buildDescendingConnectivity
5934 * "MEDCouplingUMesh::buildDescendingConnectivity" and
5935 * \ref MEDCoupling::MEDCouplingUMesh::getNodalConnectivityIndex
5936 * "MEDCouplingUMesh::getNodalConnectivityIndex" etc.
5937 * This method performs the reverse operation of DataArrayInt::computeOffsetsFull.
5938 * \return DataArrayInt * - a new instance of DataArrayInt, whose number of tuples
5939 * equals to \a this->getNumberOfComponents() - 1, and number of components is 1.
5940 * The caller is to delete this array using decrRef() as it is no more needed.
5941 * \throw If \a this is not allocated.
5942 * \throw If \a this->getNumberOfComponents() != 1.
5943 * \throw If \a this->getNumberOfTuples() < 2.
5946 * - this contains [1,3,6,7,7,9,15]
5947 * - result array contains [2,3,1,0,2,6],
5948 * where 2 = 3 - 1, 3 = 6 - 3, 1 = 7 - 6 etc.
5950 * \sa DataArrayInt::computeOffsetsFull
5952 DataArrayInt *DataArrayInt::deltaShiftIndex() const
5955 if(getNumberOfComponents()!=1)
5956 throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : only single component allowed !");
5957 int nbOfTuples=getNumberOfTuples();
5959 throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : 1 tuple at least must be present in 'this' !");
5960 const int *ptr=getConstPointer();
5961 DataArrayInt *ret=DataArrayInt::New();
5962 ret->alloc(nbOfTuples-1,1);
5963 int *out=ret->getPointer();
5964 std::transform(ptr+1,ptr+nbOfTuples,ptr,out,std::minus<int>());
5969 * Modifies \a this one-dimensional array so that value of each element \a x
5970 * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
5971 * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number of tuples
5972 * and components remains the same.<br>
5973 * This method is useful for allToAllV in MPI with contiguous policy. This method
5974 * differs from computeOffsetsFull() in that the number of tuples is \b not changed by
5976 * \throw If \a this is not allocated.
5977 * \throw If \a this->getNumberOfComponents() != 1.
5980 * - Before \a this contains [3,5,1,2,0,8]
5981 * - After \a this contains [0,3,8,9,11,11]<br>
5982 * Note that the last element 19 = 11 + 8 is missing because size of \a this
5983 * array is retained and thus there is no space to store the last element.
5985 void DataArrayInt::computeOffsets()
5988 if(getNumberOfComponents()!=1)
5989 throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets : only single component allowed !");
5990 int nbOfTuples=getNumberOfTuples();
5993 int *work=getPointer();
5996 for(int i=1;i<nbOfTuples;i++)
5999 work[i]=work[i-1]+tmp;
6007 * Modifies \a this one-dimensional array so that value of each element \a x
6008 * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
6009 * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number
6010 * components remains the same and number of tuples is inceamented by one.<br>
6011 * This method is useful for allToAllV in MPI with contiguous policy. This method
6012 * differs from computeOffsets() in that the number of tuples is changed by this one.
6013 * This method performs the reverse operation of DataArrayInt::deltaShiftIndex.
6014 * \throw If \a this is not allocated.
6015 * \throw If \a this->getNumberOfComponents() != 1.
6018 * - Before \a this contains [3,5,1,2,0,8]
6019 * - After \a this contains [0,3,8,9,11,11,19]<br>
6020 * \sa DataArrayInt::deltaShiftIndex
6022 void DataArrayInt::computeOffsetsFull()
6025 if(getNumberOfComponents()!=1)
6026 throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsetsFull : only single component allowed !");
6027 int nbOfTuples=getNumberOfTuples();
6028 int *ret=(int *)malloc((nbOfTuples+1)*sizeof(int));
6029 const int *work=getConstPointer();
6031 for(int i=0;i<nbOfTuples;i++)
6032 ret[i+1]=work[i]+ret[i];
6033 useArray(ret,true,C_DEALLOC,nbOfTuples+1,1);
6038 * Returns two new DataArrayInt instances whose contents is computed from that of \a this and \a listOfIds arrays as follows.
6039 * \a this is expected to be an offset format ( as returned by DataArrayInt::computeOffsetsFull ) that is to say with one component
6040 * and ** sorted strictly increasingly **. \a listOfIds is expected to be sorted ascendingly (not strictly needed for \a listOfIds).
6041 * This methods searches in \a this, considered as a set of contiguous \c this->getNumberOfComponents() ranges, all ids in \a listOfIds
6042 * filling completely one of the ranges in \a this.
6044 * \param [in] listOfIds a list of ids that has to be sorted ascendingly.
6045 * \param [out] rangeIdsFetched the range ids fetched
6046 * \param [out] idsInInputListThatFetch contains the list of ids in \a listOfIds that are \b fully included in a range in \a this. So
6047 * \a idsInInputListThatFetch is a part of input \a listOfIds.
6049 * \sa DataArrayInt::computeOffsetsFull
6052 * - \a this : [0,3,7,9,15,18]
6053 * - \a listOfIds contains [0,1,2,3,7,8,15,16,17]
6054 * - \a rangeIdsFetched result array: [0,2,4]
6055 * - \a idsInInputListThatFetch result array: [0,1,2,7,8,15,16,17]
6056 * In this example id 3 in input \a listOfIds is alone so it do not appear in output \a idsInInputListThatFetch.
6059 void DataArrayInt::findIdsRangesInListOfIds(const DataArrayInt *listOfIds, DataArrayInt *& rangeIdsFetched, DataArrayInt *& idsInInputListThatFetch) const
6062 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : input list of ids is null !");
6063 listOfIds->checkAllocated(); checkAllocated();
6064 if(listOfIds->getNumberOfComponents()!=1)
6065 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : input list of ids must have exactly one component !");
6066 if(getNumberOfComponents()!=1)
6067 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : this must have exactly one component !");
6068 MCAuto<DataArrayInt> ret0=DataArrayInt::New(); ret0->alloc(0,1);
6069 MCAuto<DataArrayInt> ret1=DataArrayInt::New(); ret1->alloc(0,1);
6070 const int *tupEnd(listOfIds->end()),*offBg(begin()),*offEnd(end()-1);
6071 const int *tupPtr(listOfIds->begin()),*offPtr(offBg);
6072 while(tupPtr!=tupEnd && offPtr!=offEnd)
6074 if(*tupPtr==*offPtr)
6077 while(i<offPtr[1] && *tupPtr==i && tupPtr!=tupEnd) { i++; tupPtr++; }
6080 ret0->pushBackSilent((int)std::distance(offBg,offPtr));
6081 ret1->pushBackValsSilent(tupPtr-(offPtr[1]-offPtr[0]),tupPtr);
6086 { if(*tupPtr<*offPtr) tupPtr++; else offPtr++; }
6088 rangeIdsFetched=ret0.retn();
6089 idsInInputListThatFetch=ret1.retn();
6093 * Returns a new DataArrayInt whose contents is computed from that of \a this and \a
6094 * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
6095 * "index" array of a "iota" array, thus, whose each element gives an index of a group
6096 * beginning within the "iota" array. And \a this is a one-dimensional array
6097 * considered as a selector of groups described by \a offsets to include into the result array.
6098 * \throw If \a offsets is NULL.
6099 * \throw If \a offsets is not allocated.
6100 * \throw If \a offsets->getNumberOfComponents() != 1.
6101 * \throw If \a offsets is not monotonically increasing.
6102 * \throw If \a this is not allocated.
6103 * \throw If \a this->getNumberOfComponents() != 1.
6104 * \throw If any element of \a this is not a valid index for \a offsets array.
6107 * - \a this: [0,2,3]
6108 * - \a offsets: [0,3,6,10,14,20]
6109 * - result array: [0,1,2,6,7,8,9,10,11,12,13] == <br>
6110 * \c range(0,3) + \c range(6,10) + \c range(10,14) ==<br>
6111 * \c range( \a offsets[ \a this[0] ], offsets[ \a this[0]+1 ]) +
6112 * \c range( \a offsets[ \a this[1] ], offsets[ \a this[1]+1 ]) +
6113 * \c range( \a offsets[ \a this[2] ], offsets[ \a this[2]+1 ])
6115 DataArrayInt *DataArrayInt::buildExplicitArrByRanges(const DataArrayInt *offsets) const
6118 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : DataArrayInt pointer in input is NULL !");
6120 if(getNumberOfComponents()!=1)
6121 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : only single component allowed !");
6122 offsets->checkAllocated();
6123 if(offsets->getNumberOfComponents()!=1)
6124 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : input array should have only single component !");
6125 int othNbTuples=offsets->getNumberOfTuples()-1;
6126 int nbOfTuples=getNumberOfTuples();
6127 int retNbOftuples=0;
6128 const int *work=getConstPointer();
6129 const int *offPtr=offsets->getConstPointer();
6130 for(int i=0;i<nbOfTuples;i++)
6133 if(val>=0 && val<othNbTuples)
6135 int delta=offPtr[val+1]-offPtr[val];
6137 retNbOftuples+=delta;
6140 std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << val << " of offset array has a delta < 0 !";
6141 throw INTERP_KERNEL::Exception(oss.str().c_str());
6146 std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << i << " in this contains " << val;
6147 oss << " whereas offsets array is of size " << othNbTuples+1 << " !";
6148 throw INTERP_KERNEL::Exception(oss.str().c_str());
6151 MCAuto<DataArrayInt> ret=DataArrayInt::New();
6152 ret->alloc(retNbOftuples,1);
6153 int *retPtr=ret->getPointer();
6154 for(int i=0;i<nbOfTuples;i++)
6157 int start=offPtr[val];
6158 int off=offPtr[val+1]-start;
6159 for(int j=0;j<off;j++,retPtr++)
6166 * Returns a new DataArrayInt whose contents is computed using \a this that must be a
6167 * scaled array (monotonically increasing).
6168 from that of \a this and \a
6169 * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
6170 * "index" array of a "iota" array, thus, whose each element gives an index of a group
6171 * beginning within the "iota" array. And \a this is a one-dimensional array
6172 * considered as a selector of groups described by \a offsets to include into the result array.
6173 * \throw If \a is NULL.
6174 * \throw If \a this is not allocated.
6175 * \throw If \a this->getNumberOfComponents() != 1.
6176 * \throw If \a this->getNumberOfTuples() == 0.
6177 * \throw If \a this is not monotonically increasing.
6178 * \throw If any element of ids in ( \a bg \a stop \a step ) points outside the scale in \a this.
6181 * - \a bg , \a stop and \a step : (0,5,2)
6182 * - \a this: [0,3,6,10,14,20]
6183 * - result array: [0,0,0, 2,2,2,2, 4,4,4,4,4,4] == <br>
6185 DataArrayInt *DataArrayInt::buildExplicitArrOfSliceOnScaledArr(int bg, int stop, int step) const
6188 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : not allocated array !");
6189 if(getNumberOfComponents()!=1)
6190 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of components is expected to be equal to one !");
6191 int nbOfTuples(getNumberOfTuples());
6193 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of tuples must be != 0 !");
6194 const int *ids(begin());
6195 int nbOfEltsInSlc(GetNumberOfItemGivenBESRelative(bg,stop,step,"DataArrayInt::buildExplicitArrOfSliceOnScaledArr")),sz(0),pos(bg);
6196 for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
6198 if(pos>=0 && pos<nbOfTuples-1)
6200 int delta(ids[pos+1]-ids[pos]);
6204 std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " and at this pos this is not monotonically increasing !";
6205 throw INTERP_KERNEL::Exception(oss.str().c_str());
6210 std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " should be in [0," << nbOfTuples-1 << ") !";
6211 throw INTERP_KERNEL::Exception(oss.str().c_str());
6214 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
6215 int *retPtr(ret->getPointer());
6217 for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
6219 int delta(ids[pos+1]-ids[pos]);
6220 for(int j=0;j<delta;j++,retPtr++)
6227 * 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.
6228 * 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
6229 * in tuple **i** of returned DataArrayInt.
6230 * If ranges overlapped (in theory it should not) this method do not detect it and always returns the first range.
6232 * 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)]
6233 * The return DataArrayInt will contain : **[0,4,1,2,2,3]**
6235 * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
6236 * for lower value included and 2nd component is the upper value of corresponding range **excluded**.
6237 * \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
6238 * is thrown if no ranges in \a ranges contains value in \a this.
6240 * \sa DataArrayInt::findIdInRangeForEachTuple
6242 DataArrayInt *DataArrayInt::findRangeIdForEachTuple(const DataArrayInt *ranges) const
6245 throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : null input pointer !");
6246 if(ranges->getNumberOfComponents()!=2)
6247 throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : input DataArrayInt instance should have 2 components !");
6249 if(getNumberOfComponents()!=1)
6250 throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : this should have only one component !");
6251 int nbTuples=getNumberOfTuples();
6252 MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
6253 int nbOfRanges=ranges->getNumberOfTuples();
6254 const int *rangesPtr=ranges->getConstPointer();
6255 int *retPtr=ret->getPointer();
6256 const int *inPtr=getConstPointer();
6257 for(int i=0;i<nbTuples;i++,retPtr++)
6261 for(int j=0;j<nbOfRanges && !found;j++)
6262 if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
6263 { *retPtr=j; found=true; }
6268 std::ostringstream oss; oss << "DataArrayInt::findRangeIdForEachTuple : tuple #" << i << " not found by any ranges !";
6269 throw INTERP_KERNEL::Exception(oss.str().c_str());
6276 * 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.
6277 * 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
6278 * in tuple **i** of returned DataArrayInt.
6279 * If ranges overlapped (in theory it should not) this method do not detect it and always returns the sub position of the first range.
6281 * 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)]
6282 * The return DataArrayInt will contain : **[1,2,4,0,2,2]**
6283 * This method is often called in pair with DataArrayInt::findRangeIdForEachTuple method.
6285 * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
6286 * for lower value included and 2nd component is the upper value of corresponding range **excluded**.
6287 * \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
6288 * is thrown if no ranges in \a ranges contains value in \a this.
6289 * \sa DataArrayInt::findRangeIdForEachTuple
6291 DataArrayInt *DataArrayInt::findIdInRangeForEachTuple(const DataArrayInt *ranges) const
6294 throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : null input pointer !");
6295 if(ranges->getNumberOfComponents()!=2)
6296 throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : input DataArrayInt instance should have 2 components !");
6298 if(getNumberOfComponents()!=1)
6299 throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : this should have only one component !");
6300 int nbTuples=getNumberOfTuples();
6301 MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
6302 int nbOfRanges=ranges->getNumberOfTuples();
6303 const int *rangesPtr=ranges->getConstPointer();
6304 int *retPtr=ret->getPointer();
6305 const int *inPtr=getConstPointer();
6306 for(int i=0;i<nbTuples;i++,retPtr++)
6310 for(int j=0;j<nbOfRanges && !found;j++)
6311 if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
6312 { *retPtr=val-rangesPtr[2*j]; found=true; }
6317 std::ostringstream oss; oss << "DataArrayInt::findIdInRangeForEachTuple : tuple #" << i << " not found by any ranges !";
6318 throw INTERP_KERNEL::Exception(oss.str().c_str());
6325 * \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).
6326 * 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).
6327 * 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 !
6328 * If this method has correctly worked, \a this will be able to be considered as a linked list.
6329 * This method does nothing if number of tuples is lower of equal to 1.
6331 * This method is useful for users having an unstructured mesh having only SEG2 to rearrange internally the connectibity without any coordinates consideration.
6333 * \sa MEDCouplingUMesh::orderConsecutiveCells1D, DataArrayInt::fromLinkedListOfPairToList
6335 void DataArrayInt::sortEachPairToMakeALinkedList()
6338 if(getNumberOfComponents()!=2)
6339 throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : Only works on DataArrayInt instance with nb of components equal to 2 !");
6340 int nbOfTuples(getNumberOfTuples());
6343 int *conn(getPointer());
6344 for(int i=1;i<nbOfTuples;i++,conn+=2)
6348 if(conn[2]==conn[3])
6350 std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " presence of a pair filled with same ids !";
6351 throw INTERP_KERNEL::Exception(oss.str().c_str());
6353 if(conn[2]!=conn[1] && conn[3]==conn[1] && conn[2]!=conn[0])
6354 std::swap(conn[2],conn[3]);
6355 //not(conn[2]==conn[1] && conn[3]!=conn[1] && conn[3]!=conn[0])
6356 if(conn[2]!=conn[1] || conn[3]==conn[1] || conn[3]==conn[0])
6358 std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " something is invalid !";
6359 throw INTERP_KERNEL::Exception(oss.str().c_str());
6364 if(conn[0]==conn[1] || conn[2]==conn[3])
6365 throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : In the 2 first tuples presence of a pair filled with same ids !");
6368 s.insert(conn,conn+4);
6370 throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : This can't be considered as a linked list regarding 2 first tuples !");
6371 if(std::count(conn,conn+4,conn[0])==2)
6376 if(conn[2]==conn[0])
6380 std::copy(tmp,tmp+4,conn);
6383 {//here we are sure to have (std::count(conn,conn+4,conn[1])==2)
6384 if(conn[1]==conn[3])
6385 std::swap(conn[2],conn[3]);
6392 * \a this is expected to be a correctly linked list of pairs.
6394 * \sa DataArrayInt::sortEachPairToMakeALinkedList
6396 MCAuto<DataArrayInt> DataArrayInt::fromLinkedListOfPairToList() const
6399 checkNbOfComps(2,"DataArrayInt::fromLinkedListOfPairToList : this is expected to have 2 components");
6400 int nbTuples(getNumberOfTuples());
6402 throw INTERP_KERNEL::Exception("DataArrayInt::fromLinkedListOfPairToList : no tuples in this ! Not a linked list !");
6403 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbTuples+1,1);
6404 const int *thisPtr(begin());
6405 int *retPtr(ret->getPointer());
6406 retPtr[0]=thisPtr[0];
6407 for(int i=0;i<nbTuples;i++)
6409 retPtr[i+1]=thisPtr[2*i+1];
6411 if(thisPtr[2*i+1]!=thisPtr[2*(i+1)+0])
6413 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 ?";
6414 throw INTERP_KERNEL::Exception(oss.str());
6421 * This method returns all different values found in \a this. This method throws if \a this has not been allocated.
6422 * But the number of components can be different from one.
6423 * \return a newly allocated array (that should be dealt by the caller) containing different values in \a this.
6425 DataArrayInt *DataArrayInt::getDifferentValues() const
6429 ret.insert(begin(),end());
6430 MCAuto<DataArrayInt> ret2=DataArrayInt::New(); ret2->alloc((int)ret.size(),1);
6431 std::copy(ret.begin(),ret.end(),ret2->getPointer());
6436 * This method is a refinement of DataArrayInt::getDifferentValues because it returns not only different values in \a this but also, for each of
6437 * them it tells which tuple id have this id.
6438 * This method works only on arrays with one component (if it is not the case call DataArrayInt::rearrange(1) ).
6439 * This method returns two arrays having same size.
6440 * 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.
6441 * 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]]
6443 std::vector<DataArrayInt *> DataArrayInt::partitionByDifferentValues(std::vector<int>& differentIds) const
6446 if(getNumberOfComponents()!=1)
6447 throw INTERP_KERNEL::Exception("DataArrayInt::partitionByDifferentValues : this should have only one component !");
6449 std::map<int,int> m,m2,m3;
6450 for(const int *w=begin();w!=end();w++)
6452 differentIds.resize(m.size());
6453 std::vector<DataArrayInt *> ret(m.size());
6454 std::vector<int *> retPtr(m.size());
6455 for(std::map<int,int>::const_iterator it=m.begin();it!=m.end();it++,id++)
6458 ret[id]=DataArrayInt::New();
6459 ret[id]->alloc((*it).second,1);
6460 retPtr[id]=ret[id]->getPointer();
6461 differentIds[id]=(*it).first;
6464 for(const int *w=begin();w!=end();w++,id++)
6466 retPtr[m2[*w]][m3[*w]++]=id;
6472 * This method split ids in [0, \c this->getNumberOfTuples() ) using \a this array as a field of weight (>=0 each).
6473 * The aim of this method is to return a set of \a nbOfSlices chunk of contiguous ids as balanced as possible.
6475 * \param [in] nbOfSlices - number of slices expected.
6476 * \return - a vector having a size equal to \a nbOfSlices giving the start (included) and the stop (excluded) of each chunks.
6478 * \sa DataArray::GetSlice
6479 * \throw If \a this is not allocated or not with exactly one component.
6480 * \throw If an element in \a this if < 0.
6482 std::vector< std::pair<int,int> > DataArrayInt::splitInBalancedSlices(int nbOfSlices) const
6484 if(!isAllocated() || getNumberOfComponents()!=1)
6485 throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : this array should have number of components equal to one and must be allocated !");
6487 throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : number of slices must be >= 1 !");
6488 int sum(accumulate(0)),nbOfTuples(getNumberOfTuples());
6489 int sumPerSlc(sum/nbOfSlices),pos(0);
6490 const int *w(begin());
6491 std::vector< std::pair<int,int> > ret(nbOfSlices);
6492 for(int i=0;i<nbOfSlices;i++)
6494 std::pair<int,int> p(pos,-1);
6496 while(locSum<sumPerSlc && pos<nbOfTuples) { pos++; locSum+=*w++; }
6500 p.second=nbOfTuples;
6507 * Returns a new DataArrayInt that is a modulus of two given arrays. There are 3
6509 * 1. The arrays have same number of tuples and components. Then each value of
6510 * the result array (_a_) is a division of the corresponding values of \a a1 and
6511 * \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, j ].
6512 * 2. The arrays have same number of tuples and one array, say _a2_, has one
6514 * _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, 0 ].
6515 * 3. The arrays have same number of components and one array, say _a2_, has one
6517 * _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ 0, j ].
6519 * Info on components is copied either from the first array (in the first case) or from
6520 * the array with maximal number of elements (getNbOfElems()).
6521 * \warning No check of division by zero is performed!
6522 * \param [in] a1 - a dividend array.
6523 * \param [in] a2 - a divisor array.
6524 * \return DataArrayInt * - the new instance of DataArrayInt.
6525 * The caller is to delete this result array using decrRef() as it is no more
6527 * \throw If either \a a1 or \a a2 is NULL.
6528 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
6529 * \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
6530 * none of them has number of tuples or components equal to 1.
6532 DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt *a2)
6535 throw INTERP_KERNEL::Exception("DataArrayInt::Modulus : input DataArrayInt instance is NULL !");
6536 int nbOfTuple1=a1->getNumberOfTuples();
6537 int nbOfTuple2=a2->getNumberOfTuples();
6538 int nbOfComp1=a1->getNumberOfComponents();
6539 int nbOfComp2=a2->getNumberOfComponents();
6540 if(nbOfTuple2==nbOfTuple1)
6542 if(nbOfComp1==nbOfComp2)
6544 MCAuto<DataArrayInt> ret=DataArrayInt::New();
6545 ret->alloc(nbOfTuple2,nbOfComp1);
6546 std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::modulus<int>());
6547 ret->copyStringInfoFrom(*a1);
6550 else if(nbOfComp2==1)
6552 MCAuto<DataArrayInt> ret=DataArrayInt::New();
6553 ret->alloc(nbOfTuple1,nbOfComp1);
6554 const int *a2Ptr=a2->getConstPointer();
6555 const int *a1Ptr=a1->getConstPointer();
6556 int *res=ret->getPointer();
6557 for(int i=0;i<nbOfTuple1;i++)
6558 res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::modulus<int>(),a2Ptr[i]));
6559 ret->copyStringInfoFrom(*a1);
6564 a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
6568 else if(nbOfTuple2==1)
6570 a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
6571 MCAuto<DataArrayInt> ret=DataArrayInt::New();
6572 ret->alloc(nbOfTuple1,nbOfComp1);
6573 const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
6574 int *pt=ret->getPointer();
6575 for(int i=0;i<nbOfTuple1;i++)
6576 pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::modulus<int>());
6577 ret->copyStringInfoFrom(*a1);
6582 a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Modulus !");//will always throw an exception
6588 * Modify \a this array so that each value becomes a modulus of division of this value by
6589 * a value of another DataArrayInt. There are 3 valid cases.
6590 * 1. The arrays have same number of tuples and components. Then each value of
6591 * \a this array is divided by the corresponding value of \a other one, i.e.:
6592 * _a_ [ i, j ] %= _other_ [ i, j ].
6593 * 2. The arrays have same number of tuples and \a other array has one component. Then
6594 * _a_ [ i, j ] %= _other_ [ i, 0 ].
6595 * 3. The arrays have same number of components and \a other array has one tuple. Then
6596 * _a_ [ i, j ] %= _a2_ [ 0, j ].
6598 * \warning No check of division by zero is performed!
6599 * \param [in] other - a divisor array.
6600 * \throw If \a other is NULL.
6601 * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
6602 * \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
6603 * \a other has number of both tuples and components not equal to 1.
6605 void DataArrayInt::modulusEqual(const DataArrayInt *other)
6608 throw INTERP_KERNEL::Exception("DataArrayInt::modulusEqual : input DataArrayInt instance is NULL !");
6609 const char *msg="Nb of tuples mismatch for DataArrayInt::modulusEqual !";
6610 checkAllocated(); other->checkAllocated();
6611 int nbOfTuple=getNumberOfTuples();
6612 int nbOfTuple2=other->getNumberOfTuples();
6613 int nbOfComp=getNumberOfComponents();
6614 int nbOfComp2=other->getNumberOfComponents();
6615 if(nbOfTuple==nbOfTuple2)
6617 if(nbOfComp==nbOfComp2)
6619 std::transform(begin(),end(),other->begin(),getPointer(),std::modulus<int>());
6621 else if(nbOfComp2==1)
6623 if(nbOfComp2==nbOfComp)
6625 int *ptr=getPointer();
6626 const int *ptrc=other->getConstPointer();
6627 for(int i=0;i<nbOfTuple;i++)
6628 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::modulus<int>(),*ptrc++));
6631 throw INTERP_KERNEL::Exception(msg);
6634 throw INTERP_KERNEL::Exception(msg);
6636 else if(nbOfTuple2==1)
6638 int *ptr=getPointer();
6639 const int *ptrc=other->getConstPointer();
6640 for(int i=0;i<nbOfTuple;i++)
6641 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::modulus<int>());
6644 throw INTERP_KERNEL::Exception(msg);
6649 * Returns a new DataArrayInt that is the result of pow of two given arrays. There are 3
6652 * \param [in] a1 - an array to pow up.
6653 * \param [in] a2 - another array to sum up.
6654 * \return DataArrayInt * - the new instance of DataArrayInt.
6655 * The caller is to delete this result array using decrRef() as it is no more
6657 * \throw If either \a a1 or \a a2 is NULL.
6658 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
6659 * \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
6660 * \throw If there is a negative value in \a a2.
6662 DataArrayInt *DataArrayInt::Pow(const DataArrayInt *a1, const DataArrayInt *a2)
6665 throw INTERP_KERNEL::Exception("DataArrayInt::Pow : at least one of input instances is null !");
6666 int nbOfTuple=a1->getNumberOfTuples();
6667 int nbOfTuple2=a2->getNumberOfTuples();
6668 int nbOfComp=a1->getNumberOfComponents();
6669 int nbOfComp2=a2->getNumberOfComponents();
6670 if(nbOfTuple!=nbOfTuple2)
6671 throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of tuples mismatches !");
6672 if(nbOfComp!=1 || nbOfComp2!=1)
6673 throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of components of both arrays must be equal to 1 !");
6674 MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuple,1);
6675 const int *ptr1(a1->begin()),*ptr2(a2->begin());
6676 int *ptr=ret->getPointer();
6677 for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
6682 for(int j=0;j<*ptr2;j++)
6688 std::ostringstream oss; oss << "DataArrayInt::Pow : on tuple #" << i << " of a2 value is < 0 (" << *ptr2 << ") !";
6689 throw INTERP_KERNEL::Exception(oss.str().c_str());
6696 * Apply pow on values of another DataArrayInt to values of \a this one.
6698 * \param [in] other - an array to pow to \a this one.
6699 * \throw If \a other is NULL.
6700 * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
6701 * \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
6702 * \throw If there is a negative value in \a other.
6704 void DataArrayInt::powEqual(const DataArrayInt *other)
6707 throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : input instance is null !");
6708 int nbOfTuple=getNumberOfTuples();
6709 int nbOfTuple2=other->getNumberOfTuples();
6710 int nbOfComp=getNumberOfComponents();
6711 int nbOfComp2=other->getNumberOfComponents();
6712 if(nbOfTuple!=nbOfTuple2)
6713 throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of tuples mismatches !");
6714 if(nbOfComp!=1 || nbOfComp2!=1)
6715 throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of components of both arrays must be equal to 1 !");
6716 int *ptr=getPointer();
6717 const int *ptrc=other->begin();
6718 for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
6723 for(int j=0;j<*ptrc;j++)
6729 std::ostringstream oss; oss << "DataArrayInt::powEqual : on tuple #" << i << " of other value is < 0 (" << *ptrc << ") !";
6730 throw INTERP_KERNEL::Exception(oss.str().c_str());
6737 * Returns a C array which is a renumbering map in "Old to New" mode for the input array.
6738 * This map, if applied to \a start array, would make it sorted. For example, if
6739 * \a start array contents are [9,10,0,6,4,11,3,7] then the contents of the result array is
6740 * [5,6,0,3,2,7,1,4].
6741 * \param [in] start - pointer to the first element of the array for which the
6742 * permutation map is computed.
6743 * \param [in] end - pointer specifying the end of the array \a start, so that
6744 * the last value of \a start is \a end[ -1 ].
6745 * \return int * - the result permutation array that the caller is to delete as it is no
6747 * \throw If there are equal values in the input array.
6749 int *DataArrayInt::CheckAndPreparePermutation(const int *start, const int *end)
6751 std::size_t sz=std::distance(start,end);
6752 int *ret=(int *)malloc(sz*sizeof(int));
6753 int *work=new int[sz];
6754 std::copy(start,end,work);
6755 std::sort(work,work+sz);
6756 if(std::unique(work,work+sz)!=work+sz)
6760 throw INTERP_KERNEL::Exception("Some elements are equals in the specified array !");
6762 std::map<int,int> m;
6763 for(int *workPt=work;workPt!=work+sz;workPt++)
6764 m[*workPt]=(int)std::distance(work,workPt);
6766 for(const int *iter=start;iter!=end;iter++,iter2++)
6773 * Returns a new DataArrayInt containing an arithmetic progression
6774 * that is equal to the sequence returned by Python \c range(\a begin,\a end,\a step )
6776 * \param [in] begin - the start value of the result sequence.
6777 * \param [in] end - limiting value, so that every value of the result array is less than
6779 * \param [in] step - specifies the increment or decrement.
6780 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6781 * array using decrRef() as it is no more needed.
6782 * \throw If \a step == 0.
6783 * \throw If \a end < \a begin && \a step > 0.
6784 * \throw If \a end > \a begin && \a step < 0.
6786 DataArrayInt *DataArrayInt::Range(int begin, int end, int step)
6788 int nbOfTuples=GetNumberOfItemGivenBESRelative(begin,end,step,"DataArrayInt::Range");
6789 MCAuto<DataArrayInt> ret=DataArrayInt::New();
6790 ret->alloc(nbOfTuples,1);
6791 int *ptr=ret->getPointer();
6794 for(int i=begin;i<end;i+=step,ptr++)
6799 for(int i=begin;i>end;i+=step,ptr++)
6806 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
6809 void DataArrayInt::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
6814 tinyInfo[0]=getNumberOfTuples();
6815 tinyInfo[1]=getNumberOfComponents();
6825 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
6828 void DataArrayInt::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
6832 int nbOfCompo=getNumberOfComponents();
6833 tinyInfo.resize(nbOfCompo+1);
6834 tinyInfo[0]=getName();
6835 for(int i=0;i<nbOfCompo;i++)
6836 tinyInfo[i+1]=getInfoOnComponent(i);
6841 tinyInfo[0]=getName();
6846 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
6847 * This method returns if a feeding is needed.
6849 bool DataArrayInt::resizeForUnserialization(const std::vector<int>& tinyInfoI)
6851 int nbOfTuple=tinyInfoI[0];
6852 int nbOfComp=tinyInfoI[1];
6853 if(nbOfTuple!=-1 || nbOfComp!=-1)
6855 alloc(nbOfTuple,nbOfComp);
6862 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
6863 * This method returns if a feeding is needed.
6865 void DataArrayInt::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
6867 setName(tinyInfoS[0]);
6870 int nbOfCompo=tinyInfoI[1];
6871 for(int i=0;i<nbOfCompo;i++)
6872 setInfoOnComponent(i,tinyInfoS[i+1]);
6876 DataArrayIntIterator::DataArrayIntIterator(DataArrayInt *da):DataArrayIterator<int>(da)
6880 DataArrayInt32Tuple::DataArrayInt32Tuple(int *pt, int nbOfComp):DataArrayTuple<int>(pt,nbOfComp)
6884 std::string DataArrayIntTuple::repr() const
6886 std::ostringstream oss; oss << "(";
6887 for(int i=0;i<_nb_of_compo-1;i++)
6888 oss << _pt[i] << ", ";
6889 oss << _pt[_nb_of_compo-1] << ")";
6893 int DataArrayIntTuple::intValue() const
6895 return this->zeValue();
6899 * This method returns a newly allocated instance the caller should dealed with by a MEDCoupling::DataArrayInt::decrRef.
6900 * This method performs \b no copy of data. The content is only referenced using MEDCoupling::DataArrayInt::useArray with ownership set to \b false.
6901 * 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
6902 * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
6904 DataArrayInt *DataArrayIntTuple::buildDAInt(int nbOfTuples, int nbOfCompo) const
6906 return this->buildDA(nbOfTuples,nbOfCompo);