1 // Copyright (C) 2007-2019 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::DataArrayDiscrete<Int64>;
57 template class MEDCoupling::DataArrayDiscreteSigned<Int64>;
58 template class MEDCoupling::DataArrayTuple<int>;
59 template class MEDCoupling::DataArrayTuple<double>;
60 template class MEDCoupling::DataArrayTuple<float>;
62 template<int SPACEDIM>
63 void DataArrayDouble::findCommonTuplesAlg(const double *bbox, int nbNodes, int limitNodeId, double prec, DataArrayInt *c, DataArrayInt *cI) const
65 const double *coordsPtr=getConstPointer();
66 BBTreePts<SPACEDIM,int> myTree(bbox,0,0,nbNodes,prec);
67 std::vector<bool> isDone(nbNodes);
68 for(int i=0;i<nbNodes;i++)
72 std::vector<int> intersectingElems;
73 myTree.getElementsAroundPoint(coordsPtr+i*SPACEDIM,intersectingElems);
74 if(intersectingElems.size()>1)
76 std::vector<int> commonNodes;
77 for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
81 commonNodes.push_back(*it);
84 if(!commonNodes.empty())
86 cI->pushBackSilent(cI->back()+(int)commonNodes.size()+1);
88 c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
95 template<int SPACEDIM>
96 void DataArrayDouble::FindTupleIdsNearTuplesAlg(const BBTreePts<SPACEDIM,int>& myTree, const double *pos, int nbOfTuples, double eps,
97 DataArrayInt *c, DataArrayInt *cI)
99 for(int i=0;i<nbOfTuples;i++)
101 std::vector<int> intersectingElems;
102 myTree.getElementsAroundPoint(pos+i*SPACEDIM,intersectingElems);
103 std::vector<int> commonNodes;
104 for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
105 commonNodes.push_back(*it);
106 cI->pushBackSilent(cI->back()+(int)commonNodes.size());
107 c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
111 template<int SPACEDIM>
112 void DataArrayDouble::FindClosestTupleIdAlg(const BBTreePts<SPACEDIM,int>& myTree, double dist, const double *pos, int nbOfTuples, const double *thisPt, int thisNbOfTuples, int *res)
114 double distOpt(dist);
115 const double *p(pos);
117 for(int i=0;i<nbOfTuples;i++,p+=SPACEDIM,r++)
122 double ret=myTree.getElementsAroundPoint2(p,distOpt,elem);
123 if(ret!=std::numeric_limits<double>::max())
125 distOpt=std::max(ret,1e-4);
130 { distOpt=2*distOpt; continue; }
135 int DataArray::EffectiveCircPerm(int nbOfShift, int nbOfTuples)
138 throw INTERP_KERNEL::Exception("DataArray::EffectiveCircPerm : number of tuples is expected to be > 0 !");
141 return nbOfShift%nbOfTuples;
147 return nbOfTuples-tmp;
151 std::size_t DataArray::getHeapMemorySizeWithoutChildren() const
153 std::size_t sz1=_name.capacity();
154 std::size_t sz2=_info_on_compo.capacity();
156 for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
157 sz3+=(*it).capacity();
161 std::vector<const BigMemoryObject *> DataArray::getDirectChildrenWithNull() const
163 return std::vector<const BigMemoryObject *>();
167 * Sets the attribute \a _name of \a this array.
168 * See \ref MEDCouplingArrayBasicsName "DataArrays infos" for more information.
169 * \param [in] name - new array name
171 void DataArray::setName(const std::string& name)
177 * Copies textual data from an \a other DataArray. The copied data are
178 * - the name attribute,
179 * - the information of components.
181 * For more information on these data see \ref MEDCouplingArrayBasicsName "DataArrays infos".
183 * \param [in] other - another instance of DataArray to copy the textual data from.
184 * \throw If number of components of \a this array differs from that of the \a other.
186 void DataArray::copyStringInfoFrom(const DataArray& other)
188 if(_info_on_compo.size()!=other._info_on_compo.size())
189 throw INTERP_KERNEL::Exception("Size of arrays mismatches on copyStringInfoFrom !");
191 _info_on_compo=other._info_on_compo;
194 void DataArray::copyPartOfStringInfoFrom(const DataArray& other, const std::vector<int>& compoIds)
196 int nbOfCompoOth=other.getNumberOfComponents();
197 std::size_t newNbOfCompo=compoIds.size();
198 for(std::size_t i=0;i<newNbOfCompo;i++)
199 if(compoIds[i]>=nbOfCompoOth || compoIds[i]<0)
201 std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompoOth << ")";
202 throw INTERP_KERNEL::Exception(oss.str().c_str());
204 for(std::size_t i=0;i<newNbOfCompo;i++)
205 setInfoOnComponent((int)i,other.getInfoOnComponent(compoIds[i]));
208 void DataArray::copyPartOfStringInfoFrom2(const std::vector<int>& compoIds, const DataArray& other)
210 std::size_t nbOfCompo(getNumberOfComponents());
211 std::size_t partOfCompoToSet=compoIds.size();
212 if(partOfCompoToSet!=other.getNumberOfComponents())
213 throw INTERP_KERNEL::Exception("Given compoIds has not the same size as number of components of given array !");
214 for(std::size_t i=0;i<partOfCompoToSet;i++)
215 if(compoIds[i]>=(int)nbOfCompo || compoIds[i]<0)
217 std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompo << ")";
218 throw INTERP_KERNEL::Exception(oss.str().c_str());
220 for(std::size_t i=0;i<partOfCompoToSet;i++)
221 setInfoOnComponent(compoIds[i],other.getInfoOnComponent((int)i));
224 bool DataArray::areInfoEqualsIfNotWhy(const DataArray& other, std::string& reason) const
226 std::ostringstream oss;
227 if(_name!=other._name)
229 oss << "Names DataArray mismatch : this name=\"" << _name << " other name=\"" << other._name << "\" !";
233 if(_info_on_compo!=other._info_on_compo)
235 oss << "Components DataArray mismatch : \nThis components=";
236 for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
237 oss << "\"" << *it << "\",";
238 oss << "\nOther components=";
239 for(std::vector<std::string>::const_iterator it=other._info_on_compo.begin();it!=other._info_on_compo.end();it++)
240 oss << "\"" << *it << "\",";
248 * Compares textual information of \a this DataArray with that of an \a other one.
249 * The compared data are
250 * - the name attribute,
251 * - the information of components.
253 * For more information on these data see \ref MEDCouplingArrayBasicsName "DataArrays infos".
254 * \param [in] other - another instance of DataArray to compare the textual data of.
255 * \return bool - \a true if the textual information is same, \a false else.
257 bool DataArray::areInfoEquals(const DataArray& other) const
260 return areInfoEqualsIfNotWhy(other,tmp);
263 void DataArray::reprWithoutNameStream(std::ostream& stream) const
265 stream << "Number of components : "<< getNumberOfComponents() << "\n";
266 stream << "Info of these components : ";
267 for(std::vector<std::string>::const_iterator iter=_info_on_compo.begin();iter!=_info_on_compo.end();iter++)
268 stream << "\"" << *iter << "\" ";
272 std::string DataArray::cppRepr(const std::string& varName) const
274 std::ostringstream ret;
275 reprCppStream(varName,ret);
280 * Sets information on all components. To know more on format of this information
281 * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
282 * \param [in] info - a vector of strings.
283 * \throw If size of \a info differs from the number of components of \a this.
285 void DataArray::setInfoOnComponents(const std::vector<std::string>& info)
287 if(getNumberOfComponents()!=info.size())
289 std::ostringstream oss; oss << "DataArray::setInfoOnComponents : input is of size " << info.size() << " whereas number of components is equal to " << getNumberOfComponents() << " !";
290 throw INTERP_KERNEL::Exception(oss.str().c_str());
296 * This method is only a dispatcher towards DataArrayDouble::setPartOfValues3, DataArrayInt::setPartOfValues3, DataArrayChar::setPartOfValues3 depending on the true
297 * type of \a this and \a aBase.
299 * \throw If \a aBase and \a this do not have the same type.
301 * \sa DataArrayDouble::setPartOfValues3, DataArrayInt::setPartOfValues3, DataArrayChar::setPartOfValues3.
303 void DataArray::setPartOfValuesBase3(const DataArray *aBase, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
306 throw INTERP_KERNEL::Exception("DataArray::setPartOfValuesBase3 : input aBase object is NULL !");
307 DataArrayDouble *this1(dynamic_cast<DataArrayDouble *>(this));
308 DataArrayInt *this2(dynamic_cast<DataArrayInt *>(this));
309 DataArrayChar *this3(dynamic_cast<DataArrayChar *>(this));
310 const DataArrayDouble *a1(dynamic_cast<const DataArrayDouble *>(aBase));
311 const DataArrayInt *a2(dynamic_cast<const DataArrayInt *>(aBase));
312 const DataArrayChar *a3(dynamic_cast<const DataArrayChar *>(aBase));
315 this1->setPartOfValues3(a1,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
320 this2->setPartOfValues3(a2,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
325 this3->setPartOfValues3(a3,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
328 throw INTERP_KERNEL::Exception("DataArray::setPartOfValuesBase3 : input aBase object and this do not have the same type !");
331 std::vector<std::string> DataArray::getVarsOnComponent() const
333 int nbOfCompo=(int)_info_on_compo.size();
334 std::vector<std::string> ret(nbOfCompo);
335 for(int i=0;i<nbOfCompo;i++)
336 ret[i]=getVarOnComponent(i);
340 std::vector<std::string> DataArray::getUnitsOnComponent() const
342 int nbOfCompo=(int)_info_on_compo.size();
343 std::vector<std::string> ret(nbOfCompo);
344 for(int i=0;i<nbOfCompo;i++)
345 ret[i]=getUnitOnComponent(i);
350 * Returns information on a component specified by an index.
351 * To know more on format of this information
352 * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
353 * \param [in] i - the index (zero based) of the component of interest.
354 * \return std::string - a string containing the information on \a i-th component.
355 * \throw If \a i is not a valid component index.
357 std::string DataArray::getInfoOnComponent(int i) const
359 if(i<(int)_info_on_compo.size() && i>=0)
360 return _info_on_compo[i];
363 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();
364 throw INTERP_KERNEL::Exception(oss.str().c_str());
369 * Returns the var part of the full information of the \a i-th component.
370 * For example, if \c getInfoOnComponent(0) returns "SIGXY [N/m^2]", then
371 * \c getVarOnComponent(0) returns "SIGXY".
372 * If a unit part of information is not detected by presence of
373 * two square brackets, then the full information is returned.
374 * To read more about the component information format, see
375 * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
376 * \param [in] i - the index (zero based) of the component of interest.
377 * \return std::string - a string containing the var information, or the full info.
378 * \throw If \a i is not a valid component index.
380 std::string DataArray::getVarOnComponent(int i) const
382 if(i<(int)_info_on_compo.size() && i>=0)
384 return GetVarNameFromInfo(_info_on_compo[i]);
388 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();
389 throw INTERP_KERNEL::Exception(oss.str().c_str());
394 * Returns the unit part of the full information of the \a i-th component.
395 * For example, if \c getInfoOnComponent(0) returns "SIGXY [ N/m^2]", then
396 * \c getUnitOnComponent(0) returns " N/m^2".
397 * If a unit part of information is not detected by presence of
398 * two square brackets, then an empty string is returned.
399 * To read more about the component information format, see
400 * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
401 * \param [in] i - the index (zero based) of the component of interest.
402 * \return std::string - a string containing the unit information, if any, or "".
403 * \throw If \a i is not a valid component index.
405 std::string DataArray::getUnitOnComponent(int i) const
407 if(i<(int)_info_on_compo.size() && i>=0)
409 return GetUnitFromInfo(_info_on_compo[i]);
413 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();
414 throw INTERP_KERNEL::Exception(oss.str().c_str());
419 * Returns the var part of the full component information.
420 * For example, if \a info == "SIGXY [N/m^2]", then this method returns "SIGXY".
421 * If a unit part of information is not detected by presence of
422 * two square brackets, then the whole \a info is returned.
423 * To read more about the component information format, see
424 * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
425 * \param [in] info - the full component information.
426 * \return std::string - a string containing only var information, or the \a info.
428 std::string DataArray::GetVarNameFromInfo(const std::string& info)
430 std::size_t p1=info.find_last_of('[');
431 std::size_t p2=info.find_last_of(']');
432 if(p1==std::string::npos || p2==std::string::npos)
437 return std::string();
438 std::size_t p3=info.find_last_not_of(' ',p1-1);
439 return info.substr(0,p3+1);
443 * Returns the unit part of the full component information.
444 * For example, if \a info == "SIGXY [ N/m^2]", then this method returns " N/m^2".
445 * If a unit part of information is not detected by presence of
446 * two square brackets, then an empty string is returned.
447 * To read more about the component information format, see
448 * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
449 * \param [in] info - the full component information.
450 * \return std::string - a string containing only unit information, if any, or "".
452 std::string DataArray::GetUnitFromInfo(const std::string& info)
454 std::size_t p1=info.find_last_of('[');
455 std::size_t p2=info.find_last_of(']');
456 if(p1==std::string::npos || p2==std::string::npos)
457 return std::string();
459 return std::string();
460 return info.substr(p1+1,p2-p1-1);
464 * This method put in info format the result of the merge of \a var and \a unit.
465 * The standard format for that is "var [unit]".
466 * Inversely you can retrieve the var part or the unit part of info string using resp. GetVarNameFromInfo and GetUnitFromInfo.
468 std::string DataArray::BuildInfoFromVarAndUnit(const std::string& var, const std::string& unit)
470 std::ostringstream oss;
471 oss << var << " [" << unit << "]";
475 std::string DataArray::GetAxisTypeRepr(MEDCouplingAxisType at)
480 return std::string("AX_CART");
482 return std::string("AX_CYL");
484 return std::string("AX_SPHER");
486 throw INTERP_KERNEL::Exception("DataArray::GetAxisTypeRepr : unrecognized axis type enum !");
491 * Returns a new DataArray by concatenating all given arrays, so that (1) the number
492 * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
493 * the number of component in the result array is same as that of each of given arrays.
494 * Info on components is copied from the first of the given arrays. Number of components
495 * in the given arrays must be the same.
496 * \param [in] arrs - a sequence of arrays to include in the result array. All arrays must have the same type.
497 * \return DataArray * - the new instance of DataArray (that can be either DataArrayInt, DataArrayDouble, DataArrayChar).
498 * The caller is to delete this result array using decrRef() as it is no more
500 * \throw If all arrays within \a arrs are NULL.
501 * \throw If all not null arrays in \a arrs have not the same type.
502 * \throw If getNumberOfComponents() of arrays within \a arrs.
504 DataArray *DataArray::Aggregate(const std::vector<const DataArray *>& arrs)
506 std::vector<const DataArray *> arr2;
507 for(std::vector<const DataArray *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
511 throw INTERP_KERNEL::Exception("DataArray::Aggregate : only null instance in input vector !");
512 std::vector<const DataArrayDouble *> arrd;
513 std::vector<const DataArrayInt *> arri;
514 std::vector<const DataArrayChar *> arrc;
515 for(std::vector<const DataArray *>::const_iterator it=arr2.begin();it!=arr2.end();it++)
517 const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(*it);
519 { arrd.push_back(a); continue; }
520 const DataArrayInt *b=dynamic_cast<const DataArrayInt *>(*it);
522 { arri.push_back(b); continue; }
523 const DataArrayChar *c=dynamic_cast<const DataArrayChar *>(*it);
525 { arrc.push_back(c); continue; }
526 throw INTERP_KERNEL::Exception("DataArray::Aggregate : presence of not null instance in inuput that is not in [DataArrayDouble, DataArrayInt, DataArrayChar] !");
528 if(arr2.size()==arrd.size())
529 return DataArrayDouble::Aggregate(arrd);
530 if(arr2.size()==arri.size())
531 return DataArrayInt::Aggregate(arri);
532 if(arr2.size()==arrc.size())
533 return DataArrayChar::Aggregate(arrc);
534 throw INTERP_KERNEL::Exception("DataArray::Aggregate : all input arrays must have the same type !");
538 * Sets information on a component specified by an index.
539 * To know more on format of this information
540 * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
541 * \warning Don't pass NULL as \a info!
542 * \param [in] i - the index (zero based) of the component of interest.
543 * \param [in] info - the string containing the information.
544 * \throw If \a i is not a valid component index.
546 void DataArray::setInfoOnComponent(int i, const std::string& info)
548 if(i<(int)_info_on_compo.size() && i>=0)
549 _info_on_compo[i]=info;
552 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();
553 throw INTERP_KERNEL::Exception(oss.str().c_str());
558 * Sets information on all components. This method can change number of components
559 * at certain conditions; if the conditions are not respected, an exception is thrown.
560 * The number of components can be changed in \a this only if \a this is not allocated.
561 * The condition of number of components must not be changed.
563 * To know more on format of the component information see
564 * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
565 * \param [in] info - a vector of component infos.
566 * \throw If \a this->getNumberOfComponents() != \a info.size() && \a this->isAllocated()
568 void DataArray::setInfoAndChangeNbOfCompo(const std::vector<std::string>& info)
570 if(getNumberOfComponents()!=info.size())
576 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 !";
577 throw INTERP_KERNEL::Exception(oss.str().c_str());
584 void DataArray::checkNbOfTuples(int nbOfTuples, const std::string& msg) const
586 if((int)getNumberOfTuples()!=nbOfTuples)
588 std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " << nbOfTuples << " having " << getNumberOfTuples() << " !";
589 throw INTERP_KERNEL::Exception(oss.str().c_str());
593 void DataArray::checkNbOfComps(int nbOfCompo, const std::string& msg) const
595 if((int)getNumberOfComponents()!=nbOfCompo)
597 std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << nbOfCompo << " having " << getNumberOfComponents() << " !";
598 throw INTERP_KERNEL::Exception(oss.str().c_str());
602 void DataArray::checkNbOfElems(std::size_t nbOfElems, const std::string& msg) const
604 if(getNbOfElems()!=nbOfElems)
606 std::ostringstream oss; oss << msg << " : mismatch number of elems : Expected " << nbOfElems << " having " << getNbOfElems() << " !";
607 throw INTERP_KERNEL::Exception(oss.str().c_str());
611 void DataArray::checkNbOfTuplesAndComp(const DataArray& other, const std::string& msg) const
613 if(getNumberOfTuples()!=other.getNumberOfTuples())
615 std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " << other.getNumberOfTuples() << " having " << getNumberOfTuples() << " !";
616 throw INTERP_KERNEL::Exception(oss.str().c_str());
618 if(getNumberOfComponents()!=other.getNumberOfComponents())
620 std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << other.getNumberOfComponents() << " having " << getNumberOfComponents() << " !";
621 throw INTERP_KERNEL::Exception(oss.str().c_str());
625 void DataArray::checkNbOfTuplesAndComp(int nbOfTuples, int nbOfCompo, const std::string& msg) const
627 checkNbOfTuples(nbOfTuples,msg);
628 checkNbOfComps(nbOfCompo,msg);
632 * Simply this method checks that \b value is in [0,\b ref).
634 void DataArray::CheckValueInRange(int ref, int value, const std::string& msg)
636 if(value<0 || value>=ref)
638 std::ostringstream oss; oss << "DataArray::CheckValueInRange : " << msg << " ! Expected in range [0," << ref << "[ having " << value << " !";
639 throw INTERP_KERNEL::Exception(oss.str().c_str());
644 * This method checks that [\b start, \b end) is compliant with ref length \b value.
645 * typically start in [0,\b value) and end in [0,\b value). If value==start and start==end, it is supported.
647 void DataArray::CheckValueInRangeEx(int value, int start, int end, const std::string& msg)
649 if(start<0 || start>=value)
651 if(value!=start || end!=start)
653 std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg << " ! Expected start " << start << " of input range, in [0," << value << "[ !";
654 throw INTERP_KERNEL::Exception(oss.str().c_str());
657 if(end<0 || end>value)
659 std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg << " ! Expected end " << end << " of input range, in [0," << value << "] !";
660 throw INTERP_KERNEL::Exception(oss.str().c_str());
664 void DataArray::CheckClosingParInRange(int ref, int value, const std::string& msg)
666 if(value<0 || value>ref)
668 std::ostringstream oss; oss << "DataArray::CheckClosingParInRange : " << msg << " ! Expected input range in [0," << ref << "] having closing open parenthesis " << value << " !";
669 throw INTERP_KERNEL::Exception(oss.str().c_str());
674 * 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,
675 * typically it is a whole slice of tuples of DataArray or cells, nodes of a mesh...
677 * The input \a sliceId should be an id in [0, \a nbOfSlices) that specifies the slice of work.
679 * \param [in] start - the start of the input slice of the whole work to perform split into slices.
680 * \param [in] stop - the stop of the input slice of the whole work to perform split into slices.
681 * \param [in] step - the step (that can be <0) of the input slice of the whole work to perform split into slices.
682 * \param [in] sliceId - the slice id considered
683 * \param [in] nbOfSlices - the number of slices (typically the number of cores on which the work is expected to be sliced)
684 * \param [out] startSlice - the start of the slice considered
685 * \param [out] stopSlice - the stop of the slice consided
687 * \throw If \a step == 0
688 * \throw If \a nbOfSlices not > 0
689 * \throw If \a sliceId not in [0,nbOfSlices)
691 void DataArray::GetSlice(int start, int stop, int step, int sliceId, int nbOfSlices, int& startSlice, int& stopSlice)
695 std::ostringstream oss; oss << "DataArray::GetSlice : nbOfSlices (" << nbOfSlices << ") must be > 0 !";
696 throw INTERP_KERNEL::Exception(oss.str().c_str());
698 if(sliceId<0 || sliceId>=nbOfSlices)
700 std::ostringstream oss; oss << "DataArray::GetSlice : sliceId (" << nbOfSlices << ") must be in [0 , nbOfSlices (" << nbOfSlices << ") ) !";
701 throw INTERP_KERNEL::Exception(oss.str().c_str());
703 int nbElems=GetNumberOfItemGivenBESRelative(start,stop,step,"DataArray::GetSlice");
704 int minNbOfElemsPerSlice=nbElems/nbOfSlices;
705 startSlice=start+minNbOfElemsPerSlice*step*sliceId;
706 if(sliceId<nbOfSlices-1)
707 stopSlice=start+minNbOfElemsPerSlice*step*(sliceId+1);
712 int DataArray::GetNumberOfItemGivenBES(int begin, int end, int step, const std::string& msg)
716 std::ostringstream oss; oss << msg << " : end before begin !";
717 throw INTERP_KERNEL::Exception(oss.str().c_str());
723 std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
724 throw INTERP_KERNEL::Exception(oss.str().c_str());
726 return (end-1-begin)/step+1;
729 int DataArray::GetNumberOfItemGivenBESRelative(int begin, int end, int step, const std::string& msg)
732 throw INTERP_KERNEL::Exception("DataArray::GetNumberOfItemGivenBES : step=0 is not allowed !");
733 if(end<begin && step>0)
735 std::ostringstream oss; oss << msg << " : end before begin whereas step is positive !";
736 throw INTERP_KERNEL::Exception(oss.str().c_str());
738 if(begin<end && step<0)
740 std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
741 throw INTERP_KERNEL::Exception(oss.str().c_str());
744 return (std::max(begin,end)-1-std::min(begin,end))/std::abs(step)+1;
749 int DataArray::GetPosOfItemGivenBESRelativeNoThrow(int value, int begin, int end, int step)
755 if(begin<=value && value<end)
757 if((value-begin)%step==0)
758 return (value-begin)/step;
767 if(begin>=value && value>end)
769 if((begin-value)%(-step)==0)
770 return (begin-value)/(-step);
783 * Returns a new instance of DataArrayDouble. The caller is to delete this array
784 * using decrRef() as it is no more needed.
786 DataArrayDouble *DataArrayDouble::New()
788 return new DataArrayDouble;
792 * Returns the only one value in \a this, if and only if number of elements
793 * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
794 * \return double - the sole value stored in \a this array.
795 * \throw If at least one of conditions stated above is not fulfilled.
797 double DataArrayDouble::doubleValue() const
801 if(getNbOfElems()==1)
803 return *getConstPointer();
806 throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is allocated but number of elements is not equal to 1 !");
809 throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is not allocated !");
813 * Returns a full copy of \a this. For more info on copying data arrays see
814 * \ref MEDCouplingArrayBasicsCopyDeep.
815 * \return DataArrayDouble * - a new instance of DataArrayDouble. The caller is to
816 * delete this array using decrRef() as it is no more needed.
818 DataArrayDouble *DataArrayDouble::deepCopy() const
820 return new DataArrayDouble(*this);
824 * Checks that \a this array is consistently **increasing** or **decreasing** in value,
825 * with at least absolute difference value of |\a eps| at each step.
826 * If not an exception is thrown.
827 * \param [in] increasing - if \a true, the array values should be increasing.
828 * \param [in] eps - minimal absolute difference between the neighbor values at which
829 * the values are considered different.
830 * \throw If sequence of values is not strictly monotonic in agreement with \a
832 * \throw If \a this->getNumberOfComponents() != 1.
833 * \throw If \a this is not allocated.
835 void DataArrayDouble::checkMonotonic(bool increasing, double eps) const
837 if(!isMonotonic(increasing,eps))
840 throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not INCREASING monotonic !");
842 throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not DECREASING monotonic !");
847 * Checks that \a this array is consistently **increasing** or **decreasing** in value,
848 * with at least absolute difference value of |\a eps| at each step.
849 * \param [in] increasing - if \a true, array values should be increasing.
850 * \param [in] eps - minimal absolute difference between the neighbor values at which
851 * the values are considered different.
852 * \return bool - \a true if values change in accordance with \a increasing arg.
853 * \throw If \a this->getNumberOfComponents() != 1.
854 * \throw If \a this is not allocated.
856 bool DataArrayDouble::isMonotonic(bool increasing, double eps) const
859 if(getNumberOfComponents()!=1)
860 throw INTERP_KERNEL::Exception("DataArrayDouble::isMonotonic : only supported with 'this' array with ONE component !");
861 int nbOfElements=getNumberOfTuples();
862 const double *ptr=getConstPointer();
866 double absEps=fabs(eps);
869 for(int i=1;i<nbOfElements;i++)
871 if(ptr[i]<(ref+absEps))
879 for(int i=1;i<nbOfElements;i++)
881 if(ptr[i]>(ref-absEps))
889 void DataArrayDouble::writeVTK(std::ostream& ofs, int indent, const std::string& nameInFile, DataArrayByte *byteArr) const
891 static const char SPACE[4]={' ',' ',' ',' '};
893 std::string idt(indent,' ');
895 ofs << idt << "<DataArray type=\"Float32\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
897 bool areAllEmpty(true);
898 for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
902 for(std::size_t i=0;i<_info_on_compo.size();i++)
903 ofs << " ComponentName" << i << "=\"" << _info_on_compo[i] << "\"";
907 ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
908 INTERP_KERNEL::AutoPtr<float> tmp(new float[getNbOfElems()]);
910 // to make Visual C++ happy : instead of std::copy(begin(),end(),(float *)tmp);
911 for(const double *src=begin();src!=end();src++,pt++)
913 const char *data(reinterpret_cast<const char *>((float *)tmp));
914 std::size_t sz(getNbOfElems()*sizeof(float));
915 byteArr->insertAtTheEnd(data,data+sz);
916 byteArr->insertAtTheEnd(SPACE,SPACE+4);
920 ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
921 std::copy(begin(),end(),std::ostream_iterator<double>(ofs," "));
923 ofs << std::endl << idt << "</DataArray>\n";
926 void DataArrayDouble::reprCppStream(const std::string& varName, std::ostream& stream) const
928 int nbTuples(getNumberOfTuples()),nbComp(getNumberOfComponents());
929 const double *data(getConstPointer());
930 stream.precision(17);
931 stream << "DataArrayDouble *" << varName << "=DataArrayDouble::New();" << std::endl;
932 if(nbTuples*nbComp>=1)
934 stream << "const double " << varName << "Data[" << nbTuples*nbComp << "]={";
935 std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<double>(stream,","));
936 stream << data[nbTuples*nbComp-1] << "};" << std::endl;
937 stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
940 stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
941 stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
945 * Method that gives a quick overvien of \a this for python.
947 void DataArrayDouble::reprQuickOverview(std::ostream& stream) const
949 static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
950 stream << "DataArrayDouble C++ instance at " << this << ". ";
953 std::size_t nbOfCompo(_info_on_compo.size());
956 std::size_t nbOfTuples(getNumberOfTuples());
957 stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
958 reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
961 stream << "Number of components : 0.";
964 stream << "*** No data allocated ****";
967 void DataArrayDouble::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
969 const double *data=begin();
970 int nbOfTuples=getNumberOfTuples();
971 int nbOfCompo=(int)_info_on_compo.size();
972 std::ostringstream oss2; oss2 << "[";
974 std::string oss2Str(oss2.str());
975 bool isFinished=true;
976 for(int i=0;i<nbOfTuples && isFinished;i++)
981 for(int j=0;j<nbOfCompo;j++,data++)
984 if(j!=nbOfCompo-1) oss2 << ", ";
990 if(i!=nbOfTuples-1) oss2 << ", ";
991 std::string oss3Str(oss2.str());
992 if(oss3Str.length()<maxNbOfByteInRepr)
1004 * Equivalent to DataArrayDouble::isEqual except that if false the reason of
1005 * mismatch is given.
1007 * \param [in] other the instance to be compared with \a this
1008 * \param [in] prec the precision to compare numeric data of the arrays.
1009 * \param [out] reason In case of inequality returns the reason.
1010 * \sa DataArrayDouble::isEqual
1012 bool DataArrayDouble::isEqualIfNotWhy(const DataArrayDouble& other, double prec, std::string& reason) const
1014 if(!areInfoEqualsIfNotWhy(other,reason))
1016 return _mem.isEqual(other._mem,prec,reason);
1020 * Checks if \a this and another DataArrayDouble are fully equal. For more info see
1021 * \ref MEDCouplingArrayBasicsCompare.
1022 * \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1023 * \param [in] prec - precision value to compare numeric data of the arrays.
1024 * \return bool - \a true if the two arrays are equal, \a false else.
1026 bool DataArrayDouble::isEqual(const DataArrayDouble& other, double prec) const
1029 return isEqualIfNotWhy(other,prec,tmp);
1033 * Checks if values of \a this and another DataArrayDouble are equal. For more info see
1034 * \ref MEDCouplingArrayBasicsCompare.
1035 * \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1036 * \param [in] prec - precision value to compare numeric data of the arrays.
1037 * \return bool - \a true if the values of two arrays are equal, \a false else.
1039 bool DataArrayDouble::isEqualWithoutConsideringStr(const DataArrayDouble& other, double prec) const
1042 return _mem.isEqual(other._mem,prec,tmp);
1046 * This method checks that all tuples in \a other are in \a this.
1047 * If true, the output param \a tupleIds contains the tuples ids of \a this that correspond to tupes in \a this.
1048 * 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.
1050 * \param [in] other - the array having the same number of components than \a this.
1051 * \param [out] tupleIds - the tuple ids containing the same number of tuples than \a other has.
1052 * \sa DataArrayDouble::findCommonTuples
1054 bool DataArrayDouble::areIncludedInMe(const DataArrayDouble *other, double prec, DataArrayInt *&tupleIds) const
1057 throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : input array is NULL !");
1058 checkAllocated(); other->checkAllocated();
1059 if(getNumberOfComponents()!=other->getNumberOfComponents())
1060 throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : the number of components does not match !");
1061 MCAuto<DataArrayDouble> a=DataArrayDouble::Aggregate(this,other);
1062 DataArrayInt *c=0,*ci=0;
1063 a->findCommonTuples(prec,getNumberOfTuples(),c,ci);
1064 MCAuto<DataArrayInt> cSafe(c),ciSafe(ci);
1065 int newNbOfTuples=-1;
1066 MCAuto<DataArrayInt> ids=DataArrayInt::ConvertIndexArrayToO2N(a->getNumberOfTuples(),c->begin(),ci->begin(),ci->end(),newNbOfTuples);
1067 MCAuto<DataArrayInt> ret1=ids->selectByTupleIdSafeSlice(getNumberOfTuples(),a->getNumberOfTuples(),1);
1068 tupleIds=ret1.retn();
1069 return newNbOfTuples==getNumberOfTuples();
1073 * Searches for tuples coincident within \a prec tolerance. Each tuple is considered
1074 * as coordinates of a point in getNumberOfComponents()-dimensional space. The
1075 * distance separating two points is computed with the infinite norm.
1077 * Indices of coincident tuples are stored in output arrays.
1078 * A pair of arrays (\a comm, \a commIndex) is called "Surjective Format 2".
1080 * This method is typically used by MEDCouplingPointSet::findCommonNodes() and
1081 * MEDCouplingUMesh::mergeNodes().
1082 * \param [in] prec - minimal absolute distance between two tuples (infinite norm) at which they are
1083 * considered not coincident.
1084 * \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
1085 * tuples have id strictly lower than \a limitTupleId then they are not returned.
1086 * \param [out] comm - the array holding ids (== indices) of coincident tuples.
1087 * \a comm->getNumberOfComponents() == 1.
1088 * \a comm->getNumberOfTuples() == \a commIndex->back().
1089 * \param [out] commIndex - the array dividing all indices stored in \a comm into
1090 * groups of (indices of) coincident tuples. Its every value is a tuple
1091 * index where a next group of tuples begins. For example the second
1092 * group of tuples in \a comm is described by following range of indices:
1093 * [ \a commIndex[1], \a commIndex[2] ). \a commIndex->getNumberOfTuples()-1
1094 * gives the number of groups of coincident tuples.
1095 * \throw If \a this is not allocated.
1096 * \throw If the number of components is not in [1,2,3,4].
1098 * \if ENABLE_EXAMPLES
1099 * \ref cpp_mcdataarraydouble_findcommontuples "Here is a C++ example".
1101 * \ref py_mcdataarraydouble_findcommontuples "Here is a Python example".
1103 * \sa DataArrayInt::ConvertIndexArrayToO2N(), DataArrayDouble::areIncludedInMe
1105 void DataArrayDouble::findCommonTuples(double prec, int limitTupleId, DataArrayInt *&comm, DataArrayInt *&commIndex) const
1108 int nbOfCompo=getNumberOfComponents();
1109 if ((nbOfCompo<1) || (nbOfCompo>4)) //test before work
1110 throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : Unexpected spacedim of coords. Must be 1, 2, 3 or 4.");
1112 int nbOfTuples=getNumberOfTuples();
1114 MCAuto<DataArrayInt> c(DataArrayInt::New()),cI(DataArrayInt::New()); c->alloc(0,1); cI->pushBackSilent(0);
1118 findCommonTuplesAlg<4>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1121 findCommonTuplesAlg<3>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1124 findCommonTuplesAlg<2>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1127 findCommonTuplesAlg<1>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1130 throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : nb of components managed are 1,2,3 and 4 ! not implemented for other number of components !");
1133 commIndex=cI.retn();
1137 * This methods returns the minimal distance between the two set of points \a this and \a other.
1138 * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
1139 * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
1141 * \param [out] thisTupleId the tuple id in \a this corresponding to the returned minimal distance
1142 * \param [out] otherTupleId the tuple id in \a other corresponding to the returned minimal distance
1143 * \return the minimal distance between the two set of points \a this and \a other.
1144 * \sa DataArrayDouble::findClosestTupleId
1146 double DataArrayDouble::minimalDistanceTo(const DataArrayDouble *other, int& thisTupleId, int& otherTupleId) const
1148 MCAuto<DataArrayInt> part1=findClosestTupleId(other);
1149 int nbOfCompo(getNumberOfComponents());
1150 int otherNbTuples(other->getNumberOfTuples());
1151 const double *thisPt(begin()),*otherPt(other->begin());
1152 const int *part1Pt(part1->begin());
1153 double ret=std::numeric_limits<double>::max();
1154 for(int i=0;i<otherNbTuples;i++,part1Pt++,otherPt+=nbOfCompo)
1157 for(int j=0;j<nbOfCompo;j++)
1158 tmp+=(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j])*(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j]);
1160 { ret=tmp; thisTupleId=*part1Pt; otherTupleId=i; }
1166 * This methods returns for each tuple in \a other which tuple in \a this is the closest.
1167 * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
1168 * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
1170 * \return a newly allocated (new object to be dealt by the caller) DataArrayInt having \c other->getNumberOfTuples() tuples and one components.
1171 * \sa DataArrayDouble::minimalDistanceTo
1173 DataArrayInt *DataArrayDouble::findClosestTupleId(const DataArrayDouble *other) const
1176 throw INTERP_KERNEL::Exception("DataArrayDouble::findClosestTupleId : other instance is NULL !");
1177 checkAllocated(); other->checkAllocated();
1178 std::size_t nbOfCompo(getNumberOfComponents());
1179 if(nbOfCompo!=other->getNumberOfComponents())
1181 std::ostringstream oss; oss << "DataArrayDouble::findClosestTupleId : number of components in this is " << nbOfCompo;
1182 oss << ", whereas number of components in other is " << other->getNumberOfComponents() << "! Should be equal !";
1183 throw INTERP_KERNEL::Exception(oss.str().c_str());
1185 int nbOfTuples=other->getNumberOfTuples();
1186 int thisNbOfTuples=getNumberOfTuples();
1187 MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuples,1);
1189 getMinMaxPerComponent(bounds);
1194 double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2])),zDelta(fabs(bounds[5]-bounds[4]));
1195 double delta=std::max(xDelta,yDelta); delta=std::max(delta,zDelta);
1196 double characSize=pow((delta*delta*delta)/((double)thisNbOfTuples),1./3.);
1197 BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1198 FindClosestTupleIdAlg<3>(myTree,3.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1203 double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2]));
1204 double delta=std::max(xDelta,yDelta);
1205 double characSize=sqrt(delta/(double)thisNbOfTuples);
1206 BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1207 FindClosestTupleIdAlg<2>(myTree,2.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1212 double characSize=fabs(bounds[1]-bounds[0])/thisNbOfTuples;
1213 BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1214 FindClosestTupleIdAlg<1>(myTree,1.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1218 throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for findClosestTupleId. Must be 1, 2 or 3.");
1224 * This method expects that \a this and \a otherBBoxFrmt arrays are bounding box arrays ( as the output of MEDCouplingPointSet::getBoundingBoxForBBTree method ).
1225 * 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
1226 * how many bounding boxes in \a otherBBoxFrmt.
1227 * So, this method expects that \a this and \a otherBBoxFrmt have the same number of components.
1229 * \param [in] otherBBoxFrmt - It is an array .
1230 * \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.
1231 * \sa MEDCouplingPointSet::getBoundingBoxForBBTree
1232 * \throw If \a this and \a otherBBoxFrmt have not the same number of components.
1233 * \throw If \a this and \a otherBBoxFrmt number of components is not even (BBox format).
1235 DataArrayInt *DataArrayDouble::computeNbOfInteractionsWith(const DataArrayDouble *otherBBoxFrmt, double eps) const
1238 throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : input array is NULL !");
1239 if(!isAllocated() || !otherBBoxFrmt->isAllocated())
1240 throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : this and input array must be allocated !");
1241 std::size_t nbOfComp(getNumberOfComponents()),nbOfTuples(getNumberOfTuples());
1242 if(nbOfComp!=otherBBoxFrmt->getNumberOfComponents())
1244 std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : this number of components (" << nbOfComp << ") must be equal to the number of components of input array (" << otherBBoxFrmt->getNumberOfComponents() << ") !";
1245 throw INTERP_KERNEL::Exception(oss.str().c_str());
1249 std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : Number of components (" << nbOfComp << ") is not even ! It should be to be compatible with bbox format !";
1250 throw INTERP_KERNEL::Exception(oss.str().c_str());
1252 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbOfTuples,1);
1253 const double *thisBBPtr(begin());
1254 int *retPtr(ret->getPointer());
1259 BBTree<3,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
1260 for(std::size_t i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
1261 *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
1266 BBTree<2,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
1267 for(std::size_t i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
1268 *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
1273 BBTree<1,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
1274 for(std::size_t i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
1275 *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
1279 throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : space dimension supported are [1,2,3] !");
1286 * Returns a copy of \a this array by excluding coincident tuples. Each tuple is
1287 * considered as coordinates of a point in getNumberOfComponents()-dimensional
1288 * space. The distance between tuples is computed using norm2. If several tuples are
1289 * not far each from other than \a prec, only one of them remains in the result
1290 * array. The order of tuples in the result array is same as in \a this one except
1291 * that coincident tuples are excluded.
1292 * \param [in] prec - minimal absolute distance between two tuples at which they are
1293 * considered not coincident.
1294 * \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
1295 * tuples have id strictly lower than \a limitTupleId then they are not excluded.
1296 * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1297 * is to delete using decrRef() as it is no more needed.
1298 * \throw If \a this is not allocated.
1299 * \throw If the number of components is not in [1,2,3,4].
1301 * \if ENABLE_EXAMPLES
1302 * \ref py_mcdataarraydouble_getdifferentvalues "Here is a Python example".
1305 DataArrayDouble *DataArrayDouble::getDifferentValues(double prec, int limitTupleId) const
1308 DataArrayInt *c0=0,*cI0=0;
1309 findCommonTuples(prec,limitTupleId,c0,cI0);
1310 MCAuto<DataArrayInt> c(c0),cI(cI0);
1311 int newNbOfTuples=-1;
1312 MCAuto<DataArrayInt> o2n=DataArrayInt::ConvertIndexArrayToO2N(getNumberOfTuples(),c0->begin(),cI0->begin(),cI0->end(),newNbOfTuples);
1313 return renumberAndReduce(o2n->getConstPointer(),newNbOfTuples);
1317 * Copy all components in a specified order from another DataArrayDouble.
1318 * Both numerical and textual data is copied. The number of tuples in \a this and
1319 * the other array can be different.
1320 * \param [in] a - the array to copy data from.
1321 * \param [in] compoIds - sequence of zero based indices of components, data of which is
1323 * \throw If \a a is NULL.
1324 * \throw If \a compoIds.size() != \a a->getNumberOfComponents().
1325 * \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
1327 * \if ENABLE_EXAMPLES
1328 * \ref py_mcdataarraydouble_setselectedcomponents "Here is a Python example".
1331 void DataArrayDouble::setSelectedComponents(const DataArrayDouble *a, const std::vector<int>& compoIds)
1334 throw INTERP_KERNEL::Exception("DataArrayDouble::setSelectedComponents : input DataArrayDouble is NULL !");
1336 copyPartOfStringInfoFrom2(compoIds,*a);
1337 std::size_t partOfCompoSz=compoIds.size();
1338 int nbOfCompo=getNumberOfComponents();
1339 int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
1340 const double *ac=a->getConstPointer();
1341 double *nc=getPointer();
1342 for(int i=0;i<nbOfTuples;i++)
1343 for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
1344 nc[nbOfCompo*i+compoIds[j]]=*ac;
1348 * Checks if 0.0 value is present in \a this array. If it is the case, an exception
1350 * \throw If zero is found in \a this array.
1352 void DataArrayDouble::checkNoNullValues() const
1354 const double *tmp=getConstPointer();
1355 std::size_t nbOfElems=getNbOfElems();
1356 const double *where=std::find(tmp,tmp+nbOfElems,0.);
1357 if(where!=tmp+nbOfElems)
1358 throw INTERP_KERNEL::Exception("A value 0.0 have been detected !");
1362 * Computes minimal and maximal value in each component. An output array is filled
1363 * with \c 2 * \a this->getNumberOfComponents() values, so the caller is to allocate
1364 * enough memory before calling this method.
1365 * \param [out] bounds - array of size at least 2 *\a this->getNumberOfComponents().
1366 * It is filled as follows:<br>
1367 * \a bounds[0] = \c min_of_component_0 <br>
1368 * \a bounds[1] = \c max_of_component_0 <br>
1369 * \a bounds[2] = \c min_of_component_1 <br>
1370 * \a bounds[3] = \c max_of_component_1 <br>
1373 void DataArrayDouble::getMinMaxPerComponent(double *bounds) const
1376 int dim=getNumberOfComponents();
1377 for (int idim=0; idim<dim; idim++)
1379 bounds[idim*2]=std::numeric_limits<double>::max();
1380 bounds[idim*2+1]=-std::numeric_limits<double>::max();
1382 const double *ptr=getConstPointer();
1383 int nbOfTuples=getNumberOfTuples();
1384 for(int i=0;i<nbOfTuples;i++)
1386 for(int idim=0;idim<dim;idim++)
1388 if(bounds[idim*2]>ptr[i*dim+idim])
1390 bounds[idim*2]=ptr[i*dim+idim];
1392 if(bounds[idim*2+1]<ptr[i*dim+idim])
1394 bounds[idim*2+1]=ptr[i*dim+idim];
1401 * This method retrieves a newly allocated DataArrayDouble instance having same number of tuples than \a this and twice number of components than \a this
1402 * to store both the min and max per component of each tuples.
1403 * \param [in] epsilon the width of the bbox (identical in each direction) - 0.0 by default
1405 * \return a newly created DataArrayDouble instance having \c this->getNumberOfTuples() tuples and 2 * \c this->getNumberOfComponent() components
1407 * \throw If \a this is not allocated yet.
1409 DataArrayDouble *DataArrayDouble::computeBBoxPerTuple(double epsilon) const
1412 const double *dataPtr=getConstPointer();
1413 int nbOfCompo=getNumberOfComponents();
1414 int nbTuples=getNumberOfTuples();
1415 MCAuto<DataArrayDouble> bbox=DataArrayDouble::New();
1416 bbox->alloc(nbTuples,2*nbOfCompo);
1417 double *bboxPtr=bbox->getPointer();
1418 for(int i=0;i<nbTuples;i++)
1420 for(int j=0;j<nbOfCompo;j++)
1422 bboxPtr[2*nbOfCompo*i+2*j]=dataPtr[nbOfCompo*i+j]-epsilon;
1423 bboxPtr[2*nbOfCompo*i+2*j+1]=dataPtr[nbOfCompo*i+j]+epsilon;
1430 * For each tuples **t** in \a other, this method retrieves tuples in \a this that are equal to **t**.
1431 * Two tuples are considered equal if the euclidian distance between the two tuples is lower than \a eps.
1433 * \param [in] other a DataArrayDouble having same number of components than \a this.
1434 * \param [in] eps absolute precision representing distance (using infinite norm) between 2 tuples behind which 2 tuples are considered equal.
1435 * \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.
1436 * \a cI allows to extract information in \a c.
1437 * \param [out] cI is an indirection array that allows to extract the data contained in \a c.
1439 * \throw In case of:
1440 * - \a this is not allocated
1441 * - \a other is not allocated or null
1442 * - \a this and \a other do not have the same number of components
1443 * - if number of components of \a this is not in [1,2,3]
1445 * \sa MEDCouplingPointSet::getNodeIdsNearPoints, DataArrayDouble::getDifferentValues
1447 void DataArrayDouble::computeTupleIdsNearTuples(const DataArrayDouble *other, double eps, DataArrayInt *& c, DataArrayInt *& cI) const
1450 throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : input pointer other is null !");
1452 other->checkAllocated();
1453 int nbOfCompo=getNumberOfComponents();
1454 int otherNbOfCompo=other->getNumberOfComponents();
1455 if(nbOfCompo!=otherNbOfCompo)
1456 throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : number of components should be equal between this and other !");
1457 int nbOfTuplesOther=other->getNumberOfTuples();
1458 MCAuto<DataArrayInt> cArr(DataArrayInt::New()),cIArr(DataArrayInt::New()); cArr->alloc(0,1); cIArr->pushBackSilent(0);
1463 BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
1464 FindTupleIdsNearTuplesAlg<3>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
1469 BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
1470 FindTupleIdsNearTuplesAlg<2>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
1475 BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
1476 FindTupleIdsNearTuplesAlg<1>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
1480 throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for computeTupleIdsNearTuples. Must be 1, 2 or 3.");
1482 c=cArr.retn(); cI=cIArr.retn();
1486 * 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
1487 * around origin of 'radius' 1.
1489 * \param [in] eps absolute epsilon. under that value of delta between max and min no scale is performed.
1491 void DataArrayDouble::recenterForMaxPrecision(double eps)
1494 int dim=getNumberOfComponents();
1495 std::vector<double> bounds(2*dim);
1496 getMinMaxPerComponent(&bounds[0]);
1497 for(int i=0;i<dim;i++)
1499 double delta=bounds[2*i+1]-bounds[2*i];
1500 double offset=(bounds[2*i]+bounds[2*i+1])/2.;
1502 applyLin(1./delta,-offset/delta,i);
1504 applyLin(1.,-offset,i);
1509 * Returns the maximal value and all its locations within \a this one-dimensional array.
1510 * \param [out] tupleIds - a new instance of DataArrayInt containing indices of
1511 * tuples holding the maximal value. The caller is to delete it using
1512 * decrRef() as it is no more needed.
1513 * \return double - the maximal value among all values of \a this array.
1514 * \throw If \a this->getNumberOfComponents() != 1
1515 * \throw If \a this->getNumberOfTuples() < 1
1517 double DataArrayDouble::getMaxValue2(DataArrayInt*& tupleIds) const
1521 double ret=getMaxValue(tmp);
1522 tupleIds=findIdsInRange(ret,ret);
1527 * Returns the minimal value and all its locations within \a this one-dimensional array.
1528 * \param [out] tupleIds - a new instance of DataArrayInt containing indices of
1529 * tuples holding the minimal value. The caller is to delete it using
1530 * decrRef() as it is no more needed.
1531 * \return double - the minimal value among all values of \a this array.
1532 * \throw If \a this->getNumberOfComponents() != 1
1533 * \throw If \a this->getNumberOfTuples() < 1
1535 double DataArrayDouble::getMinValue2(DataArrayInt*& tupleIds) const
1539 double ret=getMinValue(tmp);
1540 tupleIds=findIdsInRange(ret,ret);
1545 * 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.
1546 * This method only works for single component array.
1548 * \return a value in [ 0, \c this->getNumberOfTuples() )
1550 * \throw If \a this is not allocated
1553 int DataArrayDouble::count(double value, double eps) const
1557 if(getNumberOfComponents()!=1)
1558 throw INTERP_KERNEL::Exception("DataArrayDouble::count : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
1559 const double *vals=begin();
1560 int nbOfTuples=getNumberOfTuples();
1561 for(int i=0;i<nbOfTuples;i++,vals++)
1562 if(fabs(*vals-value)<=eps)
1568 * Returns the average value of \a this one-dimensional array.
1569 * \return double - the average value over all values of \a this array.
1570 * \throw If \a this->getNumberOfComponents() != 1
1571 * \throw If \a this->getNumberOfTuples() < 1
1573 double DataArrayDouble::getAverageValue() const
1575 if(getNumberOfComponents()!=1)
1576 throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
1577 int nbOfTuples=getNumberOfTuples();
1579 throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : array exists but number of tuples must be > 0 !");
1580 const double *vals=getConstPointer();
1581 double ret=std::accumulate(vals,vals+nbOfTuples,0.);
1582 return ret/nbOfTuples;
1586 * Returns the Euclidean norm of the vector defined by \a this array.
1587 * \return double - the value of the Euclidean norm, i.e.
1588 * the square root of the inner product of vector.
1589 * \throw If \a this is not allocated.
1591 double DataArrayDouble::norm2() const
1595 std::size_t nbOfElems=getNbOfElems();
1596 const double *pt=getConstPointer();
1597 for(std::size_t i=0;i<nbOfElems;i++,pt++)
1603 * Returns the maximum norm of the vector defined by \a this array.
1604 * This method works even if the number of components is different from one.
1605 * If the number of elements in \a this is 0, -1. is returned.
1606 * \return double - the value of the maximum norm, i.e.
1607 * the maximal absolute value among values of \a this array (whatever its number of components).
1608 * \throw If \a this is not allocated.
1610 double DataArrayDouble::normMax() const
1614 std::size_t nbOfElems(getNbOfElems());
1615 const double *pt(getConstPointer());
1616 for(std::size_t i=0;i<nbOfElems;i++,pt++)
1618 double val(std::abs(*pt));
1626 * Returns the maximum norm of for each component of \a this array.
1627 * If the number of elements in \a this is 0, -1. is returned.
1628 * \param [out] res - pointer to an array of result values, of size at least \a
1629 * this->getNumberOfComponents(), that is to be allocated by the caller.
1630 * \throw If \a this is not allocated.
1632 void DataArrayDouble::normMaxPerComponent(double * res) const
1635 std::size_t nbOfTuples(getNumberOfTuples());
1636 int nbOfCompos(getNumberOfComponents());
1637 std::fill(res, res+nbOfCompos, -1.0);
1638 const double *pt(getConstPointer());
1639 for(std::size_t i=0;i<nbOfTuples;i++)
1640 for (int j=0; j<nbOfCompos; j++, pt++)
1642 double val(std::abs(*pt));
1650 * Returns the minimum norm (absolute value) of the vector defined by \a this array.
1651 * This method works even if the number of components is different from one.
1652 * If the number of elements in \a this is 0, std::numeric_limits<double>::max() is returned.
1653 * \return double - the value of the minimum norm, i.e.
1654 * the minimal absolute value among values of \a this array (whatever its number of components).
1655 * \throw If \a this is not allocated.
1657 double DataArrayDouble::normMin() const
1660 double ret(std::numeric_limits<double>::max());
1661 std::size_t nbOfElems(getNbOfElems());
1662 const double *pt(getConstPointer());
1663 for(std::size_t i=0;i<nbOfElems;i++,pt++)
1665 double val(std::abs(*pt));
1673 * Accumulates values of each component of \a this array.
1674 * \param [out] res - an array of length \a this->getNumberOfComponents(), allocated
1675 * by the caller, that is filled by this method with sum value for each
1677 * \throw If \a this is not allocated.
1679 void DataArrayDouble::accumulate(double *res) const
1682 const double *ptr=getConstPointer();
1683 int nbTuple=getNumberOfTuples();
1684 int nbComps=getNumberOfComponents();
1685 std::fill(res,res+nbComps,0.);
1686 for(int i=0;i<nbTuple;i++)
1687 std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<double>());
1691 * This method returns the min distance from an external tuple defined by [ \a tupleBg , \a tupleEnd ) to \a this and
1692 * the first tuple in \a this that matches the returned distance. If there is no tuples in \a this an exception will be thrown.
1695 * \a this is expected to be allocated and expected to have a number of components equal to the distance from \a tupleBg to
1696 * \a tupleEnd. If not an exception will be thrown.
1698 * \param [in] tupleBg start pointer (included) of input external tuple
1699 * \param [in] tupleEnd end pointer (not included) of input external tuple
1700 * \param [out] tupleId the tuple id in \a this that matches the min of distance between \a this and input external tuple
1701 * \return the min distance.
1702 * \sa MEDCouplingUMesh::distanceToPoint
1704 double DataArrayDouble::distanceToTuple(const double *tupleBg, const double *tupleEnd, int& tupleId) const
1707 int nbTuple=getNumberOfTuples();
1708 int nbComps=getNumberOfComponents();
1709 if(nbComps!=(int)std::distance(tupleBg,tupleEnd))
1710 { 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()); }
1712 throw INTERP_KERNEL::Exception("DataArrayDouble::distanceToTuple : no tuple in this ! No distance to compute !");
1713 double ret0=std::numeric_limits<double>::max();
1715 const double *work=getConstPointer();
1716 for(int i=0;i<nbTuple;i++)
1719 for(int j=0;j<nbComps;j++,work++)
1720 val+=(*work-tupleBg[j])*((*work-tupleBg[j]));
1724 { ret0=val; tupleId=i; }
1730 * Accumulate values of the given component of \a this array.
1731 * \param [in] compId - the index of the component of interest.
1732 * \return double - a sum value of \a compId-th component.
1733 * \throw If \a this is not allocated.
1734 * \throw If \a the condition ( 0 <= \a compId < \a this->getNumberOfComponents() ) is
1737 double DataArrayDouble::accumulate(int compId) const
1740 const double *ptr=getConstPointer();
1741 int nbTuple=getNumberOfTuples();
1742 int nbComps=getNumberOfComponents();
1743 if(compId<0 || compId>=nbComps)
1744 throw INTERP_KERNEL::Exception("DataArrayDouble::accumulate : Invalid compId specified : No such nb of components !");
1746 for(int i=0;i<nbTuple;i++)
1747 ret+=ptr[i*nbComps+compId];
1752 * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
1753 * The returned array will have same number of components than \a this and number of tuples equal to
1754 * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
1756 * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
1757 * 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.
1759 * \param [in] bgOfIndex - begin (included) of the input index array.
1760 * \param [in] endOfIndex - end (excluded) of the input index array.
1761 * \return DataArrayDouble * - the new instance having the same number of components than \a this.
1763 * \throw If bgOfIndex or end is NULL.
1764 * \throw If input index array is not ascendingly sorted.
1765 * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
1766 * \throw If std::distance(bgOfIndex,endOfIndex)==0.
1768 DataArrayDouble *DataArrayDouble::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
1770 if(!bgOfIndex || !endOfIndex)
1771 throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : input pointer NULL !");
1773 int nbCompo=getNumberOfComponents();
1774 int nbOfTuples=getNumberOfTuples();
1775 int sz=(int)std::distance(bgOfIndex,endOfIndex);
1777 throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : invalid size of input index array !");
1779 MCAuto<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(sz,nbCompo);
1780 const int *w=bgOfIndex;
1781 if(*w<0 || *w>=nbOfTuples)
1782 throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
1783 const double *srcPt=begin()+(*w)*nbCompo;
1784 double *tmp=ret->getPointer();
1785 for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
1787 std::fill(tmp,tmp+nbCompo,0.);
1790 for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
1792 if(j>=0 && j<nbOfTuples)
1793 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<double>());
1796 std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
1797 throw INTERP_KERNEL::Exception(oss.str().c_str());
1803 std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
1804 throw INTERP_KERNEL::Exception(oss.str().c_str());
1807 ret->copyStringInfoFrom(*this);
1812 * 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.
1813 * This method expects that \a this as only one component. The returned array will have \a this->getNumberOfTuples()+1 tuple with also one component.
1814 * The ith element of returned array is equal to the sum of elements in \a this with rank strictly lower than i.
1816 * \return DataArrayDouble - A newly built array containing cum sum of \a this.
1818 MCAuto<DataArrayDouble> DataArrayDouble::cumSum() const
1821 checkNbOfComps(1,"DataArrayDouble::cumSum : this is expected to be single component");
1822 int nbOfTuple(getNumberOfTuples());
1823 MCAuto<DataArrayDouble> ret(DataArrayDouble::New()); ret->alloc(nbOfTuple+1,1);
1824 double *ptr(ret->getPointer());
1826 const double *thisPtr(begin());
1827 for(int i=0;i<nbOfTuple;i++)
1828 ptr[i+1]=ptr[i]+thisPtr[i];
1833 * Converts each 2D point defined by the tuple of \a this array from the Polar to the
1834 * Cartesian coordinate system. The two components of the tuple of \a this array are
1835 * considered to contain (1) radius and (2) angle of the point in the Polar CS.
1836 * \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
1837 * contains X and Y coordinates of the point in the Cartesian CS. The caller
1838 * is to delete this array using decrRef() as it is no more needed. The array
1839 * does not contain any textual info on components.
1840 * \throw If \a this->getNumberOfComponents() != 2.
1841 * \sa fromCartToPolar
1843 DataArrayDouble *DataArrayDouble::fromPolarToCart() const
1846 int nbOfComp(getNumberOfComponents());
1848 throw INTERP_KERNEL::Exception("DataArrayDouble::fromPolarToCart : must be an array with exactly 2 components !");
1849 int nbOfTuple(getNumberOfTuples());
1850 DataArrayDouble *ret(DataArrayDouble::New());
1851 ret->alloc(nbOfTuple,2);
1852 double *w(ret->getPointer());
1853 const double *wIn(getConstPointer());
1854 for(int i=0;i<nbOfTuple;i++,w+=2,wIn+=2)
1856 w[0]=wIn[0]*cos(wIn[1]);
1857 w[1]=wIn[0]*sin(wIn[1]);
1863 * Converts each 3D point defined by the tuple of \a this array from the Cylindrical to
1864 * the Cartesian coordinate system. The three components of the tuple of \a this array
1865 * are considered to contain (1) radius, (2) azimuth and (3) altitude of the point in
1866 * the Cylindrical CS.
1867 * \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
1868 * contains X, Y and Z coordinates of the point in the Cartesian CS. The info
1869 * on the third component is copied from \a this array. The caller
1870 * is to delete this array using decrRef() as it is no more needed.
1871 * \throw If \a this->getNumberOfComponents() != 3.
1874 DataArrayDouble *DataArrayDouble::fromCylToCart() const
1877 int nbOfComp(getNumberOfComponents());
1879 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCylToCart : must be an array with exactly 3 components !");
1880 int nbOfTuple(getNumberOfTuples());
1881 DataArrayDouble *ret(DataArrayDouble::New());
1882 ret->alloc(getNumberOfTuples(),3);
1883 double *w(ret->getPointer());
1884 const double *wIn(getConstPointer());
1885 for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
1887 w[0]=wIn[0]*cos(wIn[1]);
1888 w[1]=wIn[0]*sin(wIn[1]);
1891 ret->setInfoOnComponent(2,getInfoOnComponent(2));
1896 * Converts each 3D point defined by the tuple of \a this array from the Spherical to
1897 * the Cartesian coordinate system. The three components of the tuple of \a this array
1898 * are considered to contain (1) radius, (2) polar angle and (3) azimuthal angle of the
1899 * point in the Cylindrical CS.
1900 * \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
1901 * contains X, Y and Z coordinates of the point in the Cartesian CS. The info
1902 * on the third component is copied from \a this array. The caller
1903 * is to delete this array using decrRef() as it is no more needed.
1904 * \throw If \a this->getNumberOfComponents() != 3.
1905 * \sa fromCartToSpher
1907 DataArrayDouble *DataArrayDouble::fromSpherToCart() const
1910 int nbOfComp(getNumberOfComponents());
1912 throw INTERP_KERNEL::Exception("DataArrayDouble::fromSpherToCart : must be an array with exactly 3 components !");
1913 int nbOfTuple(getNumberOfTuples());
1914 DataArrayDouble *ret(DataArrayDouble::New());
1915 ret->alloc(getNumberOfTuples(),3);
1916 double *w(ret->getPointer());
1917 const double *wIn(getConstPointer());
1918 for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
1920 w[0]=wIn[0]*cos(wIn[2])*sin(wIn[1]);
1921 w[1]=wIn[0]*sin(wIn[2])*sin(wIn[1]);
1922 w[2]=wIn[0]*cos(wIn[1]);
1928 * 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.
1929 * 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.
1930 * If \a at equals to AX_CYL the returned array will be the result of operation cylindric to cartesian of \a this...
1932 * \param [in] atOfThis - The axis type of \a this.
1933 * \return DataArrayDouble * - the new instance of DataArrayDouble (that must be dealed by caller) containing the result of the cartesianizification of \a this.
1935 DataArrayDouble *DataArrayDouble::cartesianize(MEDCouplingAxisType atOfThis) const
1938 int nbOfComp(getNumberOfComponents());
1939 MCAuto<DataArrayDouble> ret;
1947 ret=fromCylToCart();
1952 ret=fromPolarToCart();
1956 throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : For AX_CYL, number of components must be in [2,3] !");
1960 ret=fromSpherToCart();
1965 ret=fromPolarToCart();
1969 throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : For AX_CYL, number of components must be in [2,3] !");
1971 throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : not recognized axis type ! Only AX_CART, AX_CYL and AX_SPHER supported !");
1973 ret->copyStringInfoFrom(*this);
1978 * This method returns a newly created array to be deallocated that contains the result of conversion from cartesian to polar.
1979 * This method expects that \a this has exactly 2 components.
1980 * \sa fromPolarToCart
1982 DataArrayDouble *DataArrayDouble::fromCartToPolar() const
1984 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
1986 int nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
1988 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToPolar : must be an array with exactly 2 components !");
1989 ret->alloc(nbTuples,2);
1990 double *retPtr(ret->getPointer());
1991 const double *ptr(begin());
1992 for(int i=0;i<nbTuples;i++,ptr+=2,retPtr+=2)
1994 retPtr[0]=sqrt(ptr[0]*ptr[0]+ptr[1]*ptr[1]);
1995 retPtr[1]=atan2(ptr[1],ptr[0]);
2001 * This method returns a newly created array to be deallocated that contains the result of conversion from cartesian to cylindrical.
2002 * This method expects that \a this has exactly 3 components.
2005 DataArrayDouble *DataArrayDouble::fromCartToCyl() const
2007 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2009 int nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2011 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCyl : must be an array with exactly 3 components !");
2012 ret->alloc(nbTuples,3);
2013 double *retPtr(ret->getPointer());
2014 const double *ptr(begin());
2015 for(int i=0;i<nbTuples;i++,ptr+=3,retPtr+=3)
2017 retPtr[0]=sqrt(ptr[0]*ptr[0]+ptr[1]*ptr[1]);
2018 retPtr[1]=atan2(ptr[1],ptr[0]);
2025 * This method returns a newly created array to be deallocated that contains the result of conversion from cartesian to spherical coordinates.
2026 * \sa fromSpherToCart
2028 DataArrayDouble *DataArrayDouble::fromCartToSpher() const
2030 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2032 int nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2034 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToSpher : must be an array with exactly 3 components !");
2035 ret->alloc(nbTuples,3);
2036 double *retPtr(ret->getPointer());
2037 const double *ptr(begin());
2038 for(int i=0;i<nbTuples;i++,ptr+=3,retPtr+=3)
2040 retPtr[0]=sqrt(ptr[0]*ptr[0]+ptr[1]*ptr[1]+ptr[2]*ptr[2]);
2041 retPtr[1]=acos(ptr[2]/retPtr[0]);
2042 retPtr[2]=atan2(ptr[1],ptr[0]);
2048 * 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.
2049 * This method expects that \a this has exactly 3 components.
2050 * \sa MEDCouplingFieldDouble::computeVectorFieldCyl
2052 DataArrayDouble *DataArrayDouble::fromCartToCylGiven(const DataArrayDouble *coords, const double center[3], const double vect[3]) const
2055 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : input coords are NULL !");
2056 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2057 checkAllocated(); coords->checkAllocated();
2058 std::size_t nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2060 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : must be an array with exactly 3 components !");
2061 if(coords->getNumberOfComponents()!=3)
2062 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : coords array must have exactly 3 components !");
2063 if(coords->getNumberOfTuples()!=nbTuples)
2064 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : coords array must have the same number of tuples !");
2065 ret->alloc(nbTuples,nbOfComp);
2066 double magOfVect(sqrt(vect[0]*vect[0]+vect[1]*vect[1]+vect[2]*vect[2]));
2068 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : magnitude of vect is too low !");
2069 double Ur[3],Uteta[3],Uz[3],*retPtr(ret->getPointer());
2070 const double *coo(coords->begin()),*vectField(begin());
2071 std::transform(vect,vect+3,Uz,std::bind2nd(std::multiplies<double>(),1./magOfVect));
2072 for(int i=0;i<nbTuples;i++,vectField+=3,retPtr+=3,coo+=3)
2074 std::transform(coo,coo+3,center,Ur,std::minus<double>());
2075 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];
2076 double magOfTeta(sqrt(Uteta[0]*Uteta[0]+Uteta[1]*Uteta[1]+Uteta[2]*Uteta[2]));
2077 std::transform(Uteta,Uteta+3,Uteta,std::bind2nd(std::multiplies<double>(),1./magOfTeta));
2078 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];
2079 retPtr[0]=Ur[0]*vectField[0]+Ur[1]*vectField[1]+Ur[2]*vectField[2];
2080 retPtr[1]=Uteta[0]*vectField[0]+Uteta[1]*vectField[1]+Uteta[2]*vectField[2];
2081 retPtr[2]=Uz[0]*vectField[0]+Uz[1]*vectField[1]+Uz[2]*vectField[2];
2083 ret->copyStringInfoFrom(*this);
2088 * Computes the doubly contracted product of every tensor defined by the tuple of \a this
2089 * array containing 6 components.
2090 * \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
2091 * is calculated from the tuple <em>(t)</em> of \a this array as follows:
2092 * \f$ t[0]^2+t[1]^2+t[2]^2+2*t[3]^2+2*t[4]^2+2*t[5]^2\f$.
2093 * The caller is to delete this result array using decrRef() as it is no more needed.
2094 * \throw If \a this->getNumberOfComponents() != 6.
2096 DataArrayDouble *DataArrayDouble::doublyContractedProduct() const
2099 int nbOfComp(getNumberOfComponents());
2101 throw INTERP_KERNEL::Exception("DataArrayDouble::doublyContractedProduct : must be an array with exactly 6 components !");
2102 DataArrayDouble *ret=DataArrayDouble::New();
2103 int nbOfTuple=getNumberOfTuples();
2104 ret->alloc(nbOfTuple,1);
2105 const double *src=getConstPointer();
2106 double *dest=ret->getPointer();
2107 for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
2108 *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];
2113 * Computes the determinant of every square matrix defined by the tuple of \a this
2114 * array, which contains either 4, 6 or 9 components. The case of 6 components
2115 * corresponds to that of the upper triangular matrix.
2116 * \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
2117 * is the determinant of matrix of the corresponding tuple of \a this array.
2118 * The caller is to delete this result array using decrRef() as it is no more
2120 * \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2122 DataArrayDouble *DataArrayDouble::determinant() const
2125 DataArrayDouble *ret=DataArrayDouble::New();
2126 int nbOfTuple=getNumberOfTuples();
2127 ret->alloc(nbOfTuple,1);
2128 const double *src=getConstPointer();
2129 double *dest=ret->getPointer();
2130 switch(getNumberOfComponents())
2133 for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
2134 *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];
2137 for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
2138 *dest=src[0]*src[3]-src[1]*src[2];
2141 for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
2142 *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];
2146 throw INTERP_KERNEL::Exception("DataArrayDouble::determinant : Invalid number of components ! must be in 4,6,9 !");
2151 * Computes 3 eigenvalues of every upper triangular matrix defined by the tuple of
2152 * \a this array, which contains 6 components.
2153 * \return DataArrayDouble * - the new instance of DataArrayDouble containing 3
2154 * components, whose each tuple contains the eigenvalues of the matrix of
2155 * corresponding tuple of \a this array.
2156 * The caller is to delete this result array using decrRef() as it is no more
2158 * \throw If \a this->getNumberOfComponents() != 6.
2160 DataArrayDouble *DataArrayDouble::eigenValues() const
2163 int nbOfComp=getNumberOfComponents();
2165 throw INTERP_KERNEL::Exception("DataArrayDouble::eigenValues : must be an array with exactly 6 components !");
2166 DataArrayDouble *ret=DataArrayDouble::New();
2167 int nbOfTuple=getNumberOfTuples();
2168 ret->alloc(nbOfTuple,3);
2169 const double *src=getConstPointer();
2170 double *dest=ret->getPointer();
2171 for(int i=0;i<nbOfTuple;i++,dest+=3,src+=6)
2172 INTERP_KERNEL::computeEigenValues6(src,dest);
2177 * Computes 3 eigenvectors of every upper triangular matrix defined by the tuple of
2178 * \a this array, which contains 6 components.
2179 * \return DataArrayDouble * - the new instance of DataArrayDouble containing 9
2180 * components, whose each tuple contains 3 eigenvectors of the matrix of
2181 * corresponding tuple of \a this array.
2182 * The caller is to delete this result array using decrRef() as it is no more
2184 * \throw If \a this->getNumberOfComponents() != 6.
2186 DataArrayDouble *DataArrayDouble::eigenVectors() const
2189 int nbOfComp=getNumberOfComponents();
2191 throw INTERP_KERNEL::Exception("DataArrayDouble::eigenVectors : must be an array with exactly 6 components !");
2192 DataArrayDouble *ret=DataArrayDouble::New();
2193 int nbOfTuple=getNumberOfTuples();
2194 ret->alloc(nbOfTuple,9);
2195 const double *src=getConstPointer();
2196 double *dest=ret->getPointer();
2197 for(int i=0;i<nbOfTuple;i++,src+=6)
2200 INTERP_KERNEL::computeEigenValues6(src,tmp);
2201 for(int j=0;j<3;j++,dest+=3)
2202 INTERP_KERNEL::computeEigenVectorForEigenValue6(src,tmp[j],1e-12,dest);
2208 * Computes the inverse matrix of every matrix defined by the tuple of \a this
2209 * array, which contains either 4, 6 or 9 components. The case of 6 components
2210 * corresponds to that of the upper triangular matrix.
2211 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2212 * same number of components as \a this one, whose each tuple is the inverse
2213 * matrix of the matrix of corresponding tuple of \a this array.
2214 * The caller is to delete this result array using decrRef() as it is no more
2216 * \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2218 DataArrayDouble *DataArrayDouble::inverse() const
2221 int nbOfComp=getNumberOfComponents();
2222 if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
2223 throw INTERP_KERNEL::Exception("DataArrayDouble::inversion : must be an array with 4,6 or 9 components !");
2224 DataArrayDouble *ret=DataArrayDouble::New();
2225 int nbOfTuple=getNumberOfTuples();
2226 ret->alloc(nbOfTuple,nbOfComp);
2227 const double *src=getConstPointer();
2228 double *dest=ret->getPointer();
2230 for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
2232 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];
2233 dest[0]=(src[1]*src[2]-src[4]*src[4])/det;
2234 dest[1]=(src[0]*src[2]-src[5]*src[5])/det;
2235 dest[2]=(src[0]*src[1]-src[3]*src[3])/det;
2236 dest[3]=(src[5]*src[4]-src[3]*src[2])/det;
2237 dest[4]=(src[5]*src[3]-src[0]*src[4])/det;
2238 dest[5]=(src[3]*src[4]-src[1]*src[5])/det;
2240 else if(nbOfComp==4)
2241 for(int i=0;i<nbOfTuple;i++,dest+=4,src+=4)
2243 double det=src[0]*src[3]-src[1]*src[2];
2245 dest[1]=-src[1]/det;
2246 dest[2]=-src[2]/det;
2250 for(int i=0;i<nbOfTuple;i++,dest+=9,src+=9)
2252 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];
2253 dest[0]=(src[4]*src[8]-src[7]*src[5])/det;
2254 dest[1]=(src[7]*src[2]-src[1]*src[8])/det;
2255 dest[2]=(src[1]*src[5]-src[4]*src[2])/det;
2256 dest[3]=(src[6]*src[5]-src[3]*src[8])/det;
2257 dest[4]=(src[0]*src[8]-src[6]*src[2])/det;
2258 dest[5]=(src[2]*src[3]-src[0]*src[5])/det;
2259 dest[6]=(src[3]*src[7]-src[6]*src[4])/det;
2260 dest[7]=(src[6]*src[1]-src[0]*src[7])/det;
2261 dest[8]=(src[0]*src[4]-src[1]*src[3])/det;
2267 * Computes the trace of every matrix defined by the tuple of \a this
2268 * array, which contains either 4, 6 or 9 components. The case of 6 components
2269 * corresponds to that of the upper triangular matrix.
2270 * \return DataArrayDouble * - the new instance of DataArrayDouble containing
2271 * 1 component, whose each tuple is the trace of
2272 * the matrix of corresponding tuple of \a this array.
2273 * The caller is to delete this result array using decrRef() as it is no more
2275 * \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2277 DataArrayDouble *DataArrayDouble::trace() const
2280 int nbOfComp=getNumberOfComponents();
2281 if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
2282 throw INTERP_KERNEL::Exception("DataArrayDouble::trace : must be an array with 4,6 or 9 components !");
2283 DataArrayDouble *ret=DataArrayDouble::New();
2284 int nbOfTuple=getNumberOfTuples();
2285 ret->alloc(nbOfTuple,1);
2286 const double *src=getConstPointer();
2287 double *dest=ret->getPointer();
2289 for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
2290 *dest=src[0]+src[1]+src[2];
2291 else if(nbOfComp==4)
2292 for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
2293 *dest=src[0]+src[3];
2295 for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
2296 *dest=src[0]+src[4]+src[8];
2301 * Computes the stress deviator tensor of every stress tensor defined by the tuple of
2302 * \a this array, which contains 6 components.
2303 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2304 * same number of components and tuples as \a this array.
2305 * The caller is to delete this result array using decrRef() as it is no more
2307 * \throw If \a this->getNumberOfComponents() != 6.
2309 DataArrayDouble *DataArrayDouble::deviator() const
2312 int nbOfComp=getNumberOfComponents();
2314 throw INTERP_KERNEL::Exception("DataArrayDouble::deviator : must be an array with exactly 6 components !");
2315 DataArrayDouble *ret=DataArrayDouble::New();
2316 int nbOfTuple=getNumberOfTuples();
2317 ret->alloc(nbOfTuple,6);
2318 const double *src=getConstPointer();
2319 double *dest=ret->getPointer();
2320 for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
2322 double tr=(src[0]+src[1]+src[2])/3.;
2334 * Computes the magnitude of every vector defined by the tuple of
2336 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2337 * same number of tuples as \a this array and one component.
2338 * The caller is to delete this result array using decrRef() as it is no more
2340 * \throw If \a this is not allocated.
2342 DataArrayDouble *DataArrayDouble::magnitude() const
2345 int nbOfComp=getNumberOfComponents();
2346 DataArrayDouble *ret=DataArrayDouble::New();
2347 int nbOfTuple=getNumberOfTuples();
2348 ret->alloc(nbOfTuple,1);
2349 const double *src=getConstPointer();
2350 double *dest=ret->getPointer();
2351 for(int i=0;i<nbOfTuple;i++,dest++)
2354 for(int j=0;j<nbOfComp;j++,src++)
2362 * Computes the maximal value within every tuple of \a this array.
2363 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2364 * same number of tuples as \a this array and one component.
2365 * The caller is to delete this result array using decrRef() as it is no more
2367 * \throw If \a this is not allocated.
2368 * \sa DataArrayDouble::maxPerTupleWithCompoId
2370 DataArrayDouble *DataArrayDouble::maxPerTuple() const
2373 int nbOfComp=getNumberOfComponents();
2374 MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
2375 int nbOfTuple=getNumberOfTuples();
2376 ret->alloc(nbOfTuple,1);
2377 const double *src=getConstPointer();
2378 double *dest=ret->getPointer();
2379 for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
2380 *dest=*std::max_element(src,src+nbOfComp);
2385 * Computes the maximal value within every tuple of \a this array and it returns the first component
2386 * id for each tuple that corresponds to the maximal value within the tuple.
2388 * \param [out] compoIdOfMaxPerTuple - the new new instance of DataArrayInt containing the
2389 * same number of tuples and only one component.
2390 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2391 * same number of tuples as \a this array and one component.
2392 * The caller is to delete this result array using decrRef() as it is no more
2394 * \throw If \a this is not allocated.
2395 * \sa DataArrayDouble::maxPerTuple
2397 DataArrayDouble *DataArrayDouble::maxPerTupleWithCompoId(DataArrayInt* &compoIdOfMaxPerTuple) const
2400 int nbOfComp=getNumberOfComponents();
2401 MCAuto<DataArrayDouble> ret0=DataArrayDouble::New();
2402 MCAuto<DataArrayInt> ret1=DataArrayInt::New();
2403 int nbOfTuple=getNumberOfTuples();
2404 ret0->alloc(nbOfTuple,1); ret1->alloc(nbOfTuple,1);
2405 const double *src=getConstPointer();
2406 double *dest=ret0->getPointer(); int *dest1=ret1->getPointer();
2407 for(int i=0;i<nbOfTuple;i++,dest++,dest1++,src+=nbOfComp)
2409 const double *loc=std::max_element(src,src+nbOfComp);
2411 *dest1=(int)std::distance(src,loc);
2413 compoIdOfMaxPerTuple=ret1.retn();
2418 * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c this->getNumberOfTuples() tuples.
2419 * \n This returned array contains the euclidian distance for each tuple in \a this.
2420 * \n So the returned array can be seen as a dense symmetrical matrix whose diagonal elements are equal to 0.
2421 * \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)
2423 * \warning use this method with care because it can leads to big amount of consumed memory !
2425 * \return A newly allocated (huge) MEDCoupling::DataArrayDouble instance that the caller should deal with.
2427 * \throw If \a this is not allocated.
2429 * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrixWith
2431 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrix() const
2434 int nbOfComp=getNumberOfComponents();
2435 int nbOfTuples=getNumberOfTuples();
2436 const double *inData=getConstPointer();
2437 MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
2438 ret->alloc(nbOfTuples*nbOfTuples,1);
2439 double *outData=ret->getPointer();
2440 for(int i=0;i<nbOfTuples;i++)
2442 outData[i*nbOfTuples+i]=0.;
2443 for(int j=i+1;j<nbOfTuples;j++)
2446 for(int k=0;k<nbOfComp;k++)
2447 { double delta=inData[i*nbOfComp+k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
2449 outData[i*nbOfTuples+j]=dist;
2450 outData[j*nbOfTuples+i]=dist;
2457 * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c other->getNumberOfTuples() tuples.
2458 * \n This returned array contains the euclidian distance for each tuple in \a other with each tuple in \a this.
2459 * \n So the returned array can be seen as a dense rectangular matrix with \c other->getNumberOfTuples() rows and \c this->getNumberOfTuples() columns.
2460 * \n Output rectangular matrix is sorted along rows.
2461 * \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)
2463 * \warning use this method with care because it can leads to big amount of consumed memory !
2465 * \param [in] other DataArrayDouble instance having same number of components than \a this.
2466 * \return A newly allocated (huge) MEDCoupling::DataArrayDouble instance that the caller should deal with.
2468 * \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.
2470 * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrix
2472 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrixWith(const DataArrayDouble *other) const
2475 throw INTERP_KERNEL::Exception("DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : input parameter is null !");
2477 other->checkAllocated();
2478 int nbOfComp=getNumberOfComponents();
2479 int otherNbOfComp=other->getNumberOfComponents();
2480 if(nbOfComp!=otherNbOfComp)
2482 std::ostringstream oss; oss << "DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : this nb of compo=" << nbOfComp << " and other nb of compo=" << otherNbOfComp << ". It should match !";
2483 throw INTERP_KERNEL::Exception(oss.str().c_str());
2485 int nbOfTuples=getNumberOfTuples();
2486 int otherNbOfTuples=other->getNumberOfTuples();
2487 const double *inData=getConstPointer();
2488 const double *inDataOther=other->getConstPointer();
2489 MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
2490 ret->alloc(otherNbOfTuples*nbOfTuples,1);
2491 double *outData=ret->getPointer();
2492 for(int i=0;i<otherNbOfTuples;i++,inDataOther+=nbOfComp)
2494 for(int j=0;j<nbOfTuples;j++)
2497 for(int k=0;k<nbOfComp;k++)
2498 { double delta=inDataOther[k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
2500 outData[i*nbOfTuples+j]=dist;
2507 * This method expects that \a this stores 3 tuples containing 2 components each.
2508 * Each of this tuples represent a point into 2D space.
2509 * 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).
2510 * 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[.
2512 * \throw If \a this is not allocated.
2513 * \throw If \a this has not 3 tuples of 2 components
2514 * \throw If tuples/points in \a this are aligned
2516 void DataArrayDouble::asArcOfCircle(double center[2], double& radius, double& ang) const
2519 INTERP_KERNEL::QuadraticPlanarPrecision arcPrec(1e-14);
2520 if(getNumberOfTuples()!=3 && getNumberOfComponents()!=2)
2521 throw INTERP_KERNEL::Exception("DataArrayDouble::asArcCircle : this method expects");
2522 const double *pt(begin());
2523 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]));
2525 INTERP_KERNEL::AutoCppPtr<INTERP_KERNEL::EdgeLin> e1(new INTERP_KERNEL::EdgeLin(n0,n2)),e2(new INTERP_KERNEL::EdgeLin(n2,n1));
2526 INTERP_KERNEL::SegSegIntersector inters(*e1,*e2);
2527 bool colinearity(inters.areColinears());
2529 throw INTERP_KERNEL::Exception("DataArrayDouble::asArcOfCircle : 3 points in this have been detected as colinear !");
2531 INTERP_KERNEL::AutoCppPtr<INTERP_KERNEL::EdgeArcCircle> ret(new INTERP_KERNEL::EdgeArcCircle(n0,n2,n1));
2532 const double *c(ret->getCenter());
2533 center[0]=c[0]; center[1]=c[1];
2534 radius=ret->getRadius();
2535 ang=ret->getAngle();
2539 * Sorts value within every tuple of \a this array.
2540 * \param [in] asc - if \a true, the values are sorted in ascending order, else,
2541 * in descending order.
2542 * \throw If \a this is not allocated.
2544 void DataArrayDouble::sortPerTuple(bool asc)
2547 double *pt=getPointer();
2548 int nbOfTuple=getNumberOfTuples();
2549 int nbOfComp=getNumberOfComponents();
2551 for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
2552 std::sort(pt,pt+nbOfComp);
2554 for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
2555 std::sort(pt,pt+nbOfComp,std::greater<double>());
2560 * Modify all elements of \a this array, so that
2561 * an element _x_ becomes \f$ numerator / x \f$.
2562 * \warning If an exception is thrown because of presence of 0.0 element in \a this
2563 * array, all elements processed before detection of the zero element remain
2565 * \param [in] numerator - the numerator used to modify array elements.
2566 * \throw If \a this is not allocated.
2567 * \throw If there is an element equal to 0.0 in \a this array.
2569 void DataArrayDouble::applyInv(double numerator)
2572 double *ptr=getPointer();
2573 std::size_t nbOfElems=getNbOfElems();
2574 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2576 if(std::abs(*ptr)>std::numeric_limits<double>::min())
2578 *ptr=numerator/(*ptr);
2582 std::ostringstream oss; oss << "DataArrayDouble::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
2584 throw INTERP_KERNEL::Exception(oss.str().c_str());
2591 * Modify all elements of \a this array, so that
2592 * an element _x_ becomes <em> val ^ x </em>. Contrary to DataArrayInt::applyPow
2593 * all values in \a this have to be >= 0 if val is \b not integer.
2594 * \param [in] val - the value used to apply pow on all array elements.
2595 * \throw If \a this is not allocated.
2596 * \warning If an exception is thrown because of presence of 0 element in \a this
2597 * array and \a val is \b not integer, all elements processed before detection of the zero element remain
2600 void DataArrayDouble::applyPow(double val)
2603 double *ptr=getPointer();
2604 std::size_t nbOfElems=getNbOfElems();
2606 bool isInt=((double)val2)==val;
2609 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2615 std::ostringstream oss; oss << "DataArrayDouble::applyPow (double) : At elem # " << i << " value is " << *ptr << " ! must be >=0. !";
2616 throw INTERP_KERNEL::Exception(oss.str().c_str());
2622 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2623 *ptr=pow(*ptr,val2);
2629 * Modify all elements of \a this array, so that
2630 * an element _x_ becomes \f$ val ^ x \f$.
2631 * \param [in] val - the value used to apply pow on all array elements.
2632 * \throw If \a this is not allocated.
2633 * \throw If \a val < 0.
2634 * \warning If an exception is thrown because of presence of 0 element in \a this
2635 * array, all elements processed before detection of the zero element remain
2638 void DataArrayDouble::applyRPow(double val)
2642 throw INTERP_KERNEL::Exception("DataArrayDouble::applyRPow : the input value has to be >= 0 !");
2643 double *ptr=getPointer();
2644 std::size_t nbOfElems=getNbOfElems();
2645 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2651 * Returns a new DataArrayDouble created from \a this one by applying \a
2652 * FunctionToEvaluate to every tuple of \a this array. Textual data is not copied.
2653 * For more info see \ref MEDCouplingArrayApplyFunc
2654 * \param [in] nbOfComp - number of components in the result array.
2655 * \param [in] func - the \a FunctionToEvaluate declared as
2656 * \c bool (*\a func)(\c const \c double *\a pos, \c double *\a res),
2657 * where \a pos points to the first component of a tuple of \a this array
2658 * and \a res points to the first component of a tuple of the result array.
2659 * Note that length (number of components) of \a pos can differ from
2661 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2662 * same number of tuples as \a this array.
2663 * The caller is to delete this result array using decrRef() as it is no more
2665 * \throw If \a this is not allocated.
2666 * \throw If \a func returns \a false.
2668 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, FunctionToEvaluate func) const
2671 DataArrayDouble *newArr=DataArrayDouble::New();
2672 int nbOfTuples=getNumberOfTuples();
2673 int oldNbOfComp=getNumberOfComponents();
2674 newArr->alloc(nbOfTuples,nbOfComp);
2675 const double *ptr=getConstPointer();
2676 double *ptrToFill=newArr->getPointer();
2677 for(int i=0;i<nbOfTuples;i++)
2679 if(!func(ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp))
2681 std::ostringstream oss; oss << "For tuple # " << i << " with value (";
2682 std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
2683 oss << ") : Evaluation of function failed !";
2685 throw INTERP_KERNEL::Exception(oss.str().c_str());
2692 * Returns a new DataArrayDouble created from \a this one by applying a function to every
2693 * tuple of \a this array. Textual data is not copied.
2694 * For more info see \ref MEDCouplingArrayApplyFunc1.
2695 * \param [in] nbOfComp - number of components in the result array.
2696 * \param [in] func - the expression defining how to transform a tuple of \a this array.
2697 * Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
2698 * \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
2699 * If false the computation is carried on without any notification. When false the evaluation is a little faster.
2700 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2701 * same number of tuples as \a this array and \a nbOfComp components.
2702 * The caller is to delete this result array using decrRef() as it is no more
2704 * \throw If \a this is not allocated.
2705 * \throw If computing \a func fails.
2707 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, const std::string& func, bool isSafe) const
2709 INTERP_KERNEL::ExprParser expr(func);
2711 std::set<std::string> vars;
2712 expr.getTrueSetOfVars(vars);
2713 std::vector<std::string> varsV(vars.begin(),vars.end());
2714 return applyFuncNamedCompo(nbOfComp,varsV,func,isSafe);
2718 * Returns a new DataArrayDouble created from \a this one by applying a function to every
2719 * tuple of \a this array. Textual data is not copied. This method works by tuples (whatever its size).
2720 * If \a this is a one component array, call applyFuncOnThis instead that performs the same work faster.
2722 * For more info see \ref MEDCouplingArrayApplyFunc0.
2723 * \param [in] func - the expression defining how to transform a tuple of \a this array.
2724 * Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
2725 * \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
2726 * If false the computation is carried on without any notification. When false the evaluation is a little faster.
2727 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2728 * same number of tuples and components as \a this array.
2729 * The caller is to delete this result array using decrRef() as it is no more
2731 * \sa applyFuncOnThis
2732 * \throw If \a this is not allocated.
2733 * \throw If computing \a func fails.
2735 DataArrayDouble *DataArrayDouble::applyFunc(const std::string& func, bool isSafe) const
2737 int nbOfComp(getNumberOfComponents());
2739 throw INTERP_KERNEL::Exception("DataArrayDouble::applyFunc : output number of component must be > 0 !");
2741 int nbOfTuples(getNumberOfTuples());
2742 MCAuto<DataArrayDouble> newArr(DataArrayDouble::New());
2743 newArr->alloc(nbOfTuples,nbOfComp);
2744 INTERP_KERNEL::ExprParser expr(func);
2746 std::set<std::string> vars;
2747 expr.getTrueSetOfVars(vars);
2748 if((int)vars.size()>1)
2750 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 : ";
2751 std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
2752 throw INTERP_KERNEL::Exception(oss.str().c_str());
2756 expr.prepareFastEvaluator();
2757 newArr->rearrange(1);
2758 newArr->fillWithValue(expr.evaluateDouble());
2759 newArr->rearrange(nbOfComp);
2760 return newArr.retn();
2762 std::vector<std::string> vars2(vars.begin(),vars.end());
2763 double buff,*ptrToFill(newArr->getPointer());
2764 const double *ptr(begin());
2765 std::vector<double> stck;
2766 expr.prepareExprEvaluationDouble(vars2,1,1,0,&buff,&buff+1);
2767 expr.prepareFastEvaluator();
2770 for(int i=0;i<nbOfTuples;i++)
2772 for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
2775 expr.evaluateDoubleInternal(stck);
2776 *ptrToFill=stck.back();
2783 for(int i=0;i<nbOfTuples;i++)
2785 for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
2790 expr.evaluateDoubleInternalSafe(stck);
2792 catch(INTERP_KERNEL::Exception& e)
2794 std::ostringstream oss; oss << "For tuple # " << i << " component # " << iComp << " with value (";
2796 oss << ") : Evaluation of function failed !" << e.what();
2797 throw INTERP_KERNEL::Exception(oss.str().c_str());
2799 *ptrToFill=stck.back();
2804 return newArr.retn();
2808 * This method is a non const method that modify the array in \a this.
2809 * This method only works on one component array. It means that function \a func must
2810 * contain at most one variable.
2811 * This method is a specialization of applyFunc method with one parameter on one component array.
2813 * \param [in] func - the expression defining how to transform a tuple of \a this array.
2814 * Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
2815 * \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
2816 * If false the computation is carried on without any notification. When false the evaluation is a little faster.
2820 void DataArrayDouble::applyFuncOnThis(const std::string& func, bool isSafe)
2822 int nbOfComp(getNumberOfComponents());
2824 throw INTERP_KERNEL::Exception("DataArrayDouble::applyFuncOnThis : output number of component must be > 0 !");
2826 int nbOfTuples(getNumberOfTuples());
2827 INTERP_KERNEL::ExprParser expr(func);
2829 std::set<std::string> vars;
2830 expr.getTrueSetOfVars(vars);
2831 if((int)vars.size()>1)
2833 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 : ";
2834 std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
2835 throw INTERP_KERNEL::Exception(oss.str().c_str());
2839 expr.prepareFastEvaluator();
2840 std::vector<std::string> compInfo(getInfoOnComponents());
2842 fillWithValue(expr.evaluateDouble());
2843 rearrange(nbOfComp);
2844 setInfoOnComponents(compInfo);
2847 std::vector<std::string> vars2(vars.begin(),vars.end());
2848 double buff,*ptrToFill(getPointer());
2849 const double *ptr(begin());
2850 std::vector<double> stck;
2851 expr.prepareExprEvaluationDouble(vars2,1,1,0,&buff,&buff+1);
2852 expr.prepareFastEvaluator();
2855 for(int i=0;i<nbOfTuples;i++)
2857 for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
2860 expr.evaluateDoubleInternal(stck);
2861 *ptrToFill=stck.back();
2868 for(int i=0;i<nbOfTuples;i++)
2870 for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
2875 expr.evaluateDoubleInternalSafe(stck);
2877 catch(INTERP_KERNEL::Exception& e)
2879 std::ostringstream oss; oss << "For tuple # " << i << " component # " << iComp << " with value (";
2881 oss << ") : Evaluation of function failed !" << e.what();
2882 throw INTERP_KERNEL::Exception(oss.str().c_str());
2884 *ptrToFill=stck.back();
2892 * Returns a new DataArrayDouble created from \a this one by applying a function to every
2893 * tuple of \a this array. Textual data is not copied.
2894 * For more info see \ref MEDCouplingArrayApplyFunc2.
2895 * \param [in] nbOfComp - number of components in the result array.
2896 * \param [in] func - the expression defining how to transform a tuple of \a this array.
2897 * Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
2898 * \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
2899 * If false the computation is carried on without any notification. When false the evaluation is a little faster.
2900 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2901 * same number of tuples as \a this array.
2902 * The caller is to delete this result array using decrRef() as it is no more
2904 * \throw If \a this is not allocated.
2905 * \throw If \a func contains vars that are not in \a this->getInfoOnComponent().
2906 * \throw If computing \a func fails.
2908 DataArrayDouble *DataArrayDouble::applyFuncCompo(int nbOfComp, const std::string& func, bool isSafe) const
2910 return applyFuncNamedCompo(nbOfComp,getVarsOnComponent(),func,isSafe);
2914 * Returns a new DataArrayDouble created from \a this one by applying a function to every
2915 * tuple of \a this array. Textual data is not copied.
2916 * For more info see \ref MEDCouplingArrayApplyFunc3.
2917 * \param [in] nbOfComp - number of components in the result array.
2918 * \param [in] varsOrder - sequence of vars defining their order.
2919 * \param [in] func - the expression defining how to transform a tuple of \a this array.
2920 * Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
2921 * \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
2922 * If false the computation is carried on without any notification. When false the evaluation is a little faster.
2923 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2924 * same number of tuples as \a this array.
2925 * The caller is to delete this result array using decrRef() as it is no more
2927 * \throw If \a this is not allocated.
2928 * \throw If \a func contains vars not in \a varsOrder.
2929 * \throw If computing \a func fails.
2931 DataArrayDouble *DataArrayDouble::applyFuncNamedCompo(int nbOfComp, const std::vector<std::string>& varsOrder, const std::string& func, bool isSafe) const
2934 throw INTERP_KERNEL::Exception("DataArrayDouble::applyFuncNamedCompo : output number of component must be > 0 !");
2935 std::vector<std::string> varsOrder2(varsOrder);
2936 int oldNbOfComp(getNumberOfComponents());
2937 for(int i=(int)varsOrder.size();i<oldNbOfComp;i++)
2938 varsOrder2.push_back(std::string());
2940 int nbOfTuples(getNumberOfTuples());
2941 INTERP_KERNEL::ExprParser expr(func);
2943 std::set<std::string> vars;
2944 expr.getTrueSetOfVars(vars);
2945 if((int)vars.size()>oldNbOfComp)
2947 std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
2948 oss << vars.size() << " variables : ";
2949 std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
2950 throw INTERP_KERNEL::Exception(oss.str().c_str());
2952 MCAuto<DataArrayDouble> newArr(DataArrayDouble::New());
2953 newArr->alloc(nbOfTuples,nbOfComp);
2954 INTERP_KERNEL::AutoPtr<double> buff(new double[oldNbOfComp]);
2955 double *buffPtr(buff),*ptrToFill;
2956 std::vector<double> stck;
2957 for(int iComp=0;iComp<nbOfComp;iComp++)
2959 expr.prepareExprEvaluationDouble(varsOrder2,oldNbOfComp,nbOfComp,iComp,buffPtr,buffPtr+oldNbOfComp);
2960 expr.prepareFastEvaluator();
2961 const double *ptr(getConstPointer());
2962 ptrToFill=newArr->getPointer()+iComp;
2965 for(int i=0;i<nbOfTuples;i++,ptrToFill+=nbOfComp,ptr+=oldNbOfComp)
2967 std::copy(ptr,ptr+oldNbOfComp,buffPtr);
2968 expr.evaluateDoubleInternal(stck);
2969 *ptrToFill=stck.back();
2975 for(int i=0;i<nbOfTuples;i++,ptrToFill+=nbOfComp,ptr+=oldNbOfComp)
2977 std::copy(ptr,ptr+oldNbOfComp,buffPtr);
2980 expr.evaluateDoubleInternalSafe(stck);
2981 *ptrToFill=stck.back();
2984 catch(INTERP_KERNEL::Exception& e)
2986 std::ostringstream oss; oss << "For tuple # " << i << " with value (";
2987 std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
2988 oss << ") : Evaluation of function failed !" << e.what();
2989 throw INTERP_KERNEL::Exception(oss.str().c_str());
2994 return newArr.retn();
2997 void DataArrayDouble::applyFuncFast32(const std::string& func)
3000 INTERP_KERNEL::ExprParser expr(func);
3002 char *funcStr=expr.compileX86();
3004 *((void **)&funcPtr)=funcStr;//he he...
3006 double *ptr=getPointer();
3007 int nbOfComp=getNumberOfComponents();
3008 int nbOfTuples=getNumberOfTuples();
3009 int nbOfElems=nbOfTuples*nbOfComp;
3010 for(int i=0;i<nbOfElems;i++,ptr++)
3015 void DataArrayDouble::applyFuncFast64(const std::string& func)
3018 INTERP_KERNEL::ExprParser expr(func);
3020 char *funcStr=expr.compileX86_64();
3022 *((void **)&funcPtr)=funcStr;//he he...
3024 double *ptr=getPointer();
3025 int nbOfComp=getNumberOfComponents();
3026 int nbOfTuples=getNumberOfTuples();
3027 int nbOfElems=nbOfTuples*nbOfComp;
3028 for(int i=0;i<nbOfElems;i++,ptr++)
3034 * \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.
3036 MCAuto<DataArrayDouble> DataArrayDouble::symmetry3DPlane(const double point[3], const double normalVector[3]) const
3039 if(getNumberOfComponents()!=3)
3040 throw INTERP_KERNEL::Exception("DataArrayDouble::symmetry3DPlane : this is excepted to have 3 components !");
3041 int nbTuples(getNumberOfTuples());
3042 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
3043 ret->alloc(nbTuples,3);
3044 Symmetry3DPlane(point,normalVector,nbTuples,begin(),ret->getPointer());
3048 DataArrayDoubleIterator *DataArrayDouble::iterator()
3050 return new DataArrayDoubleIterator(this);
3054 * Returns a new DataArrayInt containing indices of tuples of \a this one-dimensional
3055 * array whose values are within a given range. Textual data is not copied.
3056 * \param [in] vmin - a lowest acceptable value (included).
3057 * \param [in] vmax - a greatest acceptable value (included).
3058 * \return DataArrayInt * - the new instance of DataArrayInt.
3059 * The caller is to delete this result array using decrRef() as it is no more
3061 * \throw If \a this->getNumberOfComponents() != 1.
3063 * \sa DataArrayDouble::findIdsNotInRange
3065 * \if ENABLE_EXAMPLES
3066 * \ref cpp_mcdataarraydouble_getidsinrange "Here is a C++ example".<br>
3067 * \ref py_mcdataarraydouble_getidsinrange "Here is a Python example".
3070 DataArrayInt *DataArrayDouble::findIdsInRange(double vmin, double vmax) const
3073 if(getNumberOfComponents()!=1)
3074 throw INTERP_KERNEL::Exception("DataArrayDouble::findIdsInRange : this must have exactly one component !");
3075 const double *cptr(begin());
3076 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
3077 int nbOfTuples(getNumberOfTuples());
3078 for(int i=0;i<nbOfTuples;i++,cptr++)
3079 if(*cptr>=vmin && *cptr<=vmax)
3080 ret->pushBackSilent(i);
3085 * Returns a new DataArrayInt containing indices of tuples of \a this one-dimensional
3086 * array whose values are not within a given range. Textual data is not copied.
3087 * \param [in] vmin - a lowest not acceptable value (excluded).
3088 * \param [in] vmax - a greatest not acceptable value (excluded).
3089 * \return DataArrayInt * - the new instance of DataArrayInt.
3090 * The caller is to delete this result array using decrRef() as it is no more
3092 * \throw If \a this->getNumberOfComponents() != 1.
3094 * \sa DataArrayDouble::findIdsInRange
3096 DataArrayInt *DataArrayDouble::findIdsNotInRange(double vmin, double vmax) const
3099 if(getNumberOfComponents()!=1)
3100 throw INTERP_KERNEL::Exception("DataArrayDouble::findIdsNotInRange : this must have exactly one component !");
3101 const double *cptr(begin());
3102 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
3103 int nbOfTuples(getNumberOfTuples());
3104 for(int i=0;i<nbOfTuples;i++,cptr++)
3105 if(*cptr<vmin || *cptr>vmax)
3106 ret->pushBackSilent(i);
3111 * Returns a new DataArrayDouble by concatenating two given arrays, so that (1) the number
3112 * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
3113 * the number of component in the result array is same as that of each of given arrays.
3114 * Info on components is copied from the first of the given arrays. Number of components
3115 * in the given arrays must be the same.
3116 * \param [in] a1 - an array to include in the result array.
3117 * \param [in] a2 - another array to include in the result array.
3118 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3119 * The caller is to delete this result array using decrRef() as it is no more
3121 * \throw If both \a a1 and \a a2 are NULL.
3122 * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
3124 DataArrayDouble *DataArrayDouble::Aggregate(const DataArrayDouble *a1, const DataArrayDouble *a2)
3126 std::vector<const DataArrayDouble *> tmp(2);
3127 tmp[0]=a1; tmp[1]=a2;
3128 return Aggregate(tmp);
3132 * Returns a new DataArrayDouble by concatenating all given arrays, so that (1) the number
3133 * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
3134 * the number of component in the result array is same as that of each of given arrays.
3135 * Info on components is copied from the first of the given arrays. Number of components
3136 * in the given arrays must be the same.
3137 * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it
3138 * not the object itself.
3139 * \param [in] arr - a sequence of arrays to include in the result array.
3140 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3141 * The caller is to delete this result array using decrRef() as it is no more
3143 * \throw If all arrays within \a arr are NULL.
3144 * \throw If getNumberOfComponents() of arrays within \a arr.
3146 DataArrayDouble *DataArrayDouble::Aggregate(const std::vector<const DataArrayDouble *>& arr)
3148 std::vector<const DataArrayDouble *> a;
3149 for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
3153 throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : input list must contain at least one NON EMPTY DataArrayDouble !");
3154 std::vector<const DataArrayDouble *>::const_iterator it=a.begin();
3155 std::size_t nbOfComp((*it)->getNumberOfComponents());
3156 int nbt=(*it++)->getNumberOfTuples();
3157 for(int i=1;it!=a.end();it++,i++)
3159 if((*it)->getNumberOfComponents()!=nbOfComp)
3160 throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : Nb of components mismatch for array aggregation !");
3161 nbt+=(*it)->getNumberOfTuples();
3163 MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
3164 ret->alloc(nbt,nbOfComp);
3165 double *pt=ret->getPointer();
3166 for(it=a.begin();it!=a.end();it++)
3167 pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
3168 ret->copyStringInfoFrom(*(a[0]));
3173 * Returns a new DataArrayDouble containing a dot product of two given arrays, so that
3174 * the i-th tuple of the result array is a sum of products of j-th components of i-th
3175 * tuples of given arrays (\f$ a_i = \sum_{j=1}^n a1_j * a2_j \f$).
3176 * Info on components and name is copied from the first of the given arrays.
3177 * Number of tuples and components in the given arrays must be the same.
3178 * \param [in] a1 - a given array.
3179 * \param [in] a2 - another given array.
3180 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3181 * The caller is to delete this result array using decrRef() as it is no more
3183 * \throw If either \a a1 or \a a2 is NULL.
3184 * \throw If any given array is not allocated.
3185 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3186 * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
3188 DataArrayDouble *DataArrayDouble::Dot(const DataArrayDouble *a1, const DataArrayDouble *a2)
3191 throw INTERP_KERNEL::Exception("DataArrayDouble::Dot : input DataArrayDouble instance is NULL !");
3192 a1->checkAllocated();
3193 a2->checkAllocated();
3194 std::size_t nbOfComp(a1->getNumberOfComponents());
3195 if(nbOfComp!=a2->getNumberOfComponents())
3196 throw INTERP_KERNEL::Exception("Nb of components mismatch for array Dot !");
3197 std::size_t nbOfTuple(a1->getNumberOfTuples());
3198 if(nbOfTuple!=a2->getNumberOfTuples())
3199 throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Dot !");
3200 DataArrayDouble *ret=DataArrayDouble::New();
3201 ret->alloc(nbOfTuple,1);
3202 double *retPtr=ret->getPointer();
3203 const double *a1Ptr=a1->begin(),*a2Ptr(a2->begin());
3204 for(std::size_t i=0;i<nbOfTuple;i++)
3207 for(std::size_t j=0;j<nbOfComp;j++)
3208 sum+=a1Ptr[i*nbOfComp+j]*a2Ptr[i*nbOfComp+j];
3211 ret->setInfoOnComponent(0,a1->getInfoOnComponent(0));
3212 ret->setName(a1->getName());
3217 * Returns a new DataArrayDouble containing a cross product of two given arrays, so that
3218 * the i-th tuple of the result array contains 3 components of a vector which is a cross
3219 * product of two vectors defined by the i-th tuples of given arrays.
3220 * Info on components is copied from the first of the given arrays.
3221 * Number of tuples in the given arrays must be the same.
3222 * Number of components in the given arrays must be 3.
3223 * \param [in] a1 - a given array.
3224 * \param [in] a2 - another given array.
3225 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3226 * The caller is to delete this result array using decrRef() as it is no more
3228 * \throw If either \a a1 or \a a2 is NULL.
3229 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3230 * \throw If \a a1->getNumberOfComponents() != 3
3231 * \throw If \a a2->getNumberOfComponents() != 3
3233 DataArrayDouble *DataArrayDouble::CrossProduct(const DataArrayDouble *a1, const DataArrayDouble *a2)
3236 throw INTERP_KERNEL::Exception("DataArrayDouble::CrossProduct : input DataArrayDouble instance is NULL !");
3237 std::size_t nbOfComp(a1->getNumberOfComponents());
3238 if(nbOfComp!=a2->getNumberOfComponents())
3239 throw INTERP_KERNEL::Exception("Nb of components mismatch for array crossProduct !");
3241 throw INTERP_KERNEL::Exception("Nb of components must be equal to 3 for array crossProduct !");
3242 std::size_t nbOfTuple(a1->getNumberOfTuples());
3243 if(nbOfTuple!=a2->getNumberOfTuples())
3244 throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array crossProduct !");
3245 DataArrayDouble *ret=DataArrayDouble::New();
3246 ret->alloc(nbOfTuple,3);
3247 double *retPtr=ret->getPointer();
3248 const double *a1Ptr(a1->begin()),*a2Ptr(a2->begin());
3249 for(std::size_t i=0;i<nbOfTuple;i++)
3251 retPtr[3*i]=a1Ptr[3*i+1]*a2Ptr[3*i+2]-a1Ptr[3*i+2]*a2Ptr[3*i+1];
3252 retPtr[3*i+1]=a1Ptr[3*i+2]*a2Ptr[3*i]-a1Ptr[3*i]*a2Ptr[3*i+2];
3253 retPtr[3*i+2]=a1Ptr[3*i]*a2Ptr[3*i+1]-a1Ptr[3*i+1]*a2Ptr[3*i];
3255 ret->copyStringInfoFrom(*a1);
3260 * Returns a new DataArrayDouble containing maximal values of two given arrays.
3261 * Info on components is copied from the first of the given arrays.
3262 * Number of tuples and components in the given arrays must be the same.
3263 * \param [in] a1 - an array to compare values with another one.
3264 * \param [in] a2 - another array to compare values with the first one.
3265 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3266 * The caller is to delete this result array using decrRef() as it is no more
3268 * \throw If either \a a1 or \a a2 is NULL.
3269 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3270 * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
3272 DataArrayDouble *DataArrayDouble::Max(const DataArrayDouble *a1, const DataArrayDouble *a2)
3275 throw INTERP_KERNEL::Exception("DataArrayDouble::Max : input DataArrayDouble instance is NULL !");
3276 std::size_t nbOfComp(a1->getNumberOfComponents());
3277 if(nbOfComp!=a2->getNumberOfComponents())
3278 throw INTERP_KERNEL::Exception("Nb of components mismatch for array Max !");
3279 std::size_t nbOfTuple(a1->getNumberOfTuples());
3280 if(nbOfTuple!=a2->getNumberOfTuples())
3281 throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Max !");
3282 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
3283 ret->alloc(nbOfTuple,nbOfComp);
3284 double *retPtr(ret->getPointer());
3285 const double *a1Ptr(a1->begin()),*a2Ptr(a2->begin());
3286 std::size_t nbElem(nbOfTuple*nbOfComp);
3287 for(std::size_t i=0;i<nbElem;i++)
3288 retPtr[i]=std::max(a1Ptr[i],a2Ptr[i]);
3289 ret->copyStringInfoFrom(*a1);
3294 * Returns a new DataArrayDouble containing minimal values of two given arrays.
3295 * Info on components is copied from the first of the given arrays.
3296 * Number of tuples and components in the given arrays must be the same.
3297 * \param [in] a1 - an array to compare values with another one.
3298 * \param [in] a2 - another array to compare values with the first one.
3299 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3300 * The caller is to delete this result array using decrRef() as it is no more
3302 * \throw If either \a a1 or \a a2 is NULL.
3303 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3304 * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
3306 DataArrayDouble *DataArrayDouble::Min(const DataArrayDouble *a1, const DataArrayDouble *a2)
3309 throw INTERP_KERNEL::Exception("DataArrayDouble::Min : input DataArrayDouble instance is NULL !");
3310 std::size_t nbOfComp(a1->getNumberOfComponents());
3311 if(nbOfComp!=a2->getNumberOfComponents())
3312 throw INTERP_KERNEL::Exception("Nb of components mismatch for array min !");
3313 std::size_t nbOfTuple(a1->getNumberOfTuples());
3314 if(nbOfTuple!=a2->getNumberOfTuples())
3315 throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array min !");
3316 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
3317 ret->alloc(nbOfTuple,nbOfComp);
3318 double *retPtr(ret->getPointer());
3319 const double *a1Ptr(a1->begin()),*a2Ptr(a2->begin());
3320 std::size_t nbElem(nbOfTuple*nbOfComp);
3321 for(std::size_t i=0;i<nbElem;i++)
3322 retPtr[i]=std::min(a1Ptr[i],a2Ptr[i]);
3323 ret->copyStringInfoFrom(*a1);
3328 * Returns a new DataArrayDouble that is the result of pow of two given arrays. There are 3
3331 * \param [in] a1 - an array to pow up.
3332 * \param [in] a2 - another array to sum up.
3333 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3334 * The caller is to delete this result array using decrRef() as it is no more
3336 * \throw If either \a a1 or \a a2 is NULL.
3337 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3338 * \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
3339 * \throw If there is a negative value in \a a1.
3341 DataArrayDouble *DataArrayDouble::Pow(const DataArrayDouble *a1, const DataArrayDouble *a2)
3344 throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : at least one of input instances is null !");
3345 int nbOfTuple=a1->getNumberOfTuples();
3346 int nbOfTuple2=a2->getNumberOfTuples();
3347 int nbOfComp=a1->getNumberOfComponents();
3348 int nbOfComp2=a2->getNumberOfComponents();
3349 if(nbOfTuple!=nbOfTuple2)
3350 throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of tuples mismatches !");
3351 if(nbOfComp!=1 || nbOfComp2!=1)
3352 throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of components of both arrays must be equal to 1 !");
3353 MCAuto<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbOfTuple,1);
3354 const double *ptr1(a1->begin()),*ptr2(a2->begin());
3355 double *ptr=ret->getPointer();
3356 for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
3360 *ptr=pow(*ptr1,*ptr2);
3364 std::ostringstream oss; oss << "DataArrayDouble::Pow : on tuple #" << i << " of a1 value is < 0 (" << *ptr1 << ") !";
3365 throw INTERP_KERNEL::Exception(oss.str().c_str());
3372 * Apply pow on values of another DataArrayDouble to values of \a this one.
3374 * \param [in] other - an array to pow to \a this one.
3375 * \throw If \a other is NULL.
3376 * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
3377 * \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
3378 * \throw If there is a negative value in \a this.
3380 void DataArrayDouble::powEqual(const DataArrayDouble *other)
3383 throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : input instance is null !");
3384 int nbOfTuple=getNumberOfTuples();
3385 int nbOfTuple2=other->getNumberOfTuples();
3386 int nbOfComp=getNumberOfComponents();
3387 int nbOfComp2=other->getNumberOfComponents();
3388 if(nbOfTuple!=nbOfTuple2)
3389 throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of tuples mismatches !");
3390 if(nbOfComp!=1 || nbOfComp2!=1)
3391 throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of components of both arrays must be equal to 1 !");
3392 double *ptr=getPointer();
3393 const double *ptrc=other->begin();
3394 for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
3397 *ptr=pow(*ptr,*ptrc);
3400 std::ostringstream oss; oss << "DataArrayDouble::powEqual : on tuple #" << i << " of this value is < 0 (" << *ptr << ") !";
3401 throw INTERP_KERNEL::Exception(oss.str().c_str());
3408 * This method is \b NOT wrapped into python because it can be useful only for performance reasons in C++ context.
3409 * All values in \a this must be 0. or 1. within eps error. 0 means false, 1 means true.
3410 * If an another value than 0 or 1 appear (within eps precision) an INTERP_KERNEL::Exception will be thrown.
3412 * \throw if \a this is not allocated.
3413 * \throw if \a this has not exactly one component.
3415 std::vector<bool> DataArrayDouble::toVectorOfBool(double eps) const
3418 if(getNumberOfComponents()!=1)
3419 throw INTERP_KERNEL::Exception("DataArrayDouble::toVectorOfBool : must be applied on single component array !");
3420 int nbt(getNumberOfTuples());
3421 std::vector<bool> ret(nbt);
3422 const double *pt(begin());
3423 for(int i=0;i<nbt;i++)
3427 else if(fabs(pt[i]-1.)<eps)
3431 std::ostringstream oss; oss << "DataArrayDouble::toVectorOfBool : the tuple #" << i << " has value " << pt[i] << " is invalid ! must be 0. or 1. !";
3432 throw INTERP_KERNEL::Exception(oss.str().c_str());
3439 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
3442 void DataArrayDouble::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
3447 tinyInfo[0]=getNumberOfTuples();
3448 tinyInfo[1]=getNumberOfComponents();
3458 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
3461 void DataArrayDouble::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
3465 int nbOfCompo=getNumberOfComponents();
3466 tinyInfo.resize(nbOfCompo+1);
3467 tinyInfo[0]=getName();
3468 for(int i=0;i<nbOfCompo;i++)
3469 tinyInfo[i+1]=getInfoOnComponent(i);
3474 tinyInfo[0]=getName();
3479 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
3480 * This method returns if a feeding is needed.
3482 bool DataArrayDouble::resizeForUnserialization(const std::vector<int>& tinyInfoI)
3484 int nbOfTuple=tinyInfoI[0];
3485 int nbOfComp=tinyInfoI[1];
3486 if(nbOfTuple!=-1 || nbOfComp!=-1)
3488 alloc(nbOfTuple,nbOfComp);
3495 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
3497 void DataArrayDouble::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
3499 setName(tinyInfoS[0]);
3502 int nbOfCompo=getNumberOfComponents();
3503 for(int i=0;i<nbOfCompo;i++)
3504 setInfoOnComponent(i,tinyInfoS[i+1]);
3509 * Low static method that operates 3D rotation of 'nbNodes' 3D nodes whose coordinates are arranged in \a coordsIn
3510 * around an axe ( \a center, \a vect) and with angle \a angle.
3512 void DataArrayDouble::Rotate3DAlg(const double *center, const double *vect, double angle, int nbNodes, const double *coordsIn, double *coordsOut)
3514 if(!center || !vect)
3515 throw INTERP_KERNEL::Exception("DataArrayDouble::Rotate3DAlg : null vector in input !");
3516 double sina(sin(angle));
3517 double cosa(cos(angle));
3518 double vectorNorm[3];
3520 double matrixTmp[9];
3521 double norm(sqrt(vect[0]*vect[0]+vect[1]*vect[1]+vect[2]*vect[2]));
3522 if(norm<std::numeric_limits<double>::min())
3523 throw INTERP_KERNEL::Exception("DataArrayDouble::Rotate3DAlg : magnitude of input vector is too close of 0. !");
3524 std::transform(vect,vect+3,vectorNorm,std::bind2nd(std::multiplies<double>(),1/norm));
3525 //rotation matrix computation
3526 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;
3527 matrixTmp[0]=vectorNorm[0]*vectorNorm[0]; matrixTmp[1]=vectorNorm[0]*vectorNorm[1]; matrixTmp[2]=vectorNorm[0]*vectorNorm[2];
3528 matrixTmp[3]=vectorNorm[1]*vectorNorm[0]; matrixTmp[4]=vectorNorm[1]*vectorNorm[1]; matrixTmp[5]=vectorNorm[1]*vectorNorm[2];
3529 matrixTmp[6]=vectorNorm[2]*vectorNorm[0]; matrixTmp[7]=vectorNorm[2]*vectorNorm[1]; matrixTmp[8]=vectorNorm[2]*vectorNorm[2];
3530 std::transform(matrixTmp,matrixTmp+9,matrixTmp,std::bind2nd(std::multiplies<double>(),1-cosa));
3531 std::transform(matrix,matrix+9,matrixTmp,matrix,std::plus<double>());
3532 matrixTmp[0]=0.; matrixTmp[1]=-vectorNorm[2]; matrixTmp[2]=vectorNorm[1];
3533 matrixTmp[3]=vectorNorm[2]; matrixTmp[4]=0.; matrixTmp[5]=-vectorNorm[0];
3534 matrixTmp[6]=-vectorNorm[1]; matrixTmp[7]=vectorNorm[0]; matrixTmp[8]=0.;
3535 std::transform(matrixTmp,matrixTmp+9,matrixTmp,std::bind2nd(std::multiplies<double>(),sina));
3536 std::transform(matrix,matrix+9,matrixTmp,matrix,std::plus<double>());
3537 //rotation matrix computed.
3539 for(int i=0; i<nbNodes; i++)
3541 std::transform(coordsIn+i*3,coordsIn+(i+1)*3,center,tmp,std::minus<double>());
3542 coordsOut[i*3]=matrix[0]*tmp[0]+matrix[1]*tmp[1]+matrix[2]*tmp[2]+center[0];
3543 coordsOut[i*3+1]=matrix[3]*tmp[0]+matrix[4]*tmp[1]+matrix[5]*tmp[2]+center[1];
3544 coordsOut[i*3+2]=matrix[6]*tmp[0]+matrix[7]*tmp[1]+matrix[8]*tmp[2]+center[2];
3548 void DataArrayDouble::Symmetry3DPlane(const double point[3], const double normalVector[3], int nbNodes, const double *coordsIn, double *coordsOut)
3550 double matrix[9],matrix2[9],matrix3[9];
3551 double vect[3],crossVect[3];
3552 INTERP_KERNEL::orthogonalVect3(normalVector,vect);
3553 crossVect[0]=normalVector[1]*vect[2]-normalVector[2]*vect[1];
3554 crossVect[1]=normalVector[2]*vect[0]-normalVector[0]*vect[2];
3555 crossVect[2]=normalVector[0]*vect[1]-normalVector[1]*vect[0];
3556 double nv(INTERP_KERNEL::norm<3>(vect)),ni(INTERP_KERNEL::norm<3>(normalVector)),nc(INTERP_KERNEL::norm<3>(crossVect));
3557 matrix[0]=vect[0]/nv; matrix[1]=crossVect[0]/nc; matrix[2]=-normalVector[0]/ni;
3558 matrix[3]=vect[1]/nv; matrix[4]=crossVect[1]/nc; matrix[5]=-normalVector[1]/ni;
3559 matrix[6]=vect[2]/nv; matrix[7]=crossVect[2]/nc; matrix[8]=-normalVector[2]/ni;
3560 matrix2[0]=vect[0]/nv; matrix2[1]=vect[1]/nv; matrix2[2]=vect[2]/nv;
3561 matrix2[3]=crossVect[0]/nc; matrix2[4]=crossVect[1]/nc; matrix2[5]=crossVect[2]/nc;
3562 matrix2[6]=normalVector[0]/ni; matrix2[7]=normalVector[1]/ni; matrix2[8]=normalVector[2]/ni;
3563 for(int i=0;i<3;i++)
3564 for(int j=0;j<3;j++)
3567 for(int k=0;k<3;k++)
3568 val+=matrix[3*i+k]*matrix2[3*k+j];
3571 //rotation matrix computed.
3573 for(int i=0; i<nbNodes; i++)
3575 std::transform(coordsIn+i*3,coordsIn+(i+1)*3,point,tmp,std::minus<double>());
3576 coordsOut[i*3]=matrix3[0]*tmp[0]+matrix3[1]*tmp[1]+matrix3[2]*tmp[2]+point[0];
3577 coordsOut[i*3+1]=matrix3[3]*tmp[0]+matrix3[4]*tmp[1]+matrix3[5]*tmp[2]+point[1];
3578 coordsOut[i*3+2]=matrix3[6]*tmp[0]+matrix3[7]*tmp[1]+matrix3[8]*tmp[2]+point[2];
3582 void DataArrayDouble::GiveBaseForPlane(const double normalVector[3], double baseOfPlane[9])
3584 double vect[3],crossVect[3];
3585 INTERP_KERNEL::orthogonalVect3(normalVector,vect);
3586 crossVect[0]=normalVector[1]*vect[2]-normalVector[2]*vect[1];
3587 crossVect[1]=normalVector[2]*vect[0]-normalVector[0]*vect[2];
3588 crossVect[2]=normalVector[0]*vect[1]-normalVector[1]*vect[0];
3589 double nv(INTERP_KERNEL::norm<3>(vect)),ni(INTERP_KERNEL::norm<3>(normalVector)),nc(INTERP_KERNEL::norm<3>(crossVect));
3590 baseOfPlane[0]=vect[0]/nv; baseOfPlane[1]=vect[1]/nv; baseOfPlane[2]=vect[2]/nv;
3591 baseOfPlane[3]=crossVect[0]/nc; baseOfPlane[4]=crossVect[1]/nc; baseOfPlane[5]=crossVect[2]/nc;
3592 baseOfPlane[6]=normalVector[0]/ni; baseOfPlane[7]=normalVector[1]/ni; baseOfPlane[8]=normalVector[2]/ni;
3596 * \param [in] seg2 : coordinates of input seg2 expected to have spacedim==2
3597 * \param [in] tri3 : coordinates of input tri3 also expected to have spacedim==2
3598 * \param [out] coeffs : the result of integration normalized to 1. along \a seg2 inside tri3 sorted by the node id of \a tri3
3599 * \param [out] length : the length of seg2. That is too say the length of integration
3601 void DataArrayDouble::ComputeIntegralOfSeg2IntoTri3(const double seg2[4], const double tri3[6], double coeffs[3], double& length)
3603 length=INTERP_KERNEL::norme_vecteur(seg2,seg2+2);
3605 INTERP_KERNEL::mid_of_seg2(seg2,seg2+2,mid);
3606 INTERP_KERNEL::barycentric_coords<2>(tri3,mid,coeffs); // integral along seg2 is equal to value at the center of SEG2 !
3610 * Low static method that operates 3D rotation of \a nbNodes 3D nodes whose coordinates are arranged in \a coords
3611 * around the center point \a center and with angle \a angle.
3613 void DataArrayDouble::Rotate2DAlg(const double *center, double angle, int nbNodes, const double *coordsIn, double *coordsOut)
3615 double cosa=cos(angle);
3616 double sina=sin(angle);
3618 matrix[0]=cosa; matrix[1]=-sina; matrix[2]=sina; matrix[3]=cosa;
3620 for(int i=0; i<nbNodes; i++)
3622 std::transform(coordsIn+i*2,coordsIn+(i+1)*2,center,tmp,std::minus<double>());
3623 coordsOut[i*2]=matrix[0]*tmp[0]+matrix[1]*tmp[1]+center[0];
3624 coordsOut[i*2+1]=matrix[2]*tmp[0]+matrix[3]*tmp[1]+center[1];
3628 DataArrayDoubleIterator::DataArrayDoubleIterator(DataArrayDouble *da):DataArrayIterator<double>(da)
3632 DataArrayDoubleTuple::DataArrayDoubleTuple(double *pt, int nbOfComp):DataArrayTuple<double>(pt,nbOfComp)
3637 std::string DataArrayDoubleTuple::repr() const
3639 std::ostringstream oss; oss.precision(17); oss << "(";
3640 for(int i=0;i<_nb_of_compo-1;i++)
3641 oss << _pt[i] << ", ";
3642 oss << _pt[_nb_of_compo-1] << ")";
3646 double DataArrayDoubleTuple::doubleValue() const
3648 return this->zeValue();
3652 * This method returns a newly allocated instance the caller should dealed with by a MEDCoupling::DataArrayDouble::decrRef.
3653 * This method performs \b no copy of data. The content is only referenced using MEDCoupling::DataArrayDouble::useArray with ownership set to \b false.
3654 * 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
3655 * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
3657 DataArrayDouble *DataArrayDoubleTuple::buildDADouble(int nbOfTuples, int nbOfCompo) const
3659 return this->buildDA(nbOfTuples,nbOfCompo);
3663 * Returns the only one value in \a this, if and only if number of elements
3664 * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
3665 * \return double - the sole value stored in \a this array.
3666 * \throw If at least one of conditions stated above is not fulfilled.
3668 int DataArrayInt::intValue() const
3672 if(getNbOfElems()==1)
3674 return *getConstPointer();
3677 throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is allocated but number of elements is not equal to 1 !");
3680 throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is not allocated !");
3684 * Returns a full copy of \a this. For more info on copying data arrays see
3685 * \ref MEDCouplingArrayBasicsCopyDeep.
3686 * \return DataArrayInt * - a new instance of DataArrayInt.
3688 DataArrayInt32 *DataArrayInt32::deepCopy() const
3690 return new DataArrayInt32(*this);
3694 * Computes distribution of values of \a this one-dimensional array between given value
3695 * ranges (casts). This method is typically useful for entity number splitting by types,
3697 * \warning The values contained in \a arrBg should be sorted ascendently. No
3698 * check of this is be done. If not, the result is not warranted.
3699 * \param [in] arrBg - the array of ascending values defining the value ranges. The i-th
3700 * value of \a arrBg (\a arrBg[ i ]) gives the lowest value of the i-th range,
3701 * and the greatest value of the i-th range equals to \a arrBg[ i+1 ] - 1. \a
3702 * arrBg containing \a n values defines \a n-1 ranges. The last value of \a arrBg
3703 * should be more than every value in \a this array.
3704 * \param [in] arrEnd - specifies the end of the array \a arrBg, so that
3705 * the last value of \a arrBg is \a arrEnd[ -1 ].
3706 * \param [out] castArr - a new instance of DataArrayInt, of same size as \a this array
3707 * (same number of tuples and components), the caller is to delete
3708 * using decrRef() as it is no more needed.
3709 * This array contains indices of ranges for every value of \a this array. I.e.
3710 * the i-th value of \a castArr gives the index of range the i-th value of \a this
3711 * belongs to. Or, in other words, this parameter contains for each tuple in \a
3712 * this in which cast it holds.
3713 * \param [out] rankInsideCast - a new instance of DataArrayInt, of same size as \a this
3714 * array, the caller is to delete using decrRef() as it is no more needed.
3715 * This array contains ranks of values of \a this array within ranges
3716 * they belongs to. I.e. the i-th value of \a rankInsideCast gives the rank of
3717 * the i-th value of \a this array within the \a castArr[ i ]-th range, to which
3718 * the i-th value of \a this belongs to. Or, in other words, this param contains
3719 * for each tuple its rank inside its cast. The rank is computed as difference
3720 * between the value and the lowest value of range.
3721 * \param [out] castsPresent - a new instance of DataArrayInt, containing indices of
3722 * ranges (casts) to which at least one value of \a this array belongs.
3723 * Or, in other words, this param contains the casts that \a this contains.
3724 * The caller is to delete this array using decrRef() as it is no more needed.
3726 * \b Example: If \a this contains [6,5,0,3,2,7,8,1,4] and \a arrBg contains [0,4,9] then
3727 * the output of this method will be :
3728 * - \a castArr : [1,1,0,0,0,1,1,0,1]
3729 * - \a rankInsideCast: [2,1,0,3,2,3,4,1,0]
3730 * - \a castsPresent : [0,1]
3732 * I.e. values of \a this array belong to 2 ranges: #0 and #1. Value 6 belongs to the
3733 * range #1 and its rank within this range is 2; etc.
3735 * \throw If \a this->getNumberOfComponents() != 1.
3736 * \throw If \a arrEnd - arrBg < 2.
3737 * \throw If any value of \a this is not less than \a arrEnd[-1].
3739 void DataArrayInt::splitByValueRange(const int *arrBg, const int *arrEnd,
3740 DataArrayInt *& castArr, DataArrayInt *& rankInsideCast, DataArrayInt *& castsPresent) const
3743 if(getNumberOfComponents()!=1)
3744 throw INTERP_KERNEL::Exception("Call splitByValueRange method on DataArrayInt with only one component, you can call 'rearrange' method before !");
3745 int nbOfTuples=getNumberOfTuples();
3746 std::size_t nbOfCast=std::distance(arrBg,arrEnd);
3748 throw INTERP_KERNEL::Exception("DataArrayInt::splitByValueRange : The input array giving the cast range values should be of size >=2 !");
3750 const int *work=getConstPointer();
3751 typedef std::reverse_iterator<const int *> rintstart;
3752 rintstart bg(arrEnd);//OK no problem because size of 'arr' is greater or equal 2
3753 rintstart end2(arrBg);
3754 MCAuto<DataArrayInt> ret1=DataArrayInt::New();
3755 MCAuto<DataArrayInt> ret2=DataArrayInt::New();
3756 MCAuto<DataArrayInt> ret3=DataArrayInt::New();
3757 ret1->alloc(nbOfTuples,1);
3758 ret2->alloc(nbOfTuples,1);
3759 int *ret1Ptr=ret1->getPointer();
3760 int *ret2Ptr=ret2->getPointer();
3761 std::set<std::size_t> castsDetected;
3762 for(int i=0;i<nbOfTuples;i++)
3764 rintstart res=std::find_if(bg,end2,std::bind2nd(std::less_equal<int>(), work[i]));
3765 std::size_t pos=std::distance(bg,res);
3766 std::size_t pos2=nbOfCast-pos;
3769 ret1Ptr[i]=(int)pos2;
3770 ret2Ptr[i]=work[i]-arrBg[pos2];
3771 castsDetected.insert(pos2);
3775 std::ostringstream oss; oss << "DataArrayInt::splitByValueRange : At rank #" << i << " the value is " << work[i] << " should be in [0," << *bg << ") !";
3776 throw INTERP_KERNEL::Exception(oss.str().c_str());
3779 ret3->alloc((int)castsDetected.size(),1);
3780 std::copy(castsDetected.begin(),castsDetected.end(),ret3->getPointer());
3781 castArr=ret1.retn();
3782 rankInsideCast=ret2.retn();
3783 castsPresent=ret3.retn();
3787 * 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 ).
3788 * 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 ).
3789 * This method works only if \a this is allocated and single component. If not an exception will be thrown.
3791 * \param [out] strt - the start of the range (included) if true is returned.
3792 * \param [out] sttoopp - the end of the range (not included) if true is returned.
3793 * \param [out] stteepp - the step of the range if true is returned.
3794 * \return the verdict of the check.
3796 * \sa DataArray::GetNumberOfItemGivenBES
3798 bool DataArrayInt::isRange(int& strt, int& sttoopp, int& stteepp) const
3801 if(getNumberOfComponents()!=1)
3802 throw INTERP_KERNEL::Exception("DataArrayInt::isRange : this must be single component array !");
3803 int nbTuples(getNumberOfTuples());
3805 { strt=0; sttoopp=0; stteepp=1; return true; }
3806 const int *pt(begin());
3809 { sttoopp=strt+1; stteepp=1; return true; }
3810 strt=*pt; sttoopp=pt[nbTuples-1];
3816 int a(sttoopp-1-strt),tmp(strt);
3817 if(a%(nbTuples-1)!=0)
3819 stteepp=a/(nbTuples-1);
3820 for(int i=0;i<nbTuples;i++,tmp+=stteepp)
3828 int a(strt-sttoopp-1),tmp(strt);
3829 if(a%(nbTuples-1)!=0)
3831 stteepp=-(a/(nbTuples-1));
3832 for(int i=0;i<nbTuples;i++,tmp+=stteepp)
3840 * Creates a one-dimensional DataArrayInt (\a res) whose contents are computed from
3841 * values of \a this (\a a) and the given (\a indArr) arrays as follows:
3842 * \a res[ \a indArr[ \a a[ i ]]] = i. I.e. for each value in place i \a v = \a a[ i ],
3843 * new value in place \a indArr[ \a v ] is i.
3844 * \param [in] indArrBg - the array holding indices within the result array to assign
3845 * indices of values of \a this array pointing to values of \a indArrBg.
3846 * \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
3847 * the last value of \a indArrBg is \a indArrEnd[ -1 ].
3848 * \return DataArrayInt * - the new instance of DataArrayInt.
3849 * The caller is to delete this result array using decrRef() as it is no more
3851 * \throw If \a this->getNumberOfComponents() != 1.
3852 * \throw If any value of \a this array is not a valid index for \a indArrBg array.
3853 * \throw If any value of \a indArrBg is not a valid index for \a this array.
3855 DataArrayInt *DataArrayInt::transformWithIndArrR(const int *indArrBg, const int *indArrEnd) const
3858 if(getNumberOfComponents()!=1)
3859 throw INTERP_KERNEL::Exception("Call transformWithIndArrR method on DataArrayInt with only one component, you can call 'rearrange' method before !");
3860 int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
3861 int nbOfTuples=getNumberOfTuples();
3862 const int *pt=getConstPointer();
3863 MCAuto<DataArrayInt> ret=DataArrayInt::New();
3864 ret->alloc(nbOfTuples,1);
3865 ret->fillWithValue(-1);
3866 int *tmp=ret->getPointer();
3867 for(int i=0;i<nbOfTuples;i++,pt++)
3869 if(*pt>=0 && *pt<nbElemsIn)
3871 int pos=indArrBg[*pt];
3872 if(pos>=0 && pos<nbOfTuples)
3876 std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value of new pos is " << pos << " ( indArrBg[" << *pt << "]) ! Should be in [0," << nbOfTuples << ") !";
3877 throw INTERP_KERNEL::Exception(oss.str().c_str());
3882 std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn << " !";
3883 throw INTERP_KERNEL::Exception(oss.str().c_str());
3890 * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
3891 * from values of \a this array, which is supposed to contain a renumbering map in
3892 * "Old to New" mode. The result array contains a renumbering map in "New to Old" mode.
3893 * To know how to use the renumbering maps see \ref numbering.
3894 * \param [in] newNbOfElem - the number of tuples in the result array.
3895 * \return DataArrayInt * - the new instance of DataArrayInt.
3896 * The caller is to delete this result array using decrRef() as it is no more
3899 * \if ENABLE_EXAMPLES
3900 * \ref cpp_mcdataarrayint_invertarrayo2n2n2o "Here is a C++ example".<br>
3901 * \ref py_mcdataarrayint_invertarrayo2n2n2o "Here is a Python example".
3904 DataArrayInt *DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const
3906 MCAuto<DataArrayInt> ret(DataArrayInt::New());
3907 ret->alloc(newNbOfElem,1);
3908 int nbOfOldNodes(this->getNumberOfTuples());
3909 const int *old2New(begin());
3910 int *pt(ret->getPointer());
3911 for(int i=0;i!=nbOfOldNodes;i++)
3913 int newp(old2New[i]);
3916 if(newp>=0 && newp<newNbOfElem)
3920 std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2O : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
3921 throw INTERP_KERNEL::Exception(oss.str().c_str());
3929 * This method is similar to DataArrayInt::invertArrayO2N2N2O except that
3930 * 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]
3932 DataArrayInt *DataArrayInt::invertArrayO2N2N2OBis(int newNbOfElem) const
3934 MCAuto<DataArrayInt> ret=DataArrayInt::New();
3935 ret->alloc(newNbOfElem,1);
3936 int nbOfOldNodes=getNumberOfTuples();
3937 const int *old2New=getConstPointer();
3938 int *pt=ret->getPointer();
3939 for(int i=nbOfOldNodes-1;i>=0;i--)
3941 int newp(old2New[i]);
3944 if(newp>=0 && newp<newNbOfElem)
3948 std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2OBis : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
3949 throw INTERP_KERNEL::Exception(oss.str().c_str());
3957 * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
3958 * from values of \a this array, which is supposed to contain a renumbering map in
3959 * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
3960 * To know how to use the renumbering maps see \ref numbering.
3961 * \param [in] newNbOfElem - the number of tuples in the result array.
3962 * \return DataArrayInt * - the new instance of DataArrayInt.
3963 * The caller is to delete this result array using decrRef() as it is no more
3966 * \if ENABLE_EXAMPLES
3967 * \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
3969 * \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
3970 * \sa invertArrayN2O2O2NOptimized
3973 DataArrayInt *DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const
3976 MCAuto<DataArrayInt> ret=DataArrayInt::New();
3977 ret->alloc(oldNbOfElem,1);
3978 const int *new2Old=getConstPointer();
3979 int *pt=ret->getPointer();
3980 std::fill(pt,pt+oldNbOfElem,-1);
3981 int nbOfNewElems=getNumberOfTuples();
3982 for(int i=0;i<nbOfNewElems;i++)
3985 if(v>=0 && v<oldNbOfElem)
3989 std::ostringstream oss; oss << "DataArrayInt::invertArrayN2O2O2N : in new id #" << i << " old value is " << v << " expected to be in [0," << oldNbOfElem << ") !";
3990 throw INTERP_KERNEL::Exception(oss.str().c_str());
3997 * Creates a map, whose contents are computed
3998 * from values of \a this array, which is supposed to contain a renumbering map in
3999 * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
4000 * To know how to use the renumbering maps see \ref numbering.
4001 * \param [in] newNbOfElem - the number of tuples in the result array.
4002 * \return MapII - the new instance of Map.
4004 * \if ENABLE_EXAMPLES
4005 * \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
4007 * \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
4008 * \sa invertArrayN2O2O2N, giveN2OOptimized, MEDCouplingPointSet::renumberNodesInConn
4011 MCAuto< MapKeyVal<int> > DataArrayInt32::invertArrayN2O2O2NOptimized() const
4014 if(getNumberOfComponents()!=1)
4015 throw INTERP_KERNEL::Exception("DataArrayInt32::invertArrayN2O2O2NOptimized : single component expected !");
4016 MCAuto< MapKeyVal<int> > ret(MapKeyVal<int>::New());
4017 std::map<int,int>& m(ret->data());
4018 const int *new2Old(begin());
4019 std::size_t nbOfNewElems(this->getNumberOfTuples());
4020 for(std::size_t i=0;i<nbOfNewElems;i++)
4029 * Creates a map, whose contents are computed
4030 * from values of \a this array, which is supposed to contain a renumbering map in
4031 * "New to Old" mode. The result array contains a renumbering map in "New to Old" mode as C++ map for performance reasons.
4033 * \sa invertArrayN2O2O2NOptimized, MEDCouplingPointSet::renumberNodesInConn
4035 MCAuto< MapKeyVal<int> > DataArrayInt32::giveN2OOptimized() const
4038 if(getNumberOfComponents()!=1)
4039 throw INTERP_KERNEL::Exception("DataArrayInt32::giveN2OOptimized : single component expected !");
4040 MCAuto< MapKeyVal<int> > ret(MapKeyVal<int>::New());
4041 std::map<int,int>& m(ret->data());
4042 const int *new2Old(begin());
4043 std::size_t nbOfNewElems(this->getNumberOfTuples());
4044 for(std::size_t i=0;i<nbOfNewElems;i++)
4053 * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode.
4054 * This map, if applied to \a this array, would make it sorted. For example, if
4055 * \a this array contents are [9,10,0,6,4,11,3,7] then the contents of the result array
4056 * are [5,6,0,3,2,7,1,4]; if this result array (\a res) is used as an argument in call
4057 * \a this->renumber(\a res) then the returned array contains [0,3,4,6,7,9,10,11].
4058 * This method is useful for renumbering (in MED file for example). For more info
4059 * on renumbering see \ref numbering.
4060 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4061 * array using decrRef() as it is no more needed.
4062 * \throw If \a this is not allocated.
4063 * \throw If \a this->getNumberOfComponents() != 1.
4064 * \throw If there are equal values in \a this array.
4066 DataArrayInt *DataArrayInt::checkAndPreparePermutation() const
4069 if(getNumberOfComponents()!=1)
4070 throw INTERP_KERNEL::Exception("DataArrayInt::checkAndPreparePermutation : number of components must == 1 !");
4071 int nbTuples=getNumberOfTuples();
4072 const int *pt=getConstPointer();
4073 int *pt2=CheckAndPreparePermutation(pt,pt+nbTuples);
4074 DataArrayInt *ret=DataArrayInt::New();
4075 ret->useArray(pt2,true,DeallocType::C_DEALLOC,nbTuples,1);
4080 * 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
4081 * input array \a ids2.
4082 * \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.
4083 * 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
4085 * In case of success both assertion will be true (no throw) :
4086 * \c ids1->renumber(ret)->isEqual(ids2) where \a ret is the return of this method.
4087 * \c ret->transformWithIndArr(ids2)->isEqual(ids1)
4090 * - \a ids1 : [3,1,103,4,6,10,-7,205]
4091 * - \a ids2 : [-7,1,205,10,6,3,103,4]
4092 * - \a return is : [5,1,6,7,4,3,0,2] because ids2[5]==ids1[0], ids2[1]==ids1[1], ids2[6]==ids1[2]...
4094 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4095 * array using decrRef() as it is no more needed.
4096 * \throw If either ids1 or ids2 is null not allocated or not with one components.
4098 * \sa DataArrayInt32::findIdForEach
4100 DataArrayInt *DataArrayInt::FindPermutationFromFirstToSecond(const DataArrayInt *ids1, const DataArrayInt *ids2)
4103 throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be not null !");
4104 if(!ids1->isAllocated() || !ids2->isAllocated())
4105 throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be allocated !");
4106 if(ids1->getNumberOfComponents()!=1 || ids2->getNumberOfComponents()!=1)
4107 throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays have exactly one component !");
4108 if(ids1->getNumberOfTuples()!=ids2->getNumberOfTuples())
4110 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 !";
4111 throw INTERP_KERNEL::Exception(oss.str().c_str());
4113 MCAuto<DataArrayInt> p1(ids1->deepCopy());
4114 MCAuto<DataArrayInt> p2(ids2->deepCopy());
4115 p1->sort(true); p2->sort(true);
4116 if(!p1->isEqualWithoutConsideringStr(*p2))
4117 throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two arrays are not lying on same ids ! Impossible to find a permutation between the 2 arrays !");
4118 p1=ids1->checkAndPreparePermutation();
4119 p2=ids2->checkAndPreparePermutation();
4120 p2=p2->invertArrayO2N2N2O(p2->getNumberOfTuples());
4121 p2=p2->selectByTupleIdSafe(p1->begin(),p1->end());
4126 * Returns two arrays describing a surjective mapping from \a this set of values (\a A)
4127 * onto a set of values of size \a targetNb (\a B). The surjective function is
4128 * \a B[ \a A[ i ]] = i. That is to say that for each \a id in [0,\a targetNb), where \a
4129 * targetNb < \a this->getNumberOfTuples(), there exists at least one tupleId (\a tid) so
4130 * that <em> this->getIJ( tid, 0 ) == id</em>. <br>
4131 * The first of out arrays returns indices of elements of \a this array, grouped by their
4132 * place in the set \a B. The second out array is the index of the first one; it shows how
4133 * many elements of \a A are mapped into each element of \a B. <br>
4135 * mapping and its usage in renumbering see \ref numbering. <br>
4137 * - \a this: [0,3,2,3,2,2,1,2]
4139 * - \a arr: [0, 6, 2,4,5,7, 1,3]
4140 * - \a arrI: [0,1,2,6,8]
4142 * This result means: <br>
4143 * the element of \a B 0 encounters within \a A once (\a arrI[ 0+1 ] - \a arrI[ 0 ]) and
4144 * its index within \a A is 0 ( \a arr[ 0:1 ] == \a arr[ \a arrI[ 0 ] : \a arrI[ 0+1 ]]);<br>
4145 * the element of \a B 2 encounters within \a A 4 times (\a arrI[ 2+1 ] - \a arrI[ 2 ]) and
4146 * its indices within \a A are [2,4,5,7] ( \a arr[ 2:6 ] == \a arr[ \a arrI[ 2 ] :
4147 * \a arrI[ 2+1 ]]); <br> etc.
4148 * \param [in] targetNb - the size of the set \a B. \a targetNb must be equal or more
4149 * than the maximal value of \a A.
4150 * \param [out] arr - a new instance of DataArrayInt returning indices of
4151 * elements of \a this, grouped by their place in the set \a B. The caller is to delete
4152 * this array using decrRef() as it is no more needed.
4153 * \param [out] arrI - a new instance of DataArrayInt returning size of groups of equal
4154 * elements of \a this. The caller is to delete this array using decrRef() as it
4155 * is no more needed.
4156 * \throw If \a this is not allocated.
4157 * \throw If \a this->getNumberOfComponents() != 1.
4158 * \throw If any value in \a this is more or equal to \a targetNb.
4160 void DataArrayInt::changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, DataArrayInt *&arrI) const
4163 if(getNumberOfComponents()!=1)
4164 throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : number of components must == 1 !");
4165 int nbOfTuples=getNumberOfTuples();
4166 MCAuto<DataArrayInt> ret(DataArrayInt::New());
4167 MCAuto<DataArrayInt> retI(DataArrayInt::New());
4168 retI->alloc(targetNb+1,1);
4169 const int *input=getConstPointer();
4170 std::vector< std::vector<int> > tmp(targetNb);
4171 for(int i=0;i<nbOfTuples;i++)
4174 if(tmp2>=0 && tmp2<targetNb)
4175 tmp[tmp2].push_back(i);
4178 std::ostringstream oss; oss << "DataArrayInt::changeSurjectiveFormat : At pos " << i << " presence of element " << tmp2 << " ! should be in [0," << targetNb << ") !";
4179 throw INTERP_KERNEL::Exception(oss.str().c_str());
4182 int *retIPtr=retI->getPointer();
4184 for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++,retIPtr++)
4185 retIPtr[1]=retIPtr[0]+(int)((*it1).size());
4186 if(nbOfTuples!=retI->getIJ(targetNb,0))
4187 throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : big problem should never happen !");
4188 ret->alloc(nbOfTuples,1);
4189 int *retPtr=ret->getPointer();
4190 for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++)
4191 retPtr=std::copy((*it1).begin(),(*it1).end(),retPtr);
4198 * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode computed
4199 * from a zip representation of a surjective format (returned e.g. by
4200 * \ref MEDCoupling::DataArrayDouble::findCommonTuples() "DataArrayDouble::findCommonTuples()"
4201 * for example). The result array minimizes the permutation. <br>
4202 * For more info on renumbering see \ref numbering. <br>
4204 * - \a nbOfOldTuples: 10
4205 * - \a arr : [0,3, 5,7,9]
4206 * - \a arrIBg : [0,2,5]
4207 * - \a newNbOfTuples: 7
4208 * - result array : [0,1,2,0,3,4,5,4,6,4]
4210 * \param [in] nbOfOldTuples - number of tuples in the initial array \a arr.
4211 * \param [in] arr - the array of tuple indices grouped by \a arrIBg array.
4212 * \param [in] arrIBg - the array dividing all indices stored in \a arr into groups of
4213 * (indices of) equal values. Its every element (except the last one) points to
4214 * the first element of a group of equal values.
4215 * \param [in] arrIEnd - specifies the end of \a arrIBg, so that the last element of \a
4216 * arrIBg is \a arrIEnd[ -1 ].
4217 * \param [out] newNbOfTuples - number of tuples after surjection application.
4218 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4219 * array using decrRef() as it is no more needed.
4220 * \throw If any value of \a arr breaks condition ( 0 <= \a arr[ i ] < \a nbOfOldTuples ).
4222 DataArrayInt *DataArrayInt::ConvertIndexArrayToO2N(int nbOfOldTuples, const int *arr, const int *arrIBg, const int *arrIEnd, int &newNbOfTuples)
4224 MCAuto<DataArrayInt> ret=DataArrayInt::New();
4225 ret->alloc(nbOfOldTuples,1);
4226 int *pt=ret->getPointer();
4227 std::fill(pt,pt+nbOfOldTuples,-1);
4228 int nbOfGrps=((int)std::distance(arrIBg,arrIEnd))-1;
4229 const int *cIPtr=arrIBg;
4230 for(int i=0;i<nbOfGrps;i++)
4231 pt[arr[cIPtr[i]]]=-(i+2);
4233 for(int iNode=0;iNode<nbOfOldTuples;iNode++)
4241 int grpId=-(pt[iNode]+2);
4242 for(int j=cIPtr[grpId];j<cIPtr[grpId+1];j++)
4244 if(arr[j]>=0 && arr[j]<nbOfOldTuples)
4248 std::ostringstream oss; oss << "DataArrayInt::ConvertIndexArrayToO2N : With element #" << j << " value is " << arr[j] << " should be in [0," << nbOfOldTuples << ") !";
4249 throw INTERP_KERNEL::Exception(oss.str().c_str());
4256 newNbOfTuples=newNb;
4261 * Returns a new DataArrayInt containing a renumbering map in "New to Old" mode,
4262 * which if applied to \a this array would make it sorted ascendingly.
4263 * For more info on renumbering see \ref numbering. <br>
4265 * - \a this: [2,0,1,1,0,1,2,0,1,1,0,0]
4266 * - result: [10,0,5,6,1,7,11,2,8,9,3,4]
4267 * - after applying result to \a this: [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2]
4269 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4270 * array using decrRef() as it is no more needed.
4271 * \throw If \a this is not allocated.
4272 * \throw If \a this->getNumberOfComponents() != 1.
4274 DataArrayInt *DataArrayInt::buildPermArrPerLevel() const
4277 if(getNumberOfComponents()!=1)
4278 throw INTERP_KERNEL::Exception("DataArrayInt::buildPermArrPerLevel : number of components must == 1 !");
4279 int nbOfTuples=getNumberOfTuples();
4280 const int *pt=getConstPointer();
4281 std::map<int,int> m;
4282 MCAuto<DataArrayInt> ret=DataArrayInt::New();
4283 ret->alloc(nbOfTuples,1);
4284 int *opt=ret->getPointer();
4285 for(int i=0;i<nbOfTuples;i++,pt++,opt++)
4288 std::map<int,int>::iterator it=m.find(val);
4297 m.insert(std::pair<int,int>(val,1));
4301 for(std::map<int,int>::iterator it=m.begin();it!=m.end();it++)
4303 int vt=(*it).second;
4307 pt=getConstPointer();
4308 opt=ret->getPointer();
4309 for(int i=0;i<nbOfTuples;i++,pt++,opt++)
4316 * Checks if \a this array has the given size, and if its contents is equal to an array filled with
4317 * iota(). This method is particularly useful for DataArrayInt instances that represent
4318 * a renumbering array, to check if there is a real need in renumbering.
4319 * This method checks than \a this can be considered as an identity mapping
4320 * of a set having \a sizeExpected elements into itself.
4322 * \param [in] sizeExpected - The number of elements expected.
4323 * \return bool - \a true if \a this array contents == \a range( \a this->getNumberOfTuples())
4324 * \throw If \a this is not allocated.
4325 * \throw If \a this->getNumberOfComponents() != 1.
4327 bool DataArrayInt::isIota(int sizeExpected) const
4330 if(getNumberOfComponents()!=1)
4332 int nbOfTuples(getNumberOfTuples());
4333 if(nbOfTuples!=sizeExpected)
4335 const int *pt=getConstPointer();
4336 for(int i=0;i<nbOfTuples;i++,pt++)
4343 * Checks if all values in \a this array are equal to \a val.
4344 * \param [in] val - value to check equality of array values to.
4345 * \return bool - \a true if all values are \a val.
4346 * \throw If \a this is not allocated.
4347 * \throw If \a this->getNumberOfComponents() != 1
4348 * \sa DataArrayInt::checkUniformAndGuess
4350 bool DataArrayInt::isUniform(int val) const
4353 if(getNumberOfComponents()!=1)
4354 throw INTERP_KERNEL::Exception("DataArrayInt::isUniform : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
4355 const int *w(begin()),*end2(end());
4363 * This method checks that \a this is uniform. If not and exception will be thrown.
4364 * In case of uniformity the corresponding value is returned.
4366 * \return int - the unique value contained in this
4367 * \throw If \a this is not allocated.
4368 * \throw If \a this->getNumberOfComponents() != 1
4369 * \throw If \a this is not uniform.
4370 * \sa DataArrayInt::isUniform
4372 int DataArrayInt::checkUniformAndGuess() const
4375 if(getNumberOfComponents()!=1)
4376 throw INTERP_KERNEL::Exception("DataArrayInt::checkUniformAndGuess : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
4378 throw INTERP_KERNEL::Exception("DataArrayInt::checkUniformAndGuess : this is empty !");
4379 const int *w(begin()),*end2(end());
4383 throw INTERP_KERNEL::Exception("DataArrayInt::checkUniformAndGuess : this is not uniform !");
4388 * Checks if all values in \a this array are unique.
4389 * \return bool - \a true if condition above is true
4390 * \throw If \a this is not allocated.
4391 * \throw If \a this->getNumberOfComponents() != 1
4393 bool DataArrayInt::hasUniqueValues() const
4396 if(getNumberOfComponents()!=1)
4397 throw INTERP_KERNEL::Exception("DataArrayInt::hasOnlyUniqueValues: must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
4398 std::size_t nbOfTuples(getNumberOfTuples());
4399 std::set<int> s(begin(),end()); // in C++11, should use unordered_set (O(1) complexity)
4400 if (s.size() != nbOfTuples)
4406 * Copy all components in a specified order from another DataArrayInt.
4407 * The specified components become the first ones in \a this array.
4408 * Both numerical and textual data is copied. The number of tuples in \a this and
4409 * the other array can be different.
4410 * \param [in] a - the array to copy data from.
4411 * \param [in] compoIds - sequence of zero based indices of components, data of which is
4413 * \throw If \a a is NULL.
4414 * \throw If \a compoIds.size() != \a a->getNumberOfComponents().
4415 * \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
4417 * \if ENABLE_EXAMPLES
4418 * \ref py_mcdataarrayint_setselectedcomponents "Here is a Python example".
4421 void DataArrayInt::setSelectedComponents(const DataArrayInt *a, const std::vector<int>& compoIds)
4424 throw INTERP_KERNEL::Exception("DataArrayInt::setSelectedComponents : input DataArrayInt is NULL !");
4426 a->checkAllocated();
4427 copyPartOfStringInfoFrom2(compoIds,*a);
4428 std::size_t partOfCompoSz=compoIds.size();
4429 int nbOfCompo=getNumberOfComponents();
4430 int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
4431 const int *ac=a->getConstPointer();
4432 int *nc=getPointer();
4433 for(int i=0;i<nbOfTuples;i++)
4434 for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
4435 nc[nbOfCompo*i+compoIds[j]]=*ac;
4438 DataArrayIntIterator *DataArrayInt::iterator()
4440 return new DataArrayIntIterator(this);
4444 * Creates a new DataArrayInt containing IDs (indices) of tuples holding value \b not
4445 * equal to a given one.
4446 * \param [in] val - the value to ignore within \a this.
4447 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4448 * array using decrRef() as it is no more needed.
4449 * \throw If \a this is not allocated.
4450 * \throw If \a this->getNumberOfComponents() != 1.
4452 DataArrayInt *DataArrayInt::findIdsNotEqual(int val) const
4455 if(getNumberOfComponents()!=1)
4456 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotEqual : the array must have only one component, you can call 'rearrange' method before !");
4457 const int *cptr(getConstPointer());
4458 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4459 int nbOfTuples=getNumberOfTuples();
4460 for(int i=0;i<nbOfTuples;i++,cptr++)
4462 ret->pushBackSilent(i);
4467 * Creates a new DataArrayInt containing IDs (indices) of tuples holding tuple equal to those defined by [ \a tupleBg , \a tupleEnd )
4468 * This method is an extension of DataArrayInt::findIdsEqual method.
4470 * \param [in] tupleBg - the begin (included) of the input tuple to find within \a this.
4471 * \param [in] tupleEnd - the end (excluded) of the input tuple to find within \a this.
4472 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4473 * array using decrRef() as it is no more needed.
4474 * \throw If \a this is not allocated.
4475 * \throw If \a this->getNumberOfComponents() != std::distance(tupleBg,tupleEnd).
4476 * \throw If \a this->getNumberOfComponents() is equal to 0.
4477 * \sa DataArrayInt::findIdsEqual
4479 DataArrayInt *DataArrayInt::findIdsEqualTuple(const int *tupleBg, const int *tupleEnd) const
4481 std::size_t nbOfCompoExp(std::distance(tupleBg,tupleEnd));
4483 if(getNumberOfComponents()!=nbOfCompoExp)
4485 std::ostringstream oss; oss << "DataArrayInt::findIdsEqualTuple : mismatch of number of components. Input tuple has " << nbOfCompoExp << " whereas this array has " << getNumberOfComponents() << " components !";
4486 throw INTERP_KERNEL::Exception(oss.str().c_str());
4489 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqualTuple : number of components should be > 0 !");
4490 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4491 const int *bg(begin()),*end2(end()),*work(begin());
4494 work=std::search(work,end2,tupleBg,tupleEnd);
4497 std::size_t pos(std::distance(bg,work));
4498 if(pos%nbOfCompoExp==0)
4499 ret->pushBackSilent(pos/nbOfCompoExp);
4507 * This method finds for each element \a ELT in [valsBg,valsEnd) elements in \a this equal to it. Associated to ELT
4508 * this method will return the tuple id of last element found. If there is no element in \a this equal to ELT
4509 * an exception will be thrown.
4511 * In case of success this[ret]==vals. Samely ret->transformWithIndArr(this->begin(),this->end())==vals.
4512 * Where \a vals is the [valsBg,valsEnd) array and \a ret the array returned by this method.
4513 * This method can be seen as an extension of FindPermutationFromFirstToSecond.
4516 * - \a this: [17,27,2,10,-4,3,12,27,16]
4517 * - \a val : [3,16,-4,27,17]
4518 * - result: [5,8,4,7,0]
4520 * \return - An array of size std::distance(valsBg,valsEnd)
4522 * \sa DataArrayInt32::FindPermutationFromFirstToSecond
4524 MCAuto<DataArrayInt32> DataArrayInt32::findIdForEach(const int *valsBg, const int *valsEnd) const
4526 MCAuto<DataArrayInt32> ret(DataArrayInt32::New());
4527 std::size_t nbOfTuplesOut(std::distance(valsBg,valsEnd));
4528 ret->alloc(nbOfTuplesOut,1);
4529 MCAuto< MapKeyVal<int> > zeMap(invertArrayN2O2O2NOptimized());
4530 const std::map<int,int>& dat(zeMap->data());
4531 int *ptToFeed(ret->getPointer());
4532 for(const int *pt=valsBg;pt!=valsEnd;pt++)
4534 std::map<int,int>::const_iterator it(dat.find(*pt));
4536 *ptToFeed++=(*it).second;
4539 std::ostringstream oss; oss << "DataArrayInt32::findIdForEach : error for element at place " << std::distance(valsBg,pt);
4540 oss << " of input array value is " << *pt << " which is not in this !";
4541 throw INTERP_KERNEL::Exception(oss.str());
4548 * Assigns \a newValue to all elements holding \a oldValue within \a this
4549 * one-dimensional array.
4550 * \param [in] oldValue - the value to replace.
4551 * \param [in] newValue - the value to assign.
4552 * \return int - number of replacements performed.
4553 * \throw If \a this is not allocated.
4554 * \throw If \a this->getNumberOfComponents() != 1.
4556 int DataArrayInt::changeValue(int oldValue, int newValue)
4559 if(getNumberOfComponents()!=1)
4560 throw INTERP_KERNEL::Exception("DataArrayInt::changeValue : the array must have only one component, you can call 'rearrange' method before !");
4561 if(oldValue==newValue)
4563 int *start(getPointer()),*end2(start+getNbOfElems());
4565 for(int *val=start;val!=end2;val++)
4579 * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to
4580 * one of given values.
4581 * \param [in] valsBg - an array of values to find within \a this array.
4582 * \param [in] valsEnd - specifies the end of the array \a valsBg, so that
4583 * the last value of \a valsBg is \a valsEnd[ -1 ].
4584 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4585 * array using decrRef() as it is no more needed.
4586 * \throw If \a this->getNumberOfComponents() != 1.
4588 DataArrayInt *DataArrayInt::findIdsEqualList(const int *valsBg, const int *valsEnd) const
4590 if(getNumberOfComponents()!=1)
4591 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqualList : the array must have only one component, you can call 'rearrange' method before !");
4592 std::set<int> vals2(valsBg,valsEnd);
4593 const int *cptr(getConstPointer());
4594 std::vector<int> res;
4595 int nbOfTuples(getNumberOfTuples());
4596 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4597 for(int i=0;i<nbOfTuples;i++,cptr++)
4598 if(vals2.find(*cptr)!=vals2.end())
4599 ret->pushBackSilent(i);
4604 * Creates a new DataArrayInt containing IDs (indices) of tuples holding values \b not
4605 * equal to any of given values.
4606 * \param [in] valsBg - an array of values to ignore within \a this array.
4607 * \param [in] valsEnd - specifies the end of the array \a valsBg, so that
4608 * the last value of \a valsBg is \a valsEnd[ -1 ].
4609 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4610 * array using decrRef() as it is no more needed.
4611 * \throw If \a this->getNumberOfComponents() != 1.
4613 DataArrayInt *DataArrayInt::findIdsNotEqualList(const int *valsBg, const int *valsEnd) const
4615 if(getNumberOfComponents()!=1)
4616 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotEqualList : the array must have only one component, you can call 'rearrange' method before !");
4617 std::set<int> vals2(valsBg,valsEnd);
4618 const int *cptr=getConstPointer();
4619 std::vector<int> res;
4620 int nbOfTuples=getNumberOfTuples();
4621 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4622 for(int i=0;i<nbOfTuples;i++,cptr++)
4623 if(vals2.find(*cptr)==vals2.end())
4624 ret->pushBackSilent(i);
4629 * This method is an extension of DataArrayInt::findIdFirstEqual method because this method works for DataArrayInt with
4630 * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
4631 * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
4632 * If any the tuple id is returned. If not -1 is returned.
4634 * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
4635 * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
4637 * \return tuple id where \b tupl is. -1 if no such tuple exists in \b this.
4638 * \sa DataArrayInt::findIdSequence, DataArrayInt::presenceOfTuple.
4640 int DataArrayInt::findIdFirstEqualTuple(const std::vector<int>& tupl) const
4643 int nbOfCompo=getNumberOfComponents();
4645 throw INTERP_KERNEL::Exception("DataArrayInt::findIdFirstEqualTuple : 0 components in 'this' !");
4646 if(nbOfCompo!=(int)tupl.size())
4648 std::ostringstream oss; oss << "DataArrayInt::findIdFirstEqualTuple : 'this' contains " << nbOfCompo << " components and searching for a tuple of length " << tupl.size() << " !";
4649 throw INTERP_KERNEL::Exception(oss.str().c_str());
4651 const int *cptr=getConstPointer();
4652 std::size_t nbOfVals=getNbOfElems();
4653 for(const int *work=cptr;work!=cptr+nbOfVals;)
4655 work=std::search(work,cptr+nbOfVals,tupl.begin(),tupl.end());
4656 if(work!=cptr+nbOfVals)
4658 if(std::distance(cptr,work)%nbOfCompo!=0)
4661 return std::distance(cptr,work)/nbOfCompo;
4668 * This method searches the sequence specified in input parameter \b vals in \b this.
4669 * This works only for DataArrayInt having number of components equal to one (if not an INTERP_KERNEL::Exception will be thrown).
4670 * This method differs from DataArrayInt::findIdFirstEqualTuple in that the position is internal raw data is not considered here contrary to DataArrayInt::findIdFirstEqualTuple.
4671 * \sa DataArrayInt::findIdFirstEqualTuple
4673 int DataArrayInt::findIdSequence(const std::vector<int>& vals) const
4676 int nbOfCompo=getNumberOfComponents();
4678 throw INTERP_KERNEL::Exception("DataArrayInt::findIdSequence : works only for DataArrayInt instance with one component !");
4679 const int *cptr=getConstPointer();
4680 std::size_t nbOfVals=getNbOfElems();
4681 const int *loc=std::search(cptr,cptr+nbOfVals,vals.begin(),vals.end());
4682 if(loc!=cptr+nbOfVals)
4683 return std::distance(cptr,loc);
4688 * This method expects to be called when number of components of this is equal to one.
4689 * This method returns the tuple id, if it exists, of the first tuple equal to \b value.
4690 * If not any tuple contains \b value -1 is returned.
4691 * \sa DataArrayInt::presenceOfValue
4693 int DataArrayInt::findIdFirstEqual(int value) const
4696 if(getNumberOfComponents()!=1)
4697 throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
4698 const int *cptr=getConstPointer();
4699 int nbOfTuples=getNumberOfTuples();
4700 const int *ret=std::find(cptr,cptr+nbOfTuples,value);
4701 if(ret!=cptr+nbOfTuples)
4702 return std::distance(cptr,ret);
4707 * This method expects to be called when number of components of this is equal to one.
4708 * This method returns the tuple id, if it exists, of the first tuple so that the value is contained in \b vals.
4709 * If not any tuple contains one of the values contained in 'vals' -1 is returned.
4710 * \sa DataArrayInt::presenceOfValue
4712 int DataArrayInt::findIdFirstEqual(const std::vector<int>& vals) const
4715 if(getNumberOfComponents()!=1)
4716 throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
4717 std::set<int> vals2(vals.begin(),vals.end());
4718 const int *cptr=getConstPointer();
4719 int nbOfTuples=getNumberOfTuples();
4720 for(const int *w=cptr;w!=cptr+nbOfTuples;w++)
4721 if(vals2.find(*w)!=vals2.end())
4722 return std::distance(cptr,w);
4727 * This method returns the number of values in \a this that are equals to input parameter \a value.
4728 * This method only works for single component array.
4730 * \return a value in [ 0, \c this->getNumberOfTuples() )
4732 * \throw If \a this is not allocated
4735 int DataArrayInt::count(int value) const
4739 if(getNumberOfComponents()!=1)
4740 throw INTERP_KERNEL::Exception("DataArrayInt::count : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
4741 const int *vals=begin();
4742 int nbOfTuples=getNumberOfTuples();
4743 for(int i=0;i<nbOfTuples;i++,vals++)
4750 * This method is an extension of DataArrayInt::presenceOfValue method because this method works for DataArrayInt with
4751 * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
4752 * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
4753 * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
4754 * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
4755 * \sa DataArrayInt::findIdFirstEqualTuple
4757 bool DataArrayInt::presenceOfTuple(const std::vector<int>& tupl) const
4759 return findIdFirstEqualTuple(tupl)!=-1;
4764 * Returns \a true if a given value is present within \a this one-dimensional array.
4765 * \param [in] value - the value to find within \a this array.
4766 * \return bool - \a true in case if \a value is present within \a this array.
4767 * \throw If \a this is not allocated.
4768 * \throw If \a this->getNumberOfComponents() != 1.
4769 * \sa findIdFirstEqual()
4771 bool DataArrayInt::presenceOfValue(int value) const
4773 return findIdFirstEqual(value)!=-1;
4777 * This method expects to be called when number of components of this is equal to one.
4778 * This method returns true if it exists a tuple so that the value is contained in \b vals.
4779 * If not any tuple contains one of the values contained in 'vals' false is returned.
4780 * \sa DataArrayInt::findIdFirstEqual
4782 bool DataArrayInt::presenceOfValue(const std::vector<int>& vals) const
4784 return findIdFirstEqual(vals)!=-1;
4788 * Accumulates values of each component of \a this array.
4789 * \param [out] res - an array of length \a this->getNumberOfComponents(), allocated
4790 * by the caller, that is filled by this method with sum value for each
4792 * \throw If \a this is not allocated.
4794 void DataArrayInt::accumulate(int *res) const
4797 const int *ptr=getConstPointer();
4798 int nbTuple=getNumberOfTuples();
4799 int nbComps=getNumberOfComponents();
4800 std::fill(res,res+nbComps,0);
4801 for(int i=0;i<nbTuple;i++)
4802 std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<int>());
4805 int DataArrayInt::accumulate(int compId) const
4808 const int *ptr=getConstPointer();
4809 int nbTuple=getNumberOfTuples();
4810 int nbComps=getNumberOfComponents();
4811 if(compId<0 || compId>=nbComps)
4812 throw INTERP_KERNEL::Exception("DataArrayInt::accumulate : Invalid compId specified : No such nb of components !");
4814 for(int i=0;i<nbTuple;i++)
4815 ret+=ptr[i*nbComps+compId];
4820 * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
4821 * The returned array will have same number of components than \a this and number of tuples equal to
4822 * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
4824 * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
4826 * \param [in] bgOfIndex - begin (included) of the input index array.
4827 * \param [in] endOfIndex - end (excluded) of the input index array.
4828 * \return DataArrayInt * - the new instance having the same number of components than \a this.
4830 * \throw If bgOfIndex or end is NULL.
4831 * \throw If input index array is not ascendingly sorted.
4832 * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
4833 * \throw If std::distance(bgOfIndex,endOfIndex)==0.
4835 DataArrayInt *DataArrayInt::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
4837 if(!bgOfIndex || !endOfIndex)
4838 throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : input pointer NULL !");
4840 int nbCompo=getNumberOfComponents();
4841 int nbOfTuples=getNumberOfTuples();
4842 int sz=(int)std::distance(bgOfIndex,endOfIndex);
4844 throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : invalid size of input index array !");
4846 MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(sz,nbCompo);
4847 const int *w=bgOfIndex;
4848 if(*w<0 || *w>=nbOfTuples)
4849 throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
4850 const int *srcPt=begin()+(*w)*nbCompo;
4851 int *tmp=ret->getPointer();
4852 for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
4854 std::fill(tmp,tmp+nbCompo,0);
4857 for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
4859 if(j>=0 && j<nbOfTuples)
4860 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<int>());
4863 std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
4864 throw INTERP_KERNEL::Exception(oss.str().c_str());
4870 std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
4871 throw INTERP_KERNEL::Exception(oss.str().c_str());
4874 ret->copyStringInfoFrom(*this);
4879 * Returns a new DataArrayInt by concatenating two given arrays, so that (1) the number
4880 * of tuples in the result array is <em> a1->getNumberOfTuples() + a2->getNumberOfTuples() -
4881 * offsetA2</em> and (2)
4882 * the number of component in the result array is same as that of each of given arrays.
4883 * First \a offsetA2 tuples of \a a2 are skipped and thus are missing from the result array.
4884 * Info on components is copied from the first of the given arrays. Number of components
4885 * in the given arrays must be the same.
4886 * \param [in] a1 - an array to include in the result array.
4887 * \param [in] a2 - another array to include in the result array.
4888 * \param [in] offsetA2 - number of tuples of \a a2 to skip.
4889 * \return DataArrayInt * - the new instance of DataArrayInt.
4890 * The caller is to delete this result array using decrRef() as it is no more
4892 * \throw If either \a a1 or \a a2 is NULL.
4893 * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
4895 DataArrayInt *DataArrayInt::Aggregate(const DataArrayInt *a1, const DataArrayInt *a2, int offsetA2)
4898 throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input DataArrayInt instance is NULL !");
4899 std::size_t nbOfComp(a1->getNumberOfComponents());
4900 if(nbOfComp!=a2->getNumberOfComponents())
4901 throw INTERP_KERNEL::Exception("Nb of components mismatch for array Aggregation !");
4902 std::size_t nbOfTuple1(a1->getNumberOfTuples()),nbOfTuple2(a2->getNumberOfTuples());
4903 MCAuto<DataArrayInt> ret(DataArrayInt::New());
4904 ret->alloc(nbOfTuple1+nbOfTuple2-offsetA2,nbOfComp);
4905 int *pt=std::copy(a1->begin(),a1->end(),ret->getPointer());
4906 std::copy(a2->getConstPointer()+offsetA2*nbOfComp,a2->getConstPointer()+nbOfTuple2*nbOfComp,pt);
4907 ret->copyStringInfoFrom(*a1);
4912 * Returns a new DataArrayInt by concatenating all given arrays, so that (1) the number
4913 * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
4914 * the number of component in the result array is same as that of each of given arrays.
4915 * Info on components is copied from the first of the given arrays. Number of components
4916 * in the given arrays must be the same.
4917 * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it
4918 * not the object itself.
4919 * \param [in] arr - a sequence of arrays to include in the result array.
4920 * \return DataArrayInt * - the new instance of DataArrayInt.
4921 * The caller is to delete this result array using decrRef() as it is no more
4923 * \throw If all arrays within \a arr are NULL.
4924 * \throw If getNumberOfComponents() of arrays within \a arr.
4926 DataArrayInt *DataArrayInt::Aggregate(const std::vector<const DataArrayInt *>& arr)
4928 std::vector<const DataArrayInt *> a;
4929 for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
4933 throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input list must be NON EMPTY !");
4934 std::vector<const DataArrayInt *>::const_iterator it=a.begin();
4935 std::size_t nbOfComp((*it)->getNumberOfComponents()),nbt((*it++)->getNumberOfTuples());
4936 for(int i=1;it!=a.end();it++,i++)
4938 if((*it)->getNumberOfComponents()!=nbOfComp)
4939 throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : Nb of components mismatch for array aggregation !");
4940 nbt+=(*it)->getNumberOfTuples();
4942 MCAuto<DataArrayInt> ret=DataArrayInt::New();
4943 ret->alloc(nbt,nbOfComp);
4944 int *pt=ret->getPointer();
4945 for(it=a.begin();it!=a.end();it++)
4946 pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
4947 ret->copyStringInfoFrom(*(a[0]));
4952 * This method takes as input a list of DataArrayInt instances \a arrs that represent each a packed index arrays.
4953 * A packed index array is an allocated array with one component, and at least one tuple. The first element
4954 * of each array in \a arrs must be 0. Each array in \a arrs is expected to be increasingly monotonic.
4955 * 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.
4957 * \return DataArrayInt * - a new object to be managed by the caller.
4959 DataArrayInt *DataArrayInt::AggregateIndexes(const std::vector<const DataArrayInt *>& arrs)
4962 for(std::vector<const DataArrayInt *>::const_iterator it4=arrs.begin();it4!=arrs.end();it4++)
4966 (*it4)->checkAllocated();
4967 if((*it4)->getNumberOfComponents()!=1)
4969 std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of compo != 1 at pos " << std::distance(arrs.begin(),it4) << " !";
4970 throw INTERP_KERNEL::Exception(oss.str().c_str());
4972 int nbTupl=(*it4)->getNumberOfTuples();
4975 std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of tuples < 1 at pos " << std::distance(arrs.begin(),it4) << " !";
4976 throw INTERP_KERNEL::Exception(oss.str().c_str());
4978 if((*it4)->front()!=0)
4980 std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with front value != 0 at pos " << std::distance(arrs.begin(),it4) << " !";
4981 throw INTERP_KERNEL::Exception(oss.str().c_str());
4987 std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a null instance at pos " << std::distance(arrs.begin(),it4) << " !";
4988 throw INTERP_KERNEL::Exception(oss.str().c_str());
4992 throw INTERP_KERNEL::Exception("DataArrayInt::AggregateIndexes : input list must be NON EMPTY !");
4993 MCAuto<DataArrayInt> ret=DataArrayInt::New();
4994 ret->alloc(retSz,1);
4995 int *pt=ret->getPointer(); *pt++=0;
4996 for(std::vector<const DataArrayInt *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
4997 pt=std::transform((*it)->begin()+1,(*it)->end(),pt,std::bind2nd(std::plus<int>(),pt[-1]));
4998 ret->copyStringInfoFrom(*(arrs[0]));
5003 * Returns in a single walk in \a this the min value and the max value in \a this.
5004 * \a this is expected to be single component array.
5006 * \param [out] minValue - the min value in \a this.
5007 * \param [out] maxValue - the max value in \a this.
5009 * \sa getMinValueInArray, getMinValue, getMaxValueInArray, getMaxValue
5011 void DataArrayInt::getMinMaxValues(int& minValue, int& maxValue) const
5014 if(getNumberOfComponents()!=1)
5015 throw INTERP_KERNEL::Exception("DataArrayInt::getMinMaxValues : must be applied on DataArrayInt with only one component !");
5016 int nbTuples(getNumberOfTuples());
5017 const int *pt(begin());
5018 minValue=std::numeric_limits<int>::max(); maxValue=-std::numeric_limits<int>::max();
5019 for(int i=0;i<nbTuples;i++,pt++)
5029 * Modify all elements of \a this array, so that
5030 * an element _x_ becomes \f$ numerator / x \f$.
5031 * \warning If an exception is thrown because of presence of 0 element in \a this
5032 * array, all elements processed before detection of the zero element remain
5034 * \param [in] numerator - the numerator used to modify array elements.
5035 * \throw If \a this is not allocated.
5036 * \throw If there is an element equal to 0 in \a this array.
5038 void DataArrayInt::applyInv(int numerator)
5041 int *ptr=getPointer();
5042 std::size_t nbOfElems=getNbOfElems();
5043 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
5047 *ptr=numerator/(*ptr);
5051 std::ostringstream oss; oss << "DataArrayInt::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
5053 throw INTERP_KERNEL::Exception(oss.str().c_str());
5060 * Modify all elements of \a this array, so that
5061 * an element _x_ becomes \f$ x / val \f$.
5062 * \param [in] val - the denominator used to modify array elements.
5063 * \throw If \a this is not allocated.
5064 * \throw If \a val == 0.
5066 void DataArrayInt::applyDivideBy(int val)
5069 throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to divide by 0 !");
5071 int *ptr=getPointer();
5072 std::size_t nbOfElems=getNbOfElems();
5073 std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::divides<int>(),val));
5078 * Modify all elements of \a this array, so that
5079 * an element _x_ becomes <em> x % val </em>.
5080 * \param [in] val - the divisor used to modify array elements.
5081 * \throw If \a this is not allocated.
5082 * \throw If \a val <= 0.
5084 void DataArrayInt::applyModulus(int val)
5087 throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to operate modulus on value <= 0 !");
5089 int *ptr=getPointer();
5090 std::size_t nbOfElems=getNbOfElems();
5091 std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::modulus<int>(),val));
5096 * This method works only on data array with one component.
5097 * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
5098 * this[*id] in [\b vmin,\b vmax)
5100 * \param [in] vmin begin of range. This value is included in range (included).
5101 * \param [in] vmax end of range. This value is \b not included in range (excluded).
5102 * \return a newly allocated data array that the caller should deal with.
5104 * \sa DataArrayInt::findIdsNotInRange , DataArrayInt::findIdsStricltyNegative
5106 DataArrayInt *DataArrayInt::findIdsInRange(int vmin, int vmax) const
5108 InRange<int> ir(vmin,vmax);
5109 MCAuto<DataArrayInt> ret(findIdsAdv(ir));
5114 * This method works only on data array with one component.
5115 * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
5116 * this[*id] \b not in [\b vmin,\b vmax)
5118 * \param [in] vmin begin of range. This value is \b not included in range (excluded).
5119 * \param [in] vmax end of range. This value is included in range (included).
5120 * \return a newly allocated data array that the caller should deal with.
5122 * \sa DataArrayInt::findIdsInRange , DataArrayInt::findIdsStricltyNegative
5124 DataArrayInt *DataArrayInt::findIdsNotInRange(int vmin, int vmax) const
5126 NotInRange<int> nir(vmin,vmax);
5127 MCAuto<DataArrayInt> ret(findIdsAdv(nir));
5132 * This method works only on data array with one component.
5133 * 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.
5135 * \param [in] vmin begin of range. This value is included in range (included).
5136 * \param [in] vmax end of range. This value is \b not included in range (excluded).
5137 * \return if all ids in \a this are so that (*this)[i]==i for all i in [ 0, \c this->getNumberOfTuples() ). */
5138 bool DataArrayInt::checkAllIdsInRange(int vmin, int vmax) const
5141 if(getNumberOfComponents()!=1)
5142 throw INTERP_KERNEL::Exception("DataArrayInt::checkAllIdsInRange : this must have exactly one component !");
5143 int nbOfTuples=getNumberOfTuples();
5145 const int *cptr=getConstPointer();
5146 for(int i=0;i<nbOfTuples;i++,cptr++)
5148 if(*cptr>=vmin && *cptr<vmax)
5149 { ret=ret && *cptr==i; }
5152 std::ostringstream oss; oss << "DataArrayInt::checkAllIdsInRange : tuple #" << i << " has value " << *cptr << " should be in [" << vmin << "," << vmax << ") !";
5153 throw INTERP_KERNEL::Exception(oss.str().c_str());
5160 * Modify all elements of \a this array, so that
5161 * an element _x_ becomes <em> val % x </em>.
5162 * \warning If an exception is thrown because of presence of an element <= 0 in \a this
5163 * array, all elements processed before detection of the zero element remain
5165 * \param [in] val - the divident used to modify array elements.
5166 * \throw If \a this is not allocated.
5167 * \throw If there is an element equal to or less than 0 in \a this array.
5169 void DataArrayInt::applyRModulus(int val)
5172 int *ptr=getPointer();
5173 std::size_t nbOfElems=getNbOfElems();
5174 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
5182 std::ostringstream oss; oss << "DataArrayInt::applyRModulus : presence of value <=0 in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
5184 throw INTERP_KERNEL::Exception(oss.str().c_str());
5191 * Modify all elements of \a this array, so that
5192 * an element _x_ becomes <em> val ^ x </em>.
5193 * \param [in] val - the value used to apply pow on all array elements.
5194 * \throw If \a this is not allocated.
5195 * \throw If \a val < 0.
5197 void DataArrayInt::applyPow(int val)
5201 throw INTERP_KERNEL::Exception("DataArrayInt::applyPow : input pow in < 0 !");
5202 int *ptr=getPointer();
5203 std::size_t nbOfElems=getNbOfElems();
5206 std::fill(ptr,ptr+nbOfElems,1);
5209 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
5212 for(int j=0;j<val;j++)
5220 * Modify all elements of \a this array, so that
5221 * an element _x_ becomes \f$ val ^ x \f$.
5222 * \param [in] val - the value used to apply pow on all array elements.
5223 * \throw If \a this is not allocated.
5224 * \throw If there is an element < 0 in \a this array.
5225 * \warning If an exception is thrown because of presence of 0 element in \a this
5226 * array, all elements processed before detection of the zero element remain
5229 void DataArrayInt::applyRPow(int val)
5232 int *ptr=getPointer();
5233 std::size_t nbOfElems=getNbOfElems();
5234 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
5239 for(int j=0;j<*ptr;j++)
5245 std::ostringstream oss; oss << "DataArrayInt::applyRPow : presence of negative value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
5247 throw INTERP_KERNEL::Exception(oss.str().c_str());
5254 * Returns a new DataArrayInt which is a minimal partition of elements of \a groups.
5255 * The i-th item of the result array is an ID of a set of elements belonging to a
5256 * unique set of groups, which the i-th element is a part of. This set of elements
5257 * belonging to a unique set of groups is called \a family, so the result array contains
5258 * IDs of families each element belongs to.
5260 * \b Example: if we have two groups of elements: \a group1 [0,4] and \a group2 [ 0,1,2 ],
5261 * then there are 3 families:
5262 * - \a family1 (with ID 1) contains element [0] belonging to ( \a group1 + \a group2 ),
5263 * - \a family2 (with ID 2) contains elements [4] belonging to ( \a group1 ),
5264 * - \a family3 (with ID 3) contains element [1,2] belonging to ( \a group2 ), <br>
5265 * and the result array contains IDs of families [ 1,3,3,0,2 ]. <br> Note a family ID 0 which
5266 * stands for the element #3 which is in none of groups.
5268 * \param [in] groups - sequence of groups of element IDs.
5269 * \param [in] newNb - total number of elements; it must be more than max ID of element
5271 * \param [out] fidsOfGroups - IDs of families the elements of each group belong to.
5272 * \return DataArrayInt * - a new instance of DataArrayInt containing IDs of families
5273 * each element with ID from range [0, \a newNb ) belongs to. The caller is to
5274 * delete this array using decrRef() as it is no more needed.
5275 * \throw If any element ID in \a groups violates condition ( 0 <= ID < \a newNb ).
5277 DataArrayInt *DataArrayInt::MakePartition(const std::vector<const DataArrayInt *>& groups, int newNb, std::vector< std::vector<int> >& fidsOfGroups)
5279 std::vector<const DataArrayInt *> groups2;
5280 for(std::vector<const DataArrayInt *>::const_iterator it4=groups.begin();it4!=groups.end();it4++)
5282 groups2.push_back(*it4);
5283 MCAuto<DataArrayInt> ret=DataArrayInt::New();
5284 ret->alloc(newNb,1);
5285 int *retPtr=ret->getPointer();
5286 std::fill(retPtr,retPtr+newNb,0);
5288 for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++)
5290 const int *ptr=(*iter)->getConstPointer();
5291 std::size_t nbOfElem=(*iter)->getNbOfElems();
5293 for(int j=0;j<sfid;j++)
5296 for(std::size_t i=0;i<nbOfElem;i++)
5298 if(ptr[i]>=0 && ptr[i]<newNb)
5300 if(retPtr[ptr[i]]==j)
5308 std::ostringstream oss; oss << "DataArrayInt::MakePartition : In group \"" << (*iter)->getName() << "\" in tuple #" << i << " value = " << ptr[i] << " ! Should be in [0," << newNb;
5310 throw INTERP_KERNEL::Exception(oss.str().c_str());
5317 fidsOfGroups.clear();
5318 fidsOfGroups.resize(groups2.size());
5320 for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++,grId++)
5323 const int *ptr=(*iter)->getConstPointer();
5324 std::size_t nbOfElem=(*iter)->getNbOfElems();
5325 for(const int *p=ptr;p!=ptr+nbOfElem;p++)
5326 tmp.insert(retPtr[*p]);
5327 fidsOfGroups[grId].insert(fidsOfGroups[grId].end(),tmp.begin(),tmp.end());
5333 * Returns a new DataArrayInt which contains all elements of given one-dimensional
5334 * arrays. The result array does not contain any duplicates and its values
5335 * are sorted in ascending order.
5336 * \param [in] arr - sequence of DataArrayInt's to unite.
5337 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5338 * array using decrRef() as it is no more needed.
5339 * \throw If any \a arr[i] is not allocated.
5340 * \throw If \a arr[i]->getNumberOfComponents() != 1.
5342 DataArrayInt *DataArrayInt::BuildUnion(const std::vector<const DataArrayInt *>& arr)
5344 std::vector<const DataArrayInt *> a;
5345 for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
5348 for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
5350 (*it)->checkAllocated();
5351 if((*it)->getNumberOfComponents()!=1)
5352 throw INTERP_KERNEL::Exception("DataArrayInt::BuildUnion : only single component allowed !");
5356 for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
5358 const int *pt=(*it)->getConstPointer();
5359 int nbOfTuples=(*it)->getNumberOfTuples();
5360 r.insert(pt,pt+nbOfTuples);
5362 DataArrayInt *ret=DataArrayInt::New();
5363 ret->alloc((int)r.size(),1);
5364 std::copy(r.begin(),r.end(),ret->getPointer());
5369 * Returns a new DataArrayInt which contains elements present in each of given one-dimensional
5370 * arrays. The result array does not contain any duplicates and its values
5371 * are sorted in ascending order.
5372 * \param [in] arr - sequence of DataArrayInt's to intersect.
5373 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5374 * array using decrRef() as it is no more needed.
5375 * \throw If any \a arr[i] is not allocated.
5376 * \throw If \a arr[i]->getNumberOfComponents() != 1.
5378 DataArrayInt *DataArrayInt::BuildIntersection(const std::vector<const DataArrayInt *>& arr)
5380 std::vector<const DataArrayInt *> a;
5381 for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
5384 for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
5386 (*it)->checkAllocated();
5387 if((*it)->getNumberOfComponents()!=1)
5388 throw INTERP_KERNEL::Exception("DataArrayInt::BuildIntersection : only single component allowed !");
5392 for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
5394 const int *pt=(*it)->getConstPointer();
5395 int nbOfTuples=(*it)->getNumberOfTuples();
5396 std::set<int> s1(pt,pt+nbOfTuples);
5400 std::set_intersection(r.begin(),r.end(),s1.begin(),s1.end(),inserter(r2,r2.end()));
5406 DataArrayInt *ret(DataArrayInt::New());
5407 ret->alloc((int)r.size(),1);
5408 std::copy(r.begin(),r.end(),ret->getPointer());
5413 namespace MEDCouplingImpl
5418 OpSwitchedOn(int *pt):_pt(pt),_cnt(0) { }
5419 void operator()(const bool& b) { if(b) *_pt++=_cnt; _cnt++; }
5428 OpSwitchedOff(int *pt):_pt(pt),_cnt(0) { }
5429 void operator()(const bool& b) { if(!b) *_pt++=_cnt; _cnt++; }
5438 * This method returns the list of ids in ascending mode so that v[id]==true.
5440 DataArrayInt *DataArrayInt::BuildListOfSwitchedOn(const std::vector<bool>& v)
5442 int sz((int)std::count(v.begin(),v.end(),true));
5443 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
5444 std::for_each(v.begin(),v.end(),MEDCouplingImpl::OpSwitchedOn(ret->getPointer()));
5449 * This method returns the list of ids in ascending mode so that v[id]==false.
5451 DataArrayInt *DataArrayInt::BuildListOfSwitchedOff(const std::vector<bool>& v)
5453 int sz((int)std::count(v.begin(),v.end(),false));
5454 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
5455 std::for_each(v.begin(),v.end(),MEDCouplingImpl::OpSwitchedOff(ret->getPointer()));
5460 * This method allows to put a vector of vector of integer into a more compact data structure (skyline).
5461 * This method is not available into python because no available optimized data structure available to map std::vector< std::vector<int> >.
5463 * \param [in] v the input data structure to be translate into skyline format.
5464 * \param [out] data the first element of the skyline format. The user is expected to deal with newly allocated array.
5465 * \param [out] dataIndex the second element of the skyline format.
5467 void DataArrayInt::PutIntoToSkylineFrmt(const std::vector< std::vector<int> >& v, DataArrayInt *& data, DataArrayInt *& dataIndex)
5469 int sz((int)v.size());
5470 MCAuto<DataArrayInt> ret0(DataArrayInt::New()),ret1(DataArrayInt::New());
5471 ret1->alloc(sz+1,1);
5472 int *pt(ret1->getPointer()); *pt=0;
5473 for(int i=0;i<sz;i++,pt++)
5474 pt[1]=pt[0]+(int)v[i].size();
5475 ret0->alloc(ret1->back(),1);
5476 pt=ret0->getPointer();
5477 for(int i=0;i<sz;i++)
5478 pt=std::copy(v[i].begin(),v[i].end(),pt);
5479 data=ret0.retn(); dataIndex=ret1.retn();
5483 * Returns a new DataArrayInt which contains a complement of elements of \a this
5484 * one-dimensional array. I.e. the result array contains all elements from the range [0,
5485 * \a nbOfElement) not present in \a this array.
5486 * \param [in] nbOfElement - maximal size of the result array.
5487 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5488 * array using decrRef() as it is no more needed.
5489 * \throw If \a this is not allocated.
5490 * \throw If \a this->getNumberOfComponents() != 1.
5491 * \throw If any element \a x of \a this array violates condition ( 0 <= \a x < \a
5494 DataArrayInt *DataArrayInt::buildComplement(int nbOfElement) const
5497 if(getNumberOfComponents()!=1)
5498 throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : only single component allowed !");
5499 std::vector<bool> tmp(nbOfElement);
5500 const int *pt=getConstPointer();
5501 int nbOfTuples=getNumberOfTuples();
5502 for(const int *w=pt;w!=pt+nbOfTuples;w++)
5503 if(*w>=0 && *w<nbOfElement)
5506 throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : an element is not in valid range : [0,nbOfElement) !");
5507 int nbOfRetVal=(int)std::count(tmp.begin(),tmp.end(),false);
5508 DataArrayInt *ret=DataArrayInt::New();
5509 ret->alloc(nbOfRetVal,1);
5511 int *retPtr=ret->getPointer();
5512 for(int i=0;i<nbOfElement;i++)
5519 * Returns a new DataArrayInt containing elements of \a this one-dimensional missing
5520 * from an \a other one-dimensional array.
5521 * \param [in] other - a DataArrayInt containing elements not to include in the result array.
5522 * \return DataArrayInt * - a new instance of DataArrayInt with one component. The
5523 * caller is to delete this array using decrRef() as it is no more needed.
5524 * \throw If \a other is NULL.
5525 * \throw If \a other is not allocated.
5526 * \throw If \a other->getNumberOfComponents() != 1.
5527 * \throw If \a this is not allocated.
5528 * \throw If \a this->getNumberOfComponents() != 1.
5529 * \sa DataArrayInt::buildSubstractionOptimized()
5531 DataArrayInt *DataArrayInt::buildSubstraction(const DataArrayInt *other) const
5534 throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : DataArrayInt pointer in input is NULL !");
5536 other->checkAllocated();
5537 if(getNumberOfComponents()!=1)
5538 throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed !");
5539 if(other->getNumberOfComponents()!=1)
5540 throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed for other type !");
5541 const int *pt=getConstPointer();
5542 int nbOfTuples=getNumberOfTuples();
5543 std::set<int> s1(pt,pt+nbOfTuples);
5544 pt=other->getConstPointer();
5545 nbOfTuples=other->getNumberOfTuples();
5546 std::set<int> s2(pt,pt+nbOfTuples);
5548 std::set_difference(s1.begin(),s1.end(),s2.begin(),s2.end(),std::back_insert_iterator< std::vector<int> >(r));
5549 DataArrayInt *ret=DataArrayInt::New();
5550 ret->alloc((int)r.size(),1);
5551 std::copy(r.begin(),r.end(),ret->getPointer());
5556 * \a this is expected to have one component and to be sorted ascendingly (as for \a other).
5557 * \a other is expected to be a part of \a this. If not DataArrayInt::buildSubstraction should be called instead.
5559 * \param [in] other an array with one component and expected to be sorted ascendingly.
5560 * \ret list of ids in \a this but not in \a other.
5561 * \sa DataArrayInt::buildSubstraction
5563 DataArrayInt *DataArrayInt::buildSubstractionOptimized(const DataArrayInt *other) const
5565 static const char *MSG="DataArrayInt::buildSubstractionOptimized : only single component allowed !";
5566 if(!other) throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstractionOptimized : NULL input array !");
5567 checkAllocated(); other->checkAllocated();
5568 if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
5569 if(other->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
5570 const int *pt1Bg(begin()),*pt1End(end()),*pt2Bg(other->begin()),*pt2End(other->end());
5571 const int *work1(pt1Bg),*work2(pt2Bg);
5572 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
5573 for(;work1!=pt1End;work1++)
5575 if(work2!=pt2End && *work1==*work2)
5578 ret->pushBackSilent(*work1);
5585 * Returns a new DataArrayInt which contains all elements of \a this and a given
5586 * one-dimensional arrays. The result array does not contain any duplicates
5587 * and its values are sorted in ascending order.
5588 * \param [in] other - an array to unite with \a this one.
5589 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5590 * array using decrRef() as it is no more needed.
5591 * \throw If \a this or \a other is not allocated.
5592 * \throw If \a this->getNumberOfComponents() != 1.
5593 * \throw If \a other->getNumberOfComponents() != 1.
5595 DataArrayInt *DataArrayInt::buildUnion(const DataArrayInt *other) const
5597 std::vector<const DataArrayInt *>arrs(2);
5598 arrs[0]=this; arrs[1]=other;
5599 return BuildUnion(arrs);
5604 * Returns a new DataArrayInt which contains elements present in both \a this and a given
5605 * one-dimensional arrays. The result array does not contain any duplicates
5606 * and its values are sorted in ascending order.
5607 * \param [in] other - an array to intersect with \a this one.
5608 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5609 * array using decrRef() as it is no more needed.
5610 * \throw If \a this or \a other is not allocated.
5611 * \throw If \a this->getNumberOfComponents() != 1.
5612 * \throw If \a other->getNumberOfComponents() != 1.
5614 DataArrayInt *DataArrayInt::buildIntersection(const DataArrayInt *other) const
5616 std::vector<const DataArrayInt *>arrs(2);
5617 arrs[0]=this; arrs[1]=other;
5618 return BuildIntersection(arrs);
5622 * This method can be applied on allocated with one component DataArrayInt instance.
5623 * This method is typically relevant for sorted arrays. All consecutive duplicated items in \a this will appear only once in returned DataArrayInt instance.
5624 * 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]
5626 * \return a newly allocated array that contain the result of the unique operation applied on \a this.
5627 * \throw if \a this is not allocated or if \a this has not exactly one component.
5628 * \sa DataArrayInt::buildUniqueNotSorted
5630 DataArrayInt *DataArrayInt::buildUnique() const
5633 if(getNumberOfComponents()!=1)
5634 throw INTERP_KERNEL::Exception("DataArrayInt::buildUnique : only single component allowed !");
5635 int nbOfTuples=getNumberOfTuples();
5636 MCAuto<DataArrayInt> tmp=deepCopy();
5637 int *data=tmp->getPointer();
5638 int *last=std::unique(data,data+nbOfTuples);
5639 MCAuto<DataArrayInt> ret=DataArrayInt::New();
5640 ret->alloc(std::distance(data,last),1);
5641 std::copy(data,last,ret->getPointer());
5646 * This method can be applied on allocated with one component DataArrayInt instance.
5647 * This method keep elements only once by keeping the same order in \a this that is not expected to be sorted.
5649 * \return a newly allocated array that contain the result of the unique operation applied on \a this.
5651 * \throw if \a this is not allocated or if \a this has not exactly one component.
5653 * \sa DataArrayInt::buildUnique
5655 DataArrayInt *DataArrayInt::buildUniqueNotSorted() const
5658 if(getNumberOfComponents()!=1)
5659 throw INTERP_KERNEL::Exception("DataArrayInt::buildUniqueNotSorted : only single component allowed !");
5661 getMinMaxValues(minVal,maxVal);
5662 std::vector<bool> b(maxVal-minVal+1,false);
5663 const int *ptBg(begin()),*endBg(end());
5664 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
5665 for(const int *pt=ptBg;pt!=endBg;pt++)
5669 ret->pushBackSilent(*pt);
5673 ret->copyStringInfoFrom(*this);
5678 * Returns a new DataArrayInt which contains size of every of groups described by \a this
5679 * "index" array. Such "index" array is returned for example by
5680 * \ref MEDCoupling::MEDCouplingUMesh::buildDescendingConnectivity
5681 * "MEDCouplingUMesh::buildDescendingConnectivity" and
5682 * \ref MEDCoupling::MEDCouplingUMesh::getNodalConnectivityIndex
5683 * "MEDCouplingUMesh::getNodalConnectivityIndex" etc.
5684 * This method performs the reverse operation of DataArrayInt::computeOffsetsFull.
5685 * \return DataArrayInt * - a new instance of DataArrayInt, whose number of tuples
5686 * equals to \a this->getNumberOfComponents() - 1, and number of components is 1.
5687 * The caller is to delete this array using decrRef() as it is no more needed.
5688 * \throw If \a this is not allocated.
5689 * \throw If \a this->getNumberOfComponents() != 1.
5690 * \throw If \a this->getNumberOfTuples() < 2.
5693 * - this contains [1,3,6,7,7,9,15]
5694 * - result array contains [2,3,1,0,2,6],
5695 * where 2 = 3 - 1, 3 = 6 - 3, 1 = 7 - 6 etc.
5697 * \sa DataArrayInt::computeOffsetsFull
5699 DataArrayInt *DataArrayInt::deltaShiftIndex() const
5702 if(getNumberOfComponents()!=1)
5703 throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : only single component allowed !");
5704 int nbOfTuples=getNumberOfTuples();
5706 throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : 1 tuple at least must be present in 'this' !");
5707 const int *ptr=getConstPointer();
5708 DataArrayInt *ret=DataArrayInt::New();
5709 ret->alloc(nbOfTuples-1,1);
5710 int *out=ret->getPointer();
5711 std::transform(ptr+1,ptr+nbOfTuples,ptr,out,std::minus<int>());
5716 * Modifies \a this one-dimensional array so that value of each element \a x
5717 * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
5718 * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number of tuples
5719 * and components remains the same.<br>
5720 * This method is useful for allToAllV in MPI with contiguous policy. This method
5721 * differs from computeOffsetsFull() in that the number of tuples is \b not changed by
5723 * \throw If \a this is not allocated.
5724 * \throw If \a this->getNumberOfComponents() != 1.
5727 * - Before \a this contains [3,5,1,2,0,8]
5728 * - After \a this contains [0,3,8,9,11,11]<br>
5729 * Note that the last element 19 = 11 + 8 is missing because size of \a this
5730 * array is retained and thus there is no space to store the last element.
5732 void DataArrayInt::computeOffsets()
5735 if(getNumberOfComponents()!=1)
5736 throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets : only single component allowed !");
5737 int nbOfTuples=getNumberOfTuples();
5740 int *work=getPointer();
5743 for(int i=1;i<nbOfTuples;i++)
5746 work[i]=work[i-1]+tmp;
5754 * Modifies \a this one-dimensional array so that value of each element \a x
5755 * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
5756 * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number
5757 * components remains the same and number of tuples is inceamented by one.<br>
5758 * This method is useful for allToAllV in MPI with contiguous policy. This method
5759 * differs from computeOffsets() in that the number of tuples is changed by this one.
5760 * This method performs the reverse operation of DataArrayInt::deltaShiftIndex.
5761 * \throw If \a this is not allocated.
5762 * \throw If \a this->getNumberOfComponents() != 1.
5765 * - Before \a this contains [3,5,1,2,0,8]
5766 * - After \a this contains [0,3,8,9,11,11,19]<br>
5767 * \sa DataArrayInt::deltaShiftIndex
5769 void DataArrayInt::computeOffsetsFull()
5772 if(getNumberOfComponents()!=1)
5773 throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsetsFull : only single component allowed !");
5774 int nbOfTuples=getNumberOfTuples();
5775 int *ret=(int *)malloc((nbOfTuples+1)*sizeof(int));
5776 const int *work=getConstPointer();
5778 for(int i=0;i<nbOfTuples;i++)
5779 ret[i+1]=work[i]+ret[i];
5780 useArray(ret,true,DeallocType::C_DEALLOC,nbOfTuples+1,1);
5785 * Returns two new DataArrayInt instances whose contents is computed from that of \a this and \a listOfIds arrays as follows.
5786 * \a this is expected to be an offset format ( as returned by DataArrayInt::computeOffsetsFull ) that is to say with one component
5787 * and ** sorted strictly increasingly **. \a listOfIds is expected to be sorted ascendingly (not strictly needed for \a listOfIds).
5788 * This methods searches in \a this, considered as a set of contiguous \c this->getNumberOfComponents() ranges, all ids in \a listOfIds
5789 * filling completely one of the ranges in \a this.
5791 * \param [in] listOfIds a list of ids that has to be sorted ascendingly.
5792 * \param [out] rangeIdsFetched the range ids fetched
5793 * \param [out] idsInInputListThatFetch contains the list of ids in \a listOfIds that are \b fully included in a range in \a this. So
5794 * \a idsInInputListThatFetch is a part of input \a listOfIds.
5796 * \sa DataArrayInt::computeOffsetsFull
5799 * - \a this : [0,3,7,9,15,18]
5800 * - \a listOfIds contains [0,1,2,3,7,8,15,16,17]
5801 * - \a rangeIdsFetched result array: [0,2,4]
5802 * - \a idsInInputListThatFetch result array: [0,1,2,7,8,15,16,17]
5803 * In this example id 3 in input \a listOfIds is alone so it do not appear in output \a idsInInputListThatFetch.
5806 void DataArrayInt::findIdsRangesInListOfIds(const DataArrayInt *listOfIds, DataArrayInt *& rangeIdsFetched, DataArrayInt *& idsInInputListThatFetch) const
5809 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : input list of ids is null !");
5810 listOfIds->checkAllocated(); checkAllocated();
5811 if(listOfIds->getNumberOfComponents()!=1)
5812 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : input list of ids must have exactly one component !");
5813 if(getNumberOfComponents()!=1)
5814 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : this must have exactly one component !");
5815 MCAuto<DataArrayInt> ret0=DataArrayInt::New(); ret0->alloc(0,1);
5816 MCAuto<DataArrayInt> ret1=DataArrayInt::New(); ret1->alloc(0,1);
5817 const int *tupEnd(listOfIds->end()),*offBg(begin()),*offEnd(end()-1);
5818 const int *tupPtr(listOfIds->begin()),*offPtr(offBg);
5819 while(tupPtr!=tupEnd && offPtr!=offEnd)
5821 if(*tupPtr==*offPtr)
5824 while(i<offPtr[1] && *tupPtr==i && tupPtr!=tupEnd) { i++; tupPtr++; }
5827 ret0->pushBackSilent((int)std::distance(offBg,offPtr));
5828 ret1->pushBackValsSilent(tupPtr-(offPtr[1]-offPtr[0]),tupPtr);
5833 { if(*tupPtr<*offPtr) tupPtr++; else offPtr++; }
5835 rangeIdsFetched=ret0.retn();
5836 idsInInputListThatFetch=ret1.retn();
5840 * Returns a new DataArrayInt whose contents is computed from that of \a this and \a
5841 * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
5842 * "index" array of a "iota" array, thus, whose each element gives an index of a group
5843 * beginning within the "iota" array. And \a this is a one-dimensional array
5844 * considered as a selector of groups described by \a offsets to include into the result array.
5845 * \throw If \a offsets is NULL.
5846 * \throw If \a offsets is not allocated.
5847 * \throw If \a offsets->getNumberOfComponents() != 1.
5848 * \throw If \a offsets is not monotonically increasing.
5849 * \throw If \a this is not allocated.
5850 * \throw If \a this->getNumberOfComponents() != 1.
5851 * \throw If any element of \a this is not a valid index for \a offsets array.
5854 * - \a this: [0,2,3]
5855 * - \a offsets: [0,3,6,10,14,20]
5856 * - result array: [0,1,2,6,7,8,9,10,11,12,13] == <br>
5857 * \c range(0,3) + \c range(6,10) + \c range(10,14) ==<br>
5858 * \c range( \a offsets[ \a this[0] ], offsets[ \a this[0]+1 ]) +
5859 * \c range( \a offsets[ \a this[1] ], offsets[ \a this[1]+1 ]) +
5860 * \c range( \a offsets[ \a this[2] ], offsets[ \a this[2]+1 ])
5862 DataArrayInt *DataArrayInt::buildExplicitArrByRanges(const DataArrayInt *offsets) const
5865 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : DataArrayInt pointer in input is NULL !");
5867 if(getNumberOfComponents()!=1)
5868 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : only single component allowed !");
5869 offsets->checkAllocated();
5870 if(offsets->getNumberOfComponents()!=1)
5871 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : input array should have only single component !");
5872 int othNbTuples=offsets->getNumberOfTuples()-1;
5873 int nbOfTuples=getNumberOfTuples();
5874 int retNbOftuples=0;
5875 const int *work=getConstPointer();
5876 const int *offPtr=offsets->getConstPointer();
5877 for(int i=0;i<nbOfTuples;i++)
5880 if(val>=0 && val<othNbTuples)
5882 int delta=offPtr[val+1]-offPtr[val];
5884 retNbOftuples+=delta;
5887 std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << val << " of offset array has a delta < 0 !";
5888 throw INTERP_KERNEL::Exception(oss.str().c_str());
5893 std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << i << " in this contains " << val;
5894 oss << " whereas offsets array is of size " << othNbTuples+1 << " !";
5895 throw INTERP_KERNEL::Exception(oss.str().c_str());
5898 MCAuto<DataArrayInt> ret=DataArrayInt::New();
5899 ret->alloc(retNbOftuples,1);
5900 int *retPtr=ret->getPointer();
5901 for(int i=0;i<nbOfTuples;i++)
5904 int start=offPtr[val];
5905 int off=offPtr[val+1]-start;
5906 for(int j=0;j<off;j++,retPtr++)
5913 * Returns a new DataArrayInt whose contents is computed using \a this that must be a
5914 * scaled array (monotonically increasing).
5915 from that of \a this and \a
5916 * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
5917 * "index" array of a "iota" array, thus, whose each element gives an index of a group
5918 * beginning within the "iota" array. And \a this is a one-dimensional array
5919 * considered as a selector of groups described by \a offsets to include into the result array.
5920 * \throw If \a is NULL.
5921 * \throw If \a this is not allocated.
5922 * \throw If \a this->getNumberOfComponents() != 1.
5923 * \throw If \a this->getNumberOfTuples() == 0.
5924 * \throw If \a this is not monotonically increasing.
5925 * \throw If any element of ids in ( \a bg \a stop \a step ) points outside the scale in \a this.
5928 * - \a bg , \a stop and \a step : (0,5,2)
5929 * - \a this: [0,3,6,10,14,20]
5930 * - result array: [0,0,0, 2,2,2,2, 4,4,4,4,4,4] == <br>
5932 DataArrayInt *DataArrayInt::buildExplicitArrOfSliceOnScaledArr(int bg, int stop, int step) const
5935 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : not allocated array !");
5936 if(getNumberOfComponents()!=1)
5937 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of components is expected to be equal to one !");
5938 int nbOfTuples(getNumberOfTuples());
5940 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of tuples must be != 0 !");
5941 const int *ids(begin());
5942 int nbOfEltsInSlc(GetNumberOfItemGivenBESRelative(bg,stop,step,"DataArrayInt::buildExplicitArrOfSliceOnScaledArr")),sz(0),pos(bg);
5943 for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
5945 if(pos>=0 && pos<nbOfTuples-1)
5947 int delta(ids[pos+1]-ids[pos]);
5951 std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " and at this pos this is not monotonically increasing !";
5952 throw INTERP_KERNEL::Exception(oss.str().c_str());
5957 std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " should be in [0," << nbOfTuples-1 << ") !";
5958 throw INTERP_KERNEL::Exception(oss.str().c_str());
5961 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
5962 int *retPtr(ret->getPointer());
5964 for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
5966 int delta(ids[pos+1]-ids[pos]);
5967 for(int j=0;j<delta;j++,retPtr++)
5974 * 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.
5975 * 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
5976 * in tuple **i** of returned DataArrayInt.
5977 * If ranges overlapped (in theory it should not) this method do not detect it and always returns the first range.
5979 * 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)]
5980 * The return DataArrayInt will contain : **[0,4,1,2,2,3]**
5982 * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
5983 * for lower value included and 2nd component is the upper value of corresponding range **excluded**.
5984 * \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
5985 * is thrown if no ranges in \a ranges contains value in \a this.
5987 * \sa DataArrayInt::findIdInRangeForEachTuple
5989 DataArrayInt *DataArrayInt::findRangeIdForEachTuple(const DataArrayInt *ranges) const
5992 throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : null input pointer !");
5993 if(ranges->getNumberOfComponents()!=2)
5994 throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : input DataArrayInt instance should have 2 components !");
5996 if(getNumberOfComponents()!=1)
5997 throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : this should have only one component !");
5998 int nbTuples=getNumberOfTuples();
5999 MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
6000 int nbOfRanges=ranges->getNumberOfTuples();
6001 const int *rangesPtr=ranges->getConstPointer();
6002 int *retPtr=ret->getPointer();
6003 const int *inPtr=getConstPointer();
6004 for(int i=0;i<nbTuples;i++,retPtr++)
6008 for(int j=0;j<nbOfRanges && !found;j++)
6009 if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
6010 { *retPtr=j; found=true; }
6015 std::ostringstream oss; oss << "DataArrayInt::findRangeIdForEachTuple : tuple #" << i << " not found by any ranges !";
6016 throw INTERP_KERNEL::Exception(oss.str().c_str());
6023 * 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.
6024 * 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
6025 * in tuple **i** of returned DataArrayInt.
6026 * If ranges overlapped (in theory it should not) this method do not detect it and always returns the sub position of the first range.
6028 * 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)]
6029 * The return DataArrayInt will contain : **[1,2,4,0,2,2]**
6030 * This method is often called in pair with DataArrayInt::findRangeIdForEachTuple method.
6032 * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
6033 * for lower value included and 2nd component is the upper value of corresponding range **excluded**.
6034 * \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
6035 * is thrown if no ranges in \a ranges contains value in \a this.
6036 * \sa DataArrayInt::findRangeIdForEachTuple
6038 DataArrayInt *DataArrayInt::findIdInRangeForEachTuple(const DataArrayInt *ranges) const
6041 throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : null input pointer !");
6042 if(ranges->getNumberOfComponents()!=2)
6043 throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : input DataArrayInt instance should have 2 components !");
6045 if(getNumberOfComponents()!=1)
6046 throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : this should have only one component !");
6047 int nbTuples=getNumberOfTuples();
6048 MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
6049 int nbOfRanges=ranges->getNumberOfTuples();
6050 const int *rangesPtr=ranges->getConstPointer();
6051 int *retPtr=ret->getPointer();
6052 const int *inPtr=getConstPointer();
6053 for(int i=0;i<nbTuples;i++,retPtr++)
6057 for(int j=0;j<nbOfRanges && !found;j++)
6058 if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
6059 { *retPtr=val-rangesPtr[2*j]; found=true; }
6064 std::ostringstream oss; oss << "DataArrayInt::findIdInRangeForEachTuple : tuple #" << i << " not found by any ranges !";
6065 throw INTERP_KERNEL::Exception(oss.str().c_str());
6072 * \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).
6073 * 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).
6074 * 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 !
6075 * If this method has correctly worked, \a this will be able to be considered as a linked list.
6076 * This method does nothing if number of tuples is lower of equal to 1.
6078 * This method is useful for users having an unstructured mesh having only SEG2 to rearrange internally the connectivity without any coordinates consideration.
6080 * \sa MEDCouplingUMesh::orderConsecutiveCells1D, DataArrayInt::fromLinkedListOfPairToList
6082 void DataArrayInt::sortEachPairToMakeALinkedList()
6085 if(getNumberOfComponents()!=2)
6086 throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : Only works on DataArrayInt instance with nb of components equal to 2 !");
6087 int nbOfTuples(getNumberOfTuples());
6090 int *conn(getPointer());
6091 for(int i=1;i<nbOfTuples;i++,conn+=2)
6095 if(conn[2]==conn[3])
6097 std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " presence of a pair filled with same ids !";
6098 throw INTERP_KERNEL::Exception(oss.str().c_str());
6100 if(conn[2]!=conn[1] && conn[3]==conn[1] && conn[2]!=conn[0])
6101 std::swap(conn[2],conn[3]);
6102 //not(conn[2]==conn[1] && conn[3]!=conn[1] && conn[3]!=conn[0])
6103 if(conn[2]!=conn[1] || conn[3]==conn[1] || conn[3]==conn[0])
6105 std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " something is invalid !";
6106 throw INTERP_KERNEL::Exception(oss.str().c_str());
6111 if(conn[0]==conn[1] || conn[2]==conn[3])
6112 throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : In the 2 first tuples presence of a pair filled with same ids !");
6115 s.insert(conn,conn+4);
6117 throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : This can't be considered as a linked list regarding 2 first tuples !");
6118 if(std::count(conn,conn+4,conn[0])==2)
6123 if(conn[2]==conn[0])
6127 std::copy(tmp,tmp+4,conn);
6130 {//here we are sure to have (std::count(conn,conn+4,conn[1])==2)
6131 if(conn[1]==conn[3])
6132 std::swap(conn[2],conn[3]);
6139 * \a this is expected to be a correctly linked list of pairs.
6141 * \sa DataArrayInt::sortEachPairToMakeALinkedList
6143 MCAuto<DataArrayInt> DataArrayInt::fromLinkedListOfPairToList() const
6146 checkNbOfComps(2,"DataArrayInt::fromLinkedListOfPairToList : this is expected to have 2 components");
6147 int nbTuples(getNumberOfTuples());
6149 throw INTERP_KERNEL::Exception("DataArrayInt::fromLinkedListOfPairToList : no tuples in this ! Not a linked list !");
6150 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbTuples+1,1);
6151 const int *thisPtr(begin());
6152 int *retPtr(ret->getPointer());
6153 retPtr[0]=thisPtr[0];
6154 for(int i=0;i<nbTuples;i++)
6156 retPtr[i+1]=thisPtr[2*i+1];
6158 if(thisPtr[2*i+1]!=thisPtr[2*(i+1)+0])
6160 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 ?";
6161 throw INTERP_KERNEL::Exception(oss.str());
6168 * This method returns all different values found in \a this. This method throws if \a this has not been allocated.
6169 * But the number of components can be different from one.
6170 * \return a newly allocated array (that should be dealt by the caller) containing different values in \a this.
6172 DataArrayInt *DataArrayInt::getDifferentValues() const
6176 ret.insert(begin(),end());
6177 MCAuto<DataArrayInt> ret2=DataArrayInt::New(); ret2->alloc((int)ret.size(),1);
6178 std::copy(ret.begin(),ret.end(),ret2->getPointer());
6183 * This method is a refinement of DataArrayInt::getDifferentValues because it returns not only different values in \a this but also, for each of
6184 * them it tells which tuple id have this id.
6185 * This method works only on arrays with one component (if it is not the case call DataArrayInt::rearrange(1) ).
6186 * This method returns two arrays having same size.
6187 * 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.
6188 * 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]]
6190 std::vector<DataArrayInt *> DataArrayInt::partitionByDifferentValues(std::vector<int>& differentIds) const
6193 if(getNumberOfComponents()!=1)
6194 throw INTERP_KERNEL::Exception("DataArrayInt::partitionByDifferentValues : this should have only one component !");
6196 std::map<int,int> m,m2,m3;
6197 for(const int *w=begin();w!=end();w++)
6199 differentIds.resize(m.size());
6200 std::vector<DataArrayInt *> ret(m.size());
6201 std::vector<int *> retPtr(m.size());
6202 for(std::map<int,int>::const_iterator it=m.begin();it!=m.end();it++,id++)
6205 ret[id]=DataArrayInt::New();
6206 ret[id]->alloc((*it).second,1);
6207 retPtr[id]=ret[id]->getPointer();
6208 differentIds[id]=(*it).first;
6211 for(const int *w=begin();w!=end();w++,id++)
6213 retPtr[m2[*w]][m3[*w]++]=id;
6219 * This method split ids in [0, \c this->getNumberOfTuples() ) using \a this array as a field of weight (>=0 each).
6220 * The aim of this method is to return a set of \a nbOfSlices chunk of contiguous ids as balanced as possible.
6222 * \param [in] nbOfSlices - number of slices expected.
6223 * \return - a vector having a size equal to \a nbOfSlices giving the start (included) and the stop (excluded) of each chunks.
6225 * \sa DataArray::GetSlice
6226 * \throw If \a this is not allocated or not with exactly one component.
6227 * \throw If an element in \a this if < 0.
6229 std::vector< std::pair<int,int> > DataArrayInt::splitInBalancedSlices(int nbOfSlices) const
6231 if(!isAllocated() || getNumberOfComponents()!=1)
6232 throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : this array should have number of components equal to one and must be allocated !");
6234 throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : number of slices must be >= 1 !");
6235 int sum(accumulate(0)),nbOfTuples(getNumberOfTuples());
6236 int sumPerSlc(sum/nbOfSlices),pos(0);
6237 const int *w(begin());
6238 std::vector< std::pair<int,int> > ret(nbOfSlices);
6239 for(int i=0;i<nbOfSlices;i++)
6241 std::pair<int,int> p(pos,-1);
6243 while(locSum<sumPerSlc && pos<nbOfTuples) { pos++; locSum+=*w++; }
6247 p.second=nbOfTuples;
6254 * Returns a new DataArrayInt that is a modulus of two given arrays. There are 3
6256 * 1. The arrays have same number of tuples and components. Then each value of
6257 * the result array (_a_) is a division of the corresponding values of \a a1 and
6258 * \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, j ].
6259 * 2. The arrays have same number of tuples and one array, say _a2_, has one
6261 * _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, 0 ].
6262 * 3. The arrays have same number of components and one array, say _a2_, has one
6264 * _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ 0, j ].
6266 * Info on components is copied either from the first array (in the first case) or from
6267 * the array with maximal number of elements (getNbOfElems()).
6268 * \warning No check of division by zero is performed!
6269 * \param [in] a1 - a dividend array.
6270 * \param [in] a2 - a divisor array.
6271 * \return DataArrayInt * - the new instance of DataArrayInt.
6272 * The caller is to delete this result array using decrRef() as it is no more
6274 * \throw If either \a a1 or \a a2 is NULL.
6275 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
6276 * \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
6277 * none of them has number of tuples or components equal to 1.
6279 DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt *a2)
6282 throw INTERP_KERNEL::Exception("DataArrayInt::Modulus : input DataArrayInt instance is NULL !");
6283 int nbOfTuple1=a1->getNumberOfTuples();
6284 int nbOfTuple2=a2->getNumberOfTuples();
6285 int nbOfComp1=a1->getNumberOfComponents();
6286 int nbOfComp2=a2->getNumberOfComponents();
6287 if(nbOfTuple2==nbOfTuple1)
6289 if(nbOfComp1==nbOfComp2)
6291 MCAuto<DataArrayInt> ret=DataArrayInt::New();
6292 ret->alloc(nbOfTuple2,nbOfComp1);
6293 std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::modulus<int>());
6294 ret->copyStringInfoFrom(*a1);
6297 else if(nbOfComp2==1)
6299 MCAuto<DataArrayInt> ret=DataArrayInt::New();
6300 ret->alloc(nbOfTuple1,nbOfComp1);
6301 const int *a2Ptr=a2->getConstPointer();
6302 const int *a1Ptr=a1->getConstPointer();
6303 int *res=ret->getPointer();
6304 for(int i=0;i<nbOfTuple1;i++)
6305 res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::modulus<int>(),a2Ptr[i]));
6306 ret->copyStringInfoFrom(*a1);
6311 a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
6315 else if(nbOfTuple2==1)
6317 a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
6318 MCAuto<DataArrayInt> ret=DataArrayInt::New();
6319 ret->alloc(nbOfTuple1,nbOfComp1);
6320 const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
6321 int *pt=ret->getPointer();
6322 for(int i=0;i<nbOfTuple1;i++)
6323 pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::modulus<int>());
6324 ret->copyStringInfoFrom(*a1);
6329 a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Modulus !");//will always throw an exception
6335 * Modify \a this array so that each value becomes a modulus of division of this value by
6336 * a value of another DataArrayInt. There are 3 valid cases.
6337 * 1. The arrays have same number of tuples and components. Then each value of
6338 * \a this array is divided by the corresponding value of \a other one, i.e.:
6339 * _a_ [ i, j ] %= _other_ [ i, j ].
6340 * 2. The arrays have same number of tuples and \a other array has one component. Then
6341 * _a_ [ i, j ] %= _other_ [ i, 0 ].
6342 * 3. The arrays have same number of components and \a other array has one tuple. Then
6343 * _a_ [ i, j ] %= _a2_ [ 0, j ].
6345 * \warning No check of division by zero is performed!
6346 * \param [in] other - a divisor array.
6347 * \throw If \a other is NULL.
6348 * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
6349 * \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
6350 * \a other has number of both tuples and components not equal to 1.
6352 void DataArrayInt::modulusEqual(const DataArrayInt *other)
6355 throw INTERP_KERNEL::Exception("DataArrayInt::modulusEqual : input DataArrayInt instance is NULL !");
6356 const char *msg="Nb of tuples mismatch for DataArrayInt::modulusEqual !";
6357 checkAllocated(); other->checkAllocated();
6358 int nbOfTuple=getNumberOfTuples();
6359 int nbOfTuple2=other->getNumberOfTuples();
6360 int nbOfComp=getNumberOfComponents();
6361 int nbOfComp2=other->getNumberOfComponents();
6362 if(nbOfTuple==nbOfTuple2)
6364 if(nbOfComp==nbOfComp2)
6366 std::transform(begin(),end(),other->begin(),getPointer(),std::modulus<int>());
6368 else if(nbOfComp2==1)
6370 if(nbOfComp2==nbOfComp)
6372 int *ptr=getPointer();
6373 const int *ptrc=other->getConstPointer();
6374 for(int i=0;i<nbOfTuple;i++)
6375 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::modulus<int>(),*ptrc++));
6378 throw INTERP_KERNEL::Exception(msg);
6381 throw INTERP_KERNEL::Exception(msg);
6383 else if(nbOfTuple2==1)
6385 int *ptr=getPointer();
6386 const int *ptrc=other->getConstPointer();
6387 for(int i=0;i<nbOfTuple;i++)
6388 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::modulus<int>());
6391 throw INTERP_KERNEL::Exception(msg);
6396 * Returns a new DataArrayInt that is the result of pow of two given arrays. There are 3
6399 * \param [in] a1 - an array to pow up.
6400 * \param [in] a2 - another array to sum up.
6401 * \return DataArrayInt * - the new instance of DataArrayInt.
6402 * The caller is to delete this result array using decrRef() as it is no more
6404 * \throw If either \a a1 or \a a2 is NULL.
6405 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
6406 * \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
6407 * \throw If there is a negative value in \a a2.
6409 DataArrayInt *DataArrayInt::Pow(const DataArrayInt *a1, const DataArrayInt *a2)
6412 throw INTERP_KERNEL::Exception("DataArrayInt::Pow : at least one of input instances is null !");
6413 int nbOfTuple=a1->getNumberOfTuples();
6414 int nbOfTuple2=a2->getNumberOfTuples();
6415 int nbOfComp=a1->getNumberOfComponents();
6416 int nbOfComp2=a2->getNumberOfComponents();
6417 if(nbOfTuple!=nbOfTuple2)
6418 throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of tuples mismatches !");
6419 if(nbOfComp!=1 || nbOfComp2!=1)
6420 throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of components of both arrays must be equal to 1 !");
6421 MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuple,1);
6422 const int *ptr1(a1->begin()),*ptr2(a2->begin());
6423 int *ptr=ret->getPointer();
6424 for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
6429 for(int j=0;j<*ptr2;j++)
6435 std::ostringstream oss; oss << "DataArrayInt::Pow : on tuple #" << i << " of a2 value is < 0 (" << *ptr2 << ") !";
6436 throw INTERP_KERNEL::Exception(oss.str().c_str());
6443 * Apply pow on values of another DataArrayInt to values of \a this one.
6445 * \param [in] other - an array to pow to \a this one.
6446 * \throw If \a other is NULL.
6447 * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
6448 * \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
6449 * \throw If there is a negative value in \a other.
6451 void DataArrayInt::powEqual(const DataArrayInt *other)
6454 throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : input instance is null !");
6455 int nbOfTuple=getNumberOfTuples();
6456 int nbOfTuple2=other->getNumberOfTuples();
6457 int nbOfComp=getNumberOfComponents();
6458 int nbOfComp2=other->getNumberOfComponents();
6459 if(nbOfTuple!=nbOfTuple2)
6460 throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of tuples mismatches !");
6461 if(nbOfComp!=1 || nbOfComp2!=1)
6462 throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of components of both arrays must be equal to 1 !");
6463 int *ptr=getPointer();
6464 const int *ptrc=other->begin();
6465 for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
6470 for(int j=0;j<*ptrc;j++)
6476 std::ostringstream oss; oss << "DataArrayInt::powEqual : on tuple #" << i << " of other value is < 0 (" << *ptrc << ") !";
6477 throw INTERP_KERNEL::Exception(oss.str().c_str());
6484 * This method works on a pair input (\b arrIn, \b arrIndxIn) where \b arrIn indexes is in \b arrIndxIn
6485 * (\ref numbering-indirect).
6486 * This method returns the result of the extraction ( specified by a set of ids in [\b idsOfSelectBg , \b idsOfSelectEnd ) ).
6487 * The selection of extraction is done standardly in new2old format.
6488 * This method returns indexed arrays (\ref numbering-indirect) using 2 arrays (arrOut,arrIndexOut).
6490 * \param [in] idsOfSelectBg begin of set of ids of the input extraction (included)
6491 * \param [in] idsOfSelectEnd end of set of ids of the input extraction (excluded)
6492 * \param [in] arrIn arr origin array from which the extraction will be done.
6493 * \param [in] arrIndxIn is the input index array allowing to walk into \b arrIn
6494 * \param [out] arrOut the resulting array
6495 * \param [out] arrIndexOut the index array of the resulting array \b arrOut
6496 * \sa DataArrayInt::ExtractFromIndexedArraysSlice
6498 void DataArrayInt::ExtractFromIndexedArrays(const int *idsOfSelectBg, const int *idsOfSelectEnd, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn,
6499 DataArrayInt* &arrOut, DataArrayInt* &arrIndexOut)
6501 if(!arrIn || !arrIndxIn)
6502 throw INTERP_KERNEL::Exception("DataArrayInt::ExtractFromIndexedArrays : input pointer is NULL !");
6503 arrIn->checkAllocated(); arrIndxIn->checkAllocated();
6504 if(arrIn->getNumberOfComponents()!=1 || arrIndxIn->getNumberOfComponents()!=1)
6505 throw INTERP_KERNEL::Exception("DataArrayInt::ExtractFromIndexedArrays : input arrays must have exactly one component !");
6506 std::size_t sz=std::distance(idsOfSelectBg,idsOfSelectEnd);
6507 const int *arrInPtr=arrIn->begin();
6508 const int *arrIndxPtr=arrIndxIn->begin();
6509 int nbOfGrps=arrIndxIn->getNumberOfTuples()-1;
6511 throw INTERP_KERNEL::Exception("DataArrayInt::ExtractFromIndexedArrays : The format of \"arrIndxIn\" is invalid ! Its nb of tuples should be >=1 !");
6512 int maxSizeOfArr=arrIn->getNumberOfTuples();
6513 MCAuto<DataArrayInt> arro=DataArrayInt::New();
6514 MCAuto<DataArrayInt> arrIo=DataArrayInt::New();
6515 arrIo->alloc((int)(sz+1),1);
6516 const int *idsIt=idsOfSelectBg;
6517 int *work=arrIo->getPointer();
6520 for(std::size_t i=0;i<sz;i++,work++,idsIt++)
6522 if(*idsIt>=0 && *idsIt<nbOfGrps)
6523 lgth+=arrIndxPtr[*idsIt+1]-arrIndxPtr[*idsIt];
6526 std::ostringstream oss; oss << "DataArrayInt::ExtractFromIndexedArrays : id located on pos #" << i << " value is " << *idsIt << " ! Must be in [0," << nbOfGrps << ") !";
6527 throw INTERP_KERNEL::Exception(oss.str());
6533 std::ostringstream oss; oss << "DataArrayInt::ExtractFromIndexedArrays : id located on pos #" << i << " value is " << *idsIt << " and at this pos arrIndxIn[" << *idsIt;
6534 oss << "+1]-arrIndxIn[" << *idsIt << "] < 0 ! The input index array is bugged !";
6535 throw INTERP_KERNEL::Exception(oss.str());
6538 arro->alloc(lgth,1);
6539 work=arro->getPointer();
6540 idsIt=idsOfSelectBg;
6541 for(std::size_t i=0;i<sz;i++,idsIt++)
6543 if(arrIndxPtr[*idsIt]>=0 && arrIndxPtr[*idsIt+1]<=maxSizeOfArr)
6544 work=std::copy(arrInPtr+arrIndxPtr[*idsIt],arrInPtr+arrIndxPtr[*idsIt+1],work);
6547 std::ostringstream oss; oss << "DataArrayInt::ExtractFromIndexedArrays : id located on pos #" << i << " value is " << *idsIt << " arrIndx[" << *idsIt << "] must be >= 0 and arrIndx[";
6548 oss << *idsIt << "+1] <= " << maxSizeOfArr << " (the size of arrIn)!";
6549 throw INTERP_KERNEL::Exception(oss.str());
6553 arrIndexOut=arrIo.retn();
6557 * This method works on a pair input (\b arrIn, \b arrIndxIn) where \b arrIn indexes is in \b arrIndxIn
6558 * (\ref numbering-indirect).
6559 * This method returns the result of the extraction ( specified by a set of ids with a slice given by \a idsOfSelectStart, \a idsOfSelectStop and \a idsOfSelectStep ).
6560 * The selection of extraction is done standardly in new2old format.
6561 * This method returns indexed arrays (\ref numbering-indirect) using 2 arrays (arrOut,arrIndexOut).
6563 * \param [in] idsOfSelectStart begin of set of ids of the input extraction (included)
6564 * \param [in] idsOfSelectStop end of set of ids of the input extraction (excluded)
6565 * \param [in] idsOfSelectStep
6566 * \param [in] arrIn arr origin array from which the extraction will be done.
6567 * \param [in] arrIndxIn is the input index array allowing to walk into \b arrIn
6568 * \param [out] arrOut the resulting array
6569 * \param [out] arrIndexOut the index array of the resulting array \b arrOut
6570 * \sa DataArrayInt::ExtractFromIndexedArrays
6572 void DataArrayInt::ExtractFromIndexedArraysSlice(int idsOfSelectStart, int idsOfSelectStop, int idsOfSelectStep, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn,
6573 DataArrayInt* &arrOut, DataArrayInt* &arrIndexOut)
6575 if(!arrIn || !arrIndxIn)
6576 throw INTERP_KERNEL::Exception("DataArrayInt::ExtractFromIndexedArraysSlice : input pointer is NULL !");
6577 arrIn->checkAllocated(); arrIndxIn->checkAllocated();
6578 if(arrIn->getNumberOfComponents()!=1 || arrIndxIn->getNumberOfComponents()!=1)
6579 throw INTERP_KERNEL::Exception("DataArrayInt::ExtractFromIndexedArraysSlice : input arrays must have exactly one component !");
6580 int sz=DataArrayInt::GetNumberOfItemGivenBESRelative(idsOfSelectStart,idsOfSelectStop,idsOfSelectStep,"MEDCouplingUMesh::ExtractFromIndexedArraysSlice : Input slice ");
6581 const int *arrInPtr=arrIn->begin();
6582 const int *arrIndxPtr=arrIndxIn->begin();
6583 int nbOfGrps=arrIndxIn->getNumberOfTuples()-1;
6585 throw INTERP_KERNEL::Exception("DataArrayInt::ExtractFromIndexedArraysSlice : The format of \"arrIndxIn\" is invalid ! Its nb of tuples should be >=1 !");
6586 int maxSizeOfArr=arrIn->getNumberOfTuples();
6587 MCAuto<DataArrayInt> arro=DataArrayInt::New();
6588 MCAuto<DataArrayInt> arrIo=DataArrayInt::New();
6589 arrIo->alloc((int)(sz+1),1);
6590 int idsIt=idsOfSelectStart;
6591 int *work=arrIo->getPointer();
6594 for(int i=0;i<sz;i++,work++,idsIt+=idsOfSelectStep)
6596 if(idsIt>=0 && idsIt<nbOfGrps)
6597 lgth+=arrIndxPtr[idsIt+1]-arrIndxPtr[idsIt];
6600 std::ostringstream oss; oss << "DataArrayInt::ExtractFromIndexedArraysSlice : id located on pos #" << i << " value is " << idsIt << " ! Must be in [0," << nbOfGrps << ") !";
6601 throw INTERP_KERNEL::Exception(oss.str());
6607 std::ostringstream oss; oss << "DataArrayInt::ExtractFromIndexedArraysSlice : id located on pos #" << i << " value is " << idsIt << " and at this pos arrIndxIn[" << idsIt;
6608 oss << "+1]-arrIndxIn[" << idsIt << "] < 0 ! The input index array is bugged !";
6609 throw INTERP_KERNEL::Exception(oss.str());
6612 arro->alloc(lgth,1);
6613 work=arro->getPointer();
6614 idsIt=idsOfSelectStart;
6615 for(int i=0;i<sz;i++,idsIt+=idsOfSelectStep)
6617 if(arrIndxPtr[idsIt]>=0 && arrIndxPtr[idsIt+1]<=maxSizeOfArr)
6618 work=std::copy(arrInPtr+arrIndxPtr[idsIt],arrInPtr+arrIndxPtr[idsIt+1],work);
6621 std::ostringstream oss; oss << "DataArrayInt::ExtractFromIndexedArraysSlice : id located on pos #" << i << " value is " << idsIt << " arrIndx[" << idsIt << "] must be >= 0 and arrIndx[";
6622 oss << idsIt << "+1] <= " << maxSizeOfArr << " (the size of arrIn)!";
6623 throw INTERP_KERNEL::Exception(oss.str());
6627 arrIndexOut=arrIo.retn();
6631 * This method works on an input pair (\b arrIn, \b arrIndxIn) where \b arrIn indexes is in \b arrIndxIn.
6632 * This method builds an output pair (\b arrOut,\b arrIndexOut) that is a copy from \b arrIn for all cell ids \b not \b in [ \b idsOfSelectBg , \b idsOfSelectEnd ) and for
6633 * cellIds \b in [ \b idsOfSelectBg , \b idsOfSelectEnd ) a copy coming from the corresponding values in input pair (\b srcArr, \b srcArrIndex).
6634 * This method is an generalization of MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx that performs the same thing but by without building explicitly a result output arrays.
6636 * \param [in] idsOfSelectBg begin of set of ids of the input extraction (included)
6637 * \param [in] idsOfSelectEnd end of set of ids of the input extraction (excluded)
6638 * \param [in] arrIn arr origin array from which the extraction will be done.
6639 * \param [in] arrIndxIn is the input index array allowing to walk into \b arrIn
6640 * \param [in] srcArr input array that will be used as source of copy for ids in [ \b idsOfSelectBg, \b idsOfSelectEnd )
6641 * \param [in] srcArrIndex index array of \b srcArr
6642 * \param [out] arrOut the resulting array
6643 * \param [out] arrIndexOut the index array of the resulting array \b arrOut
6645 * \sa DataArrayInt::SetPartOfIndexedArraysSameIdx
6647 void DataArrayInt::SetPartOfIndexedArrays(const int *idsOfSelectBg, const int *idsOfSelectEnd, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn,
6648 const DataArrayInt *srcArr, const DataArrayInt *srcArrIndex,
6649 DataArrayInt* &arrOut, DataArrayInt* &arrIndexOut)
6651 if(arrIn==0 || arrIndxIn==0 || srcArr==0 || srcArrIndex==0)
6652 throw INTERP_KERNEL::Exception("DataArrayInt::SetPartOfIndexedArrays : presence of null pointer in input parameter !");
6653 MCAuto<DataArrayInt> arro=DataArrayInt::New();
6654 MCAuto<DataArrayInt> arrIo=DataArrayInt::New();
6655 int nbOfTuples=arrIndxIn->getNumberOfTuples()-1;
6656 std::vector<bool> v(nbOfTuples,true);
6658 const int *arrIndxInPtr=arrIndxIn->begin();
6659 const int *srcArrIndexPtr=srcArrIndex->begin();
6660 for(const int *it=idsOfSelectBg;it!=idsOfSelectEnd;it++,srcArrIndexPtr++)
6662 if(*it>=0 && *it<nbOfTuples)
6665 offset+=(srcArrIndexPtr[1]-srcArrIndexPtr[0])-(arrIndxInPtr[*it+1]-arrIndxInPtr[*it]);
6669 std::ostringstream oss; oss << "DataArrayInt::SetPartOfIndexedArrays : On pos #" << std::distance(idsOfSelectBg,it) << " value is " << *it << " not in [0," << nbOfTuples << ") !";
6670 throw INTERP_KERNEL::Exception(oss.str());
6673 srcArrIndexPtr=srcArrIndex->begin();
6674 arrIo->alloc(nbOfTuples+1,1);
6675 arro->alloc(arrIn->getNumberOfTuples()+offset,1);
6676 const int *arrInPtr=arrIn->begin();
6677 const int *srcArrPtr=srcArr->begin();
6678 int *arrIoPtr=arrIo->getPointer(); *arrIoPtr++=0;
6679 int *arroPtr=arro->getPointer();
6680 for(int ii=0;ii<nbOfTuples;ii++,arrIoPtr++)
6684 arroPtr=std::copy(arrInPtr+arrIndxInPtr[ii],arrInPtr+arrIndxInPtr[ii+1],arroPtr);
6685 *arrIoPtr=arrIoPtr[-1]+(arrIndxInPtr[ii+1]-arrIndxInPtr[ii]);
6689 std::size_t pos=std::distance(idsOfSelectBg,std::find(idsOfSelectBg,idsOfSelectEnd,ii));
6690 arroPtr=std::copy(srcArrPtr+srcArrIndexPtr[pos],srcArrPtr+srcArrIndexPtr[pos+1],arroPtr);
6691 *arrIoPtr=arrIoPtr[-1]+(srcArrIndexPtr[pos+1]-srcArrIndexPtr[pos]);
6695 arrIndexOut=arrIo.retn();
6700 * This method works on an input pair (\b arrIn, \b arrIndxIn) where \b arrIn indexes is in \b arrIndxIn.
6701 * This method builds an output pair (\b arrOut,\b arrIndexOut) that is a copy from \b arrIn for all cell ids \b not \b in [ \b idsOfSelectBg , \b idsOfSelectEnd ) and for
6702 * cellIds \b in [\b idsOfSelectBg, \b idsOfSelectEnd) a copy coming from the corresponding values in input pair (\b srcArr, \b srcArrIndex).
6703 * This method is an generalization of DataArrayInt::SetPartOfIndexedArraysSameIdx that performs the same thing but by without building explicitly a result output arrays.
6705 * \param [in] start begin of set of ids of the input extraction (included)
6706 * \param [in] end end of set of ids of the input extraction (excluded)
6707 * \param [in] step step of the set of ids in range mode.
6708 * \param [in] arrIn arr origin array from which the extraction will be done.
6709 * \param [in] arrIndxIn is the input index array allowing to walk into \b arrIn
6710 * \param [in] srcArr input array that will be used as source of copy for ids in [\b idsOfSelectBg, \b idsOfSelectEnd)
6711 * \param [in] srcArrIndex index array of \b srcArr
6712 * \param [out] arrOut the resulting array
6713 * \param [out] arrIndexOut the index array of the resulting array \b arrOut
6715 * \sa DataArrayInt::SetPartOfIndexedArraysSameIdx DataArrayInt::SetPartOfIndexedArrays
6717 void DataArrayInt::SetPartOfIndexedArraysSlice(int start, int end, int step, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn,
6718 const DataArrayInt *srcArr, const DataArrayInt *srcArrIndex,
6719 DataArrayInt* &arrOut, DataArrayInt* &arrIndexOut)
6721 if(arrIn==0 || arrIndxIn==0 || srcArr==0 || srcArrIndex==0)
6722 throw INTERP_KERNEL::Exception("DataArrayInt::SetPartOfIndexedArraysSlice : presence of null pointer in input parameter !");
6723 MCAuto<DataArrayInt> arro=DataArrayInt::New();
6724 MCAuto<DataArrayInt> arrIo=DataArrayInt::New();
6725 int nbOfTuples=arrIndxIn->getNumberOfTuples()-1;
6727 const int *arrIndxInPtr=arrIndxIn->begin();
6728 const int *srcArrIndexPtr=srcArrIndex->begin();
6729 int nbOfElemsToSet=DataArray::GetNumberOfItemGivenBESRelative(start,end,step,"DataArrayInt::SetPartOfIndexedArraysSlice : ");
6731 for(int i=0;i<nbOfElemsToSet;i++,srcArrIndexPtr++,it+=step)
6733 if(it>=0 && it<nbOfTuples)
6734 offset+=(srcArrIndexPtr[1]-srcArrIndexPtr[0])-(arrIndxInPtr[it+1]-arrIndxInPtr[it]);
6737 std::ostringstream oss; oss << "DataArrayInt::SetPartOfIndexedArraysSlice : On pos #" << i << " value is " << it << " not in [0," << nbOfTuples << ") !";
6738 throw INTERP_KERNEL::Exception(oss.str());
6741 srcArrIndexPtr=srcArrIndex->begin();
6742 arrIo->alloc(nbOfTuples+1,1);
6743 arro->alloc(arrIn->getNumberOfTuples()+offset,1);
6744 const int *arrInPtr=arrIn->begin();
6745 const int *srcArrPtr=srcArr->begin();
6746 int *arrIoPtr=arrIo->getPointer(); *arrIoPtr++=0;
6747 int *arroPtr=arro->getPointer();
6748 for(int ii=0;ii<nbOfTuples;ii++,arrIoPtr++)
6750 int pos=DataArray::GetPosOfItemGivenBESRelativeNoThrow(ii,start,end,step);
6753 arroPtr=std::copy(arrInPtr+arrIndxInPtr[ii],arrInPtr+arrIndxInPtr[ii+1],arroPtr);
6754 *arrIoPtr=arrIoPtr[-1]+(arrIndxInPtr[ii+1]-arrIndxInPtr[ii]);
6758 arroPtr=std::copy(srcArrPtr+srcArrIndexPtr[pos],srcArrPtr+srcArrIndexPtr[pos+1],arroPtr);
6759 *arrIoPtr=arrIoPtr[-1]+(srcArrIndexPtr[pos+1]-srcArrIndexPtr[pos]);
6763 arrIndexOut=arrIo.retn();
6768 * This method works on an input pair (\b arrIn, \b arrIndxIn) where \b arrIn indexes is in \b arrIndxIn.
6769 * This method is an specialization of MEDCouplingUMesh::SetPartOfIndexedArrays in the case of assignment do not modify the index in \b arrIndxIn.
6771 * \param [in] idsOfSelectBg begin of set of ids of the input extraction (included)
6772 * \param [in] idsOfSelectEnd end of set of ids of the input extraction (excluded)
6773 * \param [in,out] arrInOut arr origin array from which the extraction will be done.
6774 * \param [in] arrIndxIn is the input index array allowing to walk into \b arrIn
6775 * \param [in] srcArr input array that will be used as source of copy for ids in [ \b idsOfSelectBg , \b idsOfSelectEnd )
6776 * \param [in] srcArrIndex index array of \b srcArr
6778 * \sa DataArrayInt::SetPartOfIndexedArrays
6780 void DataArrayInt::SetPartOfIndexedArraysSameIdx(const int *idsOfSelectBg, const int *idsOfSelectEnd, DataArrayInt *arrInOut, const DataArrayInt *arrIndxIn,
6781 const DataArrayInt *srcArr, const DataArrayInt *srcArrIndex)
6783 if(arrInOut==0 || arrIndxIn==0 || srcArr==0 || srcArrIndex==0)
6784 throw INTERP_KERNEL::Exception("DataArrayInt::SetPartOfIndexedArraysSameIdx : presence of null pointer in input parameter !");
6785 int nbOfTuples=arrIndxIn->getNumberOfTuples()-1;
6786 const int *arrIndxInPtr=arrIndxIn->begin();
6787 const int *srcArrIndexPtr=srcArrIndex->begin();
6788 int *arrInOutPtr=arrInOut->getPointer();
6789 const int *srcArrPtr=srcArr->begin();
6790 for(const int *it=idsOfSelectBg;it!=idsOfSelectEnd;it++,srcArrIndexPtr++)
6792 if(*it>=0 && *it<nbOfTuples)
6794 if(srcArrIndexPtr[1]-srcArrIndexPtr[0]==arrIndxInPtr[*it+1]-arrIndxInPtr[*it])
6795 std::copy(srcArrPtr+srcArrIndexPtr[0],srcArrPtr+srcArrIndexPtr[1],arrInOutPtr+arrIndxInPtr[*it]);
6798 std::ostringstream oss; oss << "DataArrayInt::SetPartOfIndexedArraysSameIdx : On pos #" << std::distance(idsOfSelectBg,it) << " id (idsOfSelectBg[" << std::distance(idsOfSelectBg,it)<< "]) is " << *it << " arrIndxIn[id+1]-arrIndxIn[id]!=srcArrIndex[pos+1]-srcArrIndex[pos] !";
6799 throw INTERP_KERNEL::Exception(oss.str());
6804 std::ostringstream oss; oss << "DataArrayInt::SetPartOfIndexedArraysSameIdx : On pos #" << std::distance(idsOfSelectBg,it) << " value is " << *it << " not in [0," << nbOfTuples << ") !";
6805 throw INTERP_KERNEL::Exception(oss.str());
6811 * This method works on an input pair (\b arr, \b arrIndx) where \b arr indexes is in \b arrIndx.
6812 * This method will not impact the size of inout parameter \b arrIndx but the size of \b arr will be modified in case of suppression.
6814 * \param [in] idsToRemoveBg begin of set of ids to remove in \b arr (included)
6815 * \param [in] idsToRemoveEnd end of set of ids to remove in \b arr (excluded)
6816 * \param [in,out] arr array in which the remove operation will be done.
6817 * \param [in,out] arrIndx array in the remove operation will modify
6818 * \param [in] offsetForRemoval (by default 0) offset so that for each i in [0,arrIndx->getNumberOfTuples()-1) removal process will be performed in the following range [arr+arrIndx[i]+offsetForRemoval,arr+arr[i+1])
6819 * \return true if \b arr and \b arrIndx have been modified, false if not.
6821 bool DataArrayInt::RemoveIdsFromIndexedArrays(const int *idsToRemoveBg, const int *idsToRemoveEnd, DataArrayInt *arr, DataArrayInt *arrIndx, int offsetForRemoval)
6823 if(!arrIndx || !arr)
6824 throw INTERP_KERNEL::Exception("DataArrayInt::RemoveIdsFromIndexedArrays : some input arrays are empty !");
6825 if(offsetForRemoval<0)
6826 throw INTERP_KERNEL::Exception("DataArrayInt::RemoveIdsFromIndexedArrays : offsetForRemoval should be >=0 !");
6827 std::set<int> s(idsToRemoveBg,idsToRemoveEnd);
6828 int nbOfGrps=arrIndx->getNumberOfTuples()-1;
6829 int *arrIPtr=arrIndx->getPointer();
6832 const int *arrPtr=arr->begin();
6833 std::vector<int> arrOut;//no utility to switch to DataArrayInt because copy always needed
6834 for(int i=0;i<nbOfGrps;i++,arrIPtr++)
6836 if(*arrIPtr-previousArrI>offsetForRemoval)
6838 for(const int *work=arrPtr+previousArrI+offsetForRemoval;work!=arrPtr+*arrIPtr;work++)
6840 if(s.find(*work)==s.end())
6841 arrOut.push_back(*work);
6844 previousArrI=*arrIPtr;
6845 *arrIPtr=(int)arrOut.size();
6847 if(arr->getNumberOfTuples()==arrOut.size())
6849 arr->alloc((int)arrOut.size(),1);
6850 std::copy(arrOut.begin(),arrOut.end(),arr->getPointer());
6855 * This method works on an input pair (\b arrIn, \b arrIndxIn) where \b arrIn indexes is in \b arrIndxIn.
6856 * This method is an specialization of MEDCouplingUMesh::SetPartOfIndexedArrays in the case of assignment do not modify the index in \b arrIndxIn.
6858 * \param [in] start begin of set of ids of the input extraction (included)
6859 * \param [in] end end of set of ids of the input extraction (excluded)
6860 * \param [in] step step of the set of ids in range mode.
6861 * \param [in,out] arrInOut arr origin array from which the extraction will be done.
6862 * \param [in] arrIndxIn is the input index array allowing to walk into \b arrIn
6863 * \param [in] srcArr input array that will be used as source of copy for ids in [\b idsOfSelectBg, \b idsOfSelectEnd)
6864 * \param [in] srcArrIndex index array of \b srcArr
6866 * \sa DataArrayInt::SetPartOfIndexedArraysSlice DataArrayInt::SetPartOfIndexedArraysSameIdx
6868 void DataArrayInt::SetPartOfIndexedArraysSameIdxSlice(int start, int end, int step, DataArrayInt *arrInOut, const DataArrayInt *arrIndxIn,
6869 const DataArrayInt *srcArr, const DataArrayInt *srcArrIndex)
6871 if(arrInOut==0 || arrIndxIn==0 || srcArr==0 || srcArrIndex==0)
6872 throw INTERP_KERNEL::Exception("DataArrayInt::SetPartOfIndexedArraysSameIdxSlice : presence of null pointer in input parameter !");
6873 int nbOfTuples=arrIndxIn->getNumberOfTuples()-1;
6874 const int *arrIndxInPtr=arrIndxIn->begin();
6875 const int *srcArrIndexPtr=srcArrIndex->begin();
6876 int *arrInOutPtr=arrInOut->getPointer();
6877 const int *srcArrPtr=srcArr->begin();
6878 int nbOfElemsToSet=DataArray::GetNumberOfItemGivenBESRelative(start,end,step,"DataArrayInt::SetPartOfIndexedArraysSameIdxSlice : ");
6880 for(int i=0;i<nbOfElemsToSet;i++,srcArrIndexPtr++,it+=step)
6882 if(it>=0 && it<nbOfTuples)
6884 if(srcArrIndexPtr[1]-srcArrIndexPtr[0]==arrIndxInPtr[it+1]-arrIndxInPtr[it])
6885 std::copy(srcArrPtr+srcArrIndexPtr[0],srcArrPtr+srcArrIndexPtr[1],arrInOutPtr+arrIndxInPtr[it]);
6888 std::ostringstream oss; oss << "DataArrayInt::SetPartOfIndexedArraysSameIdxSlice : On pos #" << i << " id (idsOfSelectBg[" << i << "]) is " << it << " arrIndxIn[id+1]-arrIndxIn[id]!=srcArrIndex[pos+1]-srcArrIndex[pos] !";
6889 throw INTERP_KERNEL::Exception(oss.str());
6894 std::ostringstream oss; oss << "DataArrayInt::SetPartOfIndexedArraysSameIdxSlice : On pos #" << i << " value is " << it << " not in [0," << nbOfTuples << ") !";
6895 throw INTERP_KERNEL::Exception(oss.str());
6902 * Returns a C array which is a renumbering map in "Old to New" mode for the input array.
6903 * This map, if applied to \a start array, would make it sorted. For example, if
6904 * \a start array contents are [9,10,0,6,4,11,3,7] then the contents of the result array is
6905 * [5,6,0,3,2,7,1,4].
6906 * \param [in] start - pointer to the first element of the array for which the
6907 * permutation map is computed.
6908 * \param [in] end - pointer specifying the end of the array \a start, so that
6909 * the last value of \a start is \a end[ -1 ].
6910 * \return int * - the result permutation array that the caller is to delete as it is no
6912 * \throw If there are equal values in the input array.
6914 int *DataArrayInt::CheckAndPreparePermutation(const int *start, const int *end)
6916 std::size_t sz=std::distance(start,end);
6917 int *ret=(int *)malloc(sz*sizeof(int));
6918 int *work=new int[sz];
6919 std::copy(start,end,work);
6920 std::sort(work,work+sz);
6921 if(std::unique(work,work+sz)!=work+sz)
6925 throw INTERP_KERNEL::Exception("Some elements are equals in the specified array !");
6927 std::map<int,int> m;
6928 for(int *workPt=work;workPt!=work+sz;workPt++)
6929 m[*workPt]=(int)std::distance(work,workPt);
6931 for(const int *iter=start;iter!=end;iter++,iter2++)
6938 * Returns a new DataArrayInt containing an arithmetic progression
6939 * that is equal to the sequence returned by Python \c range(\a begin,\a end,\a step )
6941 * \param [in] begin - the start value of the result sequence.
6942 * \param [in] end - limiting value, so that every value of the result array is less than
6944 * \param [in] step - specifies the increment or decrement.
6945 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6946 * array using decrRef() as it is no more needed.
6947 * \throw If \a step == 0.
6948 * \throw If \a end < \a begin && \a step > 0.
6949 * \throw If \a end > \a begin && \a step < 0.
6951 DataArrayInt *DataArrayInt::Range(int begin, int end, int step)
6953 int nbOfTuples=GetNumberOfItemGivenBESRelative(begin,end,step,"DataArrayInt::Range");
6954 MCAuto<DataArrayInt> ret=DataArrayInt::New();
6955 ret->alloc(nbOfTuples,1);
6956 int *ptr=ret->getPointer();
6959 for(int i=begin;i<end;i+=step,ptr++)
6964 for(int i=begin;i>end;i+=step,ptr++)
6971 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
6974 void DataArrayInt::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
6979 tinyInfo[0]=getNumberOfTuples();
6980 tinyInfo[1]=getNumberOfComponents();
6990 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
6993 void DataArrayInt::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
6997 int nbOfCompo=getNumberOfComponents();
6998 tinyInfo.resize(nbOfCompo+1);
6999 tinyInfo[0]=getName();
7000 for(int i=0;i<nbOfCompo;i++)
7001 tinyInfo[i+1]=getInfoOnComponent(i);
7006 tinyInfo[0]=getName();
7011 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
7012 * This method returns if a feeding is needed.
7014 bool DataArrayInt::resizeForUnserialization(const std::vector<int>& tinyInfoI)
7016 int nbOfTuple=tinyInfoI[0];
7017 int nbOfComp=tinyInfoI[1];
7018 if(nbOfTuple!=-1 || nbOfComp!=-1)
7020 alloc(nbOfTuple,nbOfComp);
7027 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
7028 * This method returns if a feeding is needed.
7030 void DataArrayInt::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
7032 setName(tinyInfoS[0]);
7035 int nbOfCompo=tinyInfoI[1];
7036 for(int i=0;i<nbOfCompo;i++)
7037 setInfoOnComponent(i,tinyInfoS[i+1]);
7041 DataArrayIntIterator::DataArrayIntIterator(DataArrayInt *da):DataArrayIterator<int>(da)
7045 DataArrayInt32Tuple::DataArrayInt32Tuple(int *pt, int nbOfComp):DataArrayTuple<int>(pt,nbOfComp)
7049 std::string DataArrayIntTuple::repr() const
7051 std::ostringstream oss; oss << "(";
7052 for(int i=0;i<_nb_of_compo-1;i++)
7053 oss << _pt[i] << ", ";
7054 oss << _pt[_nb_of_compo-1] << ")";
7058 int DataArrayIntTuple::intValue() const
7060 return this->zeValue();
7064 * This method returns a newly allocated instance the caller should dealed with by a MEDCoupling::DataArrayInt::decrRef.
7065 * This method performs \b no copy of data. The content is only referenced using MEDCoupling::DataArrayInt::useArray with ownership set to \b false.
7066 * 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
7067 * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
7069 DataArrayInt *DataArrayIntTuple::buildDAInt(int nbOfTuples, int nbOfCompo) const
7071 return this->buildDA(nbOfTuples,nbOfCompo);
7074 DataArrayInt64 *DataArrayInt64::deepCopy() const
7076 return new DataArrayInt64(*this);