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>;
56 template class MEDCoupling::DataArrayTuple<int>;
57 template class MEDCoupling::DataArrayTuple<double>;
58 template class MEDCoupling::DataArrayTuple<float>;
60 template<int SPACEDIM>
61 void DataArrayDouble::findCommonTuplesAlg(const double *bbox, int nbNodes, int limitNodeId, double prec, DataArrayInt *c, DataArrayInt *cI) const
63 const double *coordsPtr=getConstPointer();
64 BBTreePts<SPACEDIM,int> myTree(bbox,0,0,nbNodes,prec);
65 std::vector<bool> isDone(nbNodes);
66 for(int i=0;i<nbNodes;i++)
70 std::vector<int> intersectingElems;
71 myTree.getElementsAroundPoint(coordsPtr+i*SPACEDIM,intersectingElems);
72 if(intersectingElems.size()>1)
74 std::vector<int> commonNodes;
75 for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
79 commonNodes.push_back(*it);
82 if(!commonNodes.empty())
84 cI->pushBackSilent(cI->back()+(int)commonNodes.size()+1);
86 c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
93 template<int SPACEDIM>
94 void DataArrayDouble::FindTupleIdsNearTuplesAlg(const BBTreePts<SPACEDIM,int>& myTree, const double *pos, int nbOfTuples, double eps,
95 DataArrayInt *c, DataArrayInt *cI)
97 for(int i=0;i<nbOfTuples;i++)
99 std::vector<int> intersectingElems;
100 myTree.getElementsAroundPoint(pos+i*SPACEDIM,intersectingElems);
101 std::vector<int> commonNodes;
102 for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
103 commonNodes.push_back(*it);
104 cI->pushBackSilent(cI->back()+(int)commonNodes.size());
105 c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
109 template<int SPACEDIM>
110 void DataArrayDouble::FindClosestTupleIdAlg(const BBTreePts<SPACEDIM,int>& myTree, double dist, const double *pos, int nbOfTuples, const double *thisPt, int thisNbOfTuples, int *res)
112 double distOpt(dist);
113 const double *p(pos);
115 for(int i=0;i<nbOfTuples;i++,p+=SPACEDIM,r++)
120 double ret=myTree.getElementsAroundPoint2(p,distOpt,elem);
121 if(ret!=std::numeric_limits<double>::max())
123 distOpt=std::max(ret,1e-4);
128 { distOpt=2*distOpt; continue; }
133 int DataArray::EffectiveCircPerm(int nbOfShift, int nbOfTuples)
136 throw INTERP_KERNEL::Exception("DataArray::EffectiveCircPerm : number of tuples is expected to be > 0 !");
139 return nbOfShift%nbOfTuples;
145 return nbOfTuples-tmp;
149 std::size_t DataArray::getHeapMemorySizeWithoutChildren() const
151 std::size_t sz1=_name.capacity();
152 std::size_t sz2=_info_on_compo.capacity();
154 for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
155 sz3+=(*it).capacity();
159 std::vector<const BigMemoryObject *> DataArray::getDirectChildrenWithNull() const
161 return std::vector<const BigMemoryObject *>();
165 * Sets the attribute \a _name of \a this array.
166 * See \ref MEDCouplingArrayBasicsName "DataArrays infos" for more information.
167 * \param [in] name - new array name
169 void DataArray::setName(const std::string& name)
175 * Copies textual data from an \a other DataArray. The copied data are
176 * - the name attribute,
177 * - the information of components.
179 * For more information on these data see \ref MEDCouplingArrayBasicsName "DataArrays infos".
181 * \param [in] other - another instance of DataArray to copy the textual data from.
182 * \throw If number of components of \a this array differs from that of the \a other.
184 void DataArray::copyStringInfoFrom(const DataArray& other)
186 if(_info_on_compo.size()!=other._info_on_compo.size())
187 throw INTERP_KERNEL::Exception("Size of arrays mismatches on copyStringInfoFrom !");
189 _info_on_compo=other._info_on_compo;
192 void DataArray::copyPartOfStringInfoFrom(const DataArray& other, const std::vector<int>& compoIds)
194 int nbOfCompoOth=other.getNumberOfComponents();
195 std::size_t newNbOfCompo=compoIds.size();
196 for(std::size_t i=0;i<newNbOfCompo;i++)
197 if(compoIds[i]>=nbOfCompoOth || compoIds[i]<0)
199 std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompoOth << ")";
200 throw INTERP_KERNEL::Exception(oss.str().c_str());
202 for(std::size_t i=0;i<newNbOfCompo;i++)
203 setInfoOnComponent((int)i,other.getInfoOnComponent(compoIds[i]));
206 void DataArray::copyPartOfStringInfoFrom2(const std::vector<int>& compoIds, const DataArray& other)
208 std::size_t nbOfCompo(getNumberOfComponents());
209 std::size_t partOfCompoToSet=compoIds.size();
210 if(partOfCompoToSet!=other.getNumberOfComponents())
211 throw INTERP_KERNEL::Exception("Given compoIds has not the same size as number of components of given array !");
212 for(std::size_t i=0;i<partOfCompoToSet;i++)
213 if(compoIds[i]>=(int)nbOfCompo || compoIds[i]<0)
215 std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompo << ")";
216 throw INTERP_KERNEL::Exception(oss.str().c_str());
218 for(std::size_t i=0;i<partOfCompoToSet;i++)
219 setInfoOnComponent(compoIds[i],other.getInfoOnComponent((int)i));
222 bool DataArray::areInfoEqualsIfNotWhy(const DataArray& other, std::string& reason) const
224 std::ostringstream oss;
225 if(_name!=other._name)
227 oss << "Names DataArray mismatch : this name=\"" << _name << " other name=\"" << other._name << "\" !";
231 if(_info_on_compo!=other._info_on_compo)
233 oss << "Components DataArray mismatch : \nThis components=";
234 for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
235 oss << "\"" << *it << "\",";
236 oss << "\nOther components=";
237 for(std::vector<std::string>::const_iterator it=other._info_on_compo.begin();it!=other._info_on_compo.end();it++)
238 oss << "\"" << *it << "\",";
246 * Compares textual information of \a this DataArray with that of an \a other one.
247 * The compared data are
248 * - the name attribute,
249 * - the information of components.
251 * For more information on these data see \ref MEDCouplingArrayBasicsName "DataArrays infos".
252 * \param [in] other - another instance of DataArray to compare the textual data of.
253 * \return bool - \a true if the textual information is same, \a false else.
255 bool DataArray::areInfoEquals(const DataArray& other) const
258 return areInfoEqualsIfNotWhy(other,tmp);
261 void DataArray::reprWithoutNameStream(std::ostream& stream) const
263 stream << "Number of components : "<< getNumberOfComponents() << "\n";
264 stream << "Info of these components : ";
265 for(std::vector<std::string>::const_iterator iter=_info_on_compo.begin();iter!=_info_on_compo.end();iter++)
266 stream << "\"" << *iter << "\" ";
270 std::string DataArray::cppRepr(const std::string& varName) const
272 std::ostringstream ret;
273 reprCppStream(varName,ret);
278 * Sets information on all components. To know more on format of this information
279 * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
280 * \param [in] info - a vector of strings.
281 * \throw If size of \a info differs from the number of components of \a this.
283 void DataArray::setInfoOnComponents(const std::vector<std::string>& info)
285 if(getNumberOfComponents()!=info.size())
287 std::ostringstream oss; oss << "DataArray::setInfoOnComponents : input is of size " << info.size() << " whereas number of components is equal to " << getNumberOfComponents() << " !";
288 throw INTERP_KERNEL::Exception(oss.str().c_str());
294 * This method is only a dispatcher towards DataArrayDouble::setPartOfValues3, DataArrayInt::setPartOfValues3, DataArrayChar::setPartOfValues3 depending on the true
295 * type of \a this and \a aBase.
297 * \throw If \a aBase and \a this do not have the same type.
299 * \sa DataArrayDouble::setPartOfValues3, DataArrayInt::setPartOfValues3, DataArrayChar::setPartOfValues3.
301 void DataArray::setPartOfValuesBase3(const DataArray *aBase, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
304 throw INTERP_KERNEL::Exception("DataArray::setPartOfValuesBase3 : input aBase object is NULL !");
305 DataArrayDouble *this1(dynamic_cast<DataArrayDouble *>(this));
306 DataArrayInt *this2(dynamic_cast<DataArrayInt *>(this));
307 DataArrayChar *this3(dynamic_cast<DataArrayChar *>(this));
308 const DataArrayDouble *a1(dynamic_cast<const DataArrayDouble *>(aBase));
309 const DataArrayInt *a2(dynamic_cast<const DataArrayInt *>(aBase));
310 const DataArrayChar *a3(dynamic_cast<const DataArrayChar *>(aBase));
313 this1->setPartOfValues3(a1,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
318 this2->setPartOfValues3(a2,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
323 this3->setPartOfValues3(a3,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
326 throw INTERP_KERNEL::Exception("DataArray::setPartOfValuesBase3 : input aBase object and this do not have the same type !");
329 std::vector<std::string> DataArray::getVarsOnComponent() const
331 int nbOfCompo=(int)_info_on_compo.size();
332 std::vector<std::string> ret(nbOfCompo);
333 for(int i=0;i<nbOfCompo;i++)
334 ret[i]=getVarOnComponent(i);
338 std::vector<std::string> DataArray::getUnitsOnComponent() const
340 int nbOfCompo=(int)_info_on_compo.size();
341 std::vector<std::string> ret(nbOfCompo);
342 for(int i=0;i<nbOfCompo;i++)
343 ret[i]=getUnitOnComponent(i);
348 * Returns information on a component specified by an index.
349 * To know more on format of this information
350 * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
351 * \param [in] i - the index (zero based) of the component of interest.
352 * \return std::string - a string containing the information on \a i-th component.
353 * \throw If \a i is not a valid component index.
355 std::string DataArray::getInfoOnComponent(int i) const
357 if(i<(int)_info_on_compo.size() && i>=0)
358 return _info_on_compo[i];
361 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();
362 throw INTERP_KERNEL::Exception(oss.str().c_str());
367 * Returns the var part of the full information of the \a i-th component.
368 * For example, if \c getInfoOnComponent(0) returns "SIGXY [N/m^2]", then
369 * \c getVarOnComponent(0) returns "SIGXY".
370 * If a unit part of information is not detected by presence of
371 * two square brackets, then the full information is returned.
372 * To read more about the component information format, see
373 * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
374 * \param [in] i - the index (zero based) of the component of interest.
375 * \return std::string - a string containing the var information, or the full info.
376 * \throw If \a i is not a valid component index.
378 std::string DataArray::getVarOnComponent(int i) const
380 if(i<(int)_info_on_compo.size() && i>=0)
382 return GetVarNameFromInfo(_info_on_compo[i]);
386 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();
387 throw INTERP_KERNEL::Exception(oss.str().c_str());
392 * Returns the unit part of the full information of the \a i-th component.
393 * For example, if \c getInfoOnComponent(0) returns "SIGXY [ N/m^2]", then
394 * \c getUnitOnComponent(0) returns " N/m^2".
395 * If a unit part of information is not detected by presence of
396 * two square brackets, then an empty string is returned.
397 * To read more about the component information format, see
398 * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
399 * \param [in] i - the index (zero based) of the component of interest.
400 * \return std::string - a string containing the unit information, if any, or "".
401 * \throw If \a i is not a valid component index.
403 std::string DataArray::getUnitOnComponent(int i) const
405 if(i<(int)_info_on_compo.size() && i>=0)
407 return GetUnitFromInfo(_info_on_compo[i]);
411 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();
412 throw INTERP_KERNEL::Exception(oss.str().c_str());
417 * Returns the var part of the full component information.
418 * For example, if \a info == "SIGXY [N/m^2]", then this method returns "SIGXY".
419 * If a unit part of information is not detected by presence of
420 * two square brackets, then the whole \a info is returned.
421 * To read more about the component information format, see
422 * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
423 * \param [in] info - the full component information.
424 * \return std::string - a string containing only var information, or the \a info.
426 std::string DataArray::GetVarNameFromInfo(const std::string& info)
428 std::size_t p1=info.find_last_of('[');
429 std::size_t p2=info.find_last_of(']');
430 if(p1==std::string::npos || p2==std::string::npos)
435 return std::string();
436 std::size_t p3=info.find_last_not_of(' ',p1-1);
437 return info.substr(0,p3+1);
441 * Returns the unit part of the full component information.
442 * For example, if \a info == "SIGXY [ N/m^2]", then this method returns " N/m^2".
443 * If a unit part of information is not detected by presence of
444 * two square brackets, then an empty string is returned.
445 * To read more about the component information format, see
446 * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
447 * \param [in] info - the full component information.
448 * \return std::string - a string containing only unit information, if any, or "".
450 std::string DataArray::GetUnitFromInfo(const std::string& info)
452 std::size_t p1=info.find_last_of('[');
453 std::size_t p2=info.find_last_of(']');
454 if(p1==std::string::npos || p2==std::string::npos)
455 return std::string();
457 return std::string();
458 return info.substr(p1+1,p2-p1-1);
462 * This method put in info format the result of the merge of \a var and \a unit.
463 * The standard format for that is "var [unit]".
464 * Inversely you can retrieve the var part or the unit part of info string using resp. GetVarNameFromInfo and GetUnitFromInfo.
466 std::string DataArray::BuildInfoFromVarAndUnit(const std::string& var, const std::string& unit)
468 std::ostringstream oss;
469 oss << var << " [" << unit << "]";
473 std::string DataArray::GetAxisTypeRepr(MEDCouplingAxisType at)
478 return std::string("AX_CART");
480 return std::string("AX_CYL");
482 return std::string("AX_SPHER");
484 throw INTERP_KERNEL::Exception("DataArray::GetAxisTypeRepr : unrecognized axis type enum !");
489 * Returns a new DataArray by concatenating all given arrays, so that (1) the number
490 * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
491 * the number of component in the result array is same as that of each of given arrays.
492 * Info on components is copied from the first of the given arrays. Number of components
493 * in the given arrays must be the same.
494 * \param [in] arrs - a sequence of arrays to include in the result array. All arrays must have the same type.
495 * \return DataArray * - the new instance of DataArray (that can be either DataArrayInt, DataArrayDouble, DataArrayChar).
496 * The caller is to delete this result array using decrRef() as it is no more
498 * \throw If all arrays within \a arrs are NULL.
499 * \throw If all not null arrays in \a arrs have not the same type.
500 * \throw If getNumberOfComponents() of arrays within \a arrs.
502 DataArray *DataArray::Aggregate(const std::vector<const DataArray *>& arrs)
504 std::vector<const DataArray *> arr2;
505 for(std::vector<const DataArray *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
509 throw INTERP_KERNEL::Exception("DataArray::Aggregate : only null instance in input vector !");
510 std::vector<const DataArrayDouble *> arrd;
511 std::vector<const DataArrayInt *> arri;
512 std::vector<const DataArrayChar *> arrc;
513 for(std::vector<const DataArray *>::const_iterator it=arr2.begin();it!=arr2.end();it++)
515 const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(*it);
517 { arrd.push_back(a); continue; }
518 const DataArrayInt *b=dynamic_cast<const DataArrayInt *>(*it);
520 { arri.push_back(b); continue; }
521 const DataArrayChar *c=dynamic_cast<const DataArrayChar *>(*it);
523 { arrc.push_back(c); continue; }
524 throw INTERP_KERNEL::Exception("DataArray::Aggregate : presence of not null instance in inuput that is not in [DataArrayDouble, DataArrayInt, DataArrayChar] !");
526 if(arr2.size()==arrd.size())
527 return DataArrayDouble::Aggregate(arrd);
528 if(arr2.size()==arri.size())
529 return DataArrayInt::Aggregate(arri);
530 if(arr2.size()==arrc.size())
531 return DataArrayChar::Aggregate(arrc);
532 throw INTERP_KERNEL::Exception("DataArray::Aggregate : all input arrays must have the same type !");
536 * Sets information on a component specified by an index.
537 * To know more on format of this information
538 * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
539 * \warning Don't pass NULL as \a info!
540 * \param [in] i - the index (zero based) of the component of interest.
541 * \param [in] info - the string containing the information.
542 * \throw If \a i is not a valid component index.
544 void DataArray::setInfoOnComponent(int i, const std::string& info)
546 if(i<(int)_info_on_compo.size() && i>=0)
547 _info_on_compo[i]=info;
550 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();
551 throw INTERP_KERNEL::Exception(oss.str().c_str());
556 * Sets information on all components. This method can change number of components
557 * at certain conditions; if the conditions are not respected, an exception is thrown.
558 * The number of components can be changed in \a this only if \a this is not allocated.
559 * The condition of number of components must not be changed.
561 * To know more on format of the component information see
562 * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
563 * \param [in] info - a vector of component infos.
564 * \throw If \a this->getNumberOfComponents() != \a info.size() && \a this->isAllocated()
566 void DataArray::setInfoAndChangeNbOfCompo(const std::vector<std::string>& info)
568 if(getNumberOfComponents()!=info.size())
574 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 !";
575 throw INTERP_KERNEL::Exception(oss.str().c_str());
582 void DataArray::checkNbOfTuples(int nbOfTuples, const std::string& msg) const
584 if((int)getNumberOfTuples()!=nbOfTuples)
586 std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " << nbOfTuples << " having " << getNumberOfTuples() << " !";
587 throw INTERP_KERNEL::Exception(oss.str().c_str());
591 void DataArray::checkNbOfComps(int nbOfCompo, const std::string& msg) const
593 if((int)getNumberOfComponents()!=nbOfCompo)
595 std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << nbOfCompo << " having " << getNumberOfComponents() << " !";
596 throw INTERP_KERNEL::Exception(oss.str().c_str());
600 void DataArray::checkNbOfElems(std::size_t nbOfElems, const std::string& msg) const
602 if(getNbOfElems()!=nbOfElems)
604 std::ostringstream oss; oss << msg << " : mismatch number of elems : Expected " << nbOfElems << " having " << getNbOfElems() << " !";
605 throw INTERP_KERNEL::Exception(oss.str().c_str());
609 void DataArray::checkNbOfTuplesAndComp(const DataArray& other, const std::string& msg) const
611 if(getNumberOfTuples()!=other.getNumberOfTuples())
613 std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " << other.getNumberOfTuples() << " having " << getNumberOfTuples() << " !";
614 throw INTERP_KERNEL::Exception(oss.str().c_str());
616 if(getNumberOfComponents()!=other.getNumberOfComponents())
618 std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << other.getNumberOfComponents() << " having " << getNumberOfComponents() << " !";
619 throw INTERP_KERNEL::Exception(oss.str().c_str());
623 void DataArray::checkNbOfTuplesAndComp(int nbOfTuples, int nbOfCompo, const std::string& msg) const
625 checkNbOfTuples(nbOfTuples,msg);
626 checkNbOfComps(nbOfCompo,msg);
630 * Simply this method checks that \b value is in [0,\b ref).
632 void DataArray::CheckValueInRange(int ref, int value, const std::string& msg)
634 if(value<0 || value>=ref)
636 std::ostringstream oss; oss << "DataArray::CheckValueInRange : " << msg << " ! Expected in range [0," << ref << "[ having " << value << " !";
637 throw INTERP_KERNEL::Exception(oss.str().c_str());
642 * This method checks that [\b start, \b end) is compliant with ref length \b value.
643 * typically start in [0,\b value) and end in [0,\b value). If value==start and start==end, it is supported.
645 void DataArray::CheckValueInRangeEx(int value, int start, int end, const std::string& msg)
647 if(start<0 || start>=value)
649 if(value!=start || end!=start)
651 std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg << " ! Expected start " << start << " of input range, in [0," << value << "[ !";
652 throw INTERP_KERNEL::Exception(oss.str().c_str());
655 if(end<0 || end>value)
657 std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg << " ! Expected end " << end << " of input range, in [0," << value << "] !";
658 throw INTERP_KERNEL::Exception(oss.str().c_str());
662 void DataArray::CheckClosingParInRange(int ref, int value, const std::string& msg)
664 if(value<0 || value>ref)
666 std::ostringstream oss; oss << "DataArray::CheckClosingParInRange : " << msg << " ! Expected input range in [0," << ref << "] having closing open parenthesis " << value << " !";
667 throw INTERP_KERNEL::Exception(oss.str().c_str());
672 * 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,
673 * typically it is a whole slice of tuples of DataArray or cells, nodes of a mesh...
675 * The input \a sliceId should be an id in [0, \a nbOfSlices) that specifies the slice of work.
677 * \param [in] start - the start of the input slice of the whole work to perform split into slices.
678 * \param [in] stop - the stop of the input slice of the whole work to perform split into slices.
679 * \param [in] step - the step (that can be <0) of the input slice of the whole work to perform split into slices.
680 * \param [in] sliceId - the slice id considered
681 * \param [in] nbOfSlices - the number of slices (typically the number of cores on which the work is expected to be sliced)
682 * \param [out] startSlice - the start of the slice considered
683 * \param [out] stopSlice - the stop of the slice consided
685 * \throw If \a step == 0
686 * \throw If \a nbOfSlices not > 0
687 * \throw If \a sliceId not in [0,nbOfSlices)
689 void DataArray::GetSlice(int start, int stop, int step, int sliceId, int nbOfSlices, int& startSlice, int& stopSlice)
693 std::ostringstream oss; oss << "DataArray::GetSlice : nbOfSlices (" << nbOfSlices << ") must be > 0 !";
694 throw INTERP_KERNEL::Exception(oss.str().c_str());
696 if(sliceId<0 || sliceId>=nbOfSlices)
698 std::ostringstream oss; oss << "DataArray::GetSlice : sliceId (" << nbOfSlices << ") must be in [0 , nbOfSlices (" << nbOfSlices << ") ) !";
699 throw INTERP_KERNEL::Exception(oss.str().c_str());
701 int nbElems=GetNumberOfItemGivenBESRelative(start,stop,step,"DataArray::GetSlice");
702 int minNbOfElemsPerSlice=nbElems/nbOfSlices;
703 startSlice=start+minNbOfElemsPerSlice*step*sliceId;
704 if(sliceId<nbOfSlices-1)
705 stopSlice=start+minNbOfElemsPerSlice*step*(sliceId+1);
710 int DataArray::GetNumberOfItemGivenBES(int begin, int end, int step, const std::string& msg)
714 std::ostringstream oss; oss << msg << " : end before begin !";
715 throw INTERP_KERNEL::Exception(oss.str().c_str());
721 std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
722 throw INTERP_KERNEL::Exception(oss.str().c_str());
724 return (end-1-begin)/step+1;
727 int DataArray::GetNumberOfItemGivenBESRelative(int begin, int end, int step, const std::string& msg)
730 throw INTERP_KERNEL::Exception("DataArray::GetNumberOfItemGivenBES : step=0 is not allowed !");
731 if(end<begin && step>0)
733 std::ostringstream oss; oss << msg << " : end before begin whereas step is positive !";
734 throw INTERP_KERNEL::Exception(oss.str().c_str());
736 if(begin<end && step<0)
738 std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
739 throw INTERP_KERNEL::Exception(oss.str().c_str());
742 return (std::max(begin,end)-1-std::min(begin,end))/std::abs(step)+1;
747 int DataArray::GetPosOfItemGivenBESRelativeNoThrow(int value, int begin, int end, int step)
753 if(begin<=value && value<end)
755 if((value-begin)%step==0)
756 return (value-begin)/step;
765 if(begin>=value && value>end)
767 if((begin-value)%(-step)==0)
768 return (begin-value)/(-step);
781 * Returns a new instance of DataArrayDouble. The caller is to delete this array
782 * using decrRef() as it is no more needed.
784 DataArrayDouble *DataArrayDouble::New()
786 return new DataArrayDouble;
790 * Returns the only one value in \a this, if and only if number of elements
791 * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
792 * \return double - the sole value stored in \a this array.
793 * \throw If at least one of conditions stated above is not fulfilled.
795 double DataArrayDouble::doubleValue() const
799 if(getNbOfElems()==1)
801 return *getConstPointer();
804 throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is allocated but number of elements is not equal to 1 !");
807 throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is not allocated !");
811 * Returns a full copy of \a this. For more info on copying data arrays see
812 * \ref MEDCouplingArrayBasicsCopyDeep.
813 * \return DataArrayDouble * - a new instance of DataArrayDouble. The caller is to
814 * delete this array using decrRef() as it is no more needed.
816 DataArrayDouble *DataArrayDouble::deepCopy() const
818 return new DataArrayDouble(*this);
822 * Checks that \a this array is consistently **increasing** or **decreasing** in value,
823 * with at least absolute difference value of |\a eps| at each step.
824 * If not an exception is thrown.
825 * \param [in] increasing - if \a true, the array values should be increasing.
826 * \param [in] eps - minimal absolute difference between the neighbor values at which
827 * the values are considered different.
828 * \throw If sequence of values is not strictly monotonic in agreement with \a
830 * \throw If \a this->getNumberOfComponents() != 1.
831 * \throw If \a this is not allocated.
833 void DataArrayDouble::checkMonotonic(bool increasing, double eps) const
835 if(!isMonotonic(increasing,eps))
838 throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not INCREASING monotonic !");
840 throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not DECREASING monotonic !");
845 * Checks that \a this array is consistently **increasing** or **decreasing** in value,
846 * with at least absolute difference value of |\a eps| at each step.
847 * \param [in] increasing - if \a true, array values should be increasing.
848 * \param [in] eps - minimal absolute difference between the neighbor values at which
849 * the values are considered different.
850 * \return bool - \a true if values change in accordance with \a increasing arg.
851 * \throw If \a this->getNumberOfComponents() != 1.
852 * \throw If \a this is not allocated.
854 bool DataArrayDouble::isMonotonic(bool increasing, double eps) const
857 if(getNumberOfComponents()!=1)
858 throw INTERP_KERNEL::Exception("DataArrayDouble::isMonotonic : only supported with 'this' array with ONE component !");
859 int nbOfElements=getNumberOfTuples();
860 const double *ptr=getConstPointer();
864 double absEps=fabs(eps);
867 for(int i=1;i<nbOfElements;i++)
869 if(ptr[i]<(ref+absEps))
877 for(int i=1;i<nbOfElements;i++)
879 if(ptr[i]>(ref-absEps))
888 * Returns a textual and human readable representation of \a this instance of
889 * DataArrayDouble. This text is shown when a DataArrayDouble is printed in Python.
890 * \return std::string - text describing \a this DataArrayDouble.
892 * \sa reprNotTooLong, reprZip
894 std::string DataArrayDouble::repr() const
896 std::ostringstream ret;
901 std::string DataArrayDouble::reprZip() const
903 std::ostringstream ret;
908 void DataArrayDouble::writeVTK(std::ostream& ofs, int indent, const std::string& nameInFile, DataArrayByte *byteArr) const
910 static const char SPACE[4]={' ',' ',' ',' '};
912 std::string idt(indent,' ');
914 ofs << idt << "<DataArray type=\"Float32\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
916 bool areAllEmpty(true);
917 for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
921 for(std::size_t i=0;i<_info_on_compo.size();i++)
922 ofs << " ComponentName" << i << "=\"" << _info_on_compo[i] << "\"";
926 ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
927 INTERP_KERNEL::AutoPtr<float> tmp(new float[getNbOfElems()]);
929 // to make Visual C++ happy : instead of std::copy(begin(),end(),(float *)tmp);
930 for(const double *src=begin();src!=end();src++,pt++)
932 const char *data(reinterpret_cast<const char *>((float *)tmp));
933 std::size_t sz(getNbOfElems()*sizeof(float));
934 byteArr->insertAtTheEnd(data,data+sz);
935 byteArr->insertAtTheEnd(SPACE,SPACE+4);
939 ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
940 std::copy(begin(),end(),std::ostream_iterator<double>(ofs," "));
942 ofs << std::endl << idt << "</DataArray>\n";
945 void DataArrayDouble::reprCppStream(const std::string& varName, std::ostream& stream) const
947 int nbTuples(getNumberOfTuples()),nbComp(getNumberOfComponents());
948 const double *data(getConstPointer());
949 stream.precision(17);
950 stream << "DataArrayDouble *" << varName << "=DataArrayDouble::New();" << std::endl;
951 if(nbTuples*nbComp>=1)
953 stream << "const double " << varName << "Data[" << nbTuples*nbComp << "]={";
954 std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<double>(stream,","));
955 stream << data[nbTuples*nbComp-1] << "};" << std::endl;
956 stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
959 stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
960 stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
964 * Method that gives a quick overvien of \a this for python.
966 void DataArrayDouble::reprQuickOverview(std::ostream& stream) const
968 static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
969 stream << "DataArrayDouble C++ instance at " << this << ". ";
972 int nbOfCompo=(int)_info_on_compo.size();
975 int nbOfTuples=getNumberOfTuples();
976 stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
977 reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
980 stream << "Number of components : 0.";
983 stream << "*** No data allocated ****";
986 void DataArrayDouble::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
988 const double *data=begin();
989 int nbOfTuples=getNumberOfTuples();
990 int nbOfCompo=(int)_info_on_compo.size();
991 std::ostringstream oss2; oss2 << "[";
993 std::string oss2Str(oss2.str());
994 bool isFinished=true;
995 for(int i=0;i<nbOfTuples && isFinished;i++)
1000 for(int j=0;j<nbOfCompo;j++,data++)
1003 if(j!=nbOfCompo-1) oss2 << ", ";
1009 if(i!=nbOfTuples-1) oss2 << ", ";
1010 std::string oss3Str(oss2.str());
1011 if(oss3Str.length()<maxNbOfByteInRepr)
1023 * Equivalent to DataArrayDouble::isEqual except that if false the reason of
1024 * mismatch is given.
1026 * \param [in] other the instance to be compared with \a this
1027 * \param [in] prec the precision to compare numeric data of the arrays.
1028 * \param [out] reason In case of inequality returns the reason.
1029 * \sa DataArrayDouble::isEqual
1031 bool DataArrayDouble::isEqualIfNotWhy(const DataArrayDouble& other, double prec, std::string& reason) const
1033 if(!areInfoEqualsIfNotWhy(other,reason))
1035 return _mem.isEqual(other._mem,prec,reason);
1039 * Checks if \a this and another DataArrayDouble are fully equal. For more info see
1040 * \ref MEDCouplingArrayBasicsCompare.
1041 * \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1042 * \param [in] prec - precision value to compare numeric data of the arrays.
1043 * \return bool - \a true if the two arrays are equal, \a false else.
1045 bool DataArrayDouble::isEqual(const DataArrayDouble& other, double prec) const
1048 return isEqualIfNotWhy(other,prec,tmp);
1052 * Checks if values of \a this and another DataArrayDouble are equal. For more info see
1053 * \ref MEDCouplingArrayBasicsCompare.
1054 * \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1055 * \param [in] prec - precision value to compare numeric data of the arrays.
1056 * \return bool - \a true if the values of two arrays are equal, \a false else.
1058 bool DataArrayDouble::isEqualWithoutConsideringStr(const DataArrayDouble& other, double prec) const
1061 return _mem.isEqual(other._mem,prec,tmp);
1065 * This method checks that all tuples in \a other are in \a this.
1066 * If true, the output param \a tupleIds contains the tuples ids of \a this that correspond to tupes in \a this.
1067 * 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.
1069 * \param [in] other - the array having the same number of components than \a this.
1070 * \param [out] tupleIds - the tuple ids containing the same number of tuples than \a other has.
1071 * \sa DataArrayDouble::findCommonTuples
1073 bool DataArrayDouble::areIncludedInMe(const DataArrayDouble *other, double prec, DataArrayInt *&tupleIds) const
1076 throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : input array is NULL !");
1077 checkAllocated(); other->checkAllocated();
1078 if(getNumberOfComponents()!=other->getNumberOfComponents())
1079 throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : the number of components does not match !");
1080 MCAuto<DataArrayDouble> a=DataArrayDouble::Aggregate(this,other);
1081 DataArrayInt *c=0,*ci=0;
1082 a->findCommonTuples(prec,getNumberOfTuples(),c,ci);
1083 MCAuto<DataArrayInt> cSafe(c),ciSafe(ci);
1084 int newNbOfTuples=-1;
1085 MCAuto<DataArrayInt> ids=DataArrayInt::ConvertIndexArrayToO2N(a->getNumberOfTuples(),c->begin(),ci->begin(),ci->end(),newNbOfTuples);
1086 MCAuto<DataArrayInt> ret1=ids->selectByTupleIdSafeSlice(getNumberOfTuples(),a->getNumberOfTuples(),1);
1087 tupleIds=ret1.retn();
1088 return newNbOfTuples==getNumberOfTuples();
1092 * Searches for tuples coincident within \a prec tolerance. Each tuple is considered
1093 * as coordinates of a point in getNumberOfComponents()-dimensional space. The
1094 * distance separating two points is computed with the infinite norm.
1096 * Indices of coincident tuples are stored in output arrays.
1097 * A pair of arrays (\a comm, \a commIndex) is called "Surjective Format 2".
1099 * This method is typically used by MEDCouplingPointSet::findCommonNodes() and
1100 * MEDCouplingUMesh::mergeNodes().
1101 * \param [in] prec - minimal absolute distance between two tuples (infinite norm) at which they are
1102 * considered not coincident.
1103 * \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
1104 * tuples have id strictly lower than \a limitTupleId then they are not returned.
1105 * \param [out] comm - the array holding ids (== indices) of coincident tuples.
1106 * \a comm->getNumberOfComponents() == 1.
1107 * \a comm->getNumberOfTuples() == \a commIndex->back().
1108 * \param [out] commIndex - the array dividing all indices stored in \a comm into
1109 * groups of (indices of) coincident tuples. Its every value is a tuple
1110 * index where a next group of tuples begins. For example the second
1111 * group of tuples in \a comm is described by following range of indices:
1112 * [ \a commIndex[1], \a commIndex[2] ). \a commIndex->getNumberOfTuples()-1
1113 * gives the number of groups of coincident tuples.
1114 * \throw If \a this is not allocated.
1115 * \throw If the number of components is not in [1,2,3,4].
1117 * \if ENABLE_EXAMPLES
1118 * \ref cpp_mcdataarraydouble_findcommontuples "Here is a C++ example".
1120 * \ref py_mcdataarraydouble_findcommontuples "Here is a Python example".
1122 * \sa DataArrayInt::ConvertIndexArrayToO2N(), DataArrayDouble::areIncludedInMe
1124 void DataArrayDouble::findCommonTuples(double prec, int limitTupleId, DataArrayInt *&comm, DataArrayInt *&commIndex) const
1127 int nbOfCompo=getNumberOfComponents();
1128 if ((nbOfCompo<1) || (nbOfCompo>4)) //test before work
1129 throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : Unexpected spacedim of coords. Must be 1, 2, 3 or 4.");
1131 int nbOfTuples=getNumberOfTuples();
1133 MCAuto<DataArrayInt> c(DataArrayInt::New()),cI(DataArrayInt::New()); c->alloc(0,1); cI->pushBackSilent(0);
1137 findCommonTuplesAlg<4>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1140 findCommonTuplesAlg<3>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1143 findCommonTuplesAlg<2>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1146 findCommonTuplesAlg<1>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1149 throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : nb of components managed are 1,2,3 and 4 ! not implemented for other number of components !");
1152 commIndex=cI.retn();
1156 * This methods returns the minimal distance between the two set of points \a this and \a other.
1157 * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
1158 * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
1160 * \param [out] thisTupleId the tuple id in \a this corresponding to the returned minimal distance
1161 * \param [out] otherTupleId the tuple id in \a other corresponding to the returned minimal distance
1162 * \return the minimal distance between the two set of points \a this and \a other.
1163 * \sa DataArrayDouble::findClosestTupleId
1165 double DataArrayDouble::minimalDistanceTo(const DataArrayDouble *other, int& thisTupleId, int& otherTupleId) const
1167 MCAuto<DataArrayInt> part1=findClosestTupleId(other);
1168 int nbOfCompo(getNumberOfComponents());
1169 int otherNbTuples(other->getNumberOfTuples());
1170 const double *thisPt(begin()),*otherPt(other->begin());
1171 const int *part1Pt(part1->begin());
1172 double ret=std::numeric_limits<double>::max();
1173 for(int i=0;i<otherNbTuples;i++,part1Pt++,otherPt+=nbOfCompo)
1176 for(int j=0;j<nbOfCompo;j++)
1177 tmp+=(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j])*(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j]);
1179 { ret=tmp; thisTupleId=*part1Pt; otherTupleId=i; }
1185 * This methods returns for each tuple in \a other which tuple in \a this is the closest.
1186 * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
1187 * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
1189 * \return a newly allocated (new object to be dealt by the caller) DataArrayInt having \c other->getNumberOfTuples() tuples and one components.
1190 * \sa DataArrayDouble::minimalDistanceTo
1192 DataArrayInt *DataArrayDouble::findClosestTupleId(const DataArrayDouble *other) const
1195 throw INTERP_KERNEL::Exception("DataArrayDouble::findClosestTupleId : other instance is NULL !");
1196 checkAllocated(); other->checkAllocated();
1197 std::size_t nbOfCompo(getNumberOfComponents());
1198 if(nbOfCompo!=other->getNumberOfComponents())
1200 std::ostringstream oss; oss << "DataArrayDouble::findClosestTupleId : number of components in this is " << nbOfCompo;
1201 oss << ", whereas number of components in other is " << other->getNumberOfComponents() << "! Should be equal !";
1202 throw INTERP_KERNEL::Exception(oss.str().c_str());
1204 int nbOfTuples=other->getNumberOfTuples();
1205 int thisNbOfTuples=getNumberOfTuples();
1206 MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuples,1);
1208 getMinMaxPerComponent(bounds);
1213 double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2])),zDelta(fabs(bounds[5]-bounds[4]));
1214 double delta=std::max(xDelta,yDelta); delta=std::max(delta,zDelta);
1215 double characSize=pow((delta*delta*delta)/((double)thisNbOfTuples),1./3.);
1216 BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1217 FindClosestTupleIdAlg<3>(myTree,3.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1222 double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2]));
1223 double delta=std::max(xDelta,yDelta);
1224 double characSize=sqrt(delta/(double)thisNbOfTuples);
1225 BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1226 FindClosestTupleIdAlg<2>(myTree,2.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1231 double characSize=fabs(bounds[1]-bounds[0])/thisNbOfTuples;
1232 BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1233 FindClosestTupleIdAlg<1>(myTree,1.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1237 throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for findClosestTupleId. Must be 1, 2 or 3.");
1243 * This method expects that \a this and \a otherBBoxFrmt arrays are bounding box arrays ( as the output of MEDCouplingPointSet::getBoundingBoxForBBTree method ).
1244 * 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
1245 * how many bounding boxes in \a otherBBoxFrmt.
1246 * So, this method expects that \a this and \a otherBBoxFrmt have the same number of components.
1248 * \param [in] otherBBoxFrmt - It is an array .
1249 * \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.
1250 * \sa MEDCouplingPointSet::getBoundingBoxForBBTree
1251 * \throw If \a this and \a otherBBoxFrmt have not the same number of components.
1252 * \throw If \a this and \a otherBBoxFrmt number of components is not even (BBox format).
1254 DataArrayInt *DataArrayDouble::computeNbOfInteractionsWith(const DataArrayDouble *otherBBoxFrmt, double eps) const
1257 throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : input array is NULL !");
1258 if(!isAllocated() || !otherBBoxFrmt->isAllocated())
1259 throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : this and input array must be allocated !");
1260 std::size_t nbOfComp(getNumberOfComponents()),nbOfTuples(getNumberOfTuples());
1261 if(nbOfComp!=otherBBoxFrmt->getNumberOfComponents())
1263 std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : this number of components (" << nbOfComp << ") must be equal to the number of components of input array (" << otherBBoxFrmt->getNumberOfComponents() << ") !";
1264 throw INTERP_KERNEL::Exception(oss.str().c_str());
1268 std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : Number of components (" << nbOfComp << ") is not even ! It should be to be compatible with bbox format !";
1269 throw INTERP_KERNEL::Exception(oss.str().c_str());
1271 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbOfTuples,1);
1272 const double *thisBBPtr(begin());
1273 int *retPtr(ret->getPointer());
1278 BBTree<3,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
1279 for(std::size_t i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
1280 *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
1285 BBTree<2,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
1286 for(std::size_t i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
1287 *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
1292 BBTree<1,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
1293 for(std::size_t i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
1294 *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
1298 throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : space dimension supported are [1,2,3] !");
1305 * Returns a copy of \a this array by excluding coincident tuples. Each tuple is
1306 * considered as coordinates of a point in getNumberOfComponents()-dimensional
1307 * space. The distance between tuples is computed using norm2. If several tuples are
1308 * not far each from other than \a prec, only one of them remains in the result
1309 * array. The order of tuples in the result array is same as in \a this one except
1310 * that coincident tuples are excluded.
1311 * \param [in] prec - minimal absolute distance between two tuples at which they are
1312 * considered not coincident.
1313 * \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
1314 * tuples have id strictly lower than \a limitTupleId then they are not excluded.
1315 * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1316 * is to delete using decrRef() as it is no more needed.
1317 * \throw If \a this is not allocated.
1318 * \throw If the number of components is not in [1,2,3,4].
1320 * \if ENABLE_EXAMPLES
1321 * \ref py_mcdataarraydouble_getdifferentvalues "Here is a Python example".
1324 DataArrayDouble *DataArrayDouble::getDifferentValues(double prec, int limitTupleId) const
1327 DataArrayInt *c0=0,*cI0=0;
1328 findCommonTuples(prec,limitTupleId,c0,cI0);
1329 MCAuto<DataArrayInt> c(c0),cI(cI0);
1330 int newNbOfTuples=-1;
1331 MCAuto<DataArrayInt> o2n=DataArrayInt::ConvertIndexArrayToO2N(getNumberOfTuples(),c0->begin(),cI0->begin(),cI0->end(),newNbOfTuples);
1332 return renumberAndReduce(o2n->getConstPointer(),newNbOfTuples);
1336 * Copy all components in a specified order from another DataArrayDouble.
1337 * Both numerical and textual data is copied. The number of tuples in \a this and
1338 * the other array can be different.
1339 * \param [in] a - the array to copy data from.
1340 * \param [in] compoIds - sequence of zero based indices of components, data of which is
1342 * \throw If \a a is NULL.
1343 * \throw If \a compoIds.size() != \a a->getNumberOfComponents().
1344 * \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
1346 * \if ENABLE_EXAMPLES
1347 * \ref py_mcdataarraydouble_setselectedcomponents "Here is a Python example".
1350 void DataArrayDouble::setSelectedComponents(const DataArrayDouble *a, const std::vector<int>& compoIds)
1353 throw INTERP_KERNEL::Exception("DataArrayDouble::setSelectedComponents : input DataArrayDouble is NULL !");
1355 copyPartOfStringInfoFrom2(compoIds,*a);
1356 std::size_t partOfCompoSz=compoIds.size();
1357 int nbOfCompo=getNumberOfComponents();
1358 int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
1359 const double *ac=a->getConstPointer();
1360 double *nc=getPointer();
1361 for(int i=0;i<nbOfTuples;i++)
1362 for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
1363 nc[nbOfCompo*i+compoIds[j]]=*ac;
1367 * Checks if 0.0 value is present in \a this array. If it is the case, an exception
1369 * \throw If zero is found in \a this array.
1371 void DataArrayDouble::checkNoNullValues() const
1373 const double *tmp=getConstPointer();
1374 std::size_t nbOfElems=getNbOfElems();
1375 const double *where=std::find(tmp,tmp+nbOfElems,0.);
1376 if(where!=tmp+nbOfElems)
1377 throw INTERP_KERNEL::Exception("A value 0.0 have been detected !");
1381 * Computes minimal and maximal value in each component. An output array is filled
1382 * with \c 2 * \a this->getNumberOfComponents() values, so the caller is to allocate
1383 * enough memory before calling this method.
1384 * \param [out] bounds - array of size at least 2 *\a this->getNumberOfComponents().
1385 * It is filled as follows:<br>
1386 * \a bounds[0] = \c min_of_component_0 <br>
1387 * \a bounds[1] = \c max_of_component_0 <br>
1388 * \a bounds[2] = \c min_of_component_1 <br>
1389 * \a bounds[3] = \c max_of_component_1 <br>
1392 void DataArrayDouble::getMinMaxPerComponent(double *bounds) const
1395 int dim=getNumberOfComponents();
1396 for (int idim=0; idim<dim; idim++)
1398 bounds[idim*2]=std::numeric_limits<double>::max();
1399 bounds[idim*2+1]=-std::numeric_limits<double>::max();
1401 const double *ptr=getConstPointer();
1402 int nbOfTuples=getNumberOfTuples();
1403 for(int i=0;i<nbOfTuples;i++)
1405 for(int idim=0;idim<dim;idim++)
1407 if(bounds[idim*2]>ptr[i*dim+idim])
1409 bounds[idim*2]=ptr[i*dim+idim];
1411 if(bounds[idim*2+1]<ptr[i*dim+idim])
1413 bounds[idim*2+1]=ptr[i*dim+idim];
1420 * This method retrieves a newly allocated DataArrayDouble instance having same number of tuples than \a this and twice number of components than \a this
1421 * to store both the min and max per component of each tuples.
1422 * \param [in] epsilon the width of the bbox (identical in each direction) - 0.0 by default
1424 * \return a newly created DataArrayDouble instance having \c this->getNumberOfTuples() tuples and 2 * \c this->getNumberOfComponent() components
1426 * \throw If \a this is not allocated yet.
1428 DataArrayDouble *DataArrayDouble::computeBBoxPerTuple(double epsilon) const
1431 const double *dataPtr=getConstPointer();
1432 int nbOfCompo=getNumberOfComponents();
1433 int nbTuples=getNumberOfTuples();
1434 MCAuto<DataArrayDouble> bbox=DataArrayDouble::New();
1435 bbox->alloc(nbTuples,2*nbOfCompo);
1436 double *bboxPtr=bbox->getPointer();
1437 for(int i=0;i<nbTuples;i++)
1439 for(int j=0;j<nbOfCompo;j++)
1441 bboxPtr[2*nbOfCompo*i+2*j]=dataPtr[nbOfCompo*i+j]-epsilon;
1442 bboxPtr[2*nbOfCompo*i+2*j+1]=dataPtr[nbOfCompo*i+j]+epsilon;
1449 * For each tuples **t** in \a other, this method retrieves tuples in \a this that are equal to **t**.
1450 * Two tuples are considered equal if the euclidian distance between the two tuples is lower than \a eps.
1452 * \param [in] other a DataArrayDouble having same number of components than \a this.
1453 * \param [in] eps absolute precision representing distance (using infinite norm) between 2 tuples behind which 2 tuples are considered equal.
1454 * \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.
1455 * \a cI allows to extract information in \a c.
1456 * \param [out] cI is an indirection array that allows to extract the data contained in \a c.
1458 * \throw In case of:
1459 * - \a this is not allocated
1460 * - \a other is not allocated or null
1461 * - \a this and \a other do not have the same number of components
1462 * - if number of components of \a this is not in [1,2,3]
1464 * \sa MEDCouplingPointSet::getNodeIdsNearPoints, DataArrayDouble::getDifferentValues
1466 void DataArrayDouble::computeTupleIdsNearTuples(const DataArrayDouble *other, double eps, DataArrayInt *& c, DataArrayInt *& cI) const
1469 throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : input pointer other is null !");
1471 other->checkAllocated();
1472 int nbOfCompo=getNumberOfComponents();
1473 int otherNbOfCompo=other->getNumberOfComponents();
1474 if(nbOfCompo!=otherNbOfCompo)
1475 throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : number of components should be equal between this and other !");
1476 int nbOfTuplesOther=other->getNumberOfTuples();
1477 MCAuto<DataArrayInt> cArr(DataArrayInt::New()),cIArr(DataArrayInt::New()); cArr->alloc(0,1); cIArr->pushBackSilent(0);
1482 BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
1483 FindTupleIdsNearTuplesAlg<3>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
1488 BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
1489 FindTupleIdsNearTuplesAlg<2>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
1494 BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
1495 FindTupleIdsNearTuplesAlg<1>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
1499 throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for computeTupleIdsNearTuples. Must be 1, 2 or 3.");
1501 c=cArr.retn(); cI=cIArr.retn();
1505 * 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
1506 * around origin of 'radius' 1.
1508 * \param [in] eps absolute epsilon. under that value of delta between max and min no scale is performed.
1510 void DataArrayDouble::recenterForMaxPrecision(double eps)
1513 int dim=getNumberOfComponents();
1514 std::vector<double> bounds(2*dim);
1515 getMinMaxPerComponent(&bounds[0]);
1516 for(int i=0;i<dim;i++)
1518 double delta=bounds[2*i+1]-bounds[2*i];
1519 double offset=(bounds[2*i]+bounds[2*i+1])/2.;
1521 applyLin(1./delta,-offset/delta,i);
1523 applyLin(1.,-offset,i);
1528 * Returns the maximal value and all its locations within \a this one-dimensional array.
1529 * \param [out] tupleIds - a new instance of DataArrayInt containing indices of
1530 * tuples holding the maximal value. The caller is to delete it using
1531 * decrRef() as it is no more needed.
1532 * \return double - the maximal value among all values of \a this array.
1533 * \throw If \a this->getNumberOfComponents() != 1
1534 * \throw If \a this->getNumberOfTuples() < 1
1536 double DataArrayDouble::getMaxValue2(DataArrayInt*& tupleIds) const
1540 double ret=getMaxValue(tmp);
1541 tupleIds=findIdsInRange(ret,ret);
1546 * Returns the minimal value and all its locations within \a this one-dimensional array.
1547 * \param [out] tupleIds - a new instance of DataArrayInt containing indices of
1548 * tuples holding the minimal value. The caller is to delete it using
1549 * decrRef() as it is no more needed.
1550 * \return double - the minimal value among all values of \a this array.
1551 * \throw If \a this->getNumberOfComponents() != 1
1552 * \throw If \a this->getNumberOfTuples() < 1
1554 double DataArrayDouble::getMinValue2(DataArrayInt*& tupleIds) const
1558 double ret=getMinValue(tmp);
1559 tupleIds=findIdsInRange(ret,ret);
1564 * 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.
1565 * This method only works for single component array.
1567 * \return a value in [ 0, \c this->getNumberOfTuples() )
1569 * \throw If \a this is not allocated
1572 int DataArrayDouble::count(double value, double eps) const
1576 if(getNumberOfComponents()!=1)
1577 throw INTERP_KERNEL::Exception("DataArrayDouble::count : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
1578 const double *vals=begin();
1579 int nbOfTuples=getNumberOfTuples();
1580 for(int i=0;i<nbOfTuples;i++,vals++)
1581 if(fabs(*vals-value)<=eps)
1587 * Returns the average value of \a this one-dimensional array.
1588 * \return double - the average value over all values of \a this array.
1589 * \throw If \a this->getNumberOfComponents() != 1
1590 * \throw If \a this->getNumberOfTuples() < 1
1592 double DataArrayDouble::getAverageValue() const
1594 if(getNumberOfComponents()!=1)
1595 throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
1596 int nbOfTuples=getNumberOfTuples();
1598 throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : array exists but number of tuples must be > 0 !");
1599 const double *vals=getConstPointer();
1600 double ret=std::accumulate(vals,vals+nbOfTuples,0.);
1601 return ret/nbOfTuples;
1605 * Returns the Euclidean norm of the vector defined by \a this array.
1606 * \return double - the value of the Euclidean norm, i.e.
1607 * the square root of the inner product of vector.
1608 * \throw If \a this is not allocated.
1610 double DataArrayDouble::norm2() const
1614 std::size_t nbOfElems=getNbOfElems();
1615 const double *pt=getConstPointer();
1616 for(std::size_t i=0;i<nbOfElems;i++,pt++)
1622 * Returns the maximum norm of the vector defined by \a this array.
1623 * This method works even if the number of components is different from one.
1624 * If the number of elements in \a this is 0, -1. is returned.
1625 * \return double - the value of the maximum norm, i.e.
1626 * the maximal absolute value among values of \a this array (whatever its number of components).
1627 * \throw If \a this is not allocated.
1629 double DataArrayDouble::normMax() const
1633 std::size_t nbOfElems(getNbOfElems());
1634 const double *pt(getConstPointer());
1635 for(std::size_t i=0;i<nbOfElems;i++,pt++)
1637 double val(std::abs(*pt));
1645 * Returns the maximum norm of for each component of \a this array.
1646 * If the number of elements in \a this is 0, -1. is returned.
1647 * \param [out] res - pointer to an array of result values, of size at least \a
1648 * this->getNumberOfComponents(), that is to be allocated by the caller.
1649 * \throw If \a this is not allocated.
1651 void DataArrayDouble::normMaxPerComponent(double * res) const
1654 std::size_t nbOfTuples(getNumberOfTuples());
1655 int nbOfCompos(getNumberOfComponents());
1656 std::fill(res, res+nbOfCompos, -1.0);
1657 const double *pt(getConstPointer());
1658 for(std::size_t i=0;i<nbOfTuples;i++)
1659 for (int j=0; j<nbOfCompos; j++, pt++)
1661 double val(std::abs(*pt));
1669 * Returns the minimum norm (absolute value) of the vector defined by \a this array.
1670 * This method works even if the number of components is different from one.
1671 * If the number of elements in \a this is 0, std::numeric_limits<double>::max() is returned.
1672 * \return double - the value of the minimum norm, i.e.
1673 * the minimal absolute value among values of \a this array (whatever its number of components).
1674 * \throw If \a this is not allocated.
1676 double DataArrayDouble::normMin() const
1679 double ret(std::numeric_limits<double>::max());
1680 std::size_t nbOfElems(getNbOfElems());
1681 const double *pt(getConstPointer());
1682 for(std::size_t i=0;i<nbOfElems;i++,pt++)
1684 double val(std::abs(*pt));
1692 * Accumulates values of each component of \a this array.
1693 * \param [out] res - an array of length \a this->getNumberOfComponents(), allocated
1694 * by the caller, that is filled by this method with sum value for each
1696 * \throw If \a this is not allocated.
1698 void DataArrayDouble::accumulate(double *res) const
1701 const double *ptr=getConstPointer();
1702 int nbTuple=getNumberOfTuples();
1703 int nbComps=getNumberOfComponents();
1704 std::fill(res,res+nbComps,0.);
1705 for(int i=0;i<nbTuple;i++)
1706 std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<double>());
1710 * This method returns the min distance from an external tuple defined by [ \a tupleBg , \a tupleEnd ) to \a this and
1711 * the first tuple in \a this that matches the returned distance. If there is no tuples in \a this an exception will be thrown.
1714 * \a this is expected to be allocated and expected to have a number of components equal to the distance from \a tupleBg to
1715 * \a tupleEnd. If not an exception will be thrown.
1717 * \param [in] tupleBg start pointer (included) of input external tuple
1718 * \param [in] tupleEnd end pointer (not included) of input external tuple
1719 * \param [out] tupleId the tuple id in \a this that matches the min of distance between \a this and input external tuple
1720 * \return the min distance.
1721 * \sa MEDCouplingUMesh::distanceToPoint
1723 double DataArrayDouble::distanceToTuple(const double *tupleBg, const double *tupleEnd, int& tupleId) const
1726 int nbTuple=getNumberOfTuples();
1727 int nbComps=getNumberOfComponents();
1728 if(nbComps!=(int)std::distance(tupleBg,tupleEnd))
1729 { 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()); }
1731 throw INTERP_KERNEL::Exception("DataArrayDouble::distanceToTuple : no tuple in this ! No distance to compute !");
1732 double ret0=std::numeric_limits<double>::max();
1734 const double *work=getConstPointer();
1735 for(int i=0;i<nbTuple;i++)
1738 for(int j=0;j<nbComps;j++,work++)
1739 val+=(*work-tupleBg[j])*((*work-tupleBg[j]));
1743 { ret0=val; tupleId=i; }
1749 * Accumulate values of the given component of \a this array.
1750 * \param [in] compId - the index of the component of interest.
1751 * \return double - a sum value of \a compId-th component.
1752 * \throw If \a this is not allocated.
1753 * \throw If \a the condition ( 0 <= \a compId < \a this->getNumberOfComponents() ) is
1756 double DataArrayDouble::accumulate(int compId) const
1759 const double *ptr=getConstPointer();
1760 int nbTuple=getNumberOfTuples();
1761 int nbComps=getNumberOfComponents();
1762 if(compId<0 || compId>=nbComps)
1763 throw INTERP_KERNEL::Exception("DataArrayDouble::accumulate : Invalid compId specified : No such nb of components !");
1765 for(int i=0;i<nbTuple;i++)
1766 ret+=ptr[i*nbComps+compId];
1771 * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
1772 * The returned array will have same number of components than \a this and number of tuples equal to
1773 * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
1775 * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
1776 * 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.
1778 * \param [in] bgOfIndex - begin (included) of the input index array.
1779 * \param [in] endOfIndex - end (excluded) of the input index array.
1780 * \return DataArrayDouble * - the new instance having the same number of components than \a this.
1782 * \throw If bgOfIndex or end is NULL.
1783 * \throw If input index array is not ascendingly sorted.
1784 * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
1785 * \throw If std::distance(bgOfIndex,endOfIndex)==0.
1787 DataArrayDouble *DataArrayDouble::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
1789 if(!bgOfIndex || !endOfIndex)
1790 throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : input pointer NULL !");
1792 int nbCompo=getNumberOfComponents();
1793 int nbOfTuples=getNumberOfTuples();
1794 int sz=(int)std::distance(bgOfIndex,endOfIndex);
1796 throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : invalid size of input index array !");
1798 MCAuto<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(sz,nbCompo);
1799 const int *w=bgOfIndex;
1800 if(*w<0 || *w>=nbOfTuples)
1801 throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
1802 const double *srcPt=begin()+(*w)*nbCompo;
1803 double *tmp=ret->getPointer();
1804 for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
1806 std::fill(tmp,tmp+nbCompo,0.);
1809 for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
1811 if(j>=0 && j<nbOfTuples)
1812 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<double>());
1815 std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
1816 throw INTERP_KERNEL::Exception(oss.str().c_str());
1822 std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
1823 throw INTERP_KERNEL::Exception(oss.str().c_str());
1826 ret->copyStringInfoFrom(*this);
1831 * 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.
1832 * This method expects that \a this as only one component. The returned array will have \a this->getNumberOfTuples()+1 tuple with also one component.
1833 * The ith element of returned array is equal to the sum of elements in \a this with rank strictly lower than i.
1835 * \return DataArrayDouble - A newly built array containing cum sum of \a this.
1837 MCAuto<DataArrayDouble> DataArrayDouble::cumSum() const
1840 checkNbOfComps(1,"DataArrayDouble::cumSum : this is expected to be single component");
1841 int nbOfTuple(getNumberOfTuples());
1842 MCAuto<DataArrayDouble> ret(DataArrayDouble::New()); ret->alloc(nbOfTuple+1,1);
1843 double *ptr(ret->getPointer());
1845 const double *thisPtr(begin());
1846 for(int i=0;i<nbOfTuple;i++)
1847 ptr[i+1]=ptr[i]+thisPtr[i];
1852 * Converts each 2D point defined by the tuple of \a this array from the Polar to the
1853 * Cartesian coordinate system. The two components of the tuple of \a this array are
1854 * considered to contain (1) radius and (2) angle of the point in the Polar CS.
1855 * \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
1856 * contains X and Y coordinates of the point in the Cartesian CS. The caller
1857 * is to delete this array using decrRef() as it is no more needed. The array
1858 * does not contain any textual info on components.
1859 * \throw If \a this->getNumberOfComponents() != 2.
1860 * \sa fromCartToPolar
1862 DataArrayDouble *DataArrayDouble::fromPolarToCart() const
1865 int nbOfComp(getNumberOfComponents());
1867 throw INTERP_KERNEL::Exception("DataArrayDouble::fromPolarToCart : must be an array with exactly 2 components !");
1868 int nbOfTuple(getNumberOfTuples());
1869 DataArrayDouble *ret(DataArrayDouble::New());
1870 ret->alloc(nbOfTuple,2);
1871 double *w(ret->getPointer());
1872 const double *wIn(getConstPointer());
1873 for(int i=0;i<nbOfTuple;i++,w+=2,wIn+=2)
1875 w[0]=wIn[0]*cos(wIn[1]);
1876 w[1]=wIn[0]*sin(wIn[1]);
1882 * Converts each 3D point defined by the tuple of \a this array from the Cylindrical to
1883 * the Cartesian coordinate system. The three components of the tuple of \a this array
1884 * are considered to contain (1) radius, (2) azimuth and (3) altitude of the point in
1885 * the Cylindrical CS.
1886 * \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
1887 * contains X, Y and Z coordinates of the point in the Cartesian CS. The info
1888 * on the third component is copied from \a this array. The caller
1889 * is to delete this array using decrRef() as it is no more needed.
1890 * \throw If \a this->getNumberOfComponents() != 3.
1893 DataArrayDouble *DataArrayDouble::fromCylToCart() const
1896 int nbOfComp(getNumberOfComponents());
1898 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCylToCart : must be an array with exactly 3 components !");
1899 int nbOfTuple(getNumberOfTuples());
1900 DataArrayDouble *ret(DataArrayDouble::New());
1901 ret->alloc(getNumberOfTuples(),3);
1902 double *w(ret->getPointer());
1903 const double *wIn(getConstPointer());
1904 for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
1906 w[0]=wIn[0]*cos(wIn[1]);
1907 w[1]=wIn[0]*sin(wIn[1]);
1910 ret->setInfoOnComponent(2,getInfoOnComponent(2));
1915 * Converts each 3D point defined by the tuple of \a this array from the Spherical to
1916 * the Cartesian coordinate system. The three components of the tuple of \a this array
1917 * are considered to contain (1) radius, (2) polar angle and (3) azimuthal angle of the
1918 * point in the Cylindrical CS.
1919 * \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
1920 * contains X, Y and Z coordinates of the point in the Cartesian CS. The info
1921 * on the third component is copied from \a this array. The caller
1922 * is to delete this array using decrRef() as it is no more needed.
1923 * \throw If \a this->getNumberOfComponents() != 3.
1924 * \sa fromCartToSpher
1926 DataArrayDouble *DataArrayDouble::fromSpherToCart() const
1929 int nbOfComp(getNumberOfComponents());
1931 throw INTERP_KERNEL::Exception("DataArrayDouble::fromSpherToCart : must be an array with exactly 3 components !");
1932 int nbOfTuple(getNumberOfTuples());
1933 DataArrayDouble *ret(DataArrayDouble::New());
1934 ret->alloc(getNumberOfTuples(),3);
1935 double *w(ret->getPointer());
1936 const double *wIn(getConstPointer());
1937 for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
1939 w[0]=wIn[0]*cos(wIn[2])*sin(wIn[1]);
1940 w[1]=wIn[0]*sin(wIn[2])*sin(wIn[1]);
1941 w[2]=wIn[0]*cos(wIn[1]);
1947 * 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.
1948 * 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.
1949 * If \a at equals to AX_CYL the returned array will be the result of operation cylindric to cartesian of \a this...
1951 * \param [in] atOfThis - The axis type of \a this.
1952 * \return DataArrayDouble * - the new instance of DataArrayDouble (that must be dealed by caller) containing the result of the cartesianizification of \a this.
1954 DataArrayDouble *DataArrayDouble::cartesianize(MEDCouplingAxisType atOfThis) const
1957 int nbOfComp(getNumberOfComponents());
1958 MCAuto<DataArrayDouble> ret;
1966 ret=fromCylToCart();
1971 ret=fromPolarToCart();
1975 throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : For AX_CYL, number of components must be in [2,3] !");
1979 ret=fromSpherToCart();
1984 ret=fromPolarToCart();
1988 throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : For AX_CYL, number of components must be in [2,3] !");
1990 throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : not recognized axis type ! Only AX_CART, AX_CYL and AX_SPHER supported !");
1992 ret->copyStringInfoFrom(*this);
1997 * This method returns a newly created array to be deallocated that contains the result of conversion from cartesian to polar.
1998 * This method expects that \a this has exactly 2 components.
1999 * \sa fromPolarToCart
2001 DataArrayDouble *DataArrayDouble::fromCartToPolar() const
2003 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2005 int nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2007 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToPolar : must be an array with exactly 2 components !");
2008 ret->alloc(nbTuples,2);
2009 double *retPtr(ret->getPointer());
2010 const double *ptr(begin());
2011 for(int i=0;i<nbTuples;i++,ptr+=2,retPtr+=2)
2013 retPtr[0]=sqrt(ptr[0]*ptr[0]+ptr[1]*ptr[1]);
2014 retPtr[1]=atan2(ptr[1],ptr[0]);
2020 * This method returns a newly created array to be deallocated that contains the result of conversion from cartesian to cylindrical.
2021 * This method expects that \a this has exactly 3 components.
2024 DataArrayDouble *DataArrayDouble::fromCartToCyl() const
2026 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2028 int nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2030 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCyl : must be an array with exactly 3 components !");
2031 ret->alloc(nbTuples,3);
2032 double *retPtr(ret->getPointer());
2033 const double *ptr(begin());
2034 for(int i=0;i<nbTuples;i++,ptr+=3,retPtr+=3)
2036 retPtr[0]=sqrt(ptr[0]*ptr[0]+ptr[1]*ptr[1]);
2037 retPtr[1]=atan2(ptr[1],ptr[0]);
2044 * This method returns a newly created array to be deallocated that contains the result of conversion from cartesian to spherical coordinates.
2045 * \sa fromSpherToCart
2047 DataArrayDouble *DataArrayDouble::fromCartToSpher() const
2049 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2051 int nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2053 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToSpher : must be an array with exactly 3 components !");
2054 ret->alloc(nbTuples,3);
2055 double *retPtr(ret->getPointer());
2056 const double *ptr(begin());
2057 for(int i=0;i<nbTuples;i++,ptr+=3,retPtr+=3)
2059 retPtr[0]=sqrt(ptr[0]*ptr[0]+ptr[1]*ptr[1]+ptr[2]*ptr[2]);
2060 retPtr[1]=acos(ptr[2]/retPtr[0]);
2061 retPtr[2]=atan2(ptr[1],ptr[0]);
2067 * 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.
2068 * This method expects that \a this has exactly 3 components.
2069 * \sa MEDCouplingFieldDouble::computeVectorFieldCyl
2071 DataArrayDouble *DataArrayDouble::fromCartToCylGiven(const DataArrayDouble *coords, const double center[3], const double vect[3]) const
2074 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : input coords are NULL !");
2075 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2076 checkAllocated(); coords->checkAllocated();
2077 std::size_t nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2079 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : must be an array with exactly 3 components !");
2080 if(coords->getNumberOfComponents()!=3)
2081 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : coords array must have exactly 3 components !");
2082 if(coords->getNumberOfTuples()!=nbTuples)
2083 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : coords array must have the same number of tuples !");
2084 ret->alloc(nbTuples,nbOfComp);
2085 double magOfVect(sqrt(vect[0]*vect[0]+vect[1]*vect[1]+vect[2]*vect[2]));
2087 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : magnitude of vect is too low !");
2088 double Ur[3],Uteta[3],Uz[3],*retPtr(ret->getPointer());
2089 const double *coo(coords->begin()),*vectField(begin());
2090 std::transform(vect,vect+3,Uz,std::bind2nd(std::multiplies<double>(),1./magOfVect));
2091 for(int i=0;i<nbTuples;i++,vectField+=3,retPtr+=3,coo+=3)
2093 std::transform(coo,coo+3,center,Ur,std::minus<double>());
2094 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];
2095 double magOfTeta(sqrt(Uteta[0]*Uteta[0]+Uteta[1]*Uteta[1]+Uteta[2]*Uteta[2]));
2096 std::transform(Uteta,Uteta+3,Uteta,std::bind2nd(std::multiplies<double>(),1./magOfTeta));
2097 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];
2098 retPtr[0]=Ur[0]*vectField[0]+Ur[1]*vectField[1]+Ur[2]*vectField[2];
2099 retPtr[1]=Uteta[0]*vectField[0]+Uteta[1]*vectField[1]+Uteta[2]*vectField[2];
2100 retPtr[2]=Uz[0]*vectField[0]+Uz[1]*vectField[1]+Uz[2]*vectField[2];
2102 ret->copyStringInfoFrom(*this);
2107 * Computes the doubly contracted product of every tensor defined by the tuple of \a this
2108 * array containing 6 components.
2109 * \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
2110 * is calculated from the tuple <em>(t)</em> of \a this array as follows:
2111 * \f$ t[0]^2+t[1]^2+t[2]^2+2*t[3]^2+2*t[4]^2+2*t[5]^2\f$.
2112 * The caller is to delete this result array using decrRef() as it is no more needed.
2113 * \throw If \a this->getNumberOfComponents() != 6.
2115 DataArrayDouble *DataArrayDouble::doublyContractedProduct() const
2118 int nbOfComp(getNumberOfComponents());
2120 throw INTERP_KERNEL::Exception("DataArrayDouble::doublyContractedProduct : must be an array with exactly 6 components !");
2121 DataArrayDouble *ret=DataArrayDouble::New();
2122 int nbOfTuple=getNumberOfTuples();
2123 ret->alloc(nbOfTuple,1);
2124 const double *src=getConstPointer();
2125 double *dest=ret->getPointer();
2126 for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
2127 *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];
2132 * Computes the determinant of every square matrix defined by the tuple of \a this
2133 * array, which contains either 4, 6 or 9 components. The case of 6 components
2134 * corresponds to that of the upper triangular matrix.
2135 * \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
2136 * is the determinant of matrix of the corresponding tuple of \a this array.
2137 * The caller is to delete this result array using decrRef() as it is no more
2139 * \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2141 DataArrayDouble *DataArrayDouble::determinant() const
2144 DataArrayDouble *ret=DataArrayDouble::New();
2145 int nbOfTuple=getNumberOfTuples();
2146 ret->alloc(nbOfTuple,1);
2147 const double *src=getConstPointer();
2148 double *dest=ret->getPointer();
2149 switch(getNumberOfComponents())
2152 for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
2153 *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];
2156 for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
2157 *dest=src[0]*src[3]-src[1]*src[2];
2160 for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
2161 *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];
2165 throw INTERP_KERNEL::Exception("DataArrayDouble::determinant : Invalid number of components ! must be in 4,6,9 !");
2170 * Computes 3 eigenvalues of every upper triangular matrix defined by the tuple of
2171 * \a this array, which contains 6 components.
2172 * \return DataArrayDouble * - the new instance of DataArrayDouble containing 3
2173 * components, whose each tuple contains the eigenvalues of the matrix of
2174 * corresponding tuple of \a this array.
2175 * The caller is to delete this result array using decrRef() as it is no more
2177 * \throw If \a this->getNumberOfComponents() != 6.
2179 DataArrayDouble *DataArrayDouble::eigenValues() const
2182 int nbOfComp=getNumberOfComponents();
2184 throw INTERP_KERNEL::Exception("DataArrayDouble::eigenValues : must be an array with exactly 6 components !");
2185 DataArrayDouble *ret=DataArrayDouble::New();
2186 int nbOfTuple=getNumberOfTuples();
2187 ret->alloc(nbOfTuple,3);
2188 const double *src=getConstPointer();
2189 double *dest=ret->getPointer();
2190 for(int i=0;i<nbOfTuple;i++,dest+=3,src+=6)
2191 INTERP_KERNEL::computeEigenValues6(src,dest);
2196 * Computes 3 eigenvectors of every upper triangular matrix defined by the tuple of
2197 * \a this array, which contains 6 components.
2198 * \return DataArrayDouble * - the new instance of DataArrayDouble containing 9
2199 * components, whose each tuple contains 3 eigenvectors of the matrix of
2200 * corresponding tuple of \a this array.
2201 * The caller is to delete this result array using decrRef() as it is no more
2203 * \throw If \a this->getNumberOfComponents() != 6.
2205 DataArrayDouble *DataArrayDouble::eigenVectors() const
2208 int nbOfComp=getNumberOfComponents();
2210 throw INTERP_KERNEL::Exception("DataArrayDouble::eigenVectors : must be an array with exactly 6 components !");
2211 DataArrayDouble *ret=DataArrayDouble::New();
2212 int nbOfTuple=getNumberOfTuples();
2213 ret->alloc(nbOfTuple,9);
2214 const double *src=getConstPointer();
2215 double *dest=ret->getPointer();
2216 for(int i=0;i<nbOfTuple;i++,src+=6)
2219 INTERP_KERNEL::computeEigenValues6(src,tmp);
2220 for(int j=0;j<3;j++,dest+=3)
2221 INTERP_KERNEL::computeEigenVectorForEigenValue6(src,tmp[j],1e-12,dest);
2227 * Computes the inverse matrix of every matrix defined by the tuple of \a this
2228 * array, which contains either 4, 6 or 9 components. The case of 6 components
2229 * corresponds to that of the upper triangular matrix.
2230 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2231 * same number of components as \a this one, whose each tuple is the inverse
2232 * matrix of the matrix of corresponding tuple of \a this array.
2233 * The caller is to delete this result array using decrRef() as it is no more
2235 * \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2237 DataArrayDouble *DataArrayDouble::inverse() const
2240 int nbOfComp=getNumberOfComponents();
2241 if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
2242 throw INTERP_KERNEL::Exception("DataArrayDouble::inversion : must be an array with 4,6 or 9 components !");
2243 DataArrayDouble *ret=DataArrayDouble::New();
2244 int nbOfTuple=getNumberOfTuples();
2245 ret->alloc(nbOfTuple,nbOfComp);
2246 const double *src=getConstPointer();
2247 double *dest=ret->getPointer();
2249 for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
2251 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];
2252 dest[0]=(src[1]*src[2]-src[4]*src[4])/det;
2253 dest[1]=(src[0]*src[2]-src[5]*src[5])/det;
2254 dest[2]=(src[0]*src[1]-src[3]*src[3])/det;
2255 dest[3]=(src[5]*src[4]-src[3]*src[2])/det;
2256 dest[4]=(src[5]*src[3]-src[0]*src[4])/det;
2257 dest[5]=(src[3]*src[4]-src[1]*src[5])/det;
2259 else if(nbOfComp==4)
2260 for(int i=0;i<nbOfTuple;i++,dest+=4,src+=4)
2262 double det=src[0]*src[3]-src[1]*src[2];
2264 dest[1]=-src[1]/det;
2265 dest[2]=-src[2]/det;
2269 for(int i=0;i<nbOfTuple;i++,dest+=9,src+=9)
2271 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];
2272 dest[0]=(src[4]*src[8]-src[7]*src[5])/det;
2273 dest[1]=(src[7]*src[2]-src[1]*src[8])/det;
2274 dest[2]=(src[1]*src[5]-src[4]*src[2])/det;
2275 dest[3]=(src[6]*src[5]-src[3]*src[8])/det;
2276 dest[4]=(src[0]*src[8]-src[6]*src[2])/det;
2277 dest[5]=(src[2]*src[3]-src[0]*src[5])/det;
2278 dest[6]=(src[3]*src[7]-src[6]*src[4])/det;
2279 dest[7]=(src[6]*src[1]-src[0]*src[7])/det;
2280 dest[8]=(src[0]*src[4]-src[1]*src[3])/det;
2286 * Computes the trace of every matrix defined by the tuple of \a this
2287 * array, which contains either 4, 6 or 9 components. The case of 6 components
2288 * corresponds to that of the upper triangular matrix.
2289 * \return DataArrayDouble * - the new instance of DataArrayDouble containing
2290 * 1 component, whose each tuple is the trace of
2291 * the matrix of corresponding tuple of \a this array.
2292 * The caller is to delete this result array using decrRef() as it is no more
2294 * \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2296 DataArrayDouble *DataArrayDouble::trace() const
2299 int nbOfComp=getNumberOfComponents();
2300 if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
2301 throw INTERP_KERNEL::Exception("DataArrayDouble::trace : must be an array with 4,6 or 9 components !");
2302 DataArrayDouble *ret=DataArrayDouble::New();
2303 int nbOfTuple=getNumberOfTuples();
2304 ret->alloc(nbOfTuple,1);
2305 const double *src=getConstPointer();
2306 double *dest=ret->getPointer();
2308 for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
2309 *dest=src[0]+src[1]+src[2];
2310 else if(nbOfComp==4)
2311 for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
2312 *dest=src[0]+src[3];
2314 for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
2315 *dest=src[0]+src[4]+src[8];
2320 * Computes the stress deviator tensor of every stress tensor defined by the tuple of
2321 * \a this array, which contains 6 components.
2322 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2323 * same number of components and tuples as \a this array.
2324 * The caller is to delete this result array using decrRef() as it is no more
2326 * \throw If \a this->getNumberOfComponents() != 6.
2328 DataArrayDouble *DataArrayDouble::deviator() const
2331 int nbOfComp=getNumberOfComponents();
2333 throw INTERP_KERNEL::Exception("DataArrayDouble::deviator : must be an array with exactly 6 components !");
2334 DataArrayDouble *ret=DataArrayDouble::New();
2335 int nbOfTuple=getNumberOfTuples();
2336 ret->alloc(nbOfTuple,6);
2337 const double *src=getConstPointer();
2338 double *dest=ret->getPointer();
2339 for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
2341 double tr=(src[0]+src[1]+src[2])/3.;
2353 * Computes the magnitude of every vector defined by the tuple of
2355 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2356 * same number of tuples as \a this array and one component.
2357 * The caller is to delete this result array using decrRef() as it is no more
2359 * \throw If \a this is not allocated.
2361 DataArrayDouble *DataArrayDouble::magnitude() const
2364 int nbOfComp=getNumberOfComponents();
2365 DataArrayDouble *ret=DataArrayDouble::New();
2366 int nbOfTuple=getNumberOfTuples();
2367 ret->alloc(nbOfTuple,1);
2368 const double *src=getConstPointer();
2369 double *dest=ret->getPointer();
2370 for(int i=0;i<nbOfTuple;i++,dest++)
2373 for(int j=0;j<nbOfComp;j++,src++)
2381 * Computes the maximal value within every tuple of \a this array.
2382 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2383 * same number of tuples as \a this array and one component.
2384 * The caller is to delete this result array using decrRef() as it is no more
2386 * \throw If \a this is not allocated.
2387 * \sa DataArrayDouble::maxPerTupleWithCompoId
2389 DataArrayDouble *DataArrayDouble::maxPerTuple() const
2392 int nbOfComp=getNumberOfComponents();
2393 MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
2394 int nbOfTuple=getNumberOfTuples();
2395 ret->alloc(nbOfTuple,1);
2396 const double *src=getConstPointer();
2397 double *dest=ret->getPointer();
2398 for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
2399 *dest=*std::max_element(src,src+nbOfComp);
2404 * Computes the maximal value within every tuple of \a this array and it returns the first component
2405 * id for each tuple that corresponds to the maximal value within the tuple.
2407 * \param [out] compoIdOfMaxPerTuple - the new new instance of DataArrayInt containing the
2408 * same number of tuples and only one component.
2409 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2410 * same number of tuples as \a this array and one component.
2411 * The caller is to delete this result array using decrRef() as it is no more
2413 * \throw If \a this is not allocated.
2414 * \sa DataArrayDouble::maxPerTuple
2416 DataArrayDouble *DataArrayDouble::maxPerTupleWithCompoId(DataArrayInt* &compoIdOfMaxPerTuple) const
2419 int nbOfComp=getNumberOfComponents();
2420 MCAuto<DataArrayDouble> ret0=DataArrayDouble::New();
2421 MCAuto<DataArrayInt> ret1=DataArrayInt::New();
2422 int nbOfTuple=getNumberOfTuples();
2423 ret0->alloc(nbOfTuple,1); ret1->alloc(nbOfTuple,1);
2424 const double *src=getConstPointer();
2425 double *dest=ret0->getPointer(); int *dest1=ret1->getPointer();
2426 for(int i=0;i<nbOfTuple;i++,dest++,dest1++,src+=nbOfComp)
2428 const double *loc=std::max_element(src,src+nbOfComp);
2430 *dest1=(int)std::distance(src,loc);
2432 compoIdOfMaxPerTuple=ret1.retn();
2437 * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c this->getNumberOfTuples() tuples.
2438 * \n This returned array contains the euclidian distance for each tuple in \a this.
2439 * \n So the returned array can be seen as a dense symmetrical matrix whose diagonal elements are equal to 0.
2440 * \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)
2442 * \warning use this method with care because it can leads to big amount of consumed memory !
2444 * \return A newly allocated (huge) MEDCoupling::DataArrayDouble instance that the caller should deal with.
2446 * \throw If \a this is not allocated.
2448 * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrixWith
2450 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrix() const
2453 int nbOfComp=getNumberOfComponents();
2454 int nbOfTuples=getNumberOfTuples();
2455 const double *inData=getConstPointer();
2456 MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
2457 ret->alloc(nbOfTuples*nbOfTuples,1);
2458 double *outData=ret->getPointer();
2459 for(int i=0;i<nbOfTuples;i++)
2461 outData[i*nbOfTuples+i]=0.;
2462 for(int j=i+1;j<nbOfTuples;j++)
2465 for(int k=0;k<nbOfComp;k++)
2466 { double delta=inData[i*nbOfComp+k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
2468 outData[i*nbOfTuples+j]=dist;
2469 outData[j*nbOfTuples+i]=dist;
2476 * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c other->getNumberOfTuples() tuples.
2477 * \n This returned array contains the euclidian distance for each tuple in \a other with each tuple in \a this.
2478 * \n So the returned array can be seen as a dense rectangular matrix with \c other->getNumberOfTuples() rows and \c this->getNumberOfTuples() columns.
2479 * \n Output rectangular matrix is sorted along rows.
2480 * \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)
2482 * \warning use this method with care because it can leads to big amount of consumed memory !
2484 * \param [in] other DataArrayDouble instance having same number of components than \a this.
2485 * \return A newly allocated (huge) MEDCoupling::DataArrayDouble instance that the caller should deal with.
2487 * \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.
2489 * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrix
2491 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrixWith(const DataArrayDouble *other) const
2494 throw INTERP_KERNEL::Exception("DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : input parameter is null !");
2496 other->checkAllocated();
2497 int nbOfComp=getNumberOfComponents();
2498 int otherNbOfComp=other->getNumberOfComponents();
2499 if(nbOfComp!=otherNbOfComp)
2501 std::ostringstream oss; oss << "DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : this nb of compo=" << nbOfComp << " and other nb of compo=" << otherNbOfComp << ". It should match !";
2502 throw INTERP_KERNEL::Exception(oss.str().c_str());
2504 int nbOfTuples=getNumberOfTuples();
2505 int otherNbOfTuples=other->getNumberOfTuples();
2506 const double *inData=getConstPointer();
2507 const double *inDataOther=other->getConstPointer();
2508 MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
2509 ret->alloc(otherNbOfTuples*nbOfTuples,1);
2510 double *outData=ret->getPointer();
2511 for(int i=0;i<otherNbOfTuples;i++,inDataOther+=nbOfComp)
2513 for(int j=0;j<nbOfTuples;j++)
2516 for(int k=0;k<nbOfComp;k++)
2517 { double delta=inDataOther[k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
2519 outData[i*nbOfTuples+j]=dist;
2526 * This method expects that \a this stores 3 tuples containing 2 components each.
2527 * Each of this tuples represent a point into 2D space.
2528 * 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).
2529 * 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[.
2531 * \throw If \a this is not allocated.
2532 * \throw If \a this has not 3 tuples of 2 components
2533 * \throw If tuples/points in \a this are aligned
2535 void DataArrayDouble::asArcOfCircle(double center[2], double& radius, double& ang) const
2538 INTERP_KERNEL::QuadraticPlanarPrecision arcPrec(1e-14);
2539 if(getNumberOfTuples()!=3 && getNumberOfComponents()!=2)
2540 throw INTERP_KERNEL::Exception("DataArrayDouble::asArcCircle : this method expects");
2541 const double *pt(begin());
2542 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]));
2544 INTERP_KERNEL::AutoCppPtr<INTERP_KERNEL::EdgeLin> e1(new INTERP_KERNEL::EdgeLin(n0,n2)),e2(new INTERP_KERNEL::EdgeLin(n2,n1));
2545 INTERP_KERNEL::SegSegIntersector inters(*e1,*e2);
2546 bool colinearity(inters.areColinears());
2548 throw INTERP_KERNEL::Exception("DataArrayDouble::asArcOfCircle : 3 points in this have been detected as colinear !");
2550 INTERP_KERNEL::AutoCppPtr<INTERP_KERNEL::EdgeArcCircle> ret(new INTERP_KERNEL::EdgeArcCircle(n0,n2,n1));
2551 const double *c(ret->getCenter());
2552 center[0]=c[0]; center[1]=c[1];
2553 radius=ret->getRadius();
2554 ang=ret->getAngle();
2558 * Sorts value within every tuple of \a this array.
2559 * \param [in] asc - if \a true, the values are sorted in ascending order, else,
2560 * in descending order.
2561 * \throw If \a this is not allocated.
2563 void DataArrayDouble::sortPerTuple(bool asc)
2566 double *pt=getPointer();
2567 int nbOfTuple=getNumberOfTuples();
2568 int nbOfComp=getNumberOfComponents();
2570 for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
2571 std::sort(pt,pt+nbOfComp);
2573 for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
2574 std::sort(pt,pt+nbOfComp,std::greater<double>());
2579 * Modify all elements of \a this array, so that
2580 * an element _x_ becomes \f$ numerator / x \f$.
2581 * \warning If an exception is thrown because of presence of 0.0 element in \a this
2582 * array, all elements processed before detection of the zero element remain
2584 * \param [in] numerator - the numerator used to modify array elements.
2585 * \throw If \a this is not allocated.
2586 * \throw If there is an element equal to 0.0 in \a this array.
2588 void DataArrayDouble::applyInv(double numerator)
2591 double *ptr=getPointer();
2592 std::size_t nbOfElems=getNbOfElems();
2593 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2595 if(std::abs(*ptr)>std::numeric_limits<double>::min())
2597 *ptr=numerator/(*ptr);
2601 std::ostringstream oss; oss << "DataArrayDouble::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
2603 throw INTERP_KERNEL::Exception(oss.str().c_str());
2610 * Modify all elements of \a this array, so that
2611 * an element _x_ becomes <em> val ^ x </em>. Contrary to DataArrayInt::applyPow
2612 * all values in \a this have to be >= 0 if val is \b not integer.
2613 * \param [in] val - the value used to apply pow on all array elements.
2614 * \throw If \a this is not allocated.
2615 * \warning If an exception is thrown because of presence of 0 element in \a this
2616 * array and \a val is \b not integer, all elements processed before detection of the zero element remain
2619 void DataArrayDouble::applyPow(double val)
2622 double *ptr=getPointer();
2623 std::size_t nbOfElems=getNbOfElems();
2625 bool isInt=((double)val2)==val;
2628 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2634 std::ostringstream oss; oss << "DataArrayDouble::applyPow (double) : At elem # " << i << " value is " << *ptr << " ! must be >=0. !";
2635 throw INTERP_KERNEL::Exception(oss.str().c_str());
2641 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2642 *ptr=pow(*ptr,val2);
2648 * Modify all elements of \a this array, so that
2649 * an element _x_ becomes \f$ val ^ x \f$.
2650 * \param [in] val - the value used to apply pow on all array elements.
2651 * \throw If \a this is not allocated.
2652 * \throw If \a val < 0.
2653 * \warning If an exception is thrown because of presence of 0 element in \a this
2654 * array, all elements processed before detection of the zero element remain
2657 void DataArrayDouble::applyRPow(double val)
2661 throw INTERP_KERNEL::Exception("DataArrayDouble::applyRPow : the input value has to be >= 0 !");
2662 double *ptr=getPointer();
2663 std::size_t nbOfElems=getNbOfElems();
2664 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2670 * Returns a new DataArrayDouble created from \a this one by applying \a
2671 * FunctionToEvaluate to every tuple of \a this array. Textual data is not copied.
2672 * For more info see \ref MEDCouplingArrayApplyFunc
2673 * \param [in] nbOfComp - number of components in the result array.
2674 * \param [in] func - the \a FunctionToEvaluate declared as
2675 * \c bool (*\a func)(\c const \c double *\a pos, \c double *\a res),
2676 * where \a pos points to the first component of a tuple of \a this array
2677 * and \a res points to the first component of a tuple of the result array.
2678 * Note that length (number of components) of \a pos can differ from
2680 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2681 * same number of tuples as \a this array.
2682 * The caller is to delete this result array using decrRef() as it is no more
2684 * \throw If \a this is not allocated.
2685 * \throw If \a func returns \a false.
2687 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, FunctionToEvaluate func) const
2690 DataArrayDouble *newArr=DataArrayDouble::New();
2691 int nbOfTuples=getNumberOfTuples();
2692 int oldNbOfComp=getNumberOfComponents();
2693 newArr->alloc(nbOfTuples,nbOfComp);
2694 const double *ptr=getConstPointer();
2695 double *ptrToFill=newArr->getPointer();
2696 for(int i=0;i<nbOfTuples;i++)
2698 if(!func(ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp))
2700 std::ostringstream oss; oss << "For tuple # " << i << " with value (";
2701 std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
2702 oss << ") : Evaluation of function failed !";
2704 throw INTERP_KERNEL::Exception(oss.str().c_str());
2711 * Returns a new DataArrayDouble created from \a this one by applying a function to every
2712 * tuple of \a this array. Textual data is not copied.
2713 * For more info see \ref MEDCouplingArrayApplyFunc1.
2714 * \param [in] nbOfComp - number of components in the result array.
2715 * \param [in] func - the expression defining how to transform a tuple of \a this array.
2716 * Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
2717 * \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
2718 * If false the computation is carried on without any notification. When false the evaluation is a little faster.
2719 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2720 * same number of tuples as \a this array and \a nbOfComp components.
2721 * The caller is to delete this result array using decrRef() as it is no more
2723 * \throw If \a this is not allocated.
2724 * \throw If computing \a func fails.
2726 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, const std::string& func, bool isSafe) const
2728 INTERP_KERNEL::ExprParser expr(func);
2730 std::set<std::string> vars;
2731 expr.getTrueSetOfVars(vars);
2732 std::vector<std::string> varsV(vars.begin(),vars.end());
2733 return applyFuncNamedCompo(nbOfComp,varsV,func,isSafe);
2737 * Returns a new DataArrayDouble created from \a this one by applying a function to every
2738 * tuple of \a this array. Textual data is not copied. This method works by tuples (whatever its size).
2739 * If \a this is a one component array, call applyFuncOnThis instead that performs the same work faster.
2741 * For more info see \ref MEDCouplingArrayApplyFunc0.
2742 * \param [in] func - the expression defining how to transform a tuple of \a this array.
2743 * Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
2744 * \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
2745 * If false the computation is carried on without any notification. When false the evaluation is a little faster.
2746 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2747 * same number of tuples and components as \a this array.
2748 * The caller is to delete this result array using decrRef() as it is no more
2750 * \sa applyFuncOnThis
2751 * \throw If \a this is not allocated.
2752 * \throw If computing \a func fails.
2754 DataArrayDouble *DataArrayDouble::applyFunc(const std::string& func, bool isSafe) const
2756 int nbOfComp(getNumberOfComponents());
2758 throw INTERP_KERNEL::Exception("DataArrayDouble::applyFunc : output number of component must be > 0 !");
2760 int nbOfTuples(getNumberOfTuples());
2761 MCAuto<DataArrayDouble> newArr(DataArrayDouble::New());
2762 newArr->alloc(nbOfTuples,nbOfComp);
2763 INTERP_KERNEL::ExprParser expr(func);
2765 std::set<std::string> vars;
2766 expr.getTrueSetOfVars(vars);
2767 if((int)vars.size()>1)
2769 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 : ";
2770 std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
2771 throw INTERP_KERNEL::Exception(oss.str().c_str());
2775 expr.prepareFastEvaluator();
2776 newArr->rearrange(1);
2777 newArr->fillWithValue(expr.evaluateDouble());
2778 newArr->rearrange(nbOfComp);
2779 return newArr.retn();
2781 std::vector<std::string> vars2(vars.begin(),vars.end());
2782 double buff,*ptrToFill(newArr->getPointer());
2783 const double *ptr(begin());
2784 std::vector<double> stck;
2785 expr.prepareExprEvaluationDouble(vars2,1,1,0,&buff,&buff+1);
2786 expr.prepareFastEvaluator();
2789 for(int i=0;i<nbOfTuples;i++)
2791 for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
2794 expr.evaluateDoubleInternal(stck);
2795 *ptrToFill=stck.back();
2802 for(int i=0;i<nbOfTuples;i++)
2804 for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
2809 expr.evaluateDoubleInternalSafe(stck);
2811 catch(INTERP_KERNEL::Exception& e)
2813 std::ostringstream oss; oss << "For tuple # " << i << " component # " << iComp << " with value (";
2815 oss << ") : Evaluation of function failed !" << e.what();
2816 throw INTERP_KERNEL::Exception(oss.str().c_str());
2818 *ptrToFill=stck.back();
2823 return newArr.retn();
2827 * This method is a non const method that modify the array in \a this.
2828 * This method only works on one component array. It means that function \a func must
2829 * contain at most one variable.
2830 * This method is a specialization of applyFunc method with one parameter on one component array.
2832 * \param [in] func - the expression defining how to transform a tuple of \a this array.
2833 * Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
2834 * \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
2835 * If false the computation is carried on without any notification. When false the evaluation is a little faster.
2839 void DataArrayDouble::applyFuncOnThis(const std::string& func, bool isSafe)
2841 int nbOfComp(getNumberOfComponents());
2843 throw INTERP_KERNEL::Exception("DataArrayDouble::applyFuncOnThis : output number of component must be > 0 !");
2845 int nbOfTuples(getNumberOfTuples());
2846 INTERP_KERNEL::ExprParser expr(func);
2848 std::set<std::string> vars;
2849 expr.getTrueSetOfVars(vars);
2850 if((int)vars.size()>1)
2852 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 : ";
2853 std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
2854 throw INTERP_KERNEL::Exception(oss.str().c_str());
2858 expr.prepareFastEvaluator();
2859 std::vector<std::string> compInfo(getInfoOnComponents());
2861 fillWithValue(expr.evaluateDouble());
2862 rearrange(nbOfComp);
2863 setInfoOnComponents(compInfo);
2866 std::vector<std::string> vars2(vars.begin(),vars.end());
2867 double buff,*ptrToFill(getPointer());
2868 const double *ptr(begin());
2869 std::vector<double> stck;
2870 expr.prepareExprEvaluationDouble(vars2,1,1,0,&buff,&buff+1);
2871 expr.prepareFastEvaluator();
2874 for(int i=0;i<nbOfTuples;i++)
2876 for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
2879 expr.evaluateDoubleInternal(stck);
2880 *ptrToFill=stck.back();
2887 for(int i=0;i<nbOfTuples;i++)
2889 for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
2894 expr.evaluateDoubleInternalSafe(stck);
2896 catch(INTERP_KERNEL::Exception& e)
2898 std::ostringstream oss; oss << "For tuple # " << i << " component # " << iComp << " with value (";
2900 oss << ") : Evaluation of function failed !" << e.what();
2901 throw INTERP_KERNEL::Exception(oss.str().c_str());
2903 *ptrToFill=stck.back();
2911 * Returns a new DataArrayDouble created from \a this one by applying a function to every
2912 * tuple of \a this array. Textual data is not copied.
2913 * For more info see \ref MEDCouplingArrayApplyFunc2.
2914 * \param [in] nbOfComp - number of components in the result array.
2915 * \param [in] func - the expression defining how to transform a tuple of \a this array.
2916 * Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
2917 * \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
2918 * If false the computation is carried on without any notification. When false the evaluation is a little faster.
2919 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2920 * same number of tuples as \a this array.
2921 * The caller is to delete this result array using decrRef() as it is no more
2923 * \throw If \a this is not allocated.
2924 * \throw If \a func contains vars that are not in \a this->getInfoOnComponent().
2925 * \throw If computing \a func fails.
2927 DataArrayDouble *DataArrayDouble::applyFuncCompo(int nbOfComp, const std::string& func, bool isSafe) const
2929 return applyFuncNamedCompo(nbOfComp,getVarsOnComponent(),func,isSafe);
2933 * Returns a new DataArrayDouble created from \a this one by applying a function to every
2934 * tuple of \a this array. Textual data is not copied.
2935 * For more info see \ref MEDCouplingArrayApplyFunc3.
2936 * \param [in] nbOfComp - number of components in the result array.
2937 * \param [in] varsOrder - sequence of vars defining their order.
2938 * \param [in] func - the expression defining how to transform a tuple of \a this array.
2939 * Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
2940 * \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
2941 * If false the computation is carried on without any notification. When false the evaluation is a little faster.
2942 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2943 * same number of tuples as \a this array.
2944 * The caller is to delete this result array using decrRef() as it is no more
2946 * \throw If \a this is not allocated.
2947 * \throw If \a func contains vars not in \a varsOrder.
2948 * \throw If computing \a func fails.
2950 DataArrayDouble *DataArrayDouble::applyFuncNamedCompo(int nbOfComp, const std::vector<std::string>& varsOrder, const std::string& func, bool isSafe) const
2953 throw INTERP_KERNEL::Exception("DataArrayDouble::applyFuncNamedCompo : output number of component must be > 0 !");
2954 std::vector<std::string> varsOrder2(varsOrder);
2955 int oldNbOfComp(getNumberOfComponents());
2956 for(int i=(int)varsOrder.size();i<oldNbOfComp;i++)
2957 varsOrder2.push_back(std::string());
2959 int nbOfTuples(getNumberOfTuples());
2960 INTERP_KERNEL::ExprParser expr(func);
2962 std::set<std::string> vars;
2963 expr.getTrueSetOfVars(vars);
2964 if((int)vars.size()>oldNbOfComp)
2966 std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
2967 oss << vars.size() << " variables : ";
2968 std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
2969 throw INTERP_KERNEL::Exception(oss.str().c_str());
2971 MCAuto<DataArrayDouble> newArr(DataArrayDouble::New());
2972 newArr->alloc(nbOfTuples,nbOfComp);
2973 INTERP_KERNEL::AutoPtr<double> buff(new double[oldNbOfComp]);
2974 double *buffPtr(buff),*ptrToFill;
2975 std::vector<double> stck;
2976 for(int iComp=0;iComp<nbOfComp;iComp++)
2978 expr.prepareExprEvaluationDouble(varsOrder2,oldNbOfComp,nbOfComp,iComp,buffPtr,buffPtr+oldNbOfComp);
2979 expr.prepareFastEvaluator();
2980 const double *ptr(getConstPointer());
2981 ptrToFill=newArr->getPointer()+iComp;
2984 for(int i=0;i<nbOfTuples;i++,ptrToFill+=nbOfComp,ptr+=oldNbOfComp)
2986 std::copy(ptr,ptr+oldNbOfComp,buffPtr);
2987 expr.evaluateDoubleInternal(stck);
2988 *ptrToFill=stck.back();
2994 for(int i=0;i<nbOfTuples;i++,ptrToFill+=nbOfComp,ptr+=oldNbOfComp)
2996 std::copy(ptr,ptr+oldNbOfComp,buffPtr);
2999 expr.evaluateDoubleInternalSafe(stck);
3000 *ptrToFill=stck.back();
3003 catch(INTERP_KERNEL::Exception& e)
3005 std::ostringstream oss; oss << "For tuple # " << i << " with value (";
3006 std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
3007 oss << ") : Evaluation of function failed !" << e.what();
3008 throw INTERP_KERNEL::Exception(oss.str().c_str());
3013 return newArr.retn();
3016 void DataArrayDouble::applyFuncFast32(const std::string& func)
3019 INTERP_KERNEL::ExprParser expr(func);
3021 char *funcStr=expr.compileX86();
3023 *((void **)&funcPtr)=funcStr;//he he...
3025 double *ptr=getPointer();
3026 int nbOfComp=getNumberOfComponents();
3027 int nbOfTuples=getNumberOfTuples();
3028 int nbOfElems=nbOfTuples*nbOfComp;
3029 for(int i=0;i<nbOfElems;i++,ptr++)
3034 void DataArrayDouble::applyFuncFast64(const std::string& func)
3037 INTERP_KERNEL::ExprParser expr(func);
3039 char *funcStr=expr.compileX86_64();
3041 *((void **)&funcPtr)=funcStr;//he he...
3043 double *ptr=getPointer();
3044 int nbOfComp=getNumberOfComponents();
3045 int nbOfTuples=getNumberOfTuples();
3046 int nbOfElems=nbOfTuples*nbOfComp;
3047 for(int i=0;i<nbOfElems;i++,ptr++)
3053 * \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.
3055 MCAuto<DataArrayDouble> DataArrayDouble::symmetry3DPlane(const double point[3], const double normalVector[3]) const
3058 if(getNumberOfComponents()!=3)
3059 throw INTERP_KERNEL::Exception("DataArrayDouble::symmetry3DPlane : this is excepted to have 3 components !");
3060 int nbTuples(getNumberOfTuples());
3061 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
3062 ret->alloc(nbTuples,3);
3063 Symmetry3DPlane(point,normalVector,nbTuples,begin(),ret->getPointer());
3067 DataArrayDoubleIterator *DataArrayDouble::iterator()
3069 return new DataArrayDoubleIterator(this);
3073 * Returns a new DataArrayInt containing indices of tuples of \a this one-dimensional
3074 * array whose values are within a given range. Textual data is not copied.
3075 * \param [in] vmin - a lowest acceptable value (included).
3076 * \param [in] vmax - a greatest acceptable value (included).
3077 * \return DataArrayInt * - the new instance of DataArrayInt.
3078 * The caller is to delete this result array using decrRef() as it is no more
3080 * \throw If \a this->getNumberOfComponents() != 1.
3082 * \sa DataArrayDouble::findIdsNotInRange
3084 * \if ENABLE_EXAMPLES
3085 * \ref cpp_mcdataarraydouble_getidsinrange "Here is a C++ example".<br>
3086 * \ref py_mcdataarraydouble_getidsinrange "Here is a Python example".
3089 DataArrayInt *DataArrayDouble::findIdsInRange(double vmin, double vmax) const
3092 if(getNumberOfComponents()!=1)
3093 throw INTERP_KERNEL::Exception("DataArrayDouble::findIdsInRange : this must have exactly one component !");
3094 const double *cptr(begin());
3095 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
3096 int nbOfTuples(getNumberOfTuples());
3097 for(int i=0;i<nbOfTuples;i++,cptr++)
3098 if(*cptr>=vmin && *cptr<=vmax)
3099 ret->pushBackSilent(i);
3104 * Returns a new DataArrayInt containing indices of tuples of \a this one-dimensional
3105 * array whose values are not within a given range. Textual data is not copied.
3106 * \param [in] vmin - a lowest not acceptable value (excluded).
3107 * \param [in] vmax - a greatest not acceptable value (excluded).
3108 * \return DataArrayInt * - the new instance of DataArrayInt.
3109 * The caller is to delete this result array using decrRef() as it is no more
3111 * \throw If \a this->getNumberOfComponents() != 1.
3113 * \sa DataArrayDouble::findIdsInRange
3115 DataArrayInt *DataArrayDouble::findIdsNotInRange(double vmin, double vmax) const
3118 if(getNumberOfComponents()!=1)
3119 throw INTERP_KERNEL::Exception("DataArrayDouble::findIdsNotInRange : this must have exactly one component !");
3120 const double *cptr(begin());
3121 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
3122 int nbOfTuples(getNumberOfTuples());
3123 for(int i=0;i<nbOfTuples;i++,cptr++)
3124 if(*cptr<vmin || *cptr>vmax)
3125 ret->pushBackSilent(i);
3130 * Returns a new DataArrayDouble by concatenating two given arrays, so that (1) the number
3131 * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
3132 * the number of component in the result array is same as that of each of given arrays.
3133 * Info on components is copied from the first of the given arrays. Number of components
3134 * in the given arrays must be the same.
3135 * \param [in] a1 - an array to include in the result array.
3136 * \param [in] a2 - another array to include in the result array.
3137 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3138 * The caller is to delete this result array using decrRef() as it is no more
3140 * \throw If both \a a1 and \a a2 are NULL.
3141 * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
3143 DataArrayDouble *DataArrayDouble::Aggregate(const DataArrayDouble *a1, const DataArrayDouble *a2)
3145 std::vector<const DataArrayDouble *> tmp(2);
3146 tmp[0]=a1; tmp[1]=a2;
3147 return Aggregate(tmp);
3151 * Returns a new DataArrayDouble by concatenating all given arrays, so that (1) the number
3152 * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
3153 * the number of component in the result array is same as that of each of given arrays.
3154 * Info on components is copied from the first of the given arrays. Number of components
3155 * in the given arrays must be the same.
3156 * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it
3157 * not the object itself.
3158 * \param [in] arr - a sequence of arrays to include in the result array.
3159 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3160 * The caller is to delete this result array using decrRef() as it is no more
3162 * \throw If all arrays within \a arr are NULL.
3163 * \throw If getNumberOfComponents() of arrays within \a arr.
3165 DataArrayDouble *DataArrayDouble::Aggregate(const std::vector<const DataArrayDouble *>& arr)
3167 std::vector<const DataArrayDouble *> a;
3168 for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
3172 throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : input list must contain at least one NON EMPTY DataArrayDouble !");
3173 std::vector<const DataArrayDouble *>::const_iterator it=a.begin();
3174 std::size_t nbOfComp((*it)->getNumberOfComponents());
3175 int nbt=(*it++)->getNumberOfTuples();
3176 for(int i=1;it!=a.end();it++,i++)
3178 if((*it)->getNumberOfComponents()!=nbOfComp)
3179 throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : Nb of components mismatch for array aggregation !");
3180 nbt+=(*it)->getNumberOfTuples();
3182 MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
3183 ret->alloc(nbt,nbOfComp);
3184 double *pt=ret->getPointer();
3185 for(it=a.begin();it!=a.end();it++)
3186 pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
3187 ret->copyStringInfoFrom(*(a[0]));
3192 * Returns a new DataArrayDouble containing a dot product of two given arrays, so that
3193 * the i-th tuple of the result array is a sum of products of j-th components of i-th
3194 * tuples of given arrays (\f$ a_i = \sum_{j=1}^n a1_j * a2_j \f$).
3195 * Info on components and name is copied from the first of the given arrays.
3196 * Number of tuples and components in the given arrays must be the same.
3197 * \param [in] a1 - a given array.
3198 * \param [in] a2 - another given array.
3199 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3200 * The caller is to delete this result array using decrRef() as it is no more
3202 * \throw If either \a a1 or \a a2 is NULL.
3203 * \throw If any given array is not allocated.
3204 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3205 * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
3207 DataArrayDouble *DataArrayDouble::Dot(const DataArrayDouble *a1, const DataArrayDouble *a2)
3210 throw INTERP_KERNEL::Exception("DataArrayDouble::Dot : input DataArrayDouble instance is NULL !");
3211 a1->checkAllocated();
3212 a2->checkAllocated();
3213 std::size_t nbOfComp(a1->getNumberOfComponents());
3214 if(nbOfComp!=a2->getNumberOfComponents())
3215 throw INTERP_KERNEL::Exception("Nb of components mismatch for array Dot !");
3216 std::size_t nbOfTuple(a1->getNumberOfTuples());
3217 if(nbOfTuple!=a2->getNumberOfTuples())
3218 throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Dot !");
3219 DataArrayDouble *ret=DataArrayDouble::New();
3220 ret->alloc(nbOfTuple,1);
3221 double *retPtr=ret->getPointer();
3222 const double *a1Ptr=a1->begin(),*a2Ptr(a2->begin());
3223 for(std::size_t i=0;i<nbOfTuple;i++)
3226 for(std::size_t j=0;j<nbOfComp;j++)
3227 sum+=a1Ptr[i*nbOfComp+j]*a2Ptr[i*nbOfComp+j];
3230 ret->setInfoOnComponent(0,a1->getInfoOnComponent(0));
3231 ret->setName(a1->getName());
3236 * Returns a new DataArrayDouble containing a cross product of two given arrays, so that
3237 * the i-th tuple of the result array contains 3 components of a vector which is a cross
3238 * product of two vectors defined by the i-th tuples of given arrays.
3239 * Info on components is copied from the first of the given arrays.
3240 * Number of tuples in the given arrays must be the same.
3241 * Number of components in the given arrays must be 3.
3242 * \param [in] a1 - a given array.
3243 * \param [in] a2 - another given array.
3244 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3245 * The caller is to delete this result array using decrRef() as it is no more
3247 * \throw If either \a a1 or \a a2 is NULL.
3248 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3249 * \throw If \a a1->getNumberOfComponents() != 3
3250 * \throw If \a a2->getNumberOfComponents() != 3
3252 DataArrayDouble *DataArrayDouble::CrossProduct(const DataArrayDouble *a1, const DataArrayDouble *a2)
3255 throw INTERP_KERNEL::Exception("DataArrayDouble::CrossProduct : input DataArrayDouble instance is NULL !");
3256 std::size_t nbOfComp(a1->getNumberOfComponents());
3257 if(nbOfComp!=a2->getNumberOfComponents())
3258 throw INTERP_KERNEL::Exception("Nb of components mismatch for array crossProduct !");
3260 throw INTERP_KERNEL::Exception("Nb of components must be equal to 3 for array crossProduct !");
3261 std::size_t nbOfTuple(a1->getNumberOfTuples());
3262 if(nbOfTuple!=a2->getNumberOfTuples())
3263 throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array crossProduct !");
3264 DataArrayDouble *ret=DataArrayDouble::New();
3265 ret->alloc(nbOfTuple,3);
3266 double *retPtr=ret->getPointer();
3267 const double *a1Ptr(a1->begin()),*a2Ptr(a2->begin());
3268 for(std::size_t i=0;i<nbOfTuple;i++)
3270 retPtr[3*i]=a1Ptr[3*i+1]*a2Ptr[3*i+2]-a1Ptr[3*i+2]*a2Ptr[3*i+1];
3271 retPtr[3*i+1]=a1Ptr[3*i+2]*a2Ptr[3*i]-a1Ptr[3*i]*a2Ptr[3*i+2];
3272 retPtr[3*i+2]=a1Ptr[3*i]*a2Ptr[3*i+1]-a1Ptr[3*i+1]*a2Ptr[3*i];
3274 ret->copyStringInfoFrom(*a1);
3279 * Returns a new DataArrayDouble containing maximal values of two given arrays.
3280 * Info on components is copied from the first of the given arrays.
3281 * Number of tuples and components in the given arrays must be the same.
3282 * \param [in] a1 - an array to compare values with another one.
3283 * \param [in] a2 - another array to compare values with the first one.
3284 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3285 * The caller is to delete this result array using decrRef() as it is no more
3287 * \throw If either \a a1 or \a a2 is NULL.
3288 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3289 * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
3291 DataArrayDouble *DataArrayDouble::Max(const DataArrayDouble *a1, const DataArrayDouble *a2)
3294 throw INTERP_KERNEL::Exception("DataArrayDouble::Max : input DataArrayDouble instance is NULL !");
3295 std::size_t nbOfComp(a1->getNumberOfComponents());
3296 if(nbOfComp!=a2->getNumberOfComponents())
3297 throw INTERP_KERNEL::Exception("Nb of components mismatch for array Max !");
3298 std::size_t nbOfTuple(a1->getNumberOfTuples());
3299 if(nbOfTuple!=a2->getNumberOfTuples())
3300 throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Max !");
3301 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
3302 ret->alloc(nbOfTuple,nbOfComp);
3303 double *retPtr(ret->getPointer());
3304 const double *a1Ptr(a1->begin()),*a2Ptr(a2->begin());
3305 std::size_t nbElem(nbOfTuple*nbOfComp);
3306 for(std::size_t i=0;i<nbElem;i++)
3307 retPtr[i]=std::max(a1Ptr[i],a2Ptr[i]);
3308 ret->copyStringInfoFrom(*a1);
3313 * Returns a new DataArrayDouble containing minimal values of two given arrays.
3314 * Info on components is copied from the first of the given arrays.
3315 * Number of tuples and components in the given arrays must be the same.
3316 * \param [in] a1 - an array to compare values with another one.
3317 * \param [in] a2 - another array to compare values with the first one.
3318 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3319 * The caller is to delete this result array using decrRef() as it is no more
3321 * \throw If either \a a1 or \a a2 is NULL.
3322 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3323 * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
3325 DataArrayDouble *DataArrayDouble::Min(const DataArrayDouble *a1, const DataArrayDouble *a2)
3328 throw INTERP_KERNEL::Exception("DataArrayDouble::Min : input DataArrayDouble instance is NULL !");
3329 std::size_t nbOfComp(a1->getNumberOfComponents());
3330 if(nbOfComp!=a2->getNumberOfComponents())
3331 throw INTERP_KERNEL::Exception("Nb of components mismatch for array min !");
3332 std::size_t nbOfTuple(a1->getNumberOfTuples());
3333 if(nbOfTuple!=a2->getNumberOfTuples())
3334 throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array min !");
3335 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
3336 ret->alloc(nbOfTuple,nbOfComp);
3337 double *retPtr(ret->getPointer());
3338 const double *a1Ptr(a1->begin()),*a2Ptr(a2->begin());
3339 std::size_t nbElem(nbOfTuple*nbOfComp);
3340 for(std::size_t i=0;i<nbElem;i++)
3341 retPtr[i]=std::min(a1Ptr[i],a2Ptr[i]);
3342 ret->copyStringInfoFrom(*a1);
3347 * Returns a new DataArrayDouble that is the result of pow of two given arrays. There are 3
3350 * \param [in] a1 - an array to pow up.
3351 * \param [in] a2 - another array to sum up.
3352 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3353 * The caller is to delete this result array using decrRef() as it is no more
3355 * \throw If either \a a1 or \a a2 is NULL.
3356 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3357 * \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
3358 * \throw If there is a negative value in \a a1.
3360 DataArrayDouble *DataArrayDouble::Pow(const DataArrayDouble *a1, const DataArrayDouble *a2)
3363 throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : at least one of input instances is null !");
3364 int nbOfTuple=a1->getNumberOfTuples();
3365 int nbOfTuple2=a2->getNumberOfTuples();
3366 int nbOfComp=a1->getNumberOfComponents();
3367 int nbOfComp2=a2->getNumberOfComponents();
3368 if(nbOfTuple!=nbOfTuple2)
3369 throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of tuples mismatches !");
3370 if(nbOfComp!=1 || nbOfComp2!=1)
3371 throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of components of both arrays must be equal to 1 !");
3372 MCAuto<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbOfTuple,1);
3373 const double *ptr1(a1->begin()),*ptr2(a2->begin());
3374 double *ptr=ret->getPointer();
3375 for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
3379 *ptr=pow(*ptr1,*ptr2);
3383 std::ostringstream oss; oss << "DataArrayDouble::Pow : on tuple #" << i << " of a1 value is < 0 (" << *ptr1 << ") !";
3384 throw INTERP_KERNEL::Exception(oss.str().c_str());
3391 * Apply pow on values of another DataArrayDouble to values of \a this one.
3393 * \param [in] other - an array to pow to \a this one.
3394 * \throw If \a other is NULL.
3395 * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
3396 * \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
3397 * \throw If there is a negative value in \a this.
3399 void DataArrayDouble::powEqual(const DataArrayDouble *other)
3402 throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : input instance is null !");
3403 int nbOfTuple=getNumberOfTuples();
3404 int nbOfTuple2=other->getNumberOfTuples();
3405 int nbOfComp=getNumberOfComponents();
3406 int nbOfComp2=other->getNumberOfComponents();
3407 if(nbOfTuple!=nbOfTuple2)
3408 throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of tuples mismatches !");
3409 if(nbOfComp!=1 || nbOfComp2!=1)
3410 throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of components of both arrays must be equal to 1 !");
3411 double *ptr=getPointer();
3412 const double *ptrc=other->begin();
3413 for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
3416 *ptr=pow(*ptr,*ptrc);
3419 std::ostringstream oss; oss << "DataArrayDouble::powEqual : on tuple #" << i << " of this value is < 0 (" << *ptr << ") !";
3420 throw INTERP_KERNEL::Exception(oss.str().c_str());
3427 * This method is \b NOT wrapped into python because it can be useful only for performance reasons in C++ context.
3428 * All values in \a this must be 0. or 1. within eps error. 0 means false, 1 means true.
3429 * If an another value than 0 or 1 appear (within eps precision) an INTERP_KERNEL::Exception will be thrown.
3431 * \throw if \a this is not allocated.
3432 * \throw if \a this has not exactly one component.
3434 std::vector<bool> DataArrayDouble::toVectorOfBool(double eps) const
3437 if(getNumberOfComponents()!=1)
3438 throw INTERP_KERNEL::Exception("DataArrayDouble::toVectorOfBool : must be applied on single component array !");
3439 int nbt(getNumberOfTuples());
3440 std::vector<bool> ret(nbt);
3441 const double *pt(begin());
3442 for(int i=0;i<nbt;i++)
3446 else if(fabs(pt[i]-1.)<eps)
3450 std::ostringstream oss; oss << "DataArrayDouble::toVectorOfBool : the tuple #" << i << " has value " << pt[i] << " is invalid ! must be 0. or 1. !";
3451 throw INTERP_KERNEL::Exception(oss.str().c_str());
3458 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
3461 void DataArrayDouble::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
3466 tinyInfo[0]=getNumberOfTuples();
3467 tinyInfo[1]=getNumberOfComponents();
3477 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
3480 void DataArrayDouble::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
3484 int nbOfCompo=getNumberOfComponents();
3485 tinyInfo.resize(nbOfCompo+1);
3486 tinyInfo[0]=getName();
3487 for(int i=0;i<nbOfCompo;i++)
3488 tinyInfo[i+1]=getInfoOnComponent(i);
3493 tinyInfo[0]=getName();
3498 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
3499 * This method returns if a feeding is needed.
3501 bool DataArrayDouble::resizeForUnserialization(const std::vector<int>& tinyInfoI)
3503 int nbOfTuple=tinyInfoI[0];
3504 int nbOfComp=tinyInfoI[1];
3505 if(nbOfTuple!=-1 || nbOfComp!=-1)
3507 alloc(nbOfTuple,nbOfComp);
3514 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
3516 void DataArrayDouble::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
3518 setName(tinyInfoS[0]);
3521 int nbOfCompo=getNumberOfComponents();
3522 for(int i=0;i<nbOfCompo;i++)
3523 setInfoOnComponent(i,tinyInfoS[i+1]);
3528 * Low static method that operates 3D rotation of 'nbNodes' 3D nodes whose coordinates are arranged in \a coordsIn
3529 * around an axe ( \a center, \a vect) and with angle \a angle.
3531 void DataArrayDouble::Rotate3DAlg(const double *center, const double *vect, double angle, int nbNodes, const double *coordsIn, double *coordsOut)
3533 if(!center || !vect)
3534 throw INTERP_KERNEL::Exception("DataArrayDouble::Rotate3DAlg : null vector in input !");
3535 double sina(sin(angle));
3536 double cosa(cos(angle));
3537 double vectorNorm[3];
3539 double matrixTmp[9];
3540 double norm(sqrt(vect[0]*vect[0]+vect[1]*vect[1]+vect[2]*vect[2]));
3541 if(norm<std::numeric_limits<double>::min())
3542 throw INTERP_KERNEL::Exception("DataArrayDouble::Rotate3DAlg : magnitude of input vector is too close of 0. !");
3543 std::transform(vect,vect+3,vectorNorm,std::bind2nd(std::multiplies<double>(),1/norm));
3544 //rotation matrix computation
3545 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;
3546 matrixTmp[0]=vectorNorm[0]*vectorNorm[0]; matrixTmp[1]=vectorNorm[0]*vectorNorm[1]; matrixTmp[2]=vectorNorm[0]*vectorNorm[2];
3547 matrixTmp[3]=vectorNorm[1]*vectorNorm[0]; matrixTmp[4]=vectorNorm[1]*vectorNorm[1]; matrixTmp[5]=vectorNorm[1]*vectorNorm[2];
3548 matrixTmp[6]=vectorNorm[2]*vectorNorm[0]; matrixTmp[7]=vectorNorm[2]*vectorNorm[1]; matrixTmp[8]=vectorNorm[2]*vectorNorm[2];
3549 std::transform(matrixTmp,matrixTmp+9,matrixTmp,std::bind2nd(std::multiplies<double>(),1-cosa));
3550 std::transform(matrix,matrix+9,matrixTmp,matrix,std::plus<double>());
3551 matrixTmp[0]=0.; matrixTmp[1]=-vectorNorm[2]; matrixTmp[2]=vectorNorm[1];
3552 matrixTmp[3]=vectorNorm[2]; matrixTmp[4]=0.; matrixTmp[5]=-vectorNorm[0];
3553 matrixTmp[6]=-vectorNorm[1]; matrixTmp[7]=vectorNorm[0]; matrixTmp[8]=0.;
3554 std::transform(matrixTmp,matrixTmp+9,matrixTmp,std::bind2nd(std::multiplies<double>(),sina));
3555 std::transform(matrix,matrix+9,matrixTmp,matrix,std::plus<double>());
3556 //rotation matrix computed.
3558 for(int i=0; i<nbNodes; i++)
3560 std::transform(coordsIn+i*3,coordsIn+(i+1)*3,center,tmp,std::minus<double>());
3561 coordsOut[i*3]=matrix[0]*tmp[0]+matrix[1]*tmp[1]+matrix[2]*tmp[2]+center[0];
3562 coordsOut[i*3+1]=matrix[3]*tmp[0]+matrix[4]*tmp[1]+matrix[5]*tmp[2]+center[1];
3563 coordsOut[i*3+2]=matrix[6]*tmp[0]+matrix[7]*tmp[1]+matrix[8]*tmp[2]+center[2];
3567 void DataArrayDouble::Symmetry3DPlane(const double point[3], const double normalVector[3], int nbNodes, const double *coordsIn, double *coordsOut)
3569 double matrix[9],matrix2[9],matrix3[9];
3570 double vect[3],crossVect[3];
3571 INTERP_KERNEL::orthogonalVect3(normalVector,vect);
3572 crossVect[0]=normalVector[1]*vect[2]-normalVector[2]*vect[1];
3573 crossVect[1]=normalVector[2]*vect[0]-normalVector[0]*vect[2];
3574 crossVect[2]=normalVector[0]*vect[1]-normalVector[1]*vect[0];
3575 double nv(INTERP_KERNEL::norm<3>(vect)),ni(INTERP_KERNEL::norm<3>(normalVector)),nc(INTERP_KERNEL::norm<3>(crossVect));
3576 matrix[0]=vect[0]/nv; matrix[1]=crossVect[0]/nc; matrix[2]=-normalVector[0]/ni;
3577 matrix[3]=vect[1]/nv; matrix[4]=crossVect[1]/nc; matrix[5]=-normalVector[1]/ni;
3578 matrix[6]=vect[2]/nv; matrix[7]=crossVect[2]/nc; matrix[8]=-normalVector[2]/ni;
3579 matrix2[0]=vect[0]/nv; matrix2[1]=vect[1]/nv; matrix2[2]=vect[2]/nv;
3580 matrix2[3]=crossVect[0]/nc; matrix2[4]=crossVect[1]/nc; matrix2[5]=crossVect[2]/nc;
3581 matrix2[6]=normalVector[0]/ni; matrix2[7]=normalVector[1]/ni; matrix2[8]=normalVector[2]/ni;
3582 for(int i=0;i<3;i++)
3583 for(int j=0;j<3;j++)
3586 for(int k=0;k<3;k++)
3587 val+=matrix[3*i+k]*matrix2[3*k+j];
3590 //rotation matrix computed.
3592 for(int i=0; i<nbNodes; i++)
3594 std::transform(coordsIn+i*3,coordsIn+(i+1)*3,point,tmp,std::minus<double>());
3595 coordsOut[i*3]=matrix3[0]*tmp[0]+matrix3[1]*tmp[1]+matrix3[2]*tmp[2]+point[0];
3596 coordsOut[i*3+1]=matrix3[3]*tmp[0]+matrix3[4]*tmp[1]+matrix3[5]*tmp[2]+point[1];
3597 coordsOut[i*3+2]=matrix3[6]*tmp[0]+matrix3[7]*tmp[1]+matrix3[8]*tmp[2]+point[2];
3601 void DataArrayDouble::GiveBaseForPlane(const double normalVector[3], double baseOfPlane[9])
3603 double vect[3],crossVect[3];
3604 INTERP_KERNEL::orthogonalVect3(normalVector,vect);
3605 crossVect[0]=normalVector[1]*vect[2]-normalVector[2]*vect[1];
3606 crossVect[1]=normalVector[2]*vect[0]-normalVector[0]*vect[2];
3607 crossVect[2]=normalVector[0]*vect[1]-normalVector[1]*vect[0];
3608 double nv(INTERP_KERNEL::norm<3>(vect)),ni(INTERP_KERNEL::norm<3>(normalVector)),nc(INTERP_KERNEL::norm<3>(crossVect));
3609 baseOfPlane[0]=vect[0]/nv; baseOfPlane[1]=vect[1]/nv; baseOfPlane[2]=vect[2]/nv;
3610 baseOfPlane[3]=crossVect[0]/nc; baseOfPlane[4]=crossVect[1]/nc; baseOfPlane[5]=crossVect[2]/nc;
3611 baseOfPlane[6]=normalVector[0]/ni; baseOfPlane[7]=normalVector[1]/ni; baseOfPlane[8]=normalVector[2]/ni;
3615 * Low static method that operates 3D rotation of \a nbNodes 3D nodes whose coordinates are arranged in \a coords
3616 * around the center point \a center and with angle \a angle.
3618 void DataArrayDouble::Rotate2DAlg(const double *center, double angle, int nbNodes, const double *coordsIn, double *coordsOut)
3620 double cosa=cos(angle);
3621 double sina=sin(angle);
3623 matrix[0]=cosa; matrix[1]=-sina; matrix[2]=sina; matrix[3]=cosa;
3625 for(int i=0; i<nbNodes; i++)
3627 std::transform(coordsIn+i*2,coordsIn+(i+1)*2,center,tmp,std::minus<double>());
3628 coordsOut[i*2]=matrix[0]*tmp[0]+matrix[1]*tmp[1]+center[0];
3629 coordsOut[i*2+1]=matrix[2]*tmp[0]+matrix[3]*tmp[1]+center[1];
3633 DataArrayDoubleIterator::DataArrayDoubleIterator(DataArrayDouble *da):DataArrayIterator<double>(da)
3637 DataArrayDoubleTuple::DataArrayDoubleTuple(double *pt, int nbOfComp):DataArrayTuple<double>(pt,nbOfComp)
3642 std::string DataArrayDoubleTuple::repr() const
3644 std::ostringstream oss; oss.precision(17); oss << "(";
3645 for(int i=0;i<_nb_of_compo-1;i++)
3646 oss << _pt[i] << ", ";
3647 oss << _pt[_nb_of_compo-1] << ")";
3651 double DataArrayDoubleTuple::doubleValue() const
3653 return this->zeValue();
3657 * This method returns a newly allocated instance the caller should dealed with by a MEDCoupling::DataArrayDouble::decrRef.
3658 * This method performs \b no copy of data. The content is only referenced using MEDCoupling::DataArrayDouble::useArray with ownership set to \b false.
3659 * 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
3660 * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
3662 DataArrayDouble *DataArrayDoubleTuple::buildDADouble(int nbOfTuples, int nbOfCompo) const
3664 return this->buildDA(nbOfTuples,nbOfCompo);
3668 * Returns a new instance of DataArrayInt. The caller is to delete this array
3669 * using decrRef() as it is no more needed.
3671 DataArrayInt *DataArrayInt::New()
3673 return new DataArrayInt;
3677 * Returns the only one value in \a this, if and only if number of elements
3678 * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
3679 * \return double - the sole value stored in \a this array.
3680 * \throw If at least one of conditions stated above is not fulfilled.
3682 int DataArrayInt::intValue() const
3686 if(getNbOfElems()==1)
3688 return *getConstPointer();
3691 throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is allocated but number of elements is not equal to 1 !");
3694 throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is not allocated !");
3698 * Returns an integer value characterizing \a this array, which is useful for a quick
3699 * comparison of many instances of DataArrayInt.
3700 * \return int - the hash value.
3701 * \throw If \a this is not allocated.
3703 int DataArrayInt::getHashCode() const
3706 std::size_t nbOfElems=getNbOfElems();
3707 int ret=nbOfElems*65536;
3712 const int *pt=begin();
3713 for(std::size_t i=0;i<nbOfElems;i+=delta)
3714 ret0+=pt[i] & 0x1FFF;
3719 * Returns a full copy of \a this. For more info on copying data arrays see
3720 * \ref MEDCouplingArrayBasicsCopyDeep.
3721 * \return DataArrayInt * - a new instance of DataArrayInt.
3723 DataArrayInt32 *DataArrayInt32::deepCopy() const
3725 return new DataArrayInt32(*this);
3729 * Returns a textual and human readable representation of \a this instance of
3730 * DataArrayInt. This text is shown when a DataArrayInt is printed in Python.
3731 * \return std::string - text describing \a this DataArrayInt.
3733 * \sa reprNotTooLong, reprZip
3735 std::string DataArrayInt::repr() const
3737 std::ostringstream ret;
3742 std::string DataArrayInt::reprZip() const
3744 std::ostringstream ret;
3749 void DataArrayInt::writeVTK(std::ostream& ofs, int indent, const std::string& type, const std::string& nameInFile, DataArrayByte *byteArr) const
3751 static const char SPACE[4]={' ',' ',' ',' '};
3753 std::string idt(indent,' ');
3754 ofs << idt << "<DataArray type=\"" << type << "\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
3757 ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
3758 if(std::string(type)=="Int32")
3760 const char *data(reinterpret_cast<const char *>(begin()));
3761 std::size_t sz(getNbOfElems()*sizeof(int));
3762 byteArr->insertAtTheEnd(data,data+sz);
3763 byteArr->insertAtTheEnd(SPACE,SPACE+4);
3765 else if(std::string(type)=="Int8")
3767 INTERP_KERNEL::AutoPtr<char> tmp(new char[getNbOfElems()]);
3768 std::copy(begin(),end(),(char *)tmp);
3769 byteArr->insertAtTheEnd((char *)tmp,(char *)tmp+getNbOfElems());
3770 byteArr->insertAtTheEnd(SPACE,SPACE+4);
3772 else if(std::string(type)=="UInt8")
3774 INTERP_KERNEL::AutoPtr<unsigned char> tmp(new unsigned char[getNbOfElems()]);
3775 std::copy(begin(),end(),(unsigned char *)tmp);
3776 byteArr->insertAtTheEnd((unsigned char *)tmp,(unsigned char *)tmp+getNbOfElems());
3777 byteArr->insertAtTheEnd(SPACE,SPACE+4);
3780 throw INTERP_KERNEL::Exception("DataArrayInt::writeVTK : Only Int32, Int8 and UInt8 supported !");
3784 ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
3785 std::copy(begin(),end(),std::ostream_iterator<int>(ofs," "));
3787 ofs << std::endl << idt << "</DataArray>\n";
3790 void DataArrayInt::reprCppStream(const std::string& varName, std::ostream& stream) const
3792 int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
3793 const int *data=getConstPointer();
3794 stream << "DataArrayInt *" << varName << "=DataArrayInt::New();" << std::endl;
3795 if(nbTuples*nbComp>=1)
3797 stream << "const int " << varName << "Data[" << nbTuples*nbComp << "]={";
3798 std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<int>(stream,","));
3799 stream << data[nbTuples*nbComp-1] << "};" << std::endl;
3800 stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
3803 stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
3804 stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
3808 * Method that gives a quick overvien of \a this for python.
3810 void DataArrayInt::reprQuickOverview(std::ostream& stream) const
3812 static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
3813 stream << "DataArrayInt C++ instance at " << this << ". ";
3816 int nbOfCompo=(int)_info_on_compo.size();
3819 int nbOfTuples=getNumberOfTuples();
3820 stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
3821 reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
3824 stream << "Number of components : 0.";
3827 stream << "*** No data allocated ****";
3830 void DataArrayInt::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
3832 const int *data=begin();
3833 int nbOfTuples=getNumberOfTuples();
3834 int nbOfCompo=(int)_info_on_compo.size();
3835 std::ostringstream oss2; oss2 << "[";
3836 std::string oss2Str(oss2.str());
3837 bool isFinished=true;
3838 for(int i=0;i<nbOfTuples && isFinished;i++)
3843 for(int j=0;j<nbOfCompo;j++,data++)
3846 if(j!=nbOfCompo-1) oss2 << ", ";
3852 if(i!=nbOfTuples-1) oss2 << ", ";
3853 std::string oss3Str(oss2.str());
3854 if(oss3Str.length()<maxNbOfByteInRepr)
3866 * Computes distribution of values of \a this one-dimensional array between given value
3867 * ranges (casts). This method is typically useful for entity number splitting by types,
3869 * \warning The values contained in \a arrBg should be sorted ascendently. No
3870 * check of this is be done. If not, the result is not warranted.
3871 * \param [in] arrBg - the array of ascending values defining the value ranges. The i-th
3872 * value of \a arrBg (\a arrBg[ i ]) gives the lowest value of the i-th range,
3873 * and the greatest value of the i-th range equals to \a arrBg[ i+1 ] - 1. \a
3874 * arrBg containing \a n values defines \a n-1 ranges. The last value of \a arrBg
3875 * should be more than every value in \a this array.
3876 * \param [in] arrEnd - specifies the end of the array \a arrBg, so that
3877 * the last value of \a arrBg is \a arrEnd[ -1 ].
3878 * \param [out] castArr - a new instance of DataArrayInt, of same size as \a this array
3879 * (same number of tuples and components), the caller is to delete
3880 * using decrRef() as it is no more needed.
3881 * This array contains indices of ranges for every value of \a this array. I.e.
3882 * the i-th value of \a castArr gives the index of range the i-th value of \a this
3883 * belongs to. Or, in other words, this parameter contains for each tuple in \a
3884 * this in which cast it holds.
3885 * \param [out] rankInsideCast - a new instance of DataArrayInt, of same size as \a this
3886 * array, the caller is to delete using decrRef() as it is no more needed.
3887 * This array contains ranks of values of \a this array within ranges
3888 * they belongs to. I.e. the i-th value of \a rankInsideCast gives the rank of
3889 * the i-th value of \a this array within the \a castArr[ i ]-th range, to which
3890 * the i-th value of \a this belongs to. Or, in other words, this param contains
3891 * for each tuple its rank inside its cast. The rank is computed as difference
3892 * between the value and the lowest value of range.
3893 * \param [out] castsPresent - a new instance of DataArrayInt, containing indices of
3894 * ranges (casts) to which at least one value of \a this array belongs.
3895 * Or, in other words, this param contains the casts that \a this contains.
3896 * The caller is to delete this array using decrRef() as it is no more needed.
3898 * \b Example: If \a this contains [6,5,0,3,2,7,8,1,4] and \a arrBg contains [0,4,9] then
3899 * the output of this method will be :
3900 * - \a castArr : [1,1,0,0,0,1,1,0,1]
3901 * - \a rankInsideCast: [2,1,0,3,2,3,4,1,0]
3902 * - \a castsPresent : [0,1]
3904 * I.e. values of \a this array belong to 2 ranges: #0 and #1. Value 6 belongs to the
3905 * range #1 and its rank within this range is 2; etc.
3907 * \throw If \a this->getNumberOfComponents() != 1.
3908 * \throw If \a arrEnd - arrBg < 2.
3909 * \throw If any value of \a this is not less than \a arrEnd[-1].
3911 void DataArrayInt::splitByValueRange(const int *arrBg, const int *arrEnd,
3912 DataArrayInt *& castArr, DataArrayInt *& rankInsideCast, DataArrayInt *& castsPresent) const
3915 if(getNumberOfComponents()!=1)
3916 throw INTERP_KERNEL::Exception("Call splitByValueRange method on DataArrayInt with only one component, you can call 'rearrange' method before !");
3917 int nbOfTuples=getNumberOfTuples();
3918 std::size_t nbOfCast=std::distance(arrBg,arrEnd);
3920 throw INTERP_KERNEL::Exception("DataArrayInt::splitByValueRange : The input array giving the cast range values should be of size >=2 !");
3922 const int *work=getConstPointer();
3923 typedef std::reverse_iterator<const int *> rintstart;
3924 rintstart bg(arrEnd);//OK no problem because size of 'arr' is greater or equal 2
3925 rintstart end2(arrBg);
3926 MCAuto<DataArrayInt> ret1=DataArrayInt::New();
3927 MCAuto<DataArrayInt> ret2=DataArrayInt::New();
3928 MCAuto<DataArrayInt> ret3=DataArrayInt::New();
3929 ret1->alloc(nbOfTuples,1);
3930 ret2->alloc(nbOfTuples,1);
3931 int *ret1Ptr=ret1->getPointer();
3932 int *ret2Ptr=ret2->getPointer();
3933 std::set<std::size_t> castsDetected;
3934 for(int i=0;i<nbOfTuples;i++)
3936 rintstart res=std::find_if(bg,end2,std::bind2nd(std::less_equal<int>(), work[i]));
3937 std::size_t pos=std::distance(bg,res);
3938 std::size_t pos2=nbOfCast-pos;
3941 ret1Ptr[i]=(int)pos2;
3942 ret2Ptr[i]=work[i]-arrBg[pos2];
3943 castsDetected.insert(pos2);
3947 std::ostringstream oss; oss << "DataArrayInt::splitByValueRange : At rank #" << i << " the value is " << work[i] << " should be in [0," << *bg << ") !";
3948 throw INTERP_KERNEL::Exception(oss.str().c_str());
3951 ret3->alloc((int)castsDetected.size(),1);
3952 std::copy(castsDetected.begin(),castsDetected.end(),ret3->getPointer());
3953 castArr=ret1.retn();
3954 rankInsideCast=ret2.retn();
3955 castsPresent=ret3.retn();
3959 * 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 ).
3960 * 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 ).
3961 * This method works only if \a this is allocated and single component. If not an exception will be thrown.
3963 * \param [out] strt - the start of the range (included) if true is returned.
3964 * \param [out] sttoopp - the end of the range (not included) if true is returned.
3965 * \param [out] stteepp - the step of the range if true is returned.
3966 * \return the verdict of the check.
3968 * \sa DataArray::GetNumberOfItemGivenBES
3970 bool DataArrayInt::isRange(int& strt, int& sttoopp, int& stteepp) const
3973 if(getNumberOfComponents()!=1)
3974 throw INTERP_KERNEL::Exception("DataArrayInt::isRange : this must be single component array !");
3975 int nbTuples(getNumberOfTuples());
3977 { strt=0; sttoopp=0; stteepp=1; return true; }
3978 const int *pt(begin());
3981 { sttoopp=strt+1; stteepp=1; return true; }
3982 strt=*pt; sttoopp=pt[nbTuples-1];
3988 int a(sttoopp-1-strt),tmp(strt);
3989 if(a%(nbTuples-1)!=0)
3991 stteepp=a/(nbTuples-1);
3992 for(int i=0;i<nbTuples;i++,tmp+=stteepp)
4000 int a(strt-sttoopp-1),tmp(strt);
4001 if(a%(nbTuples-1)!=0)
4003 stteepp=-(a/(nbTuples-1));
4004 for(int i=0;i<nbTuples;i++,tmp+=stteepp)
4013 * Modifies in place \a this one-dimensional array so that each value \a v = \a indArrBg[ \a v ],
4014 * i.e. a current value is used as in index to get a new value from \a indArrBg.
4015 * \param [in] indArrBg - pointer to the first element of array of new values to assign
4017 * \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
4018 * the last value of \a indArrBg is \a indArrEnd[ -1 ].
4019 * \throw If \a this->getNumberOfComponents() != 1
4020 * \throw If any value of \a this can't be used as a valid index for
4021 * [\a indArrBg, \a indArrEnd).
4023 * \sa changeValue, findIdForEach
4025 void DataArrayInt::transformWithIndArr(const int *indArrBg, const int *indArrEnd)
4027 this->checkAllocated();
4028 if(this->getNumberOfComponents()!=1)
4029 throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
4030 int nbElemsIn((int)std::distance(indArrBg,indArrEnd)),nbOfTuples(getNumberOfTuples()),*pt(getPointer());
4031 for(int i=0;i<nbOfTuples;i++,pt++)
4033 if(*pt>=0 && *pt<nbElemsIn)
4037 std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " of this value is " << *pt << ", should be in [0," << nbElemsIn << ") !";
4038 throw INTERP_KERNEL::Exception(oss.str());
4041 this->declareAsNew();
4044 void DataArrayInt::transformWithIndArr(const MapKeyVal<int>& m)
4046 this->checkAllocated();
4047 if(this->getNumberOfComponents()!=1)
4048 throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
4049 const std::map<int,int>& dat(m.data());
4050 int nbOfTuples(getNumberOfTuples()),*pt(getPointer());
4051 for(int i=0;i<nbOfTuples;i++,pt++)
4053 std::map<int,int>::const_iterator it(dat.find(*pt));
4058 std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " of this value is " << *pt << " not in map !";
4059 throw INTERP_KERNEL::Exception(oss.str());
4062 this->declareAsNew();
4066 * Creates a one-dimensional DataArrayInt (\a res) whose contents are computed from
4067 * values of \a this (\a a) and the given (\a indArr) arrays as follows:
4068 * \a res[ \a indArr[ \a a[ i ]]] = i. I.e. for each value in place i \a v = \a a[ i ],
4069 * new value in place \a indArr[ \a v ] is i.
4070 * \param [in] indArrBg - the array holding indices within the result array to assign
4071 * indices of values of \a this array pointing to values of \a indArrBg.
4072 * \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
4073 * the last value of \a indArrBg is \a indArrEnd[ -1 ].
4074 * \return DataArrayInt * - the new instance of DataArrayInt.
4075 * The caller is to delete this result array using decrRef() as it is no more
4077 * \throw If \a this->getNumberOfComponents() != 1.
4078 * \throw If any value of \a this array is not a valid index for \a indArrBg array.
4079 * \throw If any value of \a indArrBg is not a valid index for \a this array.
4081 DataArrayInt *DataArrayInt::transformWithIndArrR(const int *indArrBg, const int *indArrEnd) const
4084 if(getNumberOfComponents()!=1)
4085 throw INTERP_KERNEL::Exception("Call transformWithIndArrR method on DataArrayInt with only one component, you can call 'rearrange' method before !");
4086 int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
4087 int nbOfTuples=getNumberOfTuples();
4088 const int *pt=getConstPointer();
4089 MCAuto<DataArrayInt> ret=DataArrayInt::New();
4090 ret->alloc(nbOfTuples,1);
4091 ret->fillWithValue(-1);
4092 int *tmp=ret->getPointer();
4093 for(int i=0;i<nbOfTuples;i++,pt++)
4095 if(*pt>=0 && *pt<nbElemsIn)
4097 int pos=indArrBg[*pt];
4098 if(pos>=0 && pos<nbOfTuples)
4102 std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value of new pos is " << pos << " ( indArrBg[" << *pt << "]) ! Should be in [0," << nbOfTuples << ") !";
4103 throw INTERP_KERNEL::Exception(oss.str().c_str());
4108 std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn << " !";
4109 throw INTERP_KERNEL::Exception(oss.str().c_str());
4116 * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
4117 * from values of \a this array, which is supposed to contain a renumbering map in
4118 * "Old to New" mode. The result array contains a renumbering map in "New to Old" mode.
4119 * To know how to use the renumbering maps see \ref numbering.
4120 * \param [in] newNbOfElem - the number of tuples in the result array.
4121 * \return DataArrayInt * - the new instance of DataArrayInt.
4122 * The caller is to delete this result array using decrRef() as it is no more
4125 * \if ENABLE_EXAMPLES
4126 * \ref cpp_mcdataarrayint_invertarrayo2n2n2o "Here is a C++ example".<br>
4127 * \ref py_mcdataarrayint_invertarrayo2n2n2o "Here is a Python example".
4130 DataArrayInt *DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const
4132 MCAuto<DataArrayInt> ret(DataArrayInt::New());
4133 ret->alloc(newNbOfElem,1);
4134 int nbOfOldNodes(this->getNumberOfTuples());
4135 const int *old2New(begin());
4136 int *pt(ret->getPointer());
4137 for(int i=0;i!=nbOfOldNodes;i++)
4139 int newp(old2New[i]);
4142 if(newp>=0 && newp<newNbOfElem)
4146 std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2O : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
4147 throw INTERP_KERNEL::Exception(oss.str().c_str());
4155 * This method is similar to DataArrayInt::invertArrayO2N2N2O except that
4156 * 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]
4158 DataArrayInt *DataArrayInt::invertArrayO2N2N2OBis(int newNbOfElem) const
4160 MCAuto<DataArrayInt> ret=DataArrayInt::New();
4161 ret->alloc(newNbOfElem,1);
4162 int nbOfOldNodes=getNumberOfTuples();
4163 const int *old2New=getConstPointer();
4164 int *pt=ret->getPointer();
4165 for(int i=nbOfOldNodes-1;i>=0;i--)
4167 int newp(old2New[i]);
4170 if(newp>=0 && newp<newNbOfElem)
4174 std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2OBis : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
4175 throw INTERP_KERNEL::Exception(oss.str().c_str());
4183 * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
4184 * from values of \a this array, which is supposed to contain a renumbering map in
4185 * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
4186 * To know how to use the renumbering maps see \ref numbering.
4187 * \param [in] newNbOfElem - the number of tuples in the result array.
4188 * \return DataArrayInt * - the new instance of DataArrayInt.
4189 * The caller is to delete this result array using decrRef() as it is no more
4192 * \if ENABLE_EXAMPLES
4193 * \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
4195 * \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
4196 * \sa invertArrayN2O2O2NOptimized
4199 DataArrayInt *DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const
4202 MCAuto<DataArrayInt> ret=DataArrayInt::New();
4203 ret->alloc(oldNbOfElem,1);
4204 const int *new2Old=getConstPointer();
4205 int *pt=ret->getPointer();
4206 std::fill(pt,pt+oldNbOfElem,-1);
4207 int nbOfNewElems=getNumberOfTuples();
4208 for(int i=0;i<nbOfNewElems;i++)
4211 if(v>=0 && v<oldNbOfElem)
4215 std::ostringstream oss; oss << "DataArrayInt::invertArrayN2O2O2N : in new id #" << i << " old value is " << v << " expected to be in [0," << oldNbOfElem << ") !";
4216 throw INTERP_KERNEL::Exception(oss.str().c_str());
4223 * Creates a map, whose contents are computed
4224 * from values of \a this array, which is supposed to contain a renumbering map in
4225 * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
4226 * To know how to use the renumbering maps see \ref numbering.
4227 * \param [in] newNbOfElem - the number of tuples in the result array.
4228 * \return MapII - the new instance of Map.
4230 * \if ENABLE_EXAMPLES
4231 * \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
4233 * \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
4234 * \sa invertArrayN2O2O2N, giveN2OOptimized, MEDCouplingPointSet::renumberNodesInConn
4237 MCAuto< MapKeyVal<int> > DataArrayInt32::invertArrayN2O2O2NOptimized() const
4240 if(getNumberOfComponents()!=1)
4241 throw INTERP_KERNEL::Exception("DataArrayInt32::invertArrayN2O2O2NOptimized : single component expected !");
4242 MCAuto< MapKeyVal<int> > ret(MapKeyVal<int>::New());
4243 std::map<int,int>& m(ret->data());
4244 const int *new2Old(begin());
4245 std::size_t nbOfNewElems(this->getNumberOfTuples());
4246 for(std::size_t i=0;i<nbOfNewElems;i++)
4255 * Creates a map, whose contents are computed
4256 * from values of \a this array, which is supposed to contain a renumbering map in
4257 * "New to Old" mode. The result array contains a renumbering map in "New to Old" mode as C++ map for performance reasons.
4259 * \sa invertArrayN2O2O2NOptimized, MEDCouplingPointSet::renumberNodesInConn
4261 MCAuto< MapKeyVal<int> > DataArrayInt32::giveN2OOptimized() const
4264 if(getNumberOfComponents()!=1)
4265 throw INTERP_KERNEL::Exception("DataArrayInt32::giveN2OOptimized : single component expected !");
4266 MCAuto< MapKeyVal<int> > ret(MapKeyVal<int>::New());
4267 std::map<int,int>& m(ret->data());
4268 const int *new2Old(begin());
4269 std::size_t nbOfNewElems(this->getNumberOfTuples());
4270 for(std::size_t i=0;i<nbOfNewElems;i++)
4279 * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode.
4280 * This map, if applied to \a this array, would make it sorted. For example, if
4281 * \a this array contents are [9,10,0,6,4,11,3,7] then the contents of the result array
4282 * are [5,6,0,3,2,7,1,4]; if this result array (\a res) is used as an argument in call
4283 * \a this->renumber(\a res) then the returned array contains [0,3,4,6,7,9,10,11].
4284 * This method is useful for renumbering (in MED file for example). For more info
4285 * on renumbering see \ref numbering.
4286 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4287 * array using decrRef() as it is no more needed.
4288 * \throw If \a this is not allocated.
4289 * \throw If \a this->getNumberOfComponents() != 1.
4290 * \throw If there are equal values in \a this array.
4292 DataArrayInt *DataArrayInt::checkAndPreparePermutation() const
4295 if(getNumberOfComponents()!=1)
4296 throw INTERP_KERNEL::Exception("DataArrayInt::checkAndPreparePermutation : number of components must == 1 !");
4297 int nbTuples=getNumberOfTuples();
4298 const int *pt=getConstPointer();
4299 int *pt2=CheckAndPreparePermutation(pt,pt+nbTuples);
4300 DataArrayInt *ret=DataArrayInt::New();
4301 ret->useArray(pt2,true,C_DEALLOC,nbTuples,1);
4306 * 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
4307 * input array \a ids2.
4308 * \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.
4309 * 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
4311 * In case of success both assertion will be true (no throw) :
4312 * \c ids1->renumber(ret)->isEqual(ids2) where \a ret is the return of this method.
4313 * \c ret->transformWithIndArr(ids2)->isEqual(ids1)
4316 * - \a ids1 : [3,1,103,4,6,10,-7,205]
4317 * - \a ids2 : [-7,1,205,10,6,3,103,4]
4318 * - \a return is : [5,1,6,7,4,3,0,2] because ids2[5]==ids1[0], ids2[1]==ids1[1], ids2[6]==ids1[2]...
4320 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4321 * array using decrRef() as it is no more needed.
4322 * \throw If either ids1 or ids2 is null not allocated or not with one components.
4324 * \sa DataArrayInt32::findIdForEach
4326 DataArrayInt *DataArrayInt::FindPermutationFromFirstToSecond(const DataArrayInt *ids1, const DataArrayInt *ids2)
4329 throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be not null !");
4330 if(!ids1->isAllocated() || !ids2->isAllocated())
4331 throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be allocated !");
4332 if(ids1->getNumberOfComponents()!=1 || ids2->getNumberOfComponents()!=1)
4333 throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays have exactly one component !");
4334 if(ids1->getNumberOfTuples()!=ids2->getNumberOfTuples())
4336 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 !";
4337 throw INTERP_KERNEL::Exception(oss.str().c_str());
4339 MCAuto<DataArrayInt> p1(ids1->deepCopy());
4340 MCAuto<DataArrayInt> p2(ids2->deepCopy());
4341 p1->sort(true); p2->sort(true);
4342 if(!p1->isEqualWithoutConsideringStr(*p2))
4343 throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two arrays are not lying on same ids ! Impossible to find a permutation between the 2 arrays !");
4344 p1=ids1->checkAndPreparePermutation();
4345 p2=ids2->checkAndPreparePermutation();
4346 p2=p2->invertArrayO2N2N2O(p2->getNumberOfTuples());
4347 p2=p2->selectByTupleIdSafe(p1->begin(),p1->end());
4352 * Returns two arrays describing a surjective mapping from \a this set of values (\a A)
4353 * onto a set of values of size \a targetNb (\a B). The surjective function is
4354 * \a B[ \a A[ i ]] = i. That is to say that for each \a id in [0,\a targetNb), where \a
4355 * targetNb < \a this->getNumberOfTuples(), there exists at least one tupleId (\a tid) so
4356 * that <em> this->getIJ( tid, 0 ) == id</em>. <br>
4357 * The first of out arrays returns indices of elements of \a this array, grouped by their
4358 * place in the set \a B. The second out array is the index of the first one; it shows how
4359 * many elements of \a A are mapped into each element of \a B. <br>
4361 * mapping and its usage in renumbering see \ref numbering. <br>
4363 * - \a this: [0,3,2,3,2,2,1,2]
4365 * - \a arr: [0, 6, 2,4,5,7, 1,3]
4366 * - \a arrI: [0,1,2,6,8]
4368 * This result means: <br>
4369 * the element of \a B 0 encounters within \a A once (\a arrI[ 0+1 ] - \a arrI[ 0 ]) and
4370 * its index within \a A is 0 ( \a arr[ 0:1 ] == \a arr[ \a arrI[ 0 ] : \a arrI[ 0+1 ]]);<br>
4371 * the element of \a B 2 encounters within \a A 4 times (\a arrI[ 2+1 ] - \a arrI[ 2 ]) and
4372 * its indices within \a A are [2,4,5,7] ( \a arr[ 2:6 ] == \a arr[ \a arrI[ 2 ] :
4373 * \a arrI[ 2+1 ]]); <br> etc.
4374 * \param [in] targetNb - the size of the set \a B. \a targetNb must be equal or more
4375 * than the maximal value of \a A.
4376 * \param [out] arr - a new instance of DataArrayInt returning indices of
4377 * elements of \a this, grouped by their place in the set \a B. The caller is to delete
4378 * this array using decrRef() as it is no more needed.
4379 * \param [out] arrI - a new instance of DataArrayInt returning size of groups of equal
4380 * elements of \a this. The caller is to delete this array using decrRef() as it
4381 * is no more needed.
4382 * \throw If \a this is not allocated.
4383 * \throw If \a this->getNumberOfComponents() != 1.
4384 * \throw If any value in \a this is more or equal to \a targetNb.
4386 void DataArrayInt::changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, DataArrayInt *&arrI) const
4389 if(getNumberOfComponents()!=1)
4390 throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : number of components must == 1 !");
4391 int nbOfTuples=getNumberOfTuples();
4392 MCAuto<DataArrayInt> ret(DataArrayInt::New());
4393 MCAuto<DataArrayInt> retI(DataArrayInt::New());
4394 retI->alloc(targetNb+1,1);
4395 const int *input=getConstPointer();
4396 std::vector< std::vector<int> > tmp(targetNb);
4397 for(int i=0;i<nbOfTuples;i++)
4400 if(tmp2>=0 && tmp2<targetNb)
4401 tmp[tmp2].push_back(i);
4404 std::ostringstream oss; oss << "DataArrayInt::changeSurjectiveFormat : At pos " << i << " presence of element " << tmp2 << " ! should be in [0," << targetNb << ") !";
4405 throw INTERP_KERNEL::Exception(oss.str().c_str());
4408 int *retIPtr=retI->getPointer();
4410 for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++,retIPtr++)
4411 retIPtr[1]=retIPtr[0]+(int)((*it1).size());
4412 if(nbOfTuples!=retI->getIJ(targetNb,0))
4413 throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : big problem should never happen !");
4414 ret->alloc(nbOfTuples,1);
4415 int *retPtr=ret->getPointer();
4416 for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++)
4417 retPtr=std::copy((*it1).begin(),(*it1).end(),retPtr);
4424 * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode computed
4425 * from a zip representation of a surjective format (returned e.g. by
4426 * \ref MEDCoupling::DataArrayDouble::findCommonTuples() "DataArrayDouble::findCommonTuples()"
4427 * for example). The result array minimizes the permutation. <br>
4428 * For more info on renumbering see \ref numbering. <br>
4430 * - \a nbOfOldTuples: 10
4431 * - \a arr : [0,3, 5,7,9]
4432 * - \a arrIBg : [0,2,5]
4433 * - \a newNbOfTuples: 7
4434 * - result array : [0,1,2,0,3,4,5,4,6,4]
4436 * \param [in] nbOfOldTuples - number of tuples in the initial array \a arr.
4437 * \param [in] arr - the array of tuple indices grouped by \a arrIBg array.
4438 * \param [in] arrIBg - the array dividing all indices stored in \a arr into groups of
4439 * (indices of) equal values. Its every element (except the last one) points to
4440 * the first element of a group of equal values.
4441 * \param [in] arrIEnd - specifies the end of \a arrIBg, so that the last element of \a
4442 * arrIBg is \a arrIEnd[ -1 ].
4443 * \param [out] newNbOfTuples - number of tuples after surjection application.
4444 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4445 * array using decrRef() as it is no more needed.
4446 * \throw If any value of \a arr breaks condition ( 0 <= \a arr[ i ] < \a nbOfOldTuples ).
4448 DataArrayInt *DataArrayInt::ConvertIndexArrayToO2N(int nbOfOldTuples, const int *arr, const int *arrIBg, const int *arrIEnd, int &newNbOfTuples)
4450 MCAuto<DataArrayInt> ret=DataArrayInt::New();
4451 ret->alloc(nbOfOldTuples,1);
4452 int *pt=ret->getPointer();
4453 std::fill(pt,pt+nbOfOldTuples,-1);
4454 int nbOfGrps=((int)std::distance(arrIBg,arrIEnd))-1;
4455 const int *cIPtr=arrIBg;
4456 for(int i=0;i<nbOfGrps;i++)
4457 pt[arr[cIPtr[i]]]=-(i+2);
4459 for(int iNode=0;iNode<nbOfOldTuples;iNode++)
4467 int grpId=-(pt[iNode]+2);
4468 for(int j=cIPtr[grpId];j<cIPtr[grpId+1];j++)
4470 if(arr[j]>=0 && arr[j]<nbOfOldTuples)
4474 std::ostringstream oss; oss << "DataArrayInt::ConvertIndexArrayToO2N : With element #" << j << " value is " << arr[j] << " should be in [0," << nbOfOldTuples << ") !";
4475 throw INTERP_KERNEL::Exception(oss.str().c_str());
4482 newNbOfTuples=newNb;
4487 * Returns a new DataArrayInt containing a renumbering map in "New to Old" mode,
4488 * which if applied to \a this array would make it sorted ascendingly.
4489 * For more info on renumbering see \ref numbering. <br>
4491 * - \a this: [2,0,1,1,0,1,2,0,1,1,0,0]
4492 * - result: [10,0,5,6,1,7,11,2,8,9,3,4]
4493 * - after applying result to \a this: [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2]
4495 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4496 * array using decrRef() as it is no more needed.
4497 * \throw If \a this is not allocated.
4498 * \throw If \a this->getNumberOfComponents() != 1.
4500 DataArrayInt *DataArrayInt::buildPermArrPerLevel() const
4503 if(getNumberOfComponents()!=1)
4504 throw INTERP_KERNEL::Exception("DataArrayInt::buildPermArrPerLevel : number of components must == 1 !");
4505 int nbOfTuples=getNumberOfTuples();
4506 const int *pt=getConstPointer();
4507 std::map<int,int> m;
4508 MCAuto<DataArrayInt> ret=DataArrayInt::New();
4509 ret->alloc(nbOfTuples,1);
4510 int *opt=ret->getPointer();
4511 for(int i=0;i<nbOfTuples;i++,pt++,opt++)
4514 std::map<int,int>::iterator it=m.find(val);
4523 m.insert(std::pair<int,int>(val,1));
4527 for(std::map<int,int>::iterator it=m.begin();it!=m.end();it++)
4529 int vt=(*it).second;
4533 pt=getConstPointer();
4534 opt=ret->getPointer();
4535 for(int i=0;i<nbOfTuples;i++,pt++,opt++)
4542 * Checks if \a this array has the given size, and if its contents is equal to an array filled with
4543 * iota(). This method is particularly useful for DataArrayInt instances that represent
4544 * a renumbering array, to check if there is a real need in renumbering.
4545 * This method checks than \a this can be considered as an identity mapping
4546 * of a set having \a sizeExpected elements into itself.
4548 * \param [in] sizeExpected - The number of elements expected.
4549 * \return bool - \a true if \a this array contents == \a range( \a this->getNumberOfTuples())
4550 * \throw If \a this is not allocated.
4551 * \throw If \a this->getNumberOfComponents() != 1.
4553 bool DataArrayInt::isIota(int sizeExpected) const
4556 if(getNumberOfComponents()!=1)
4558 int nbOfTuples(getNumberOfTuples());
4559 if(nbOfTuples!=sizeExpected)
4561 const int *pt=getConstPointer();
4562 for(int i=0;i<nbOfTuples;i++,pt++)
4569 * Checks if all values in \a this array are equal to \a val.
4570 * \param [in] val - value to check equality of array values to.
4571 * \return bool - \a true if all values are \a val.
4572 * \throw If \a this is not allocated.
4573 * \throw If \a this->getNumberOfComponents() != 1
4574 * \sa DataArrayInt::checkUniformAndGuess
4576 bool DataArrayInt::isUniform(int val) const
4579 if(getNumberOfComponents()!=1)
4580 throw INTERP_KERNEL::Exception("DataArrayInt::isUniform : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
4581 const int *w(begin()),*end2(end());
4589 * This method checks that \a this is uniform. If not and exception will be thrown.
4590 * In case of uniformity the corresponding value is returned.
4592 * \return int - the unique value contained in this
4593 * \throw If \a this is not allocated.
4594 * \throw If \a this->getNumberOfComponents() != 1
4595 * \throw If \a this is not uniform.
4596 * \sa DataArrayInt::isUniform
4598 int DataArrayInt::checkUniformAndGuess() const
4601 if(getNumberOfComponents()!=1)
4602 throw INTERP_KERNEL::Exception("DataArrayInt::checkUniformAndGuess : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
4604 throw INTERP_KERNEL::Exception("DataArrayInt::checkUniformAndGuess : this is empty !");
4605 const int *w(begin()),*end2(end());
4609 throw INTERP_KERNEL::Exception("DataArrayInt::checkUniformAndGuess : this is not uniform !");
4614 * Checks if all values in \a this array are unique.
4615 * \return bool - \a true if condition above is true
4616 * \throw If \a this is not allocated.
4617 * \throw If \a this->getNumberOfComponents() != 1
4619 bool DataArrayInt::hasUniqueValues() const
4622 if(getNumberOfComponents()!=1)
4623 throw INTERP_KERNEL::Exception("DataArrayInt::hasOnlyUniqueValues: must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
4624 std::size_t nbOfTuples(getNumberOfTuples());
4625 std::set<int> s(begin(),end()); // in C++11, should use unordered_set (O(1) complexity)
4626 if (s.size() != nbOfTuples)
4632 * Copy all components in a specified order from another DataArrayInt.
4633 * The specified components become the first ones in \a this array.
4634 * Both numerical and textual data is copied. The number of tuples in \a this and
4635 * the other array can be different.
4636 * \param [in] a - the array to copy data from.
4637 * \param [in] compoIds - sequence of zero based indices of components, data of which is
4639 * \throw If \a a is NULL.
4640 * \throw If \a compoIds.size() != \a a->getNumberOfComponents().
4641 * \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
4643 * \if ENABLE_EXAMPLES
4644 * \ref py_mcdataarrayint_setselectedcomponents "Here is a Python example".
4647 void DataArrayInt::setSelectedComponents(const DataArrayInt *a, const std::vector<int>& compoIds)
4650 throw INTERP_KERNEL::Exception("DataArrayInt::setSelectedComponents : input DataArrayInt is NULL !");
4652 a->checkAllocated();
4653 copyPartOfStringInfoFrom2(compoIds,*a);
4654 std::size_t partOfCompoSz=compoIds.size();
4655 int nbOfCompo=getNumberOfComponents();
4656 int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
4657 const int *ac=a->getConstPointer();
4658 int *nc=getPointer();
4659 for(int i=0;i<nbOfTuples;i++)
4660 for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
4661 nc[nbOfCompo*i+compoIds[j]]=*ac;
4664 DataArrayIntIterator *DataArrayInt::iterator()
4666 return new DataArrayIntIterator(this);
4670 * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to a
4671 * given one. The ids are sorted in the ascending order.
4672 * \param [in] val - the value to find within \a this.
4673 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4674 * array using decrRef() as it is no more needed.
4675 * \throw If \a this is not allocated.
4676 * \throw If \a this->getNumberOfComponents() != 1.
4677 * \sa DataArrayInt::findIdsEqualTuple
4679 DataArrayInt *DataArrayInt::findIdsEqual(int val) const
4682 if(getNumberOfComponents()!=1)
4683 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqual : the array must have only one component, you can call 'rearrange' method before !");
4684 const int *cptr(getConstPointer());
4685 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4686 int nbOfTuples=getNumberOfTuples();
4687 for(int i=0;i<nbOfTuples;i++,cptr++)
4689 ret->pushBackSilent(i);
4694 * Creates a new DataArrayInt containing IDs (indices) of tuples holding value \b not
4695 * equal to a given one.
4696 * \param [in] val - the value to ignore within \a this.
4697 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4698 * array using decrRef() as it is no more needed.
4699 * \throw If \a this is not allocated.
4700 * \throw If \a this->getNumberOfComponents() != 1.
4702 DataArrayInt *DataArrayInt::findIdsNotEqual(int val) const
4705 if(getNumberOfComponents()!=1)
4706 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotEqual : the array must have only one component, you can call 'rearrange' method before !");
4707 const int *cptr(getConstPointer());
4708 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4709 int nbOfTuples=getNumberOfTuples();
4710 for(int i=0;i<nbOfTuples;i++,cptr++)
4712 ret->pushBackSilent(i);
4717 * Creates a new DataArrayInt containing IDs (indices) of tuples holding tuple equal to those defined by [ \a tupleBg , \a tupleEnd )
4718 * This method is an extension of DataArrayInt::findIdsEqual method.
4720 * \param [in] tupleBg - the begin (included) of the input tuple to find within \a this.
4721 * \param [in] tupleEnd - the end (excluded) of the input tuple to find within \a this.
4722 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4723 * array using decrRef() as it is no more needed.
4724 * \throw If \a this is not allocated.
4725 * \throw If \a this->getNumberOfComponents() != std::distance(tupleBg,tupleEnd).
4726 * \throw If \a this->getNumberOfComponents() is equal to 0.
4727 * \sa DataArrayInt::findIdsEqual
4729 DataArrayInt *DataArrayInt::findIdsEqualTuple(const int *tupleBg, const int *tupleEnd) const
4731 std::size_t nbOfCompoExp(std::distance(tupleBg,tupleEnd));
4733 if(getNumberOfComponents()!=nbOfCompoExp)
4735 std::ostringstream oss; oss << "DataArrayInt::findIdsEqualTuple : mismatch of number of components. Input tuple has " << nbOfCompoExp << " whereas this array has " << getNumberOfComponents() << " components !";
4736 throw INTERP_KERNEL::Exception(oss.str().c_str());
4739 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqualTuple : number of components should be > 0 !");
4740 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4741 const int *bg(begin()),*end2(end()),*work(begin());
4744 work=std::search(work,end2,tupleBg,tupleEnd);
4747 std::size_t pos(std::distance(bg,work));
4748 if(pos%nbOfCompoExp==0)
4749 ret->pushBackSilent(pos/nbOfCompoExp);
4757 * This method finds for each element \a ELT in [valsBg,valsEnd) elements in \a this equal to it. Associated to ELT
4758 * this method will return the tuple id of last element found. If there is no element in \a this equal to ELT
4759 * an exception will be thrown.
4761 * In case of success this[ret]==vals. Samely ret->transformWithIndArr(this->begin(),this->end())==vals.
4762 * Where \a vals is the [valsBg,valsEnd) array and \a ret the array returned by this method.
4763 * This method can be seen as an extension of FindPermutationFromFirstToSecond.
4766 * - \a this: [17,27,2,10,-4,3,12,27,16]
4767 * - \a val : [3,16,-4,27,17]
4768 * - result: [5,8,4,7,0]
4770 * \return - An array of size std::distance(valsBg,valsEnd)
4772 * \sa DataArrayInt32::FindPermutationFromFirstToSecond
4774 MCAuto<DataArrayInt32> DataArrayInt32::findIdForEach(const int *valsBg, const int *valsEnd) const
4776 MCAuto<DataArrayInt32> ret(DataArrayInt32::New());
4777 std::size_t nbOfTuplesOut(std::distance(valsBg,valsEnd));
4778 ret->alloc(nbOfTuplesOut,1);
4779 MCAuto< MapKeyVal<int> > zeMap(invertArrayN2O2O2NOptimized());
4780 const std::map<int,int>& dat(zeMap->data());
4781 int *ptToFeed(ret->getPointer());
4782 for(const int *pt=valsBg;pt!=valsEnd;pt++)
4784 std::map<int,int>::const_iterator it(dat.find(*pt));
4786 *ptToFeed++=(*it).second;
4789 std::ostringstream oss; oss << "DataArrayInt32::findIdForEach : error for element at place " << std::distance(valsBg,pt);
4790 oss << " of input array value is " << *pt << " which is not in this !";
4791 throw INTERP_KERNEL::Exception(oss.str());
4798 * Assigns \a newValue to all elements holding \a oldValue within \a this
4799 * one-dimensional array.
4800 * \param [in] oldValue - the value to replace.
4801 * \param [in] newValue - the value to assign.
4802 * \return int - number of replacements performed.
4803 * \throw If \a this is not allocated.
4804 * \throw If \a this->getNumberOfComponents() != 1.
4806 int DataArrayInt::changeValue(int oldValue, int newValue)
4809 if(getNumberOfComponents()!=1)
4810 throw INTERP_KERNEL::Exception("DataArrayInt::changeValue : the array must have only one component, you can call 'rearrange' method before !");
4811 if(oldValue==newValue)
4813 int *start(getPointer()),*end2(start+getNbOfElems());
4815 for(int *val=start;val!=end2;val++)
4829 * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to
4830 * one of given values.
4831 * \param [in] valsBg - an array of values to find within \a this array.
4832 * \param [in] valsEnd - specifies the end of the array \a valsBg, so that
4833 * the last value of \a valsBg is \a valsEnd[ -1 ].
4834 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4835 * array using decrRef() as it is no more needed.
4836 * \throw If \a this->getNumberOfComponents() != 1.
4838 DataArrayInt *DataArrayInt::findIdsEqualList(const int *valsBg, const int *valsEnd) const
4840 if(getNumberOfComponents()!=1)
4841 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqualList : the array must have only one component, you can call 'rearrange' method before !");
4842 std::set<int> vals2(valsBg,valsEnd);
4843 const int *cptr(getConstPointer());
4844 std::vector<int> res;
4845 int nbOfTuples(getNumberOfTuples());
4846 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4847 for(int i=0;i<nbOfTuples;i++,cptr++)
4848 if(vals2.find(*cptr)!=vals2.end())
4849 ret->pushBackSilent(i);
4854 * Creates a new DataArrayInt containing IDs (indices) of tuples holding values \b not
4855 * equal to any of given values.
4856 * \param [in] valsBg - an array of values to ignore within \a this array.
4857 * \param [in] valsEnd - specifies the end of the array \a valsBg, so that
4858 * the last value of \a valsBg is \a valsEnd[ -1 ].
4859 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4860 * array using decrRef() as it is no more needed.
4861 * \throw If \a this->getNumberOfComponents() != 1.
4863 DataArrayInt *DataArrayInt::findIdsNotEqualList(const int *valsBg, const int *valsEnd) const
4865 if(getNumberOfComponents()!=1)
4866 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotEqualList : the array must have only one component, you can call 'rearrange' method before !");
4867 std::set<int> vals2(valsBg,valsEnd);
4868 const int *cptr=getConstPointer();
4869 std::vector<int> res;
4870 int nbOfTuples=getNumberOfTuples();
4871 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4872 for(int i=0;i<nbOfTuples;i++,cptr++)
4873 if(vals2.find(*cptr)==vals2.end())
4874 ret->pushBackSilent(i);
4879 * This method is an extension of DataArrayInt::findIdFirstEqual method because this method works for DataArrayInt with
4880 * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
4881 * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
4882 * If any the tuple id is returned. If not -1 is returned.
4884 * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
4885 * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
4887 * \return tuple id where \b tupl is. -1 if no such tuple exists in \b this.
4888 * \sa DataArrayInt::findIdSequence, DataArrayInt::presenceOfTuple.
4890 int DataArrayInt::findIdFirstEqualTuple(const std::vector<int>& tupl) const
4893 int nbOfCompo=getNumberOfComponents();
4895 throw INTERP_KERNEL::Exception("DataArrayInt::findIdFirstEqualTuple : 0 components in 'this' !");
4896 if(nbOfCompo!=(int)tupl.size())
4898 std::ostringstream oss; oss << "DataArrayInt::findIdFirstEqualTuple : 'this' contains " << nbOfCompo << " components and searching for a tuple of length " << tupl.size() << " !";
4899 throw INTERP_KERNEL::Exception(oss.str().c_str());
4901 const int *cptr=getConstPointer();
4902 std::size_t nbOfVals=getNbOfElems();
4903 for(const int *work=cptr;work!=cptr+nbOfVals;)
4905 work=std::search(work,cptr+nbOfVals,tupl.begin(),tupl.end());
4906 if(work!=cptr+nbOfVals)
4908 if(std::distance(cptr,work)%nbOfCompo!=0)
4911 return std::distance(cptr,work)/nbOfCompo;
4918 * This method searches the sequence specified in input parameter \b vals in \b this.
4919 * This works only for DataArrayInt having number of components equal to one (if not an INTERP_KERNEL::Exception will be thrown).
4920 * This method differs from DataArrayInt::findIdFirstEqualTuple in that the position is internal raw data is not considered here contrary to DataArrayInt::findIdFirstEqualTuple.
4921 * \sa DataArrayInt::findIdFirstEqualTuple
4923 int DataArrayInt::findIdSequence(const std::vector<int>& vals) const
4926 int nbOfCompo=getNumberOfComponents();
4928 throw INTERP_KERNEL::Exception("DataArrayInt::findIdSequence : works only for DataArrayInt instance with one component !");
4929 const int *cptr=getConstPointer();
4930 std::size_t nbOfVals=getNbOfElems();
4931 const int *loc=std::search(cptr,cptr+nbOfVals,vals.begin(),vals.end());
4932 if(loc!=cptr+nbOfVals)
4933 return std::distance(cptr,loc);
4938 * This method expects to be called when number of components of this is equal to one.
4939 * This method returns the tuple id, if it exists, of the first tuple equal to \b value.
4940 * If not any tuple contains \b value -1 is returned.
4941 * \sa DataArrayInt::presenceOfValue
4943 int DataArrayInt::findIdFirstEqual(int value) const
4946 if(getNumberOfComponents()!=1)
4947 throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
4948 const int *cptr=getConstPointer();
4949 int nbOfTuples=getNumberOfTuples();
4950 const int *ret=std::find(cptr,cptr+nbOfTuples,value);
4951 if(ret!=cptr+nbOfTuples)
4952 return std::distance(cptr,ret);
4957 * This method expects to be called when number of components of this is equal to one.
4958 * This method returns the tuple id, if it exists, of the first tuple so that the value is contained in \b vals.
4959 * If not any tuple contains one of the values contained in 'vals' -1 is returned.
4960 * \sa DataArrayInt::presenceOfValue
4962 int DataArrayInt::findIdFirstEqual(const std::vector<int>& vals) const
4965 if(getNumberOfComponents()!=1)
4966 throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
4967 std::set<int> vals2(vals.begin(),vals.end());
4968 const int *cptr=getConstPointer();
4969 int nbOfTuples=getNumberOfTuples();
4970 for(const int *w=cptr;w!=cptr+nbOfTuples;w++)
4971 if(vals2.find(*w)!=vals2.end())
4972 return std::distance(cptr,w);
4977 * This method returns the number of values in \a this that are equals to input parameter \a value.
4978 * This method only works for single component array.
4980 * \return a value in [ 0, \c this->getNumberOfTuples() )
4982 * \throw If \a this is not allocated
4985 int DataArrayInt::count(int value) const
4989 if(getNumberOfComponents()!=1)
4990 throw INTERP_KERNEL::Exception("DataArrayInt::count : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
4991 const int *vals=begin();
4992 int nbOfTuples=getNumberOfTuples();
4993 for(int i=0;i<nbOfTuples;i++,vals++)
5000 * This method is an extension of DataArrayInt::presenceOfValue method because this method works for DataArrayInt with
5001 * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
5002 * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
5003 * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
5004 * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
5005 * \sa DataArrayInt::findIdFirstEqualTuple
5007 bool DataArrayInt::presenceOfTuple(const std::vector<int>& tupl) const
5009 return findIdFirstEqualTuple(tupl)!=-1;
5014 * Returns \a true if a given value is present within \a this one-dimensional array.
5015 * \param [in] value - the value to find within \a this array.
5016 * \return bool - \a true in case if \a value is present within \a this array.
5017 * \throw If \a this is not allocated.
5018 * \throw If \a this->getNumberOfComponents() != 1.
5019 * \sa findIdFirstEqual()
5021 bool DataArrayInt::presenceOfValue(int value) const
5023 return findIdFirstEqual(value)!=-1;
5027 * This method expects to be called when number of components of this is equal to one.
5028 * This method returns true if it exists a tuple so that the value is contained in \b vals.
5029 * If not any tuple contains one of the values contained in 'vals' false is returned.
5030 * \sa DataArrayInt::findIdFirstEqual
5032 bool DataArrayInt::presenceOfValue(const std::vector<int>& vals) const
5034 return findIdFirstEqual(vals)!=-1;
5038 * Accumulates values of each component of \a this array.
5039 * \param [out] res - an array of length \a this->getNumberOfComponents(), allocated
5040 * by the caller, that is filled by this method with sum value for each
5042 * \throw If \a this is not allocated.
5044 void DataArrayInt::accumulate(int *res) const
5047 const int *ptr=getConstPointer();
5048 int nbTuple=getNumberOfTuples();
5049 int nbComps=getNumberOfComponents();
5050 std::fill(res,res+nbComps,0);
5051 for(int i=0;i<nbTuple;i++)
5052 std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<int>());
5055 int DataArrayInt::accumulate(int compId) const
5058 const int *ptr=getConstPointer();
5059 int nbTuple=getNumberOfTuples();
5060 int nbComps=getNumberOfComponents();
5061 if(compId<0 || compId>=nbComps)
5062 throw INTERP_KERNEL::Exception("DataArrayInt::accumulate : Invalid compId specified : No such nb of components !");
5064 for(int i=0;i<nbTuple;i++)
5065 ret+=ptr[i*nbComps+compId];
5070 * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
5071 * The returned array will have same number of components than \a this and number of tuples equal to
5072 * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
5074 * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
5076 * \param [in] bgOfIndex - begin (included) of the input index array.
5077 * \param [in] endOfIndex - end (excluded) of the input index array.
5078 * \return DataArrayInt * - the new instance having the same number of components than \a this.
5080 * \throw If bgOfIndex or end is NULL.
5081 * \throw If input index array is not ascendingly sorted.
5082 * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
5083 * \throw If std::distance(bgOfIndex,endOfIndex)==0.
5085 DataArrayInt *DataArrayInt::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
5087 if(!bgOfIndex || !endOfIndex)
5088 throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : input pointer NULL !");
5090 int nbCompo=getNumberOfComponents();
5091 int nbOfTuples=getNumberOfTuples();
5092 int sz=(int)std::distance(bgOfIndex,endOfIndex);
5094 throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : invalid size of input index array !");
5096 MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(sz,nbCompo);
5097 const int *w=bgOfIndex;
5098 if(*w<0 || *w>=nbOfTuples)
5099 throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
5100 const int *srcPt=begin()+(*w)*nbCompo;
5101 int *tmp=ret->getPointer();
5102 for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
5104 std::fill(tmp,tmp+nbCompo,0);
5107 for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
5109 if(j>=0 && j<nbOfTuples)
5110 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<int>());
5113 std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
5114 throw INTERP_KERNEL::Exception(oss.str().c_str());
5120 std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
5121 throw INTERP_KERNEL::Exception(oss.str().c_str());
5124 ret->copyStringInfoFrom(*this);
5129 * Returns a new DataArrayInt by concatenating two given arrays, so that (1) the number
5130 * of tuples in the result array is <em> a1->getNumberOfTuples() + a2->getNumberOfTuples() -
5131 * offsetA2</em> and (2)
5132 * the number of component in the result array is same as that of each of given arrays.
5133 * First \a offsetA2 tuples of \a a2 are skipped and thus are missing from the result array.
5134 * Info on components is copied from the first of the given arrays. Number of components
5135 * in the given arrays must be the same.
5136 * \param [in] a1 - an array to include in the result array.
5137 * \param [in] a2 - another array to include in the result array.
5138 * \param [in] offsetA2 - number of tuples of \a a2 to skip.
5139 * \return DataArrayInt * - the new instance of DataArrayInt.
5140 * The caller is to delete this result array using decrRef() as it is no more
5142 * \throw If either \a a1 or \a a2 is NULL.
5143 * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
5145 DataArrayInt *DataArrayInt::Aggregate(const DataArrayInt *a1, const DataArrayInt *a2, int offsetA2)
5148 throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input DataArrayInt instance is NULL !");
5149 std::size_t nbOfComp(a1->getNumberOfComponents());
5150 if(nbOfComp!=a2->getNumberOfComponents())
5151 throw INTERP_KERNEL::Exception("Nb of components mismatch for array Aggregation !");
5152 std::size_t nbOfTuple1(a1->getNumberOfTuples()),nbOfTuple2(a2->getNumberOfTuples());
5153 MCAuto<DataArrayInt> ret(DataArrayInt::New());
5154 ret->alloc(nbOfTuple1+nbOfTuple2-offsetA2,nbOfComp);
5155 int *pt=std::copy(a1->begin(),a1->end(),ret->getPointer());
5156 std::copy(a2->getConstPointer()+offsetA2*nbOfComp,a2->getConstPointer()+nbOfTuple2*nbOfComp,pt);
5157 ret->copyStringInfoFrom(*a1);
5162 * Returns a new DataArrayInt by concatenating all given arrays, so that (1) the number
5163 * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
5164 * the number of component in the result array is same as that of each of given arrays.
5165 * Info on components is copied from the first of the given arrays. Number of components
5166 * in the given arrays must be the same.
5167 * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it
5168 * not the object itself.
5169 * \param [in] arr - a sequence of arrays to include in the result array.
5170 * \return DataArrayInt * - the new instance of DataArrayInt.
5171 * The caller is to delete this result array using decrRef() as it is no more
5173 * \throw If all arrays within \a arr are NULL.
5174 * \throw If getNumberOfComponents() of arrays within \a arr.
5176 DataArrayInt *DataArrayInt::Aggregate(const std::vector<const DataArrayInt *>& arr)
5178 std::vector<const DataArrayInt *> a;
5179 for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
5183 throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input list must be NON EMPTY !");
5184 std::vector<const DataArrayInt *>::const_iterator it=a.begin();
5185 std::size_t nbOfComp((*it)->getNumberOfComponents()),nbt((*it++)->getNumberOfTuples());
5186 for(int i=1;it!=a.end();it++,i++)
5188 if((*it)->getNumberOfComponents()!=nbOfComp)
5189 throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : Nb of components mismatch for array aggregation !");
5190 nbt+=(*it)->getNumberOfTuples();
5192 MCAuto<DataArrayInt> ret=DataArrayInt::New();
5193 ret->alloc(nbt,nbOfComp);
5194 int *pt=ret->getPointer();
5195 for(it=a.begin();it!=a.end();it++)
5196 pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
5197 ret->copyStringInfoFrom(*(a[0]));
5202 * This method takes as input a list of DataArrayInt instances \a arrs that represent each a packed index arrays.
5203 * A packed index array is an allocated array with one component, and at least one tuple. The first element
5204 * of each array in \a arrs must be 0. Each array in \a arrs is expected to be increasingly monotonic.
5205 * 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.
5207 * \return DataArrayInt * - a new object to be managed by the caller.
5209 DataArrayInt *DataArrayInt::AggregateIndexes(const std::vector<const DataArrayInt *>& arrs)
5212 for(std::vector<const DataArrayInt *>::const_iterator it4=arrs.begin();it4!=arrs.end();it4++)
5216 (*it4)->checkAllocated();
5217 if((*it4)->getNumberOfComponents()!=1)
5219 std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of compo != 1 at pos " << std::distance(arrs.begin(),it4) << " !";
5220 throw INTERP_KERNEL::Exception(oss.str().c_str());
5222 int nbTupl=(*it4)->getNumberOfTuples();
5225 std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of tuples < 1 at pos " << std::distance(arrs.begin(),it4) << " !";
5226 throw INTERP_KERNEL::Exception(oss.str().c_str());
5228 if((*it4)->front()!=0)
5230 std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with front value != 0 at pos " << std::distance(arrs.begin(),it4) << " !";
5231 throw INTERP_KERNEL::Exception(oss.str().c_str());
5237 std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a null instance at pos " << std::distance(arrs.begin(),it4) << " !";
5238 throw INTERP_KERNEL::Exception(oss.str().c_str());
5242 throw INTERP_KERNEL::Exception("DataArrayInt::AggregateIndexes : input list must be NON EMPTY !");
5243 MCAuto<DataArrayInt> ret=DataArrayInt::New();
5244 ret->alloc(retSz,1);
5245 int *pt=ret->getPointer(); *pt++=0;
5246 for(std::vector<const DataArrayInt *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
5247 pt=std::transform((*it)->begin()+1,(*it)->end(),pt,std::bind2nd(std::plus<int>(),pt[-1]));
5248 ret->copyStringInfoFrom(*(arrs[0]));
5253 * Returns in a single walk in \a this the min value and the max value in \a this.
5254 * \a this is expected to be single component array.
5256 * \param [out] minValue - the min value in \a this.
5257 * \param [out] maxValue - the max value in \a this.
5259 * \sa getMinValueInArray, getMinValue, getMaxValueInArray, getMaxValue
5261 void DataArrayInt::getMinMaxValues(int& minValue, int& maxValue) const
5264 if(getNumberOfComponents()!=1)
5265 throw INTERP_KERNEL::Exception("DataArrayInt::getMinMaxValues : must be applied on DataArrayInt with only one component !");
5266 int nbTuples(getNumberOfTuples());
5267 const int *pt(begin());
5268 minValue=std::numeric_limits<int>::max(); maxValue=-std::numeric_limits<int>::max();
5269 for(int i=0;i<nbTuples;i++,pt++)
5279 * Modify all elements of \a this array, so that
5280 * an element _x_ becomes \f$ numerator / x \f$.
5281 * \warning If an exception is thrown because of presence of 0 element in \a this
5282 * array, all elements processed before detection of the zero element remain
5284 * \param [in] numerator - the numerator used to modify array elements.
5285 * \throw If \a this is not allocated.
5286 * \throw If there is an element equal to 0 in \a this array.
5288 void DataArrayInt::applyInv(int numerator)
5291 int *ptr=getPointer();
5292 std::size_t nbOfElems=getNbOfElems();
5293 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
5297 *ptr=numerator/(*ptr);
5301 std::ostringstream oss; oss << "DataArrayInt::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
5303 throw INTERP_KERNEL::Exception(oss.str().c_str());
5310 * Modify all elements of \a this array, so that
5311 * an element _x_ becomes \f$ x / val \f$.
5312 * \param [in] val - the denominator used to modify array elements.
5313 * \throw If \a this is not allocated.
5314 * \throw If \a val == 0.
5316 void DataArrayInt::applyDivideBy(int val)
5319 throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to divide by 0 !");
5321 int *ptr=getPointer();
5322 std::size_t nbOfElems=getNbOfElems();
5323 std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::divides<int>(),val));
5328 * Modify all elements of \a this array, so that
5329 * an element _x_ becomes <em> x % val </em>.
5330 * \param [in] val - the divisor used to modify array elements.
5331 * \throw If \a this is not allocated.
5332 * \throw If \a val <= 0.
5334 void DataArrayInt::applyModulus(int val)
5337 throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to operate modulus on value <= 0 !");
5339 int *ptr=getPointer();
5340 std::size_t nbOfElems=getNbOfElems();
5341 std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::modulus<int>(),val));
5346 * This method works only on data array with one component.
5347 * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
5348 * this[*id] in [\b vmin,\b vmax)
5350 * \param [in] vmin begin of range. This value is included in range (included).
5351 * \param [in] vmax end of range. This value is \b not included in range (excluded).
5352 * \return a newly allocated data array that the caller should deal with.
5354 * \sa DataArrayInt::findIdsNotInRange , DataArrayInt::findIdsStricltyNegative
5356 DataArrayInt *DataArrayInt::findIdsInRange(int vmin, int vmax) const
5358 InRange<int> ir(vmin,vmax);
5359 MCAuto<DataArrayInt> ret(findIdsAdv(ir));
5364 * This method works only on data array with one component.
5365 * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
5366 * this[*id] \b not in [\b vmin,\b vmax)
5368 * \param [in] vmin begin of range. This value is \b not included in range (excluded).
5369 * \param [in] vmax end of range. This value is included in range (included).
5370 * \return a newly allocated data array that the caller should deal with.
5372 * \sa DataArrayInt::findIdsInRange , DataArrayInt::findIdsStricltyNegative
5374 DataArrayInt *DataArrayInt::findIdsNotInRange(int vmin, int vmax) const
5376 NotInRange<int> nir(vmin,vmax);
5377 MCAuto<DataArrayInt> ret(findIdsAdv(nir));
5382 * This method works only on data array with one component.
5383 * 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.
5385 * \param [in] vmin begin of range. This value is included in range (included).
5386 * \param [in] vmax end of range. This value is \b not included in range (excluded).
5387 * \return if all ids in \a this are so that (*this)[i]==i for all i in [ 0, \c this->getNumberOfTuples() ). */
5388 bool DataArrayInt::checkAllIdsInRange(int vmin, int vmax) const
5391 if(getNumberOfComponents()!=1)
5392 throw INTERP_KERNEL::Exception("DataArrayInt::checkAllIdsInRange : this must have exactly one component !");
5393 int nbOfTuples=getNumberOfTuples();
5395 const int *cptr=getConstPointer();
5396 for(int i=0;i<nbOfTuples;i++,cptr++)
5398 if(*cptr>=vmin && *cptr<vmax)
5399 { ret=ret && *cptr==i; }
5402 std::ostringstream oss; oss << "DataArrayInt::checkAllIdsInRange : tuple #" << i << " has value " << *cptr << " should be in [" << vmin << "," << vmax << ") !";
5403 throw INTERP_KERNEL::Exception(oss.str().c_str());
5410 * Modify all elements of \a this array, so that
5411 * an element _x_ becomes <em> val % x </em>.
5412 * \warning If an exception is thrown because of presence of an element <= 0 in \a this
5413 * array, all elements processed before detection of the zero element remain
5415 * \param [in] val - the divident used to modify array elements.
5416 * \throw If \a this is not allocated.
5417 * \throw If there is an element equal to or less than 0 in \a this array.
5419 void DataArrayInt::applyRModulus(int val)
5422 int *ptr=getPointer();
5423 std::size_t nbOfElems=getNbOfElems();
5424 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
5432 std::ostringstream oss; oss << "DataArrayInt::applyRModulus : presence of value <=0 in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
5434 throw INTERP_KERNEL::Exception(oss.str().c_str());
5441 * Modify all elements of \a this array, so that
5442 * an element _x_ becomes <em> val ^ x </em>.
5443 * \param [in] val - the value used to apply pow on all array elements.
5444 * \throw If \a this is not allocated.
5445 * \throw If \a val < 0.
5447 void DataArrayInt::applyPow(int val)
5451 throw INTERP_KERNEL::Exception("DataArrayInt::applyPow : input pow in < 0 !");
5452 int *ptr=getPointer();
5453 std::size_t nbOfElems=getNbOfElems();
5456 std::fill(ptr,ptr+nbOfElems,1);
5459 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
5462 for(int j=0;j<val;j++)
5470 * Modify all elements of \a this array, so that
5471 * an element _x_ becomes \f$ val ^ x \f$.
5472 * \param [in] val - the value used to apply pow on all array elements.
5473 * \throw If \a this is not allocated.
5474 * \throw If there is an element < 0 in \a this array.
5475 * \warning If an exception is thrown because of presence of 0 element in \a this
5476 * array, all elements processed before detection of the zero element remain
5479 void DataArrayInt::applyRPow(int val)
5482 int *ptr=getPointer();
5483 std::size_t nbOfElems=getNbOfElems();
5484 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
5489 for(int j=0;j<*ptr;j++)
5495 std::ostringstream oss; oss << "DataArrayInt::applyRPow : presence of negative value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
5497 throw INTERP_KERNEL::Exception(oss.str().c_str());
5504 * Returns a new DataArrayInt which is a minimal partition of elements of \a groups.
5505 * The i-th item of the result array is an ID of a set of elements belonging to a
5506 * unique set of groups, which the i-th element is a part of. This set of elements
5507 * belonging to a unique set of groups is called \a family, so the result array contains
5508 * IDs of families each element belongs to.
5510 * \b Example: if we have two groups of elements: \a group1 [0,4] and \a group2 [ 0,1,2 ],
5511 * then there are 3 families:
5512 * - \a family1 (with ID 1) contains element [0] belonging to ( \a group1 + \a group2 ),
5513 * - \a family2 (with ID 2) contains elements [4] belonging to ( \a group1 ),
5514 * - \a family3 (with ID 3) contains element [1,2] belonging to ( \a group2 ), <br>
5515 * and the result array contains IDs of families [ 1,3,3,0,2 ]. <br> Note a family ID 0 which
5516 * stands for the element #3 which is in none of groups.
5518 * \param [in] groups - sequence of groups of element IDs.
5519 * \param [in] newNb - total number of elements; it must be more than max ID of element
5521 * \param [out] fidsOfGroups - IDs of families the elements of each group belong to.
5522 * \return DataArrayInt * - a new instance of DataArrayInt containing IDs of families
5523 * each element with ID from range [0, \a newNb ) belongs to. The caller is to
5524 * delete this array using decrRef() as it is no more needed.
5525 * \throw If any element ID in \a groups violates condition ( 0 <= ID < \a newNb ).
5527 DataArrayInt *DataArrayInt::MakePartition(const std::vector<const DataArrayInt *>& groups, int newNb, std::vector< std::vector<int> >& fidsOfGroups)
5529 std::vector<const DataArrayInt *> groups2;
5530 for(std::vector<const DataArrayInt *>::const_iterator it4=groups.begin();it4!=groups.end();it4++)
5532 groups2.push_back(*it4);
5533 MCAuto<DataArrayInt> ret=DataArrayInt::New();
5534 ret->alloc(newNb,1);
5535 int *retPtr=ret->getPointer();
5536 std::fill(retPtr,retPtr+newNb,0);
5538 for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++)
5540 const int *ptr=(*iter)->getConstPointer();
5541 std::size_t nbOfElem=(*iter)->getNbOfElems();
5543 for(int j=0;j<sfid;j++)
5546 for(std::size_t i=0;i<nbOfElem;i++)
5548 if(ptr[i]>=0 && ptr[i]<newNb)
5550 if(retPtr[ptr[i]]==j)
5558 std::ostringstream oss; oss << "DataArrayInt::MakePartition : In group \"" << (*iter)->getName() << "\" in tuple #" << i << " value = " << ptr[i] << " ! Should be in [0," << newNb;
5560 throw INTERP_KERNEL::Exception(oss.str().c_str());
5567 fidsOfGroups.clear();
5568 fidsOfGroups.resize(groups2.size());
5570 for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++,grId++)
5573 const int *ptr=(*iter)->getConstPointer();
5574 std::size_t nbOfElem=(*iter)->getNbOfElems();
5575 for(const int *p=ptr;p!=ptr+nbOfElem;p++)
5576 tmp.insert(retPtr[*p]);
5577 fidsOfGroups[grId].insert(fidsOfGroups[grId].end(),tmp.begin(),tmp.end());
5583 * Returns a new DataArrayInt which contains all elements of given one-dimensional
5584 * arrays. The result array does not contain any duplicates and its values
5585 * are sorted in ascending order.
5586 * \param [in] arr - sequence of DataArrayInt's to unite.
5587 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5588 * array using decrRef() as it is no more needed.
5589 * \throw If any \a arr[i] is not allocated.
5590 * \throw If \a arr[i]->getNumberOfComponents() != 1.
5592 DataArrayInt *DataArrayInt::BuildUnion(const std::vector<const DataArrayInt *>& arr)
5594 std::vector<const DataArrayInt *> a;
5595 for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
5598 for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
5600 (*it)->checkAllocated();
5601 if((*it)->getNumberOfComponents()!=1)
5602 throw INTERP_KERNEL::Exception("DataArrayInt::BuildUnion : only single component allowed !");
5606 for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
5608 const int *pt=(*it)->getConstPointer();
5609 int nbOfTuples=(*it)->getNumberOfTuples();
5610 r.insert(pt,pt+nbOfTuples);
5612 DataArrayInt *ret=DataArrayInt::New();
5613 ret->alloc((int)r.size(),1);
5614 std::copy(r.begin(),r.end(),ret->getPointer());
5619 * Returns a new DataArrayInt which contains elements present in each of given one-dimensional
5620 * arrays. The result array does not contain any duplicates and its values
5621 * are sorted in ascending order.
5622 * \param [in] arr - sequence of DataArrayInt's to intersect.
5623 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5624 * array using decrRef() as it is no more needed.
5625 * \throw If any \a arr[i] is not allocated.
5626 * \throw If \a arr[i]->getNumberOfComponents() != 1.
5628 DataArrayInt *DataArrayInt::BuildIntersection(const std::vector<const DataArrayInt *>& arr)
5630 std::vector<const DataArrayInt *> a;
5631 for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
5634 for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
5636 (*it)->checkAllocated();
5637 if((*it)->getNumberOfComponents()!=1)
5638 throw INTERP_KERNEL::Exception("DataArrayInt::BuildIntersection : only single component allowed !");
5642 for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
5644 const int *pt=(*it)->getConstPointer();
5645 int nbOfTuples=(*it)->getNumberOfTuples();
5646 std::set<int> s1(pt,pt+nbOfTuples);
5650 std::set_intersection(r.begin(),r.end(),s1.begin(),s1.end(),inserter(r2,r2.end()));
5656 DataArrayInt *ret(DataArrayInt::New());
5657 ret->alloc((int)r.size(),1);
5658 std::copy(r.begin(),r.end(),ret->getPointer());
5663 namespace MEDCouplingImpl
5668 OpSwitchedOn(int *pt):_pt(pt),_cnt(0) { }
5669 void operator()(const bool& b) { if(b) *_pt++=_cnt; _cnt++; }
5678 OpSwitchedOff(int *pt):_pt(pt),_cnt(0) { }
5679 void operator()(const bool& b) { if(!b) *_pt++=_cnt; _cnt++; }
5688 * This method returns the list of ids in ascending mode so that v[id]==true.
5690 DataArrayInt *DataArrayInt::BuildListOfSwitchedOn(const std::vector<bool>& v)
5692 int sz((int)std::count(v.begin(),v.end(),true));
5693 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
5694 std::for_each(v.begin(),v.end(),MEDCouplingImpl::OpSwitchedOn(ret->getPointer()));
5699 * This method returns the list of ids in ascending mode so that v[id]==false.
5701 DataArrayInt *DataArrayInt::BuildListOfSwitchedOff(const std::vector<bool>& v)
5703 int sz((int)std::count(v.begin(),v.end(),false));
5704 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
5705 std::for_each(v.begin(),v.end(),MEDCouplingImpl::OpSwitchedOff(ret->getPointer()));
5710 * This method allows to put a vector of vector of integer into a more compact data structure (skyline).
5711 * This method is not available into python because no available optimized data structure available to map std::vector< std::vector<int> >.
5713 * \param [in] v the input data structure to be translate into skyline format.
5714 * \param [out] data the first element of the skyline format. The user is expected to deal with newly allocated array.
5715 * \param [out] dataIndex the second element of the skyline format.
5717 void DataArrayInt::PutIntoToSkylineFrmt(const std::vector< std::vector<int> >& v, DataArrayInt *& data, DataArrayInt *& dataIndex)
5719 int sz((int)v.size());
5720 MCAuto<DataArrayInt> ret0(DataArrayInt::New()),ret1(DataArrayInt::New());
5721 ret1->alloc(sz+1,1);
5722 int *pt(ret1->getPointer()); *pt=0;
5723 for(int i=0;i<sz;i++,pt++)
5724 pt[1]=pt[0]+(int)v[i].size();
5725 ret0->alloc(ret1->back(),1);
5726 pt=ret0->getPointer();
5727 for(int i=0;i<sz;i++)
5728 pt=std::copy(v[i].begin(),v[i].end(),pt);
5729 data=ret0.retn(); dataIndex=ret1.retn();
5733 * Returns a new DataArrayInt which contains a complement of elements of \a this
5734 * one-dimensional array. I.e. the result array contains all elements from the range [0,
5735 * \a nbOfElement) not present in \a this array.
5736 * \param [in] nbOfElement - maximal size of the result array.
5737 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5738 * array using decrRef() as it is no more needed.
5739 * \throw If \a this is not allocated.
5740 * \throw If \a this->getNumberOfComponents() != 1.
5741 * \throw If any element \a x of \a this array violates condition ( 0 <= \a x < \a
5744 DataArrayInt *DataArrayInt::buildComplement(int nbOfElement) const
5747 if(getNumberOfComponents()!=1)
5748 throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : only single component allowed !");
5749 std::vector<bool> tmp(nbOfElement);
5750 const int *pt=getConstPointer();
5751 int nbOfTuples=getNumberOfTuples();
5752 for(const int *w=pt;w!=pt+nbOfTuples;w++)
5753 if(*w>=0 && *w<nbOfElement)
5756 throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : an element is not in valid range : [0,nbOfElement) !");
5757 int nbOfRetVal=(int)std::count(tmp.begin(),tmp.end(),false);
5758 DataArrayInt *ret=DataArrayInt::New();
5759 ret->alloc(nbOfRetVal,1);
5761 int *retPtr=ret->getPointer();
5762 for(int i=0;i<nbOfElement;i++)
5769 * Returns a new DataArrayInt containing elements of \a this one-dimensional missing
5770 * from an \a other one-dimensional array.
5771 * \param [in] other - a DataArrayInt containing elements not to include in the result array.
5772 * \return DataArrayInt * - a new instance of DataArrayInt with one component. The
5773 * caller is to delete this array using decrRef() as it is no more needed.
5774 * \throw If \a other is NULL.
5775 * \throw If \a other is not allocated.
5776 * \throw If \a other->getNumberOfComponents() != 1.
5777 * \throw If \a this is not allocated.
5778 * \throw If \a this->getNumberOfComponents() != 1.
5779 * \sa DataArrayInt::buildSubstractionOptimized()
5781 DataArrayInt *DataArrayInt::buildSubstraction(const DataArrayInt *other) const
5784 throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : DataArrayInt pointer in input is NULL !");
5786 other->checkAllocated();
5787 if(getNumberOfComponents()!=1)
5788 throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed !");
5789 if(other->getNumberOfComponents()!=1)
5790 throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed for other type !");
5791 const int *pt=getConstPointer();
5792 int nbOfTuples=getNumberOfTuples();
5793 std::set<int> s1(pt,pt+nbOfTuples);
5794 pt=other->getConstPointer();
5795 nbOfTuples=other->getNumberOfTuples();
5796 std::set<int> s2(pt,pt+nbOfTuples);
5798 std::set_difference(s1.begin(),s1.end(),s2.begin(),s2.end(),std::back_insert_iterator< std::vector<int> >(r));
5799 DataArrayInt *ret=DataArrayInt::New();
5800 ret->alloc((int)r.size(),1);
5801 std::copy(r.begin(),r.end(),ret->getPointer());
5806 * \a this is expected to have one component and to be sorted ascendingly (as for \a other).
5807 * \a other is expected to be a part of \a this. If not DataArrayInt::buildSubstraction should be called instead.
5809 * \param [in] other an array with one component and expected to be sorted ascendingly.
5810 * \ret list of ids in \a this but not in \a other.
5811 * \sa DataArrayInt::buildSubstraction
5813 DataArrayInt *DataArrayInt::buildSubstractionOptimized(const DataArrayInt *other) const
5815 static const char *MSG="DataArrayInt::buildSubstractionOptimized : only single component allowed !";
5816 if(!other) throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstractionOptimized : NULL input array !");
5817 checkAllocated(); other->checkAllocated();
5818 if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
5819 if(other->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
5820 const int *pt1Bg(begin()),*pt1End(end()),*pt2Bg(other->begin()),*pt2End(other->end());
5821 const int *work1(pt1Bg),*work2(pt2Bg);
5822 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
5823 for(;work1!=pt1End;work1++)
5825 if(work2!=pt2End && *work1==*work2)
5828 ret->pushBackSilent(*work1);
5835 * Returns a new DataArrayInt which contains all elements of \a this and a given
5836 * one-dimensional arrays. The result array does not contain any duplicates
5837 * and its values are sorted in ascending order.
5838 * \param [in] other - an array to unite with \a this one.
5839 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5840 * array using decrRef() as it is no more needed.
5841 * \throw If \a this or \a other is not allocated.
5842 * \throw If \a this->getNumberOfComponents() != 1.
5843 * \throw If \a other->getNumberOfComponents() != 1.
5845 DataArrayInt *DataArrayInt::buildUnion(const DataArrayInt *other) const
5847 std::vector<const DataArrayInt *>arrs(2);
5848 arrs[0]=this; arrs[1]=other;
5849 return BuildUnion(arrs);
5854 * Returns a new DataArrayInt which contains elements present in both \a this and a given
5855 * one-dimensional arrays. The result array does not contain any duplicates
5856 * and its values are sorted in ascending order.
5857 * \param [in] other - an array to intersect with \a this one.
5858 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5859 * array using decrRef() as it is no more needed.
5860 * \throw If \a this or \a other is not allocated.
5861 * \throw If \a this->getNumberOfComponents() != 1.
5862 * \throw If \a other->getNumberOfComponents() != 1.
5864 DataArrayInt *DataArrayInt::buildIntersection(const DataArrayInt *other) const
5866 std::vector<const DataArrayInt *>arrs(2);
5867 arrs[0]=this; arrs[1]=other;
5868 return BuildIntersection(arrs);
5872 * This method can be applied on allocated with one component DataArrayInt instance.
5873 * This method is typically relevant for sorted arrays. All consecutive duplicated items in \a this will appear only once in returned DataArrayInt instance.
5874 * 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]
5876 * \return a newly allocated array that contain the result of the unique operation applied on \a this.
5877 * \throw if \a this is not allocated or if \a this has not exactly one component.
5878 * \sa DataArrayInt::buildUniqueNotSorted
5880 DataArrayInt *DataArrayInt::buildUnique() const
5883 if(getNumberOfComponents()!=1)
5884 throw INTERP_KERNEL::Exception("DataArrayInt::buildUnique : only single component allowed !");
5885 int nbOfTuples=getNumberOfTuples();
5886 MCAuto<DataArrayInt> tmp=deepCopy();
5887 int *data=tmp->getPointer();
5888 int *last=std::unique(data,data+nbOfTuples);
5889 MCAuto<DataArrayInt> ret=DataArrayInt::New();
5890 ret->alloc(std::distance(data,last),1);
5891 std::copy(data,last,ret->getPointer());
5896 * This method can be applied on allocated with one component DataArrayInt instance.
5897 * This method keep elements only once by keeping the same order in \a this that is not expected to be sorted.
5899 * \return a newly allocated array that contain the result of the unique operation applied on \a this.
5901 * \throw if \a this is not allocated or if \a this has not exactly one component.
5903 * \sa DataArrayInt::buildUnique
5905 DataArrayInt *DataArrayInt::buildUniqueNotSorted() const
5908 if(getNumberOfComponents()!=1)
5909 throw INTERP_KERNEL::Exception("DataArrayInt::buildUniqueNotSorted : only single component allowed !");
5911 getMinMaxValues(minVal,maxVal);
5912 std::vector<bool> b(maxVal-minVal+1,false);
5913 const int *ptBg(begin()),*endBg(end());
5914 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
5915 for(const int *pt=ptBg;pt!=endBg;pt++)
5919 ret->pushBackSilent(*pt);
5923 ret->copyStringInfoFrom(*this);
5928 * Returns a new DataArrayInt which contains size of every of groups described by \a this
5929 * "index" array. Such "index" array is returned for example by
5930 * \ref MEDCoupling::MEDCouplingUMesh::buildDescendingConnectivity
5931 * "MEDCouplingUMesh::buildDescendingConnectivity" and
5932 * \ref MEDCoupling::MEDCouplingUMesh::getNodalConnectivityIndex
5933 * "MEDCouplingUMesh::getNodalConnectivityIndex" etc.
5934 * This method performs the reverse operation of DataArrayInt::computeOffsetsFull.
5935 * \return DataArrayInt * - a new instance of DataArrayInt, whose number of tuples
5936 * equals to \a this->getNumberOfComponents() - 1, and number of components is 1.
5937 * The caller is to delete this array using decrRef() as it is no more needed.
5938 * \throw If \a this is not allocated.
5939 * \throw If \a this->getNumberOfComponents() != 1.
5940 * \throw If \a this->getNumberOfTuples() < 2.
5943 * - this contains [1,3,6,7,7,9,15]
5944 * - result array contains [2,3,1,0,2,6],
5945 * where 2 = 3 - 1, 3 = 6 - 3, 1 = 7 - 6 etc.
5947 * \sa DataArrayInt::computeOffsetsFull
5949 DataArrayInt *DataArrayInt::deltaShiftIndex() const
5952 if(getNumberOfComponents()!=1)
5953 throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : only single component allowed !");
5954 int nbOfTuples=getNumberOfTuples();
5956 throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : 1 tuple at least must be present in 'this' !");
5957 const int *ptr=getConstPointer();
5958 DataArrayInt *ret=DataArrayInt::New();
5959 ret->alloc(nbOfTuples-1,1);
5960 int *out=ret->getPointer();
5961 std::transform(ptr+1,ptr+nbOfTuples,ptr,out,std::minus<int>());
5966 * Modifies \a this one-dimensional array so that value of each element \a x
5967 * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
5968 * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number of tuples
5969 * and components remains the same.<br>
5970 * This method is useful for allToAllV in MPI with contiguous policy. This method
5971 * differs from computeOffsetsFull() in that the number of tuples is \b not changed by
5973 * \throw If \a this is not allocated.
5974 * \throw If \a this->getNumberOfComponents() != 1.
5977 * - Before \a this contains [3,5,1,2,0,8]
5978 * - After \a this contains [0,3,8,9,11,11]<br>
5979 * Note that the last element 19 = 11 + 8 is missing because size of \a this
5980 * array is retained and thus there is no space to store the last element.
5982 void DataArrayInt::computeOffsets()
5985 if(getNumberOfComponents()!=1)
5986 throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets : only single component allowed !");
5987 int nbOfTuples=getNumberOfTuples();
5990 int *work=getPointer();
5993 for(int i=1;i<nbOfTuples;i++)
5996 work[i]=work[i-1]+tmp;
6004 * Modifies \a this one-dimensional array so that value of each element \a x
6005 * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
6006 * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number
6007 * components remains the same and number of tuples is inceamented by one.<br>
6008 * This method is useful for allToAllV in MPI with contiguous policy. This method
6009 * differs from computeOffsets() in that the number of tuples is changed by this one.
6010 * This method performs the reverse operation of DataArrayInt::deltaShiftIndex.
6011 * \throw If \a this is not allocated.
6012 * \throw If \a this->getNumberOfComponents() != 1.
6015 * - Before \a this contains [3,5,1,2,0,8]
6016 * - After \a this contains [0,3,8,9,11,11,19]<br>
6017 * \sa DataArrayInt::deltaShiftIndex
6019 void DataArrayInt::computeOffsetsFull()
6022 if(getNumberOfComponents()!=1)
6023 throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsetsFull : only single component allowed !");
6024 int nbOfTuples=getNumberOfTuples();
6025 int *ret=(int *)malloc((nbOfTuples+1)*sizeof(int));
6026 const int *work=getConstPointer();
6028 for(int i=0;i<nbOfTuples;i++)
6029 ret[i+1]=work[i]+ret[i];
6030 useArray(ret,true,C_DEALLOC,nbOfTuples+1,1);
6035 * Returns two new DataArrayInt instances whose contents is computed from that of \a this and \a listOfIds arrays as follows.
6036 * \a this is expected to be an offset format ( as returned by DataArrayInt::computeOffsetsFull ) that is to say with one component
6037 * and ** sorted strictly increasingly **. \a listOfIds is expected to be sorted ascendingly (not strictly needed for \a listOfIds).
6038 * This methods searches in \a this, considered as a set of contiguous \c this->getNumberOfComponents() ranges, all ids in \a listOfIds
6039 * filling completely one of the ranges in \a this.
6041 * \param [in] listOfIds a list of ids that has to be sorted ascendingly.
6042 * \param [out] rangeIdsFetched the range ids fetched
6043 * \param [out] idsInInputListThatFetch contains the list of ids in \a listOfIds that are \b fully included in a range in \a this. So
6044 * \a idsInInputListThatFetch is a part of input \a listOfIds.
6046 * \sa DataArrayInt::computeOffsetsFull
6049 * - \a this : [0,3,7,9,15,18]
6050 * - \a listOfIds contains [0,1,2,3,7,8,15,16,17]
6051 * - \a rangeIdsFetched result array: [0,2,4]
6052 * - \a idsInInputListThatFetch result array: [0,1,2,7,8,15,16,17]
6053 * In this example id 3 in input \a listOfIds is alone so it do not appear in output \a idsInInputListThatFetch.
6056 void DataArrayInt::findIdsRangesInListOfIds(const DataArrayInt *listOfIds, DataArrayInt *& rangeIdsFetched, DataArrayInt *& idsInInputListThatFetch) const
6059 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : input list of ids is null !");
6060 listOfIds->checkAllocated(); checkAllocated();
6061 if(listOfIds->getNumberOfComponents()!=1)
6062 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : input list of ids must have exactly one component !");
6063 if(getNumberOfComponents()!=1)
6064 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : this must have exactly one component !");
6065 MCAuto<DataArrayInt> ret0=DataArrayInt::New(); ret0->alloc(0,1);
6066 MCAuto<DataArrayInt> ret1=DataArrayInt::New(); ret1->alloc(0,1);
6067 const int *tupEnd(listOfIds->end()),*offBg(begin()),*offEnd(end()-1);
6068 const int *tupPtr(listOfIds->begin()),*offPtr(offBg);
6069 while(tupPtr!=tupEnd && offPtr!=offEnd)
6071 if(*tupPtr==*offPtr)
6074 while(i<offPtr[1] && *tupPtr==i && tupPtr!=tupEnd) { i++; tupPtr++; }
6077 ret0->pushBackSilent((int)std::distance(offBg,offPtr));
6078 ret1->pushBackValsSilent(tupPtr-(offPtr[1]-offPtr[0]),tupPtr);
6083 { if(*tupPtr<*offPtr) tupPtr++; else offPtr++; }
6085 rangeIdsFetched=ret0.retn();
6086 idsInInputListThatFetch=ret1.retn();
6090 * Returns a new DataArrayInt whose contents is computed from that of \a this and \a
6091 * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
6092 * "index" array of a "iota" array, thus, whose each element gives an index of a group
6093 * beginning within the "iota" array. And \a this is a one-dimensional array
6094 * considered as a selector of groups described by \a offsets to include into the result array.
6095 * \throw If \a offsets is NULL.
6096 * \throw If \a offsets is not allocated.
6097 * \throw If \a offsets->getNumberOfComponents() != 1.
6098 * \throw If \a offsets is not monotonically increasing.
6099 * \throw If \a this is not allocated.
6100 * \throw If \a this->getNumberOfComponents() != 1.
6101 * \throw If any element of \a this is not a valid index for \a offsets array.
6104 * - \a this: [0,2,3]
6105 * - \a offsets: [0,3,6,10,14,20]
6106 * - result array: [0,1,2,6,7,8,9,10,11,12,13] == <br>
6107 * \c range(0,3) + \c range(6,10) + \c range(10,14) ==<br>
6108 * \c range( \a offsets[ \a this[0] ], offsets[ \a this[0]+1 ]) +
6109 * \c range( \a offsets[ \a this[1] ], offsets[ \a this[1]+1 ]) +
6110 * \c range( \a offsets[ \a this[2] ], offsets[ \a this[2]+1 ])
6112 DataArrayInt *DataArrayInt::buildExplicitArrByRanges(const DataArrayInt *offsets) const
6115 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : DataArrayInt pointer in input is NULL !");
6117 if(getNumberOfComponents()!=1)
6118 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : only single component allowed !");
6119 offsets->checkAllocated();
6120 if(offsets->getNumberOfComponents()!=1)
6121 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : input array should have only single component !");
6122 int othNbTuples=offsets->getNumberOfTuples()-1;
6123 int nbOfTuples=getNumberOfTuples();
6124 int retNbOftuples=0;
6125 const int *work=getConstPointer();
6126 const int *offPtr=offsets->getConstPointer();
6127 for(int i=0;i<nbOfTuples;i++)
6130 if(val>=0 && val<othNbTuples)
6132 int delta=offPtr[val+1]-offPtr[val];
6134 retNbOftuples+=delta;
6137 std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << val << " of offset array has a delta < 0 !";
6138 throw INTERP_KERNEL::Exception(oss.str().c_str());
6143 std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << i << " in this contains " << val;
6144 oss << " whereas offsets array is of size " << othNbTuples+1 << " !";
6145 throw INTERP_KERNEL::Exception(oss.str().c_str());
6148 MCAuto<DataArrayInt> ret=DataArrayInt::New();
6149 ret->alloc(retNbOftuples,1);
6150 int *retPtr=ret->getPointer();
6151 for(int i=0;i<nbOfTuples;i++)
6154 int start=offPtr[val];
6155 int off=offPtr[val+1]-start;
6156 for(int j=0;j<off;j++,retPtr++)
6163 * Returns a new DataArrayInt whose contents is computed using \a this that must be a
6164 * scaled array (monotonically increasing).
6165 from that of \a this and \a
6166 * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
6167 * "index" array of a "iota" array, thus, whose each element gives an index of a group
6168 * beginning within the "iota" array. And \a this is a one-dimensional array
6169 * considered as a selector of groups described by \a offsets to include into the result array.
6170 * \throw If \a is NULL.
6171 * \throw If \a this is not allocated.
6172 * \throw If \a this->getNumberOfComponents() != 1.
6173 * \throw If \a this->getNumberOfTuples() == 0.
6174 * \throw If \a this is not monotonically increasing.
6175 * \throw If any element of ids in ( \a bg \a stop \a step ) points outside the scale in \a this.
6178 * - \a bg , \a stop and \a step : (0,5,2)
6179 * - \a this: [0,3,6,10,14,20]
6180 * - result array: [0,0,0, 2,2,2,2, 4,4,4,4,4,4] == <br>
6182 DataArrayInt *DataArrayInt::buildExplicitArrOfSliceOnScaledArr(int bg, int stop, int step) const
6185 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : not allocated array !");
6186 if(getNumberOfComponents()!=1)
6187 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of components is expected to be equal to one !");
6188 int nbOfTuples(getNumberOfTuples());
6190 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of tuples must be != 0 !");
6191 const int *ids(begin());
6192 int nbOfEltsInSlc(GetNumberOfItemGivenBESRelative(bg,stop,step,"DataArrayInt::buildExplicitArrOfSliceOnScaledArr")),sz(0),pos(bg);
6193 for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
6195 if(pos>=0 && pos<nbOfTuples-1)
6197 int delta(ids[pos+1]-ids[pos]);
6201 std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " and at this pos this is not monotonically increasing !";
6202 throw INTERP_KERNEL::Exception(oss.str().c_str());
6207 std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " should be in [0," << nbOfTuples-1 << ") !";
6208 throw INTERP_KERNEL::Exception(oss.str().c_str());
6211 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
6212 int *retPtr(ret->getPointer());
6214 for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
6216 int delta(ids[pos+1]-ids[pos]);
6217 for(int j=0;j<delta;j++,retPtr++)
6224 * 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.
6225 * 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
6226 * in tuple **i** of returned DataArrayInt.
6227 * If ranges overlapped (in theory it should not) this method do not detect it and always returns the first range.
6229 * 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)]
6230 * The return DataArrayInt will contain : **[0,4,1,2,2,3]**
6232 * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
6233 * for lower value included and 2nd component is the upper value of corresponding range **excluded**.
6234 * \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
6235 * is thrown if no ranges in \a ranges contains value in \a this.
6237 * \sa DataArrayInt::findIdInRangeForEachTuple
6239 DataArrayInt *DataArrayInt::findRangeIdForEachTuple(const DataArrayInt *ranges) const
6242 throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : null input pointer !");
6243 if(ranges->getNumberOfComponents()!=2)
6244 throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : input DataArrayInt instance should have 2 components !");
6246 if(getNumberOfComponents()!=1)
6247 throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : this should have only one component !");
6248 int nbTuples=getNumberOfTuples();
6249 MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
6250 int nbOfRanges=ranges->getNumberOfTuples();
6251 const int *rangesPtr=ranges->getConstPointer();
6252 int *retPtr=ret->getPointer();
6253 const int *inPtr=getConstPointer();
6254 for(int i=0;i<nbTuples;i++,retPtr++)
6258 for(int j=0;j<nbOfRanges && !found;j++)
6259 if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
6260 { *retPtr=j; found=true; }
6265 std::ostringstream oss; oss << "DataArrayInt::findRangeIdForEachTuple : tuple #" << i << " not found by any ranges !";
6266 throw INTERP_KERNEL::Exception(oss.str().c_str());
6273 * 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.
6274 * 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
6275 * in tuple **i** of returned DataArrayInt.
6276 * If ranges overlapped (in theory it should not) this method do not detect it and always returns the sub position of the first range.
6278 * 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)]
6279 * The return DataArrayInt will contain : **[1,2,4,0,2,2]**
6280 * This method is often called in pair with DataArrayInt::findRangeIdForEachTuple method.
6282 * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
6283 * for lower value included and 2nd component is the upper value of corresponding range **excluded**.
6284 * \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
6285 * is thrown if no ranges in \a ranges contains value in \a this.
6286 * \sa DataArrayInt::findRangeIdForEachTuple
6288 DataArrayInt *DataArrayInt::findIdInRangeForEachTuple(const DataArrayInt *ranges) const
6291 throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : null input pointer !");
6292 if(ranges->getNumberOfComponents()!=2)
6293 throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : input DataArrayInt instance should have 2 components !");
6295 if(getNumberOfComponents()!=1)
6296 throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : this should have only one component !");
6297 int nbTuples=getNumberOfTuples();
6298 MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
6299 int nbOfRanges=ranges->getNumberOfTuples();
6300 const int *rangesPtr=ranges->getConstPointer();
6301 int *retPtr=ret->getPointer();
6302 const int *inPtr=getConstPointer();
6303 for(int i=0;i<nbTuples;i++,retPtr++)
6307 for(int j=0;j<nbOfRanges && !found;j++)
6308 if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
6309 { *retPtr=val-rangesPtr[2*j]; found=true; }
6314 std::ostringstream oss; oss << "DataArrayInt::findIdInRangeForEachTuple : tuple #" << i << " not found by any ranges !";
6315 throw INTERP_KERNEL::Exception(oss.str().c_str());
6322 * \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).
6323 * 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).
6324 * 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 !
6325 * If this method has correctly worked, \a this will be able to be considered as a linked list.
6326 * This method does nothing if number of tuples is lower of equal to 1.
6328 * This method is useful for users having an unstructured mesh having only SEG2 to rearrange internally the connectibity without any coordinates consideration.
6330 * \sa MEDCouplingUMesh::orderConsecutiveCells1D, DataArrayInt::fromLinkedListOfPairToList
6332 void DataArrayInt::sortEachPairToMakeALinkedList()
6335 if(getNumberOfComponents()!=2)
6336 throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : Only works on DataArrayInt instance with nb of components equal to 2 !");
6337 int nbOfTuples(getNumberOfTuples());
6340 int *conn(getPointer());
6341 for(int i=1;i<nbOfTuples;i++,conn+=2)
6345 if(conn[2]==conn[3])
6347 std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " presence of a pair filled with same ids !";
6348 throw INTERP_KERNEL::Exception(oss.str().c_str());
6350 if(conn[2]!=conn[1] && conn[3]==conn[1] && conn[2]!=conn[0])
6351 std::swap(conn[2],conn[3]);
6352 //not(conn[2]==conn[1] && conn[3]!=conn[1] && conn[3]!=conn[0])
6353 if(conn[2]!=conn[1] || conn[3]==conn[1] || conn[3]==conn[0])
6355 std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " something is invalid !";
6356 throw INTERP_KERNEL::Exception(oss.str().c_str());
6361 if(conn[0]==conn[1] || conn[2]==conn[3])
6362 throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : In the 2 first tuples presence of a pair filled with same ids !");
6365 s.insert(conn,conn+4);
6367 throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : This can't be considered as a linked list regarding 2 first tuples !");
6368 if(std::count(conn,conn+4,conn[0])==2)
6373 if(conn[2]==conn[0])
6377 std::copy(tmp,tmp+4,conn);
6380 {//here we are sure to have (std::count(conn,conn+4,conn[1])==2)
6381 if(conn[1]==conn[3])
6382 std::swap(conn[2],conn[3]);
6389 * \a this is expected to be a correctly linked list of pairs.
6391 * \sa DataArrayInt::sortEachPairToMakeALinkedList
6393 MCAuto<DataArrayInt> DataArrayInt::fromLinkedListOfPairToList() const
6396 checkNbOfComps(2,"DataArrayInt::fromLinkedListOfPairToList : this is expected to have 2 components");
6397 int nbTuples(getNumberOfTuples());
6399 throw INTERP_KERNEL::Exception("DataArrayInt::fromLinkedListOfPairToList : no tuples in this ! Not a linked list !");
6400 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbTuples+1,1);
6401 const int *thisPtr(begin());
6402 int *retPtr(ret->getPointer());
6403 retPtr[0]=thisPtr[0];
6404 for(int i=0;i<nbTuples;i++)
6406 retPtr[i+1]=thisPtr[2*i+1];
6408 if(thisPtr[2*i+1]!=thisPtr[2*(i+1)+0])
6410 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 ?";
6411 throw INTERP_KERNEL::Exception(oss.str());
6418 * This method returns all different values found in \a this. This method throws if \a this has not been allocated.
6419 * But the number of components can be different from one.
6420 * \return a newly allocated array (that should be dealt by the caller) containing different values in \a this.
6422 DataArrayInt *DataArrayInt::getDifferentValues() const
6426 ret.insert(begin(),end());
6427 MCAuto<DataArrayInt> ret2=DataArrayInt::New(); ret2->alloc((int)ret.size(),1);
6428 std::copy(ret.begin(),ret.end(),ret2->getPointer());
6433 * This method is a refinement of DataArrayInt::getDifferentValues because it returns not only different values in \a this but also, for each of
6434 * them it tells which tuple id have this id.
6435 * This method works only on arrays with one component (if it is not the case call DataArrayInt::rearrange(1) ).
6436 * This method returns two arrays having same size.
6437 * 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.
6438 * 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]]
6440 std::vector<DataArrayInt *> DataArrayInt::partitionByDifferentValues(std::vector<int>& differentIds) const
6443 if(getNumberOfComponents()!=1)
6444 throw INTERP_KERNEL::Exception("DataArrayInt::partitionByDifferentValues : this should have only one component !");
6446 std::map<int,int> m,m2,m3;
6447 for(const int *w=begin();w!=end();w++)
6449 differentIds.resize(m.size());
6450 std::vector<DataArrayInt *> ret(m.size());
6451 std::vector<int *> retPtr(m.size());
6452 for(std::map<int,int>::const_iterator it=m.begin();it!=m.end();it++,id++)
6455 ret[id]=DataArrayInt::New();
6456 ret[id]->alloc((*it).second,1);
6457 retPtr[id]=ret[id]->getPointer();
6458 differentIds[id]=(*it).first;
6461 for(const int *w=begin();w!=end();w++,id++)
6463 retPtr[m2[*w]][m3[*w]++]=id;
6469 * This method split ids in [0, \c this->getNumberOfTuples() ) using \a this array as a field of weight (>=0 each).
6470 * The aim of this method is to return a set of \a nbOfSlices chunk of contiguous ids as balanced as possible.
6472 * \param [in] nbOfSlices - number of slices expected.
6473 * \return - a vector having a size equal to \a nbOfSlices giving the start (included) and the stop (excluded) of each chunks.
6475 * \sa DataArray::GetSlice
6476 * \throw If \a this is not allocated or not with exactly one component.
6477 * \throw If an element in \a this if < 0.
6479 std::vector< std::pair<int,int> > DataArrayInt::splitInBalancedSlices(int nbOfSlices) const
6481 if(!isAllocated() || getNumberOfComponents()!=1)
6482 throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : this array should have number of components equal to one and must be allocated !");
6484 throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : number of slices must be >= 1 !");
6485 int sum(accumulate(0)),nbOfTuples(getNumberOfTuples());
6486 int sumPerSlc(sum/nbOfSlices),pos(0);
6487 const int *w(begin());
6488 std::vector< std::pair<int,int> > ret(nbOfSlices);
6489 for(int i=0;i<nbOfSlices;i++)
6491 std::pair<int,int> p(pos,-1);
6493 while(locSum<sumPerSlc && pos<nbOfTuples) { pos++; locSum+=*w++; }
6497 p.second=nbOfTuples;
6504 * Returns a new DataArrayInt that is a modulus of two given arrays. There are 3
6506 * 1. The arrays have same number of tuples and components. Then each value of
6507 * the result array (_a_) is a division of the corresponding values of \a a1 and
6508 * \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, j ].
6509 * 2. The arrays have same number of tuples and one array, say _a2_, has one
6511 * _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, 0 ].
6512 * 3. The arrays have same number of components and one array, say _a2_, has one
6514 * _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ 0, j ].
6516 * Info on components is copied either from the first array (in the first case) or from
6517 * the array with maximal number of elements (getNbOfElems()).
6518 * \warning No check of division by zero is performed!
6519 * \param [in] a1 - a dividend array.
6520 * \param [in] a2 - a divisor array.
6521 * \return DataArrayInt * - the new instance of DataArrayInt.
6522 * The caller is to delete this result array using decrRef() as it is no more
6524 * \throw If either \a a1 or \a a2 is NULL.
6525 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
6526 * \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
6527 * none of them has number of tuples or components equal to 1.
6529 DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt *a2)
6532 throw INTERP_KERNEL::Exception("DataArrayInt::Modulus : input DataArrayInt instance is NULL !");
6533 int nbOfTuple1=a1->getNumberOfTuples();
6534 int nbOfTuple2=a2->getNumberOfTuples();
6535 int nbOfComp1=a1->getNumberOfComponents();
6536 int nbOfComp2=a2->getNumberOfComponents();
6537 if(nbOfTuple2==nbOfTuple1)
6539 if(nbOfComp1==nbOfComp2)
6541 MCAuto<DataArrayInt> ret=DataArrayInt::New();
6542 ret->alloc(nbOfTuple2,nbOfComp1);
6543 std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::modulus<int>());
6544 ret->copyStringInfoFrom(*a1);
6547 else if(nbOfComp2==1)
6549 MCAuto<DataArrayInt> ret=DataArrayInt::New();
6550 ret->alloc(nbOfTuple1,nbOfComp1);
6551 const int *a2Ptr=a2->getConstPointer();
6552 const int *a1Ptr=a1->getConstPointer();
6553 int *res=ret->getPointer();
6554 for(int i=0;i<nbOfTuple1;i++)
6555 res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::modulus<int>(),a2Ptr[i]));
6556 ret->copyStringInfoFrom(*a1);
6561 a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
6565 else if(nbOfTuple2==1)
6567 a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
6568 MCAuto<DataArrayInt> ret=DataArrayInt::New();
6569 ret->alloc(nbOfTuple1,nbOfComp1);
6570 const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
6571 int *pt=ret->getPointer();
6572 for(int i=0;i<nbOfTuple1;i++)
6573 pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::modulus<int>());
6574 ret->copyStringInfoFrom(*a1);
6579 a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Modulus !");//will always throw an exception
6585 * Modify \a this array so that each value becomes a modulus of division of this value by
6586 * a value of another DataArrayInt. There are 3 valid cases.
6587 * 1. The arrays have same number of tuples and components. Then each value of
6588 * \a this array is divided by the corresponding value of \a other one, i.e.:
6589 * _a_ [ i, j ] %= _other_ [ i, j ].
6590 * 2. The arrays have same number of tuples and \a other array has one component. Then
6591 * _a_ [ i, j ] %= _other_ [ i, 0 ].
6592 * 3. The arrays have same number of components and \a other array has one tuple. Then
6593 * _a_ [ i, j ] %= _a2_ [ 0, j ].
6595 * \warning No check of division by zero is performed!
6596 * \param [in] other - a divisor array.
6597 * \throw If \a other is NULL.
6598 * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
6599 * \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
6600 * \a other has number of both tuples and components not equal to 1.
6602 void DataArrayInt::modulusEqual(const DataArrayInt *other)
6605 throw INTERP_KERNEL::Exception("DataArrayInt::modulusEqual : input DataArrayInt instance is NULL !");
6606 const char *msg="Nb of tuples mismatch for DataArrayInt::modulusEqual !";
6607 checkAllocated(); other->checkAllocated();
6608 int nbOfTuple=getNumberOfTuples();
6609 int nbOfTuple2=other->getNumberOfTuples();
6610 int nbOfComp=getNumberOfComponents();
6611 int nbOfComp2=other->getNumberOfComponents();
6612 if(nbOfTuple==nbOfTuple2)
6614 if(nbOfComp==nbOfComp2)
6616 std::transform(begin(),end(),other->begin(),getPointer(),std::modulus<int>());
6618 else if(nbOfComp2==1)
6620 if(nbOfComp2==nbOfComp)
6622 int *ptr=getPointer();
6623 const int *ptrc=other->getConstPointer();
6624 for(int i=0;i<nbOfTuple;i++)
6625 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::modulus<int>(),*ptrc++));
6628 throw INTERP_KERNEL::Exception(msg);
6631 throw INTERP_KERNEL::Exception(msg);
6633 else if(nbOfTuple2==1)
6635 int *ptr=getPointer();
6636 const int *ptrc=other->getConstPointer();
6637 for(int i=0;i<nbOfTuple;i++)
6638 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::modulus<int>());
6641 throw INTERP_KERNEL::Exception(msg);
6646 * Returns a new DataArrayInt that is the result of pow of two given arrays. There are 3
6649 * \param [in] a1 - an array to pow up.
6650 * \param [in] a2 - another array to sum up.
6651 * \return DataArrayInt * - the new instance of DataArrayInt.
6652 * The caller is to delete this result array using decrRef() as it is no more
6654 * \throw If either \a a1 or \a a2 is NULL.
6655 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
6656 * \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
6657 * \throw If there is a negative value in \a a2.
6659 DataArrayInt *DataArrayInt::Pow(const DataArrayInt *a1, const DataArrayInt *a2)
6662 throw INTERP_KERNEL::Exception("DataArrayInt::Pow : at least one of input instances is null !");
6663 int nbOfTuple=a1->getNumberOfTuples();
6664 int nbOfTuple2=a2->getNumberOfTuples();
6665 int nbOfComp=a1->getNumberOfComponents();
6666 int nbOfComp2=a2->getNumberOfComponents();
6667 if(nbOfTuple!=nbOfTuple2)
6668 throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of tuples mismatches !");
6669 if(nbOfComp!=1 || nbOfComp2!=1)
6670 throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of components of both arrays must be equal to 1 !");
6671 MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuple,1);
6672 const int *ptr1(a1->begin()),*ptr2(a2->begin());
6673 int *ptr=ret->getPointer();
6674 for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
6679 for(int j=0;j<*ptr2;j++)
6685 std::ostringstream oss; oss << "DataArrayInt::Pow : on tuple #" << i << " of a2 value is < 0 (" << *ptr2 << ") !";
6686 throw INTERP_KERNEL::Exception(oss.str().c_str());
6693 * Apply pow on values of another DataArrayInt to values of \a this one.
6695 * \param [in] other - an array to pow to \a this one.
6696 * \throw If \a other is NULL.
6697 * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
6698 * \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
6699 * \throw If there is a negative value in \a other.
6701 void DataArrayInt::powEqual(const DataArrayInt *other)
6704 throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : input instance is null !");
6705 int nbOfTuple=getNumberOfTuples();
6706 int nbOfTuple2=other->getNumberOfTuples();
6707 int nbOfComp=getNumberOfComponents();
6708 int nbOfComp2=other->getNumberOfComponents();
6709 if(nbOfTuple!=nbOfTuple2)
6710 throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of tuples mismatches !");
6711 if(nbOfComp!=1 || nbOfComp2!=1)
6712 throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of components of both arrays must be equal to 1 !");
6713 int *ptr=getPointer();
6714 const int *ptrc=other->begin();
6715 for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
6720 for(int j=0;j<*ptrc;j++)
6726 std::ostringstream oss; oss << "DataArrayInt::powEqual : on tuple #" << i << " of other value is < 0 (" << *ptrc << ") !";
6727 throw INTERP_KERNEL::Exception(oss.str().c_str());
6734 * Returns a C array which is a renumbering map in "Old to New" mode for the input array.
6735 * This map, if applied to \a start array, would make it sorted. For example, if
6736 * \a start array contents are [9,10,0,6,4,11,3,7] then the contents of the result array is
6737 * [5,6,0,3,2,7,1,4].
6738 * \param [in] start - pointer to the first element of the array for which the
6739 * permutation map is computed.
6740 * \param [in] end - pointer specifying the end of the array \a start, so that
6741 * the last value of \a start is \a end[ -1 ].
6742 * \return int * - the result permutation array that the caller is to delete as it is no
6744 * \throw If there are equal values in the input array.
6746 int *DataArrayInt::CheckAndPreparePermutation(const int *start, const int *end)
6748 std::size_t sz=std::distance(start,end);
6749 int *ret=(int *)malloc(sz*sizeof(int));
6750 int *work=new int[sz];
6751 std::copy(start,end,work);
6752 std::sort(work,work+sz);
6753 if(std::unique(work,work+sz)!=work+sz)
6757 throw INTERP_KERNEL::Exception("Some elements are equals in the specified array !");
6759 std::map<int,int> m;
6760 for(int *workPt=work;workPt!=work+sz;workPt++)
6761 m[*workPt]=(int)std::distance(work,workPt);
6763 for(const int *iter=start;iter!=end;iter++,iter2++)
6770 * Returns a new DataArrayInt containing an arithmetic progression
6771 * that is equal to the sequence returned by Python \c range(\a begin,\a end,\a step )
6773 * \param [in] begin - the start value of the result sequence.
6774 * \param [in] end - limiting value, so that every value of the result array is less than
6776 * \param [in] step - specifies the increment or decrement.
6777 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6778 * array using decrRef() as it is no more needed.
6779 * \throw If \a step == 0.
6780 * \throw If \a end < \a begin && \a step > 0.
6781 * \throw If \a end > \a begin && \a step < 0.
6783 DataArrayInt *DataArrayInt::Range(int begin, int end, int step)
6785 int nbOfTuples=GetNumberOfItemGivenBESRelative(begin,end,step,"DataArrayInt::Range");
6786 MCAuto<DataArrayInt> ret=DataArrayInt::New();
6787 ret->alloc(nbOfTuples,1);
6788 int *ptr=ret->getPointer();
6791 for(int i=begin;i<end;i+=step,ptr++)
6796 for(int i=begin;i>end;i+=step,ptr++)
6803 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
6806 void DataArrayInt::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
6811 tinyInfo[0]=getNumberOfTuples();
6812 tinyInfo[1]=getNumberOfComponents();
6822 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
6825 void DataArrayInt::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
6829 int nbOfCompo=getNumberOfComponents();
6830 tinyInfo.resize(nbOfCompo+1);
6831 tinyInfo[0]=getName();
6832 for(int i=0;i<nbOfCompo;i++)
6833 tinyInfo[i+1]=getInfoOnComponent(i);
6838 tinyInfo[0]=getName();
6843 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
6844 * This method returns if a feeding is needed.
6846 bool DataArrayInt::resizeForUnserialization(const std::vector<int>& tinyInfoI)
6848 int nbOfTuple=tinyInfoI[0];
6849 int nbOfComp=tinyInfoI[1];
6850 if(nbOfTuple!=-1 || nbOfComp!=-1)
6852 alloc(nbOfTuple,nbOfComp);
6859 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
6860 * This method returns if a feeding is needed.
6862 void DataArrayInt::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
6864 setName(tinyInfoS[0]);
6867 int nbOfCompo=tinyInfoI[1];
6868 for(int i=0;i<nbOfCompo;i++)
6869 setInfoOnComponent(i,tinyInfoS[i+1]);
6873 DataArrayIntIterator::DataArrayIntIterator(DataArrayInt *da):DataArrayIterator<int>(da)
6877 DataArrayInt32Tuple::DataArrayInt32Tuple(int *pt, int nbOfComp):DataArrayTuple<int>(pt,nbOfComp)
6881 std::string DataArrayIntTuple::repr() const
6883 std::ostringstream oss; oss << "(";
6884 for(int i=0;i<_nb_of_compo-1;i++)
6885 oss << _pt[i] << ", ";
6886 oss << _pt[_nb_of_compo-1] << ")";
6890 int DataArrayIntTuple::intValue() const
6892 return this->zeValue();
6896 * This method returns a newly allocated instance the caller should dealed with by a MEDCoupling::DataArrayInt::decrRef.
6897 * This method performs \b no copy of data. The content is only referenced using MEDCoupling::DataArrayInt::useArray with ownership set to \b false.
6898 * 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
6899 * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
6901 DataArrayInt *DataArrayIntTuple::buildDAInt(int nbOfTuples, int nbOfCompo) const
6903 return this->buildDA(nbOfTuples,nbOfCompo);