1 // Copyright (C) 2007-2016 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 // Author : Anthony Geay (EDF R&D)
21 #include "MEDCouplingMemArray.txx"
24 #include "GenMathFormulae.hxx"
25 #include "InterpKernelAutoPtr.hxx"
26 #include "InterpKernelExprParser.hxx"
28 #include "InterpKernelAutoPtr.hxx"
29 #include "InterpKernelGeo2DEdgeArcCircle.hxx"
30 #include "InterpKernelAutoPtr.hxx"
31 #include "InterpKernelGeo2DNode.hxx"
32 #include "InterpKernelGeo2DEdgeLin.hxx"
41 typedef double (*MYFUNCPTR)(double);
43 using namespace MEDCoupling;
45 template class MEDCoupling::MemArray<int>;
46 template class MEDCoupling::MemArray<double>;
47 template class MEDCoupling::DataArrayTemplate<int>;
48 template class MEDCoupling::DataArrayTemplate<double>;
49 template class MEDCoupling::DataArrayTemplateClassic<int>;
50 template class MEDCoupling::DataArrayTemplateClassic<double>;
51 template class MEDCoupling::DataArrayTemplateFP<double>;
52 template class MEDCoupling::DataArrayIterator<double>;
53 template class MEDCoupling::DataArrayIterator<int>;
54 template class MEDCoupling::DataArrayDiscrete<Int32>;
55 template class MEDCoupling::DataArrayDiscreteSigned<Int32>;
57 // [ABN] : Newest Intel compilers need this:
58 template Traits<Int32>::ArrayType* MEDCoupling::DataArrayTuple<Int32>::buildDA(int, int) const;
59 template Traits<double>::ArrayType* MEDCoupling::DataArrayTuple<double>::buildDA(int, int) const;
60 template Traits<float>::ArrayType* MEDCoupling::DataArrayTuple<float>::buildDA(int, int) const;
63 template<int SPACEDIM>
64 void DataArrayDouble::findCommonTuplesAlg(const double *bbox, int nbNodes, int limitNodeId, double prec, DataArrayInt *c, DataArrayInt *cI) const
66 const double *coordsPtr=getConstPointer();
67 BBTreePts<SPACEDIM,int> myTree(bbox,0,0,nbNodes,prec);
68 std::vector<bool> isDone(nbNodes);
69 for(int i=0;i<nbNodes;i++)
73 std::vector<int> intersectingElems;
74 myTree.getElementsAroundPoint(coordsPtr+i*SPACEDIM,intersectingElems);
75 if(intersectingElems.size()>1)
77 std::vector<int> commonNodes;
78 for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
82 commonNodes.push_back(*it);
85 if(!commonNodes.empty())
87 cI->pushBackSilent(cI->back()+(int)commonNodes.size()+1);
89 c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
96 template<int SPACEDIM>
97 void DataArrayDouble::FindTupleIdsNearTuplesAlg(const BBTreePts<SPACEDIM,int>& myTree, const double *pos, int nbOfTuples, double eps,
98 DataArrayInt *c, DataArrayInt *cI)
100 for(int i=0;i<nbOfTuples;i++)
102 std::vector<int> intersectingElems;
103 myTree.getElementsAroundPoint(pos+i*SPACEDIM,intersectingElems);
104 std::vector<int> commonNodes;
105 for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
106 commonNodes.push_back(*it);
107 cI->pushBackSilent(cI->back()+(int)commonNodes.size());
108 c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
112 template<int SPACEDIM>
113 void DataArrayDouble::FindClosestTupleIdAlg(const BBTreePts<SPACEDIM,int>& myTree, double dist, const double *pos, int nbOfTuples, const double *thisPt, int thisNbOfTuples, int *res)
115 double distOpt(dist);
116 const double *p(pos);
118 for(int i=0;i<nbOfTuples;i++,p+=SPACEDIM,r++)
123 double ret=myTree.getElementsAroundPoint2(p,distOpt,elem);
124 if(ret!=std::numeric_limits<double>::max())
126 distOpt=std::max(ret,1e-4);
131 { distOpt=2*distOpt; continue; }
136 int DataArray::EffectiveCircPerm(int nbOfShift, int nbOfTuples)
139 throw INTERP_KERNEL::Exception("DataArray::EffectiveCircPerm : number of tuples is expected to be > 0 !");
142 return nbOfShift%nbOfTuples;
148 return nbOfTuples-tmp;
152 std::size_t DataArray::getHeapMemorySizeWithoutChildren() const
154 std::size_t sz1=_name.capacity();
155 std::size_t sz2=_info_on_compo.capacity();
157 for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
158 sz3+=(*it).capacity();
162 std::vector<const BigMemoryObject *> DataArray::getDirectChildrenWithNull() const
164 return std::vector<const BigMemoryObject *>();
168 * Sets the attribute \a _name of \a this array.
169 * See \ref MEDCouplingArrayBasicsName "DataArrays infos" for more information.
170 * \param [in] name - new array name
172 void DataArray::setName(const std::string& name)
178 * Copies textual data from an \a other DataArray. The copied data are
179 * - the name attribute,
180 * - the information of components.
182 * For more information on these data see \ref MEDCouplingArrayBasicsName "DataArrays infos".
184 * \param [in] other - another instance of DataArray to copy the textual data from.
185 * \throw If number of components of \a this array differs from that of the \a other.
187 void DataArray::copyStringInfoFrom(const DataArray& other)
189 if(_info_on_compo.size()!=other._info_on_compo.size())
190 throw INTERP_KERNEL::Exception("Size of arrays mismatches on copyStringInfoFrom !");
192 _info_on_compo=other._info_on_compo;
195 void DataArray::copyPartOfStringInfoFrom(const DataArray& other, const std::vector<int>& compoIds)
197 int nbOfCompoOth=other.getNumberOfComponents();
198 std::size_t newNbOfCompo=compoIds.size();
199 for(std::size_t i=0;i<newNbOfCompo;i++)
200 if(compoIds[i]>=nbOfCompoOth || compoIds[i]<0)
202 std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompoOth << ")";
203 throw INTERP_KERNEL::Exception(oss.str().c_str());
205 for(std::size_t i=0;i<newNbOfCompo;i++)
206 setInfoOnComponent((int)i,other.getInfoOnComponent(compoIds[i]));
209 void DataArray::copyPartOfStringInfoFrom2(const std::vector<int>& compoIds, const DataArray& other)
211 std::size_t nbOfCompo(getNumberOfComponents());
212 std::size_t partOfCompoToSet=compoIds.size();
213 if(partOfCompoToSet!=other.getNumberOfComponents())
214 throw INTERP_KERNEL::Exception("Given compoIds has not the same size as number of components of given array !");
215 for(std::size_t i=0;i<partOfCompoToSet;i++)
216 if(compoIds[i]>=(int)nbOfCompo || compoIds[i]<0)
218 std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompo << ")";
219 throw INTERP_KERNEL::Exception(oss.str().c_str());
221 for(std::size_t i=0;i<partOfCompoToSet;i++)
222 setInfoOnComponent(compoIds[i],other.getInfoOnComponent((int)i));
225 bool DataArray::areInfoEqualsIfNotWhy(const DataArray& other, std::string& reason) const
227 std::ostringstream oss;
228 if(_name!=other._name)
230 oss << "Names DataArray mismatch : this name=\"" << _name << " other name=\"" << other._name << "\" !";
234 if(_info_on_compo!=other._info_on_compo)
236 oss << "Components DataArray mismatch : \nThis components=";
237 for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
238 oss << "\"" << *it << "\",";
239 oss << "\nOther components=";
240 for(std::vector<std::string>::const_iterator it=other._info_on_compo.begin();it!=other._info_on_compo.end();it++)
241 oss << "\"" << *it << "\",";
249 * Compares textual information of \a this DataArray with that of an \a other one.
250 * The compared data are
251 * - the name attribute,
252 * - the information of components.
254 * For more information on these data see \ref MEDCouplingArrayBasicsName "DataArrays infos".
255 * \param [in] other - another instance of DataArray to compare the textual data of.
256 * \return bool - \a true if the textual information is same, \a false else.
258 bool DataArray::areInfoEquals(const DataArray& other) const
261 return areInfoEqualsIfNotWhy(other,tmp);
264 void DataArray::reprWithoutNameStream(std::ostream& stream) const
266 stream << "Number of components : "<< getNumberOfComponents() << "\n";
267 stream << "Info of these components : ";
268 for(std::vector<std::string>::const_iterator iter=_info_on_compo.begin();iter!=_info_on_compo.end();iter++)
269 stream << "\"" << *iter << "\" ";
273 std::string DataArray::cppRepr(const std::string& varName) const
275 std::ostringstream ret;
276 reprCppStream(varName,ret);
281 * Sets information on all components. To know more on format of this information
282 * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
283 * \param [in] info - a vector of strings.
284 * \throw If size of \a info differs from the number of components of \a this.
286 void DataArray::setInfoOnComponents(const std::vector<std::string>& info)
288 if(getNumberOfComponents()!=info.size())
290 std::ostringstream oss; oss << "DataArray::setInfoOnComponents : input is of size " << info.size() << " whereas number of components is equal to " << getNumberOfComponents() << " !";
291 throw INTERP_KERNEL::Exception(oss.str().c_str());
297 * This method is only a dispatcher towards DataArrayDouble::setPartOfValues3, DataArrayInt::setPartOfValues3, DataArrayChar::setPartOfValues3 depending on the true
298 * type of \a this and \a aBase.
300 * \throw If \a aBase and \a this do not have the same type.
302 * \sa DataArrayDouble::setPartOfValues3, DataArrayInt::setPartOfValues3, DataArrayChar::setPartOfValues3.
304 void DataArray::setPartOfValuesBase3(const DataArray *aBase, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
307 throw INTERP_KERNEL::Exception("DataArray::setPartOfValuesBase3 : input aBase object is NULL !");
308 DataArrayDouble *this1(dynamic_cast<DataArrayDouble *>(this));
309 DataArrayInt *this2(dynamic_cast<DataArrayInt *>(this));
310 DataArrayChar *this3(dynamic_cast<DataArrayChar *>(this));
311 const DataArrayDouble *a1(dynamic_cast<const DataArrayDouble *>(aBase));
312 const DataArrayInt *a2(dynamic_cast<const DataArrayInt *>(aBase));
313 const DataArrayChar *a3(dynamic_cast<const DataArrayChar *>(aBase));
316 this1->setPartOfValues3(a1,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
321 this2->setPartOfValues3(a2,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
326 this3->setPartOfValues3(a3,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
329 throw INTERP_KERNEL::Exception("DataArray::setPartOfValuesBase3 : input aBase object and this do not have the same type !");
332 std::vector<std::string> DataArray::getVarsOnComponent() const
334 int nbOfCompo=(int)_info_on_compo.size();
335 std::vector<std::string> ret(nbOfCompo);
336 for(int i=0;i<nbOfCompo;i++)
337 ret[i]=getVarOnComponent(i);
341 std::vector<std::string> DataArray::getUnitsOnComponent() const
343 int nbOfCompo=(int)_info_on_compo.size();
344 std::vector<std::string> ret(nbOfCompo);
345 for(int i=0;i<nbOfCompo;i++)
346 ret[i]=getUnitOnComponent(i);
351 * Returns information on a component specified by an index.
352 * To know more on format of this information
353 * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
354 * \param [in] i - the index (zero based) of the component of interest.
355 * \return std::string - a string containing the information on \a i-th component.
356 * \throw If \a i is not a valid component index.
358 std::string DataArray::getInfoOnComponent(int i) const
360 if(i<(int)_info_on_compo.size() && i>=0)
361 return _info_on_compo[i];
364 std::ostringstream oss; oss << "DataArray::getInfoOnComponent : Specified component id is out of range (" << i << ") compared with nb of actual components (" << (int) _info_on_compo.size();
365 throw INTERP_KERNEL::Exception(oss.str().c_str());
370 * Returns the var part of the full information of the \a i-th component.
371 * For example, if \c getInfoOnComponent(0) returns "SIGXY [N/m^2]", then
372 * \c getVarOnComponent(0) returns "SIGXY".
373 * If a unit part of information is not detected by presence of
374 * two square brackets, then the full information is returned.
375 * To read more about the component information format, see
376 * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
377 * \param [in] i - the index (zero based) of the component of interest.
378 * \return std::string - a string containing the var information, or the full info.
379 * \throw If \a i is not a valid component index.
381 std::string DataArray::getVarOnComponent(int i) const
383 if(i<(int)_info_on_compo.size() && i>=0)
385 return GetVarNameFromInfo(_info_on_compo[i]);
389 std::ostringstream oss; oss << "DataArray::getVarOnComponent : Specified component id is out of range (" << i << ") compared with nb of actual components (" << (int) _info_on_compo.size();
390 throw INTERP_KERNEL::Exception(oss.str().c_str());
395 * Returns the unit part of the full information of the \a i-th component.
396 * For example, if \c getInfoOnComponent(0) returns "SIGXY [ N/m^2]", then
397 * \c getUnitOnComponent(0) returns " N/m^2".
398 * If a unit part of information is not detected by presence of
399 * two square brackets, then an empty string is returned.
400 * To read more about the component information format, see
401 * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
402 * \param [in] i - the index (zero based) of the component of interest.
403 * \return std::string - a string containing the unit information, if any, or "".
404 * \throw If \a i is not a valid component index.
406 std::string DataArray::getUnitOnComponent(int i) const
408 if(i<(int)_info_on_compo.size() && i>=0)
410 return GetUnitFromInfo(_info_on_compo[i]);
414 std::ostringstream oss; oss << "DataArray::getUnitOnComponent : Specified component id is out of range (" << i << ") compared with nb of actual components (" << (int) _info_on_compo.size();
415 throw INTERP_KERNEL::Exception(oss.str().c_str());
420 * Returns the var part of the full component information.
421 * For example, if \a info == "SIGXY [N/m^2]", then this method returns "SIGXY".
422 * If a unit part of information is not detected by presence of
423 * two square brackets, then the whole \a info is returned.
424 * To read more about the component information format, see
425 * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
426 * \param [in] info - the full component information.
427 * \return std::string - a string containing only var information, or the \a info.
429 std::string DataArray::GetVarNameFromInfo(const std::string& info)
431 std::size_t p1=info.find_last_of('[');
432 std::size_t p2=info.find_last_of(']');
433 if(p1==std::string::npos || p2==std::string::npos)
438 return std::string();
439 std::size_t p3=info.find_last_not_of(' ',p1-1);
440 return info.substr(0,p3+1);
444 * Returns the unit part of the full component information.
445 * For example, if \a info == "SIGXY [ N/m^2]", then this method returns " N/m^2".
446 * If a unit part of information is not detected by presence of
447 * two square brackets, then an empty string is returned.
448 * To read more about the component information format, see
449 * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
450 * \param [in] info - the full component information.
451 * \return std::string - a string containing only unit information, if any, or "".
453 std::string DataArray::GetUnitFromInfo(const std::string& info)
455 std::size_t p1=info.find_last_of('[');
456 std::size_t p2=info.find_last_of(']');
457 if(p1==std::string::npos || p2==std::string::npos)
458 return std::string();
460 return std::string();
461 return info.substr(p1+1,p2-p1-1);
465 * This method put in info format the result of the merge of \a var and \a unit.
466 * The standard format for that is "var [unit]".
467 * Inversely you can retrieve the var part or the unit part of info string using resp. GetVarNameFromInfo and GetUnitFromInfo.
469 std::string DataArray::BuildInfoFromVarAndUnit(const std::string& var, const std::string& unit)
471 std::ostringstream oss;
472 oss << var << " [" << unit << "]";
476 std::string DataArray::GetAxisTypeRepr(MEDCouplingAxisType at)
481 return std::string("AX_CART");
483 return std::string("AX_CYL");
485 return std::string("AX_SPHER");
487 throw INTERP_KERNEL::Exception("DataArray::GetAxisTypeRepr : unrecognized axis type enum !");
492 * Returns a new DataArray by concatenating all given arrays, so that (1) the number
493 * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
494 * the number of component in the result array is same as that of each of given arrays.
495 * Info on components is copied from the first of the given arrays. Number of components
496 * in the given arrays must be the same.
497 * \param [in] arrs - a sequence of arrays to include in the result array. All arrays must have the same type.
498 * \return DataArray * - the new instance of DataArray (that can be either DataArrayInt, DataArrayDouble, DataArrayChar).
499 * The caller is to delete this result array using decrRef() as it is no more
501 * \throw If all arrays within \a arrs are NULL.
502 * \throw If all not null arrays in \a arrs have not the same type.
503 * \throw If getNumberOfComponents() of arrays within \a arrs.
505 DataArray *DataArray::Aggregate(const std::vector<const DataArray *>& arrs)
507 std::vector<const DataArray *> arr2;
508 for(std::vector<const DataArray *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
512 throw INTERP_KERNEL::Exception("DataArray::Aggregate : only null instance in input vector !");
513 std::vector<const DataArrayDouble *> arrd;
514 std::vector<const DataArrayInt *> arri;
515 std::vector<const DataArrayChar *> arrc;
516 for(std::vector<const DataArray *>::const_iterator it=arr2.begin();it!=arr2.end();it++)
518 const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(*it);
520 { arrd.push_back(a); continue; }
521 const DataArrayInt *b=dynamic_cast<const DataArrayInt *>(*it);
523 { arri.push_back(b); continue; }
524 const DataArrayChar *c=dynamic_cast<const DataArrayChar *>(*it);
526 { arrc.push_back(c); continue; }
527 throw INTERP_KERNEL::Exception("DataArray::Aggregate : presence of not null instance in inuput that is not in [DataArrayDouble, DataArrayInt, DataArrayChar] !");
529 if(arr2.size()==arrd.size())
530 return DataArrayDouble::Aggregate(arrd);
531 if(arr2.size()==arri.size())
532 return DataArrayInt::Aggregate(arri);
533 if(arr2.size()==arrc.size())
534 return DataArrayChar::Aggregate(arrc);
535 throw INTERP_KERNEL::Exception("DataArray::Aggregate : all input arrays must have the same type !");
539 * Sets information on a component specified by an index.
540 * To know more on format of this information
541 * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
542 * \warning Don't pass NULL as \a info!
543 * \param [in] i - the index (zero based) of the component of interest.
544 * \param [in] info - the string containing the information.
545 * \throw If \a i is not a valid component index.
547 void DataArray::setInfoOnComponent(int i, const std::string& info)
549 if(i<(int)_info_on_compo.size() && i>=0)
550 _info_on_compo[i]=info;
553 std::ostringstream oss; oss << "DataArray::setInfoOnComponent : Specified component id is out of range (" << i << ") compared with nb of actual components (" << (int) _info_on_compo.size();
554 throw INTERP_KERNEL::Exception(oss.str().c_str());
559 * Sets information on all components. This method can change number of components
560 * at certain conditions; if the conditions are not respected, an exception is thrown.
561 * The number of components can be changed in \a this only if \a this is not allocated.
562 * The condition of number of components must not be changed.
564 * To know more on format of the component information see
565 * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
566 * \param [in] info - a vector of component infos.
567 * \throw If \a this->getNumberOfComponents() != \a info.size() && \a this->isAllocated()
569 void DataArray::setInfoAndChangeNbOfCompo(const std::vector<std::string>& info)
571 if(getNumberOfComponents()!=info.size())
577 std::ostringstream oss; oss << "DataArray::setInfoAndChangeNbOfCompo : input is of size " << info.size() << " whereas number of components is equal to " << getNumberOfComponents() << " and this is already allocated !";
578 throw INTERP_KERNEL::Exception(oss.str().c_str());
585 void DataArray::checkNbOfTuples(int nbOfTuples, const std::string& msg) const
587 if((int)getNumberOfTuples()!=nbOfTuples)
589 std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " << nbOfTuples << " having " << getNumberOfTuples() << " !";
590 throw INTERP_KERNEL::Exception(oss.str().c_str());
594 void DataArray::checkNbOfComps(int nbOfCompo, const std::string& msg) const
596 if((int)getNumberOfComponents()!=nbOfCompo)
598 std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << nbOfCompo << " having " << getNumberOfComponents() << " !";
599 throw INTERP_KERNEL::Exception(oss.str().c_str());
603 void DataArray::checkNbOfElems(std::size_t nbOfElems, const std::string& msg) const
605 if(getNbOfElems()!=nbOfElems)
607 std::ostringstream oss; oss << msg << " : mismatch number of elems : Expected " << nbOfElems << " having " << getNbOfElems() << " !";
608 throw INTERP_KERNEL::Exception(oss.str().c_str());
612 void DataArray::checkNbOfTuplesAndComp(const DataArray& other, const std::string& msg) const
614 if(getNumberOfTuples()!=other.getNumberOfTuples())
616 std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " << other.getNumberOfTuples() << " having " << getNumberOfTuples() << " !";
617 throw INTERP_KERNEL::Exception(oss.str().c_str());
619 if(getNumberOfComponents()!=other.getNumberOfComponents())
621 std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << other.getNumberOfComponents() << " having " << getNumberOfComponents() << " !";
622 throw INTERP_KERNEL::Exception(oss.str().c_str());
626 void DataArray::checkNbOfTuplesAndComp(int nbOfTuples, int nbOfCompo, const std::string& msg) const
628 checkNbOfTuples(nbOfTuples,msg);
629 checkNbOfComps(nbOfCompo,msg);
633 * Simply this method checks that \b value is in [0,\b ref).
635 void DataArray::CheckValueInRange(int ref, int value, const std::string& msg)
637 if(value<0 || value>=ref)
639 std::ostringstream oss; oss << "DataArray::CheckValueInRange : " << msg << " ! Expected in range [0," << ref << "[ having " << value << " !";
640 throw INTERP_KERNEL::Exception(oss.str().c_str());
645 * This method checks that [\b start, \b end) is compliant with ref length \b value.
646 * typically start in [0,\b value) and end in [0,\b value). If value==start and start==end, it is supported.
648 void DataArray::CheckValueInRangeEx(int value, int start, int end, const std::string& msg)
650 if(start<0 || start>=value)
652 if(value!=start || end!=start)
654 std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg << " ! Expected start " << start << " of input range, in [0," << value << "[ !";
655 throw INTERP_KERNEL::Exception(oss.str().c_str());
658 if(end<0 || end>value)
660 std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg << " ! Expected end " << end << " of input range, in [0," << value << "] !";
661 throw INTERP_KERNEL::Exception(oss.str().c_str());
665 void DataArray::CheckClosingParInRange(int ref, int value, const std::string& msg)
667 if(value<0 || value>ref)
669 std::ostringstream oss; oss << "DataArray::CheckClosingParInRange : " << msg << " ! Expected input range in [0," << ref << "] having closing open parenthesis " << value << " !";
670 throw INTERP_KERNEL::Exception(oss.str().c_str());
675 * This method is useful to slice work among a pool of threads or processes. \a begin, \a end \a step is the input whole slice of work to perform,
676 * typically it is a whole slice of tuples of DataArray or cells, nodes of a mesh...
678 * The input \a sliceId should be an id in [0, \a nbOfSlices) that specifies the slice of work.
680 * \param [in] start - the start of the input slice of the whole work to perform split into slices.
681 * \param [in] stop - the stop of the input slice of the whole work to perform split into slices.
682 * \param [in] step - the step (that can be <0) of the input slice of the whole work to perform split into slices.
683 * \param [in] sliceId - the slice id considered
684 * \param [in] nbOfSlices - the number of slices (typically the number of cores on which the work is expected to be sliced)
685 * \param [out] startSlice - the start of the slice considered
686 * \param [out] stopSlice - the stop of the slice consided
688 * \throw If \a step == 0
689 * \throw If \a nbOfSlices not > 0
690 * \throw If \a sliceId not in [0,nbOfSlices)
692 void DataArray::GetSlice(int start, int stop, int step, int sliceId, int nbOfSlices, int& startSlice, int& stopSlice)
696 std::ostringstream oss; oss << "DataArray::GetSlice : nbOfSlices (" << nbOfSlices << ") must be > 0 !";
697 throw INTERP_KERNEL::Exception(oss.str().c_str());
699 if(sliceId<0 || sliceId>=nbOfSlices)
701 std::ostringstream oss; oss << "DataArray::GetSlice : sliceId (" << nbOfSlices << ") must be in [0 , nbOfSlices (" << nbOfSlices << ") ) !";
702 throw INTERP_KERNEL::Exception(oss.str().c_str());
704 int nbElems=GetNumberOfItemGivenBESRelative(start,stop,step,"DataArray::GetSlice");
705 int minNbOfElemsPerSlice=nbElems/nbOfSlices;
706 startSlice=start+minNbOfElemsPerSlice*step*sliceId;
707 if(sliceId<nbOfSlices-1)
708 stopSlice=start+minNbOfElemsPerSlice*step*(sliceId+1);
713 int DataArray::GetNumberOfItemGivenBES(int begin, int end, int step, const std::string& msg)
717 std::ostringstream oss; oss << msg << " : end before begin !";
718 throw INTERP_KERNEL::Exception(oss.str().c_str());
724 std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
725 throw INTERP_KERNEL::Exception(oss.str().c_str());
727 return (end-1-begin)/step+1;
730 int DataArray::GetNumberOfItemGivenBESRelative(int begin, int end, int step, const std::string& msg)
733 throw INTERP_KERNEL::Exception("DataArray::GetNumberOfItemGivenBES : step=0 is not allowed !");
734 if(end<begin && step>0)
736 std::ostringstream oss; oss << msg << " : end before begin whereas step is positive !";
737 throw INTERP_KERNEL::Exception(oss.str().c_str());
739 if(begin<end && step<0)
741 std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
742 throw INTERP_KERNEL::Exception(oss.str().c_str());
745 return (std::max(begin,end)-1-std::min(begin,end))/std::abs(step)+1;
750 int DataArray::GetPosOfItemGivenBESRelativeNoThrow(int value, int begin, int end, int step)
756 if(begin<=value && value<end)
758 if((value-begin)%step==0)
759 return (value-begin)/step;
768 if(begin>=value && value>end)
770 if((begin-value)%(-step)==0)
771 return (begin-value)/(-step);
784 * Returns a new instance of DataArrayDouble. The caller is to delete this array
785 * using decrRef() as it is no more needed.
787 DataArrayDouble *DataArrayDouble::New()
789 return new DataArrayDouble;
793 * Returns the only one value in \a this, if and only if number of elements
794 * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
795 * \return double - the sole value stored in \a this array.
796 * \throw If at least one of conditions stated above is not fulfilled.
798 double DataArrayDouble::doubleValue() const
802 if(getNbOfElems()==1)
804 return *getConstPointer();
807 throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is allocated but number of elements is not equal to 1 !");
810 throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is not allocated !");
814 * Returns a full copy of \a this. For more info on copying data arrays see
815 * \ref MEDCouplingArrayBasicsCopyDeep.
816 * \return DataArrayDouble * - a new instance of DataArrayDouble. The caller is to
817 * delete this array using decrRef() as it is no more needed.
819 DataArrayDouble *DataArrayDouble::deepCopy() const
821 return new DataArrayDouble(*this);
825 * Checks that \a this array is consistently **increasing** or **decreasing** in value,
826 * with at least absolute difference value of |\a eps| at each step.
827 * If not an exception is thrown.
828 * \param [in] increasing - if \a true, the array values should be increasing.
829 * \param [in] eps - minimal absolute difference between the neighbor values at which
830 * the values are considered different.
831 * \throw If sequence of values is not strictly monotonic in agreement with \a
833 * \throw If \a this->getNumberOfComponents() != 1.
834 * \throw If \a this is not allocated.
836 void DataArrayDouble::checkMonotonic(bool increasing, double eps) const
838 if(!isMonotonic(increasing,eps))
841 throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not INCREASING monotonic !");
843 throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not DECREASING monotonic !");
848 * Checks that \a this array is consistently **increasing** or **decreasing** in value,
849 * with at least absolute difference value of |\a eps| at each step.
850 * \param [in] increasing - if \a true, array values should be increasing.
851 * \param [in] eps - minimal absolute difference between the neighbor values at which
852 * the values are considered different.
853 * \return bool - \a true if values change in accordance with \a increasing arg.
854 * \throw If \a this->getNumberOfComponents() != 1.
855 * \throw If \a this is not allocated.
857 bool DataArrayDouble::isMonotonic(bool increasing, double eps) const
860 if(getNumberOfComponents()!=1)
861 throw INTERP_KERNEL::Exception("DataArrayDouble::isMonotonic : only supported with 'this' array with ONE component !");
862 int nbOfElements=getNumberOfTuples();
863 const double *ptr=getConstPointer();
867 double absEps=fabs(eps);
870 for(int i=1;i<nbOfElements;i++)
872 if(ptr[i]<(ref+absEps))
880 for(int i=1;i<nbOfElements;i++)
882 if(ptr[i]>(ref-absEps))
891 * Returns a textual and human readable representation of \a this instance of
892 * DataArrayDouble. This text is shown when a DataArrayDouble is printed in Python.
893 * \return std::string - text describing \a this DataArrayDouble.
895 * \sa reprNotTooLong, reprZip
897 std::string DataArrayDouble::repr() const
899 std::ostringstream ret;
904 std::string DataArrayDouble::reprZip() const
906 std::ostringstream ret;
911 void DataArrayDouble::writeVTK(std::ostream& ofs, int indent, const std::string& nameInFile, DataArrayByte *byteArr) const
913 static const char SPACE[4]={' ',' ',' ',' '};
915 std::string idt(indent,' ');
917 ofs << idt << "<DataArray type=\"Float32\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
919 bool areAllEmpty(true);
920 for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
924 for(std::size_t i=0;i<_info_on_compo.size();i++)
925 ofs << " ComponentName" << i << "=\"" << _info_on_compo[i] << "\"";
929 ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
930 INTERP_KERNEL::AutoPtr<float> tmp(new float[getNbOfElems()]);
932 // to make Visual C++ happy : instead of std::copy(begin(),end(),(float *)tmp);
933 for(const double *src=begin();src!=end();src++,pt++)
935 const char *data(reinterpret_cast<const char *>((float *)tmp));
936 std::size_t sz(getNbOfElems()*sizeof(float));
937 byteArr->insertAtTheEnd(data,data+sz);
938 byteArr->insertAtTheEnd(SPACE,SPACE+4);
942 ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
943 std::copy(begin(),end(),std::ostream_iterator<double>(ofs," "));
945 ofs << std::endl << idt << "</DataArray>\n";
948 void DataArrayDouble::reprCppStream(const std::string& varName, std::ostream& stream) const
950 int nbTuples(getNumberOfTuples()),nbComp(getNumberOfComponents());
951 const double *data(getConstPointer());
952 stream.precision(17);
953 stream << "DataArrayDouble *" << varName << "=DataArrayDouble::New();" << std::endl;
954 if(nbTuples*nbComp>=1)
956 stream << "const double " << varName << "Data[" << nbTuples*nbComp << "]={";
957 std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<double>(stream,","));
958 stream << data[nbTuples*nbComp-1] << "};" << std::endl;
959 stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
962 stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
963 stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
967 * Method that gives a quick overvien of \a this for python.
969 void DataArrayDouble::reprQuickOverview(std::ostream& stream) const
971 static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
972 stream << "DataArrayDouble C++ instance at " << this << ". ";
975 int nbOfCompo=(int)_info_on_compo.size();
978 int nbOfTuples=getNumberOfTuples();
979 stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
980 reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
983 stream << "Number of components : 0.";
986 stream << "*** No data allocated ****";
989 void DataArrayDouble::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
991 const double *data=begin();
992 int nbOfTuples=getNumberOfTuples();
993 int nbOfCompo=(int)_info_on_compo.size();
994 std::ostringstream oss2; oss2 << "[";
996 std::string oss2Str(oss2.str());
997 bool isFinished=true;
998 for(int i=0;i<nbOfTuples && isFinished;i++)
1003 for(int j=0;j<nbOfCompo;j++,data++)
1006 if(j!=nbOfCompo-1) oss2 << ", ";
1012 if(i!=nbOfTuples-1) oss2 << ", ";
1013 std::string oss3Str(oss2.str());
1014 if(oss3Str.length()<maxNbOfByteInRepr)
1026 * Equivalent to DataArrayDouble::isEqual except that if false the reason of
1027 * mismatch is given.
1029 * \param [in] other the instance to be compared with \a this
1030 * \param [in] prec the precision to compare numeric data of the arrays.
1031 * \param [out] reason In case of inequality returns the reason.
1032 * \sa DataArrayDouble::isEqual
1034 bool DataArrayDouble::isEqualIfNotWhy(const DataArrayDouble& other, double prec, std::string& reason) const
1036 if(!areInfoEqualsIfNotWhy(other,reason))
1038 return _mem.isEqual(other._mem,prec,reason);
1042 * Checks if \a this and another DataArrayDouble are fully equal. For more info see
1043 * \ref MEDCouplingArrayBasicsCompare.
1044 * \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1045 * \param [in] prec - precision value to compare numeric data of the arrays.
1046 * \return bool - \a true if the two arrays are equal, \a false else.
1048 bool DataArrayDouble::isEqual(const DataArrayDouble& other, double prec) const
1051 return isEqualIfNotWhy(other,prec,tmp);
1055 * Checks if values of \a this and another DataArrayDouble are equal. For more info see
1056 * \ref MEDCouplingArrayBasicsCompare.
1057 * \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1058 * \param [in] prec - precision value to compare numeric data of the arrays.
1059 * \return bool - \a true if the values of two arrays are equal, \a false else.
1061 bool DataArrayDouble::isEqualWithoutConsideringStr(const DataArrayDouble& other, double prec) const
1064 return _mem.isEqual(other._mem,prec,tmp);
1068 * This method checks that all tuples in \a other are in \a this.
1069 * If true, the output param \a tupleIds contains the tuples ids of \a this that correspond to tupes in \a this.
1070 * For each i in [ 0 , other->getNumberOfTuples() ) tuple #i in \a other is equal ( regarding input precision \a prec ) to tuple tupleIds[i] in \a this.
1072 * \param [in] other - the array having the same number of components than \a this.
1073 * \param [out] tupleIds - the tuple ids containing the same number of tuples than \a other has.
1074 * \sa DataArrayDouble::findCommonTuples
1076 bool DataArrayDouble::areIncludedInMe(const DataArrayDouble *other, double prec, DataArrayInt *&tupleIds) const
1079 throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : input array is NULL !");
1080 checkAllocated(); other->checkAllocated();
1081 if(getNumberOfComponents()!=other->getNumberOfComponents())
1082 throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : the number of components does not match !");
1083 MCAuto<DataArrayDouble> a=DataArrayDouble::Aggregate(this,other);
1084 DataArrayInt *c=0,*ci=0;
1085 a->findCommonTuples(prec,getNumberOfTuples(),c,ci);
1086 MCAuto<DataArrayInt> cSafe(c),ciSafe(ci);
1087 int newNbOfTuples=-1;
1088 MCAuto<DataArrayInt> ids=DataArrayInt::ConvertIndexArrayToO2N(a->getNumberOfTuples(),c->begin(),ci->begin(),ci->end(),newNbOfTuples);
1089 MCAuto<DataArrayInt> ret1=ids->selectByTupleIdSafeSlice(getNumberOfTuples(),a->getNumberOfTuples(),1);
1090 tupleIds=ret1.retn();
1091 return newNbOfTuples==getNumberOfTuples();
1095 * Searches for tuples coincident within \a prec tolerance. Each tuple is considered
1096 * as coordinates of a point in getNumberOfComponents()-dimensional space. The
1097 * distance separating two points is computed with the infinite norm.
1099 * Indices of coincident tuples are stored in output arrays.
1100 * A pair of arrays (\a comm, \a commIndex) is called "Surjective Format 2".
1102 * This method is typically used by MEDCouplingPointSet::findCommonNodes() and
1103 * MEDCouplingUMesh::mergeNodes().
1104 * \param [in] prec - minimal absolute distance between two tuples (infinite norm) at which they are
1105 * considered not coincident.
1106 * \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
1107 * tuples have id strictly lower than \a limitTupleId then they are not returned.
1108 * \param [out] comm - the array holding ids (== indices) of coincident tuples.
1109 * \a comm->getNumberOfComponents() == 1.
1110 * \a comm->getNumberOfTuples() == \a commIndex->back().
1111 * \param [out] commIndex - the array dividing all indices stored in \a comm into
1112 * groups of (indices of) coincident tuples. Its every value is a tuple
1113 * index where a next group of tuples begins. For example the second
1114 * group of tuples in \a comm is described by following range of indices:
1115 * [ \a commIndex[1], \a commIndex[2] ). \a commIndex->getNumberOfTuples()-1
1116 * gives the number of groups of coincident tuples.
1117 * \throw If \a this is not allocated.
1118 * \throw If the number of components is not in [1,2,3,4].
1120 * \if ENABLE_EXAMPLES
1121 * \ref cpp_mcdataarraydouble_findcommontuples "Here is a C++ example".
1123 * \ref py_mcdataarraydouble_findcommontuples "Here is a Python example".
1125 * \sa DataArrayInt::ConvertIndexArrayToO2N(), DataArrayDouble::areIncludedInMe
1127 void DataArrayDouble::findCommonTuples(double prec, int limitTupleId, DataArrayInt *&comm, DataArrayInt *&commIndex) const
1130 int nbOfCompo=getNumberOfComponents();
1131 if ((nbOfCompo<1) || (nbOfCompo>4)) //test before work
1132 throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : Unexpected spacedim of coords. Must be 1, 2, 3 or 4.");
1134 int nbOfTuples=getNumberOfTuples();
1136 MCAuto<DataArrayInt> c(DataArrayInt::New()),cI(DataArrayInt::New()); c->alloc(0,1); cI->pushBackSilent(0);
1140 findCommonTuplesAlg<4>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1143 findCommonTuplesAlg<3>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1146 findCommonTuplesAlg<2>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1149 findCommonTuplesAlg<1>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1152 throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : nb of components managed are 1,2,3 and 4 ! not implemented for other number of components !");
1155 commIndex=cI.retn();
1159 * This methods returns the minimal distance between the two set of points \a this and \a other.
1160 * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
1161 * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
1163 * \param [out] thisTupleId the tuple id in \a this corresponding to the returned minimal distance
1164 * \param [out] otherTupleId the tuple id in \a other corresponding to the returned minimal distance
1165 * \return the minimal distance between the two set of points \a this and \a other.
1166 * \sa DataArrayDouble::findClosestTupleId
1168 double DataArrayDouble::minimalDistanceTo(const DataArrayDouble *other, int& thisTupleId, int& otherTupleId) const
1170 MCAuto<DataArrayInt> part1=findClosestTupleId(other);
1171 int nbOfCompo(getNumberOfComponents());
1172 int otherNbTuples(other->getNumberOfTuples());
1173 const double *thisPt(begin()),*otherPt(other->begin());
1174 const int *part1Pt(part1->begin());
1175 double ret=std::numeric_limits<double>::max();
1176 for(int i=0;i<otherNbTuples;i++,part1Pt++,otherPt+=nbOfCompo)
1179 for(int j=0;j<nbOfCompo;j++)
1180 tmp+=(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j])*(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j]);
1182 { ret=tmp; thisTupleId=*part1Pt; otherTupleId=i; }
1188 * This methods returns for each tuple in \a other which tuple in \a this is the closest.
1189 * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
1190 * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
1192 * \return a newly allocated (new object to be dealt by the caller) DataArrayInt having \c other->getNumberOfTuples() tuples and one components.
1193 * \sa DataArrayDouble::minimalDistanceTo
1195 DataArrayInt *DataArrayDouble::findClosestTupleId(const DataArrayDouble *other) const
1198 throw INTERP_KERNEL::Exception("DataArrayDouble::findClosestTupleId : other instance is NULL !");
1199 checkAllocated(); other->checkAllocated();
1200 std::size_t nbOfCompo(getNumberOfComponents());
1201 if(nbOfCompo!=other->getNumberOfComponents())
1203 std::ostringstream oss; oss << "DataArrayDouble::findClosestTupleId : number of components in this is " << nbOfCompo;
1204 oss << ", whereas number of components in other is " << other->getNumberOfComponents() << "! Should be equal !";
1205 throw INTERP_KERNEL::Exception(oss.str().c_str());
1207 int nbOfTuples=other->getNumberOfTuples();
1208 int thisNbOfTuples=getNumberOfTuples();
1209 MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuples,1);
1211 getMinMaxPerComponent(bounds);
1216 double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2])),zDelta(fabs(bounds[5]-bounds[4]));
1217 double delta=std::max(xDelta,yDelta); delta=std::max(delta,zDelta);
1218 double characSize=pow((delta*delta*delta)/((double)thisNbOfTuples),1./3.);
1219 BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1220 FindClosestTupleIdAlg<3>(myTree,3.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1225 double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2]));
1226 double delta=std::max(xDelta,yDelta);
1227 double characSize=sqrt(delta/(double)thisNbOfTuples);
1228 BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1229 FindClosestTupleIdAlg<2>(myTree,2.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1234 double characSize=fabs(bounds[1]-bounds[0])/thisNbOfTuples;
1235 BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1236 FindClosestTupleIdAlg<1>(myTree,1.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1240 throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for findClosestTupleId. Must be 1, 2 or 3.");
1246 * This method expects that \a this and \a otherBBoxFrmt arrays are bounding box arrays ( as the output of MEDCouplingPointSet::getBoundingBoxForBBTree method ).
1247 * This method will return a DataArrayInt array having the same number of tuples than \a this. This returned array tells for each cell in \a this
1248 * how many bounding boxes in \a otherBBoxFrmt.
1249 * So, this method expects that \a this and \a otherBBoxFrmt have the same number of components.
1251 * \param [in] otherBBoxFrmt - It is an array .
1252 * \param [in] eps - the absolute precision of the detection. when eps < 0 the bboxes are enlarged so more interactions are detected. Inversely when > 0 the bboxes are stretched.
1253 * \sa MEDCouplingPointSet::getBoundingBoxForBBTree
1254 * \throw If \a this and \a otherBBoxFrmt have not the same number of components.
1255 * \throw If \a this and \a otherBBoxFrmt number of components is not even (BBox format).
1257 DataArrayInt *DataArrayDouble::computeNbOfInteractionsWith(const DataArrayDouble *otherBBoxFrmt, double eps) const
1260 throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : input array is NULL !");
1261 if(!isAllocated() || !otherBBoxFrmt->isAllocated())
1262 throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : this and input array must be allocated !");
1263 std::size_t nbOfComp(getNumberOfComponents()),nbOfTuples(getNumberOfTuples());
1264 if(nbOfComp!=otherBBoxFrmt->getNumberOfComponents())
1266 std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : this number of components (" << nbOfComp << ") must be equal to the number of components of input array (" << otherBBoxFrmt->getNumberOfComponents() << ") !";
1267 throw INTERP_KERNEL::Exception(oss.str().c_str());
1271 std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : Number of components (" << nbOfComp << ") is not even ! It should be to be compatible with bbox format !";
1272 throw INTERP_KERNEL::Exception(oss.str().c_str());
1274 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbOfTuples,1);
1275 const double *thisBBPtr(begin());
1276 int *retPtr(ret->getPointer());
1281 BBTree<3,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
1282 for(std::size_t i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
1283 *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
1288 BBTree<2,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
1289 for(std::size_t i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
1290 *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
1295 BBTree<1,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
1296 for(std::size_t i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
1297 *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
1301 throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : space dimension supported are [1,2,3] !");
1308 * Returns a copy of \a this array by excluding coincident tuples. Each tuple is
1309 * considered as coordinates of a point in getNumberOfComponents()-dimensional
1310 * space. The distance between tuples is computed using norm2. If several tuples are
1311 * not far each from other than \a prec, only one of them remains in the result
1312 * array. The order of tuples in the result array is same as in \a this one except
1313 * that coincident tuples are excluded.
1314 * \param [in] prec - minimal absolute distance between two tuples at which they are
1315 * considered not coincident.
1316 * \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
1317 * tuples have id strictly lower than \a limitTupleId then they are not excluded.
1318 * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1319 * is to delete using decrRef() as it is no more needed.
1320 * \throw If \a this is not allocated.
1321 * \throw If the number of components is not in [1,2,3,4].
1323 * \if ENABLE_EXAMPLES
1324 * \ref py_mcdataarraydouble_getdifferentvalues "Here is a Python example".
1327 DataArrayDouble *DataArrayDouble::getDifferentValues(double prec, int limitTupleId) const
1330 DataArrayInt *c0=0,*cI0=0;
1331 findCommonTuples(prec,limitTupleId,c0,cI0);
1332 MCAuto<DataArrayInt> c(c0),cI(cI0);
1333 int newNbOfTuples=-1;
1334 MCAuto<DataArrayInt> o2n=DataArrayInt::ConvertIndexArrayToO2N(getNumberOfTuples(),c0->begin(),cI0->begin(),cI0->end(),newNbOfTuples);
1335 return renumberAndReduce(o2n->getConstPointer(),newNbOfTuples);
1339 * Copy all components in a specified order from another DataArrayDouble.
1340 * Both numerical and textual data is copied. The number of tuples in \a this and
1341 * the other array can be different.
1342 * \param [in] a - the array to copy data from.
1343 * \param [in] compoIds - sequence of zero based indices of components, data of which is
1345 * \throw If \a a is NULL.
1346 * \throw If \a compoIds.size() != \a a->getNumberOfComponents().
1347 * \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
1349 * \if ENABLE_EXAMPLES
1350 * \ref py_mcdataarraydouble_setselectedcomponents "Here is a Python example".
1353 void DataArrayDouble::setSelectedComponents(const DataArrayDouble *a, const std::vector<int>& compoIds)
1356 throw INTERP_KERNEL::Exception("DataArrayDouble::setSelectedComponents : input DataArrayDouble is NULL !");
1358 copyPartOfStringInfoFrom2(compoIds,*a);
1359 std::size_t partOfCompoSz=compoIds.size();
1360 int nbOfCompo=getNumberOfComponents();
1361 int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
1362 const double *ac=a->getConstPointer();
1363 double *nc=getPointer();
1364 for(int i=0;i<nbOfTuples;i++)
1365 for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
1366 nc[nbOfCompo*i+compoIds[j]]=*ac;
1370 * Checks if 0.0 value is present in \a this array. If it is the case, an exception
1372 * \throw If zero is found in \a this array.
1374 void DataArrayDouble::checkNoNullValues() const
1376 const double *tmp=getConstPointer();
1377 std::size_t nbOfElems=getNbOfElems();
1378 const double *where=std::find(tmp,tmp+nbOfElems,0.);
1379 if(where!=tmp+nbOfElems)
1380 throw INTERP_KERNEL::Exception("A value 0.0 have been detected !");
1384 * Computes minimal and maximal value in each component. An output array is filled
1385 * with \c 2 * \a this->getNumberOfComponents() values, so the caller is to allocate
1386 * enough memory before calling this method.
1387 * \param [out] bounds - array of size at least 2 *\a this->getNumberOfComponents().
1388 * It is filled as follows:<br>
1389 * \a bounds[0] = \c min_of_component_0 <br>
1390 * \a bounds[1] = \c max_of_component_0 <br>
1391 * \a bounds[2] = \c min_of_component_1 <br>
1392 * \a bounds[3] = \c max_of_component_1 <br>
1395 void DataArrayDouble::getMinMaxPerComponent(double *bounds) const
1398 int dim=getNumberOfComponents();
1399 for (int idim=0; idim<dim; idim++)
1401 bounds[idim*2]=std::numeric_limits<double>::max();
1402 bounds[idim*2+1]=-std::numeric_limits<double>::max();
1404 const double *ptr=getConstPointer();
1405 int nbOfTuples=getNumberOfTuples();
1406 for(int i=0;i<nbOfTuples;i++)
1408 for(int idim=0;idim<dim;idim++)
1410 if(bounds[idim*2]>ptr[i*dim+idim])
1412 bounds[idim*2]=ptr[i*dim+idim];
1414 if(bounds[idim*2+1]<ptr[i*dim+idim])
1416 bounds[idim*2+1]=ptr[i*dim+idim];
1423 * This method retrieves a newly allocated DataArrayDouble instance having same number of tuples than \a this and twice number of components than \a this
1424 * to store both the min and max per component of each tuples.
1425 * \param [in] epsilon the width of the bbox (identical in each direction) - 0.0 by default
1427 * \return a newly created DataArrayDouble instance having \c this->getNumberOfTuples() tuples and 2 * \c this->getNumberOfComponent() components
1429 * \throw If \a this is not allocated yet.
1431 DataArrayDouble *DataArrayDouble::computeBBoxPerTuple(double epsilon) const
1434 const double *dataPtr=getConstPointer();
1435 int nbOfCompo=getNumberOfComponents();
1436 int nbTuples=getNumberOfTuples();
1437 MCAuto<DataArrayDouble> bbox=DataArrayDouble::New();
1438 bbox->alloc(nbTuples,2*nbOfCompo);
1439 double *bboxPtr=bbox->getPointer();
1440 for(int i=0;i<nbTuples;i++)
1442 for(int j=0;j<nbOfCompo;j++)
1444 bboxPtr[2*nbOfCompo*i+2*j]=dataPtr[nbOfCompo*i+j]-epsilon;
1445 bboxPtr[2*nbOfCompo*i+2*j+1]=dataPtr[nbOfCompo*i+j]+epsilon;
1452 * For each tuples **t** in \a other, this method retrieves tuples in \a this that are equal to **t**.
1453 * Two tuples are considered equal if the euclidian distance between the two tuples is lower than \a eps.
1455 * \param [in] other a DataArrayDouble having same number of components than \a this.
1456 * \param [in] eps absolute precision representing distance (using infinite norm) between 2 tuples behind which 2 tuples are considered equal.
1457 * \param [out] c will contain the set of tuple ids in \a this that are equal to to the tuple ids in \a other contiguously.
1458 * \a cI allows to extract information in \a c.
1459 * \param [out] cI is an indirection array that allows to extract the data contained in \a c.
1461 * \throw In case of:
1462 * - \a this is not allocated
1463 * - \a other is not allocated or null
1464 * - \a this and \a other do not have the same number of components
1465 * - if number of components of \a this is not in [1,2,3]
1467 * \sa MEDCouplingPointSet::getNodeIdsNearPoints, DataArrayDouble::getDifferentValues
1469 void DataArrayDouble::computeTupleIdsNearTuples(const DataArrayDouble *other, double eps, DataArrayInt *& c, DataArrayInt *& cI) const
1472 throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : input pointer other is null !");
1474 other->checkAllocated();
1475 int nbOfCompo=getNumberOfComponents();
1476 int otherNbOfCompo=other->getNumberOfComponents();
1477 if(nbOfCompo!=otherNbOfCompo)
1478 throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : number of components should be equal between this and other !");
1479 int nbOfTuplesOther=other->getNumberOfTuples();
1480 MCAuto<DataArrayInt> cArr(DataArrayInt::New()),cIArr(DataArrayInt::New()); cArr->alloc(0,1); cIArr->pushBackSilent(0);
1485 BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
1486 FindTupleIdsNearTuplesAlg<3>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
1491 BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
1492 FindTupleIdsNearTuplesAlg<2>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
1497 BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
1498 FindTupleIdsNearTuplesAlg<1>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
1502 throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for computeTupleIdsNearTuples. Must be 1, 2 or 3.");
1504 c=cArr.retn(); cI=cIArr.retn();
1508 * This method recenter tuples in \b this in order to be centered at the origin to benefit about the advantages of maximal precision to be around the box
1509 * around origin of 'radius' 1.
1511 * \param [in] eps absolute epsilon. under that value of delta between max and min no scale is performed.
1513 void DataArrayDouble::recenterForMaxPrecision(double eps)
1516 int dim=getNumberOfComponents();
1517 std::vector<double> bounds(2*dim);
1518 getMinMaxPerComponent(&bounds[0]);
1519 for(int i=0;i<dim;i++)
1521 double delta=bounds[2*i+1]-bounds[2*i];
1522 double offset=(bounds[2*i]+bounds[2*i+1])/2.;
1524 applyLin(1./delta,-offset/delta,i);
1526 applyLin(1.,-offset,i);
1531 * Returns the maximal value and all its locations within \a this one-dimensional array.
1532 * \param [out] tupleIds - a new instance of DataArrayInt containing indices of
1533 * tuples holding the maximal value. The caller is to delete it using
1534 * decrRef() as it is no more needed.
1535 * \return double - the maximal value among all values of \a this array.
1536 * \throw If \a this->getNumberOfComponents() != 1
1537 * \throw If \a this->getNumberOfTuples() < 1
1539 double DataArrayDouble::getMaxValue2(DataArrayInt*& tupleIds) const
1543 double ret=getMaxValue(tmp);
1544 tupleIds=findIdsInRange(ret,ret);
1549 * Returns the minimal value and all its locations within \a this one-dimensional array.
1550 * \param [out] tupleIds - a new instance of DataArrayInt containing indices of
1551 * tuples holding the minimal value. The caller is to delete it using
1552 * decrRef() as it is no more needed.
1553 * \return double - the minimal value among all values of \a this array.
1554 * \throw If \a this->getNumberOfComponents() != 1
1555 * \throw If \a this->getNumberOfTuples() < 1
1557 double DataArrayDouble::getMinValue2(DataArrayInt*& tupleIds) const
1561 double ret=getMinValue(tmp);
1562 tupleIds=findIdsInRange(ret,ret);
1567 * This method returns the number of values in \a this that are equals ( within an absolute precision of \a eps ) to input parameter \a value.
1568 * This method only works for single component array.
1570 * \return a value in [ 0, \c this->getNumberOfTuples() )
1572 * \throw If \a this is not allocated
1575 int DataArrayDouble::count(double value, double eps) const
1579 if(getNumberOfComponents()!=1)
1580 throw INTERP_KERNEL::Exception("DataArrayDouble::count : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
1581 const double *vals=begin();
1582 int nbOfTuples=getNumberOfTuples();
1583 for(int i=0;i<nbOfTuples;i++,vals++)
1584 if(fabs(*vals-value)<=eps)
1590 * Returns the average value of \a this one-dimensional array.
1591 * \return double - the average value over all values of \a this array.
1592 * \throw If \a this->getNumberOfComponents() != 1
1593 * \throw If \a this->getNumberOfTuples() < 1
1595 double DataArrayDouble::getAverageValue() const
1597 if(getNumberOfComponents()!=1)
1598 throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
1599 int nbOfTuples=getNumberOfTuples();
1601 throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : array exists but number of tuples must be > 0 !");
1602 const double *vals=getConstPointer();
1603 double ret=std::accumulate(vals,vals+nbOfTuples,0.);
1604 return ret/nbOfTuples;
1608 * Returns the Euclidean norm of the vector defined by \a this array.
1609 * \return double - the value of the Euclidean norm, i.e.
1610 * the square root of the inner product of vector.
1611 * \throw If \a this is not allocated.
1613 double DataArrayDouble::norm2() const
1617 std::size_t nbOfElems=getNbOfElems();
1618 const double *pt=getConstPointer();
1619 for(std::size_t i=0;i<nbOfElems;i++,pt++)
1625 * Returns the maximum norm of the vector defined by \a this array.
1626 * This method works even if the number of components is different from one.
1627 * If the number of elements in \a this is 0, -1. is returned.
1628 * \return double - the value of the maximum norm, i.e.
1629 * the maximal absolute value among values of \a this array (whatever its number of components).
1630 * \throw If \a this is not allocated.
1632 double DataArrayDouble::normMax() const
1636 std::size_t nbOfElems(getNbOfElems());
1637 const double *pt(getConstPointer());
1638 for(std::size_t i=0;i<nbOfElems;i++,pt++)
1640 double val(std::abs(*pt));
1648 * Returns the minimum norm (absolute value) of the vector defined by \a this array.
1649 * This method works even if the number of components is different from one.
1650 * If the number of elements in \a this is 0, std::numeric_limits<double>::max() is returned.
1651 * \return double - the value of the minimum norm, i.e.
1652 * the minimal absolute value among values of \a this array (whatever its number of components).
1653 * \throw If \a this is not allocated.
1655 double DataArrayDouble::normMin() const
1658 double ret(std::numeric_limits<double>::max());
1659 std::size_t nbOfElems(getNbOfElems());
1660 const double *pt(getConstPointer());
1661 for(std::size_t i=0;i<nbOfElems;i++,pt++)
1663 double val(std::abs(*pt));
1671 * Accumulates values of each component of \a this array.
1672 * \param [out] res - an array of length \a this->getNumberOfComponents(), allocated
1673 * by the caller, that is filled by this method with sum value for each
1675 * \throw If \a this is not allocated.
1677 void DataArrayDouble::accumulate(double *res) const
1680 const double *ptr=getConstPointer();
1681 int nbTuple=getNumberOfTuples();
1682 int nbComps=getNumberOfComponents();
1683 std::fill(res,res+nbComps,0.);
1684 for(int i=0;i<nbTuple;i++)
1685 std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<double>());
1689 * This method returns the min distance from an external tuple defined by [ \a tupleBg , \a tupleEnd ) to \a this and
1690 * the first tuple in \a this that matches the returned distance. If there is no tuples in \a this an exception will be thrown.
1693 * \a this is expected to be allocated and expected to have a number of components equal to the distance from \a tupleBg to
1694 * \a tupleEnd. If not an exception will be thrown.
1696 * \param [in] tupleBg start pointer (included) of input external tuple
1697 * \param [in] tupleEnd end pointer (not included) of input external tuple
1698 * \param [out] tupleId the tuple id in \a this that matches the min of distance between \a this and input external tuple
1699 * \return the min distance.
1700 * \sa MEDCouplingUMesh::distanceToPoint
1702 double DataArrayDouble::distanceToTuple(const double *tupleBg, const double *tupleEnd, int& tupleId) const
1705 int nbTuple=getNumberOfTuples();
1706 int nbComps=getNumberOfComponents();
1707 if(nbComps!=(int)std::distance(tupleBg,tupleEnd))
1708 { 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()); }
1710 throw INTERP_KERNEL::Exception("DataArrayDouble::distanceToTuple : no tuple in this ! No distance to compute !");
1711 double ret0=std::numeric_limits<double>::max();
1713 const double *work=getConstPointer();
1714 for(int i=0;i<nbTuple;i++)
1717 for(int j=0;j<nbComps;j++,work++)
1718 val+=(*work-tupleBg[j])*((*work-tupleBg[j]));
1722 { ret0=val; tupleId=i; }
1728 * Accumulate values of the given component of \a this array.
1729 * \param [in] compId - the index of the component of interest.
1730 * \return double - a sum value of \a compId-th component.
1731 * \throw If \a this is not allocated.
1732 * \throw If \a the condition ( 0 <= \a compId < \a this->getNumberOfComponents() ) is
1735 double DataArrayDouble::accumulate(int compId) const
1738 const double *ptr=getConstPointer();
1739 int nbTuple=getNumberOfTuples();
1740 int nbComps=getNumberOfComponents();
1741 if(compId<0 || compId>=nbComps)
1742 throw INTERP_KERNEL::Exception("DataArrayDouble::accumulate : Invalid compId specified : No such nb of components !");
1744 for(int i=0;i<nbTuple;i++)
1745 ret+=ptr[i*nbComps+compId];
1750 * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
1751 * The returned array will have same number of components than \a this and number of tuples equal to
1752 * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
1754 * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
1755 * 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.
1757 * \param [in] bgOfIndex - begin (included) of the input index array.
1758 * \param [in] endOfIndex - end (excluded) of the input index array.
1759 * \return DataArrayDouble * - the new instance having the same number of components than \a this.
1761 * \throw If bgOfIndex or end is NULL.
1762 * \throw If input index array is not ascendingly sorted.
1763 * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
1764 * \throw If std::distance(bgOfIndex,endOfIndex)==0.
1766 DataArrayDouble *DataArrayDouble::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
1768 if(!bgOfIndex || !endOfIndex)
1769 throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : input pointer NULL !");
1771 int nbCompo=getNumberOfComponents();
1772 int nbOfTuples=getNumberOfTuples();
1773 int sz=(int)std::distance(bgOfIndex,endOfIndex);
1775 throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : invalid size of input index array !");
1777 MCAuto<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(sz,nbCompo);
1778 const int *w=bgOfIndex;
1779 if(*w<0 || *w>=nbOfTuples)
1780 throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
1781 const double *srcPt=begin()+(*w)*nbCompo;
1782 double *tmp=ret->getPointer();
1783 for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
1785 std::fill(tmp,tmp+nbCompo,0.);
1788 for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
1790 if(j>=0 && j<nbOfTuples)
1791 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<double>());
1794 std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
1795 throw INTERP_KERNEL::Exception(oss.str().c_str());
1801 std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
1802 throw INTERP_KERNEL::Exception(oss.str().c_str());
1805 ret->copyStringInfoFrom(*this);
1810 * 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.
1811 * This method expects that \a this as only one component. The returned array will have \a this->getNumberOfTuples()+1 tuple with also one component.
1812 * The ith element of returned array is equal to the sum of elements in \a this with rank strictly lower than i.
1814 * \return DataArrayDouble - A newly built array containing cum sum of \a this.
1816 MCAuto<DataArrayDouble> DataArrayDouble::cumSum() const
1819 checkNbOfComps(1,"DataArrayDouble::cumSum : this is expected to be single component");
1820 int nbOfTuple(getNumberOfTuples());
1821 MCAuto<DataArrayDouble> ret(DataArrayDouble::New()); ret->alloc(nbOfTuple+1,1);
1822 double *ptr(ret->getPointer());
1824 const double *thisPtr(begin());
1825 for(int i=0;i<nbOfTuple;i++)
1826 ptr[i+1]=ptr[i]+thisPtr[i];
1831 * Converts each 2D point defined by the tuple of \a this array from the Polar to the
1832 * Cartesian coordinate system. The two components of the tuple of \a this array are
1833 * considered to contain (1) radius and (2) angle of the point in the Polar CS.
1834 * \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
1835 * contains X and Y coordinates of the point in the Cartesian CS. The caller
1836 * is to delete this array using decrRef() as it is no more needed. The array
1837 * does not contain any textual info on components.
1838 * \throw If \a this->getNumberOfComponents() != 2.
1839 * \sa fromCartToPolar
1841 DataArrayDouble *DataArrayDouble::fromPolarToCart() const
1844 int nbOfComp(getNumberOfComponents());
1846 throw INTERP_KERNEL::Exception("DataArrayDouble::fromPolarToCart : must be an array with exactly 2 components !");
1847 int nbOfTuple(getNumberOfTuples());
1848 DataArrayDouble *ret(DataArrayDouble::New());
1849 ret->alloc(nbOfTuple,2);
1850 double *w(ret->getPointer());
1851 const double *wIn(getConstPointer());
1852 for(int i=0;i<nbOfTuple;i++,w+=2,wIn+=2)
1854 w[0]=wIn[0]*cos(wIn[1]);
1855 w[1]=wIn[0]*sin(wIn[1]);
1861 * Converts each 3D point defined by the tuple of \a this array from the Cylindrical to
1862 * the Cartesian coordinate system. The three components of the tuple of \a this array
1863 * are considered to contain (1) radius, (2) azimuth and (3) altitude of the point in
1864 * the Cylindrical CS.
1865 * \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
1866 * contains X, Y and Z coordinates of the point in the Cartesian CS. The info
1867 * on the third component is copied from \a this array. The caller
1868 * is to delete this array using decrRef() as it is no more needed.
1869 * \throw If \a this->getNumberOfComponents() != 3.
1872 DataArrayDouble *DataArrayDouble::fromCylToCart() const
1875 int nbOfComp(getNumberOfComponents());
1877 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCylToCart : must be an array with exactly 3 components !");
1878 int nbOfTuple(getNumberOfTuples());
1879 DataArrayDouble *ret(DataArrayDouble::New());
1880 ret->alloc(getNumberOfTuples(),3);
1881 double *w(ret->getPointer());
1882 const double *wIn(getConstPointer());
1883 for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
1885 w[0]=wIn[0]*cos(wIn[1]);
1886 w[1]=wIn[0]*sin(wIn[1]);
1889 ret->setInfoOnComponent(2,getInfoOnComponent(2));
1894 * Converts each 3D point defined by the tuple of \a this array from the Spherical to
1895 * the Cartesian coordinate system. The three components of the tuple of \a this array
1896 * are considered to contain (1) radius, (2) polar angle and (3) azimuthal angle of the
1897 * point in the Cylindrical CS.
1898 * \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
1899 * contains X, Y and Z coordinates of the point in the Cartesian CS. The info
1900 * on the third component is copied from \a this array. The caller
1901 * is to delete this array using decrRef() as it is no more needed.
1902 * \throw If \a this->getNumberOfComponents() != 3.
1903 * \sa fromCartToSpher
1905 DataArrayDouble *DataArrayDouble::fromSpherToCart() const
1908 int nbOfComp(getNumberOfComponents());
1910 throw INTERP_KERNEL::Exception("DataArrayDouble::fromSpherToCart : must be an array with exactly 3 components !");
1911 int nbOfTuple(getNumberOfTuples());
1912 DataArrayDouble *ret(DataArrayDouble::New());
1913 ret->alloc(getNumberOfTuples(),3);
1914 double *w(ret->getPointer());
1915 const double *wIn(getConstPointer());
1916 for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
1918 w[0]=wIn[0]*cos(wIn[2])*sin(wIn[1]);
1919 w[1]=wIn[0]*sin(wIn[2])*sin(wIn[1]);
1920 w[2]=wIn[0]*cos(wIn[1]);
1926 * 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.
1927 * 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.
1928 * If \a at equals to AX_CYL the returned array will be the result of operation cylindric to cartesian of \a this...
1930 * \param [in] atOfThis - The axis type of \a this.
1931 * \return DataArrayDouble * - the new instance of DataArrayDouble (that must be dealed by caller) containing the result of the cartesianizification of \a this.
1933 DataArrayDouble *DataArrayDouble::cartesianize(MEDCouplingAxisType atOfThis) const
1936 int nbOfComp(getNumberOfComponents());
1937 MCAuto<DataArrayDouble> ret;
1945 ret=fromCylToCart();
1950 ret=fromPolarToCart();
1954 throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : For AX_CYL, number of components must be in [2,3] !");
1958 ret=fromSpherToCart();
1963 ret=fromPolarToCart();
1967 throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : For AX_CYL, number of components must be in [2,3] !");
1969 throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : not recognized axis type ! Only AX_CART, AX_CYL and AX_SPHER supported !");
1971 ret->copyStringInfoFrom(*this);
1976 * This method returns a newly created array to be deallocated that contains the result of conversion from cartesian to polar.
1977 * This method expects that \a this has exactly 2 components.
1978 * \sa fromPolarToCart
1980 DataArrayDouble *DataArrayDouble::fromCartToPolar() const
1982 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
1984 int nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
1986 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToPolar : must be an array with exactly 2 components !");
1987 ret->alloc(nbTuples,2);
1988 double *retPtr(ret->getPointer());
1989 const double *ptr(begin());
1990 for(int i=0;i<nbTuples;i++,ptr+=2,retPtr+=2)
1992 retPtr[0]=sqrt(ptr[0]*ptr[0]+ptr[1]*ptr[1]);
1993 retPtr[1]=atan2(ptr[1],ptr[0]);
1999 * This method returns a newly created array to be deallocated that contains the result of conversion from cartesian to cylindrical.
2000 * This method expects that \a this has exactly 3 components.
2003 DataArrayDouble *DataArrayDouble::fromCartToCyl() const
2005 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2007 int nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2009 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCyl : must be an array with exactly 3 components !");
2010 ret->alloc(nbTuples,3);
2011 double *retPtr(ret->getPointer());
2012 const double *ptr(begin());
2013 for(int i=0;i<nbTuples;i++,ptr+=3,retPtr+=3)
2015 retPtr[0]=sqrt(ptr[0]*ptr[0]+ptr[1]*ptr[1]);
2016 retPtr[1]=atan2(ptr[1],ptr[0]);
2023 * This method returns a newly created array to be deallocated that contains the result of conversion from cartesian to spherical coordinates.
2024 * \sa fromSpherToCart
2026 DataArrayDouble *DataArrayDouble::fromCartToSpher() const
2028 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2030 int nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2032 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToSpher : must be an array with exactly 3 components !");
2033 ret->alloc(nbTuples,3);
2034 double *retPtr(ret->getPointer());
2035 const double *ptr(begin());
2036 for(int i=0;i<nbTuples;i++,ptr+=3,retPtr+=3)
2038 retPtr[0]=sqrt(ptr[0]*ptr[0]+ptr[1]*ptr[1]+ptr[2]*ptr[2]);
2039 retPtr[1]=acos(ptr[2]/retPtr[0]);
2040 retPtr[2]=atan2(ptr[1],ptr[0]);
2046 * 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.
2047 * This method expects that \a this has exactly 3 components.
2048 * \sa MEDCouplingFieldDouble::computeVectorFieldCyl
2050 DataArrayDouble *DataArrayDouble::fromCartToCylGiven(const DataArrayDouble *coords, const double center[3], const double vect[3]) const
2053 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : input coords are NULL !");
2054 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2055 checkAllocated(); coords->checkAllocated();
2056 std::size_t nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2058 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : must be an array with exactly 3 components !");
2059 if(coords->getNumberOfComponents()!=3)
2060 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : coords array must have exactly 3 components !");
2061 if(coords->getNumberOfTuples()!=nbTuples)
2062 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : coords array must have the same number of tuples !");
2063 ret->alloc(nbTuples,nbOfComp);
2064 double magOfVect(sqrt(vect[0]*vect[0]+vect[1]*vect[1]+vect[2]*vect[2]));
2066 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : magnitude of vect is too low !");
2067 double Ur[3],Uteta[3],Uz[3],*retPtr(ret->getPointer());
2068 const double *coo(coords->begin()),*vectField(begin());
2069 std::transform(vect,vect+3,Uz,std::bind2nd(std::multiplies<double>(),1./magOfVect));
2070 for(int i=0;i<nbTuples;i++,vectField+=3,retPtr+=3,coo+=3)
2072 std::transform(coo,coo+3,center,Ur,std::minus<double>());
2073 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];
2074 double magOfTeta(sqrt(Uteta[0]*Uteta[0]+Uteta[1]*Uteta[1]+Uteta[2]*Uteta[2]));
2075 std::transform(Uteta,Uteta+3,Uteta,std::bind2nd(std::multiplies<double>(),1./magOfTeta));
2076 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];
2077 retPtr[0]=Ur[0]*vectField[0]+Ur[1]*vectField[1]+Ur[2]*vectField[2];
2078 retPtr[1]=Uteta[0]*vectField[0]+Uteta[1]*vectField[1]+Uteta[2]*vectField[2];
2079 retPtr[2]=Uz[0]*vectField[0]+Uz[1]*vectField[1]+Uz[2]*vectField[2];
2081 ret->copyStringInfoFrom(*this);
2086 * Computes the doubly contracted product of every tensor defined by the tuple of \a this
2087 * array containing 6 components.
2088 * \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
2089 * is calculated from the tuple <em>(t)</em> of \a this array as follows:
2090 * \f$ t[0]^2+t[1]^2+t[2]^2+2*t[3]^2+2*t[4]^2+2*t[5]^2\f$.
2091 * The caller is to delete this result array using decrRef() as it is no more needed.
2092 * \throw If \a this->getNumberOfComponents() != 6.
2094 DataArrayDouble *DataArrayDouble::doublyContractedProduct() const
2097 int nbOfComp(getNumberOfComponents());
2099 throw INTERP_KERNEL::Exception("DataArrayDouble::doublyContractedProduct : must be an array with exactly 6 components !");
2100 DataArrayDouble *ret=DataArrayDouble::New();
2101 int nbOfTuple=getNumberOfTuples();
2102 ret->alloc(nbOfTuple,1);
2103 const double *src=getConstPointer();
2104 double *dest=ret->getPointer();
2105 for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
2106 *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];
2111 * Computes the determinant of every square matrix defined by the tuple of \a this
2112 * array, which contains either 4, 6 or 9 components. The case of 6 components
2113 * corresponds to that of the upper triangular matrix.
2114 * \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
2115 * is the determinant of matrix of the corresponding tuple of \a this array.
2116 * The caller is to delete this result array using decrRef() as it is no more
2118 * \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2120 DataArrayDouble *DataArrayDouble::determinant() const
2123 DataArrayDouble *ret=DataArrayDouble::New();
2124 int nbOfTuple=getNumberOfTuples();
2125 ret->alloc(nbOfTuple,1);
2126 const double *src=getConstPointer();
2127 double *dest=ret->getPointer();
2128 switch(getNumberOfComponents())
2131 for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
2132 *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];
2135 for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
2136 *dest=src[0]*src[3]-src[1]*src[2];
2139 for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
2140 *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];
2144 throw INTERP_KERNEL::Exception("DataArrayDouble::determinant : Invalid number of components ! must be in 4,6,9 !");
2149 * Computes 3 eigenvalues of every upper triangular matrix defined by the tuple of
2150 * \a this array, which contains 6 components.
2151 * \return DataArrayDouble * - the new instance of DataArrayDouble containing 3
2152 * components, whose each tuple contains the eigenvalues of the matrix of
2153 * corresponding tuple of \a this array.
2154 * The caller is to delete this result array using decrRef() as it is no more
2156 * \throw If \a this->getNumberOfComponents() != 6.
2158 DataArrayDouble *DataArrayDouble::eigenValues() const
2161 int nbOfComp=getNumberOfComponents();
2163 throw INTERP_KERNEL::Exception("DataArrayDouble::eigenValues : must be an array with exactly 6 components !");
2164 DataArrayDouble *ret=DataArrayDouble::New();
2165 int nbOfTuple=getNumberOfTuples();
2166 ret->alloc(nbOfTuple,3);
2167 const double *src=getConstPointer();
2168 double *dest=ret->getPointer();
2169 for(int i=0;i<nbOfTuple;i++,dest+=3,src+=6)
2170 INTERP_KERNEL::computeEigenValues6(src,dest);
2175 * Computes 3 eigenvectors of every upper triangular matrix defined by the tuple of
2176 * \a this array, which contains 6 components.
2177 * \return DataArrayDouble * - the new instance of DataArrayDouble containing 9
2178 * components, whose each tuple contains 3 eigenvectors of the matrix of
2179 * corresponding tuple of \a this array.
2180 * The caller is to delete this result array using decrRef() as it is no more
2182 * \throw If \a this->getNumberOfComponents() != 6.
2184 DataArrayDouble *DataArrayDouble::eigenVectors() const
2187 int nbOfComp=getNumberOfComponents();
2189 throw INTERP_KERNEL::Exception("DataArrayDouble::eigenVectors : must be an array with exactly 6 components !");
2190 DataArrayDouble *ret=DataArrayDouble::New();
2191 int nbOfTuple=getNumberOfTuples();
2192 ret->alloc(nbOfTuple,9);
2193 const double *src=getConstPointer();
2194 double *dest=ret->getPointer();
2195 for(int i=0;i<nbOfTuple;i++,src+=6)
2198 INTERP_KERNEL::computeEigenValues6(src,tmp);
2199 for(int j=0;j<3;j++,dest+=3)
2200 INTERP_KERNEL::computeEigenVectorForEigenValue6(src,tmp[j],1e-12,dest);
2206 * Computes the inverse matrix of every matrix defined by the tuple of \a this
2207 * array, which contains either 4, 6 or 9 components. The case of 6 components
2208 * corresponds to that of the upper triangular matrix.
2209 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2210 * same number of components as \a this one, whose each tuple is the inverse
2211 * matrix of the matrix of corresponding tuple of \a this array.
2212 * The caller is to delete this result array using decrRef() as it is no more
2214 * \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2216 DataArrayDouble *DataArrayDouble::inverse() const
2219 int nbOfComp=getNumberOfComponents();
2220 if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
2221 throw INTERP_KERNEL::Exception("DataArrayDouble::inversion : must be an array with 4,6 or 9 components !");
2222 DataArrayDouble *ret=DataArrayDouble::New();
2223 int nbOfTuple=getNumberOfTuples();
2224 ret->alloc(nbOfTuple,nbOfComp);
2225 const double *src=getConstPointer();
2226 double *dest=ret->getPointer();
2228 for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
2230 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];
2231 dest[0]=(src[1]*src[2]-src[4]*src[4])/det;
2232 dest[1]=(src[0]*src[2]-src[5]*src[5])/det;
2233 dest[2]=(src[0]*src[1]-src[3]*src[3])/det;
2234 dest[3]=(src[5]*src[4]-src[3]*src[2])/det;
2235 dest[4]=(src[5]*src[3]-src[0]*src[4])/det;
2236 dest[5]=(src[3]*src[4]-src[1]*src[5])/det;
2238 else if(nbOfComp==4)
2239 for(int i=0;i<nbOfTuple;i++,dest+=4,src+=4)
2241 double det=src[0]*src[3]-src[1]*src[2];
2243 dest[1]=-src[1]/det;
2244 dest[2]=-src[2]/det;
2248 for(int i=0;i<nbOfTuple;i++,dest+=9,src+=9)
2250 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];
2251 dest[0]=(src[4]*src[8]-src[7]*src[5])/det;
2252 dest[1]=(src[7]*src[2]-src[1]*src[8])/det;
2253 dest[2]=(src[1]*src[5]-src[4]*src[2])/det;
2254 dest[3]=(src[6]*src[5]-src[3]*src[8])/det;
2255 dest[4]=(src[0]*src[8]-src[6]*src[2])/det;
2256 dest[5]=(src[2]*src[3]-src[0]*src[5])/det;
2257 dest[6]=(src[3]*src[7]-src[6]*src[4])/det;
2258 dest[7]=(src[6]*src[1]-src[0]*src[7])/det;
2259 dest[8]=(src[0]*src[4]-src[1]*src[3])/det;
2265 * Computes the trace of every matrix defined by the tuple of \a this
2266 * array, which contains either 4, 6 or 9 components. The case of 6 components
2267 * corresponds to that of the upper triangular matrix.
2268 * \return DataArrayDouble * - the new instance of DataArrayDouble containing
2269 * 1 component, whose each tuple is the trace of
2270 * the matrix of corresponding tuple of \a this array.
2271 * The caller is to delete this result array using decrRef() as it is no more
2273 * \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2275 DataArrayDouble *DataArrayDouble::trace() const
2278 int nbOfComp=getNumberOfComponents();
2279 if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
2280 throw INTERP_KERNEL::Exception("DataArrayDouble::trace : must be an array with 4,6 or 9 components !");
2281 DataArrayDouble *ret=DataArrayDouble::New();
2282 int nbOfTuple=getNumberOfTuples();
2283 ret->alloc(nbOfTuple,1);
2284 const double *src=getConstPointer();
2285 double *dest=ret->getPointer();
2287 for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
2288 *dest=src[0]+src[1]+src[2];
2289 else if(nbOfComp==4)
2290 for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
2291 *dest=src[0]+src[3];
2293 for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
2294 *dest=src[0]+src[4]+src[8];
2299 * Computes the stress deviator tensor of every stress tensor defined by the tuple of
2300 * \a this array, which contains 6 components.
2301 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2302 * same number of components and tuples as \a this array.
2303 * The caller is to delete this result array using decrRef() as it is no more
2305 * \throw If \a this->getNumberOfComponents() != 6.
2307 DataArrayDouble *DataArrayDouble::deviator() const
2310 int nbOfComp=getNumberOfComponents();
2312 throw INTERP_KERNEL::Exception("DataArrayDouble::deviator : must be an array with exactly 6 components !");
2313 DataArrayDouble *ret=DataArrayDouble::New();
2314 int nbOfTuple=getNumberOfTuples();
2315 ret->alloc(nbOfTuple,6);
2316 const double *src=getConstPointer();
2317 double *dest=ret->getPointer();
2318 for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
2320 double tr=(src[0]+src[1]+src[2])/3.;
2332 * Computes the magnitude of every vector defined by the tuple of
2334 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2335 * same number of tuples as \a this array and one component.
2336 * The caller is to delete this result array using decrRef() as it is no more
2338 * \throw If \a this is not allocated.
2340 DataArrayDouble *DataArrayDouble::magnitude() const
2343 int nbOfComp=getNumberOfComponents();
2344 DataArrayDouble *ret=DataArrayDouble::New();
2345 int nbOfTuple=getNumberOfTuples();
2346 ret->alloc(nbOfTuple,1);
2347 const double *src=getConstPointer();
2348 double *dest=ret->getPointer();
2349 for(int i=0;i<nbOfTuple;i++,dest++)
2352 for(int j=0;j<nbOfComp;j++,src++)
2360 * Computes the maximal value within every tuple of \a this array.
2361 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2362 * same number of tuples as \a this array and one component.
2363 * The caller is to delete this result array using decrRef() as it is no more
2365 * \throw If \a this is not allocated.
2366 * \sa DataArrayDouble::maxPerTupleWithCompoId
2368 DataArrayDouble *DataArrayDouble::maxPerTuple() const
2371 int nbOfComp=getNumberOfComponents();
2372 MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
2373 int nbOfTuple=getNumberOfTuples();
2374 ret->alloc(nbOfTuple,1);
2375 const double *src=getConstPointer();
2376 double *dest=ret->getPointer();
2377 for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
2378 *dest=*std::max_element(src,src+nbOfComp);
2383 * Computes the maximal value within every tuple of \a this array and it returns the first component
2384 * id for each tuple that corresponds to the maximal value within the tuple.
2386 * \param [out] compoIdOfMaxPerTuple - the new new instance of DataArrayInt containing the
2387 * same number of tuples and only one component.
2388 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2389 * same number of tuples as \a this array and one component.
2390 * The caller is to delete this result array using decrRef() as it is no more
2392 * \throw If \a this is not allocated.
2393 * \sa DataArrayDouble::maxPerTuple
2395 DataArrayDouble *DataArrayDouble::maxPerTupleWithCompoId(DataArrayInt* &compoIdOfMaxPerTuple) const
2398 int nbOfComp=getNumberOfComponents();
2399 MCAuto<DataArrayDouble> ret0=DataArrayDouble::New();
2400 MCAuto<DataArrayInt> ret1=DataArrayInt::New();
2401 int nbOfTuple=getNumberOfTuples();
2402 ret0->alloc(nbOfTuple,1); ret1->alloc(nbOfTuple,1);
2403 const double *src=getConstPointer();
2404 double *dest=ret0->getPointer(); int *dest1=ret1->getPointer();
2405 for(int i=0;i<nbOfTuple;i++,dest++,dest1++,src+=nbOfComp)
2407 const double *loc=std::max_element(src,src+nbOfComp);
2409 *dest1=(int)std::distance(src,loc);
2411 compoIdOfMaxPerTuple=ret1.retn();
2416 * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c this->getNumberOfTuples() tuples.
2417 * \n This returned array contains the euclidian distance for each tuple in \a this.
2418 * \n So the returned array can be seen as a dense symmetrical matrix whose diagonal elements are equal to 0.
2419 * \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)
2421 * \warning use this method with care because it can leads to big amount of consumed memory !
2423 * \return A newly allocated (huge) MEDCoupling::DataArrayDouble instance that the caller should deal with.
2425 * \throw If \a this is not allocated.
2427 * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrixWith
2429 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrix() const
2432 int nbOfComp=getNumberOfComponents();
2433 int nbOfTuples=getNumberOfTuples();
2434 const double *inData=getConstPointer();
2435 MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
2436 ret->alloc(nbOfTuples*nbOfTuples,1);
2437 double *outData=ret->getPointer();
2438 for(int i=0;i<nbOfTuples;i++)
2440 outData[i*nbOfTuples+i]=0.;
2441 for(int j=i+1;j<nbOfTuples;j++)
2444 for(int k=0;k<nbOfComp;k++)
2445 { double delta=inData[i*nbOfComp+k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
2447 outData[i*nbOfTuples+j]=dist;
2448 outData[j*nbOfTuples+i]=dist;
2455 * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c other->getNumberOfTuples() tuples.
2456 * \n This returned array contains the euclidian distance for each tuple in \a other with each tuple in \a this.
2457 * \n So the returned array can be seen as a dense rectangular matrix with \c other->getNumberOfTuples() rows and \c this->getNumberOfTuples() columns.
2458 * \n Output rectangular matrix is sorted along rows.
2459 * \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)
2461 * \warning use this method with care because it can leads to big amount of consumed memory !
2463 * \param [in] other DataArrayDouble instance having same number of components than \a this.
2464 * \return A newly allocated (huge) MEDCoupling::DataArrayDouble instance that the caller should deal with.
2466 * \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.
2468 * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrix
2470 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrixWith(const DataArrayDouble *other) const
2473 throw INTERP_KERNEL::Exception("DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : input parameter is null !");
2475 other->checkAllocated();
2476 int nbOfComp=getNumberOfComponents();
2477 int otherNbOfComp=other->getNumberOfComponents();
2478 if(nbOfComp!=otherNbOfComp)
2480 std::ostringstream oss; oss << "DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : this nb of compo=" << nbOfComp << " and other nb of compo=" << otherNbOfComp << ". It should match !";
2481 throw INTERP_KERNEL::Exception(oss.str().c_str());
2483 int nbOfTuples=getNumberOfTuples();
2484 int otherNbOfTuples=other->getNumberOfTuples();
2485 const double *inData=getConstPointer();
2486 const double *inDataOther=other->getConstPointer();
2487 MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
2488 ret->alloc(otherNbOfTuples*nbOfTuples,1);
2489 double *outData=ret->getPointer();
2490 for(int i=0;i<otherNbOfTuples;i++,inDataOther+=nbOfComp)
2492 for(int j=0;j<nbOfTuples;j++)
2495 for(int k=0;k<nbOfComp;k++)
2496 { double delta=inDataOther[k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
2498 outData[i*nbOfTuples+j]=dist;
2505 * This method expects that \a this stores 3 tuples containing 2 components each.
2506 * Each of this tuples represent a point into 2D space.
2507 * 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).
2508 * 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[.
2510 * \throw If \a this is not allocated.
2511 * \throw If \a this has not 3 tuples of 2 components
2512 * \throw If tuples/points in \a this are aligned
2514 void DataArrayDouble::asArcOfCircle(double center[2], double& radius, double& ang) const
2517 INTERP_KERNEL::QuadraticPlanarPrecision arcPrec(1e-14);
2518 if(getNumberOfTuples()!=3 && getNumberOfComponents()!=2)
2519 throw INTERP_KERNEL::Exception("DataArrayDouble::asArcCircle : this method expects");
2520 const double *pt(begin());
2521 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]));
2523 INTERP_KERNEL::AutoCppPtr<INTERP_KERNEL::EdgeLin> e1(new INTERP_KERNEL::EdgeLin(n0,n2)),e2(new INTERP_KERNEL::EdgeLin(n2,n1));
2524 INTERP_KERNEL::SegSegIntersector inters(*e1,*e2);
2525 bool colinearity(inters.areColinears());
2527 throw INTERP_KERNEL::Exception("DataArrayDouble::asArcOfCircle : 3 points in this have been detected as colinear !");
2529 INTERP_KERNEL::AutoCppPtr<INTERP_KERNEL::EdgeArcCircle> ret(new INTERP_KERNEL::EdgeArcCircle(n0,n2,n1));
2530 const double *c(ret->getCenter());
2531 center[0]=c[0]; center[1]=c[1];
2532 radius=ret->getRadius();
2533 ang=ret->getAngle();
2537 * Sorts value within every tuple of \a this array.
2538 * \param [in] asc - if \a true, the values are sorted in ascending order, else,
2539 * in descending order.
2540 * \throw If \a this is not allocated.
2542 void DataArrayDouble::sortPerTuple(bool asc)
2545 double *pt=getPointer();
2546 int nbOfTuple=getNumberOfTuples();
2547 int nbOfComp=getNumberOfComponents();
2549 for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
2550 std::sort(pt,pt+nbOfComp);
2552 for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
2553 std::sort(pt,pt+nbOfComp,std::greater<double>());
2558 * Modify all elements of \a this array, so that
2559 * an element _x_ becomes \f$ numerator / x \f$.
2560 * \warning If an exception is thrown because of presence of 0.0 element in \a this
2561 * array, all elements processed before detection of the zero element remain
2563 * \param [in] numerator - the numerator used to modify array elements.
2564 * \throw If \a this is not allocated.
2565 * \throw If there is an element equal to 0.0 in \a this array.
2567 void DataArrayDouble::applyInv(double numerator)
2570 double *ptr=getPointer();
2571 std::size_t nbOfElems=getNbOfElems();
2572 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2574 if(std::abs(*ptr)>std::numeric_limits<double>::min())
2576 *ptr=numerator/(*ptr);
2580 std::ostringstream oss; oss << "DataArrayDouble::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
2582 throw INTERP_KERNEL::Exception(oss.str().c_str());
2589 * Modify all elements of \a this array, so that
2590 * an element _x_ becomes <em> val ^ x </em>. Contrary to DataArrayInt::applyPow
2591 * all values in \a this have to be >= 0 if val is \b not integer.
2592 * \param [in] val - the value used to apply pow on all array elements.
2593 * \throw If \a this is not allocated.
2594 * \warning If an exception is thrown because of presence of 0 element in \a this
2595 * array and \a val is \b not integer, all elements processed before detection of the zero element remain
2598 void DataArrayDouble::applyPow(double val)
2601 double *ptr=getPointer();
2602 std::size_t nbOfElems=getNbOfElems();
2604 bool isInt=((double)val2)==val;
2607 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2613 std::ostringstream oss; oss << "DataArrayDouble::applyPow (double) : At elem # " << i << " value is " << *ptr << " ! must be >=0. !";
2614 throw INTERP_KERNEL::Exception(oss.str().c_str());
2620 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2621 *ptr=pow(*ptr,val2);
2627 * Modify all elements of \a this array, so that
2628 * an element _x_ becomes \f$ val ^ x \f$.
2629 * \param [in] val - the value used to apply pow on all array elements.
2630 * \throw If \a this is not allocated.
2631 * \throw If \a val < 0.
2632 * \warning If an exception is thrown because of presence of 0 element in \a this
2633 * array, all elements processed before detection of the zero element remain
2636 void DataArrayDouble::applyRPow(double val)
2640 throw INTERP_KERNEL::Exception("DataArrayDouble::applyRPow : the input value has to be >= 0 !");
2641 double *ptr=getPointer();
2642 std::size_t nbOfElems=getNbOfElems();
2643 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2649 * Returns a new DataArrayDouble created from \a this one by applying \a
2650 * FunctionToEvaluate to every tuple of \a this array. Textual data is not copied.
2651 * For more info see \ref MEDCouplingArrayApplyFunc
2652 * \param [in] nbOfComp - number of components in the result array.
2653 * \param [in] func - the \a FunctionToEvaluate declared as
2654 * \c bool (*\a func)(\c const \c double *\a pos, \c double *\a res),
2655 * where \a pos points to the first component of a tuple of \a this array
2656 * and \a res points to the first component of a tuple of the result array.
2657 * Note that length (number of components) of \a pos can differ from
2659 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2660 * same number of tuples as \a this array.
2661 * The caller is to delete this result array using decrRef() as it is no more
2663 * \throw If \a this is not allocated.
2664 * \throw If \a func returns \a false.
2666 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, FunctionToEvaluate func) const
2669 DataArrayDouble *newArr=DataArrayDouble::New();
2670 int nbOfTuples=getNumberOfTuples();
2671 int oldNbOfComp=getNumberOfComponents();
2672 newArr->alloc(nbOfTuples,nbOfComp);
2673 const double *ptr=getConstPointer();
2674 double *ptrToFill=newArr->getPointer();
2675 for(int i=0;i<nbOfTuples;i++)
2677 if(!func(ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp))
2679 std::ostringstream oss; oss << "For tuple # " << i << " with value (";
2680 std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
2681 oss << ") : Evaluation of function failed !";
2683 throw INTERP_KERNEL::Exception(oss.str().c_str());
2690 * Returns a new DataArrayDouble created from \a this one by applying a function to every
2691 * tuple of \a this array. Textual data is not copied.
2692 * For more info see \ref MEDCouplingArrayApplyFunc1.
2693 * \param [in] nbOfComp - number of components in the result array.
2694 * \param [in] func - the expression defining how to transform a tuple of \a this array.
2695 * Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
2696 * \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
2697 * If false the computation is carried on without any notification. When false the evaluation is a little faster.
2698 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2699 * same number of tuples as \a this array and \a nbOfComp components.
2700 * The caller is to delete this result array using decrRef() as it is no more
2702 * \throw If \a this is not allocated.
2703 * \throw If computing \a func fails.
2705 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, const std::string& func, bool isSafe) const
2707 INTERP_KERNEL::ExprParser expr(func);
2709 std::set<std::string> vars;
2710 expr.getTrueSetOfVars(vars);
2711 std::vector<std::string> varsV(vars.begin(),vars.end());
2712 return applyFuncNamedCompo(nbOfComp,varsV,func,isSafe);
2716 * Returns a new DataArrayDouble created from \a this one by applying a function to every
2717 * tuple of \a this array. Textual data is not copied. This method works by tuples (whatever its size).
2718 * If \a this is a one component array, call applyFuncOnThis instead that performs the same work faster.
2720 * For more info see \ref MEDCouplingArrayApplyFunc0.
2721 * \param [in] func - the expression defining how to transform a tuple of \a this array.
2722 * Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
2723 * \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
2724 * If false the computation is carried on without any notification. When false the evaluation is a little faster.
2725 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2726 * same number of tuples and components as \a this array.
2727 * The caller is to delete this result array using decrRef() as it is no more
2729 * \sa applyFuncOnThis
2730 * \throw If \a this is not allocated.
2731 * \throw If computing \a func fails.
2733 DataArrayDouble *DataArrayDouble::applyFunc(const std::string& func, bool isSafe) const
2735 int nbOfComp(getNumberOfComponents());
2737 throw INTERP_KERNEL::Exception("DataArrayDouble::applyFunc : output number of component must be > 0 !");
2739 int nbOfTuples(getNumberOfTuples());
2740 MCAuto<DataArrayDouble> newArr(DataArrayDouble::New());
2741 newArr->alloc(nbOfTuples,nbOfComp);
2742 INTERP_KERNEL::ExprParser expr(func);
2744 std::set<std::string> vars;
2745 expr.getTrueSetOfVars(vars);
2746 if((int)vars.size()>1)
2748 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 : ";
2749 std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
2750 throw INTERP_KERNEL::Exception(oss.str().c_str());
2754 expr.prepareFastEvaluator();
2755 newArr->rearrange(1);
2756 newArr->fillWithValue(expr.evaluateDouble());
2757 newArr->rearrange(nbOfComp);
2758 return newArr.retn();
2760 std::vector<std::string> vars2(vars.begin(),vars.end());
2761 double buff,*ptrToFill(newArr->getPointer());
2762 const double *ptr(begin());
2763 std::vector<double> stck;
2764 expr.prepareExprEvaluationDouble(vars2,1,1,0,&buff,&buff+1);
2765 expr.prepareFastEvaluator();
2768 for(int i=0;i<nbOfTuples;i++)
2770 for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
2773 expr.evaluateDoubleInternal(stck);
2774 *ptrToFill=stck.back();
2781 for(int i=0;i<nbOfTuples;i++)
2783 for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
2788 expr.evaluateDoubleInternalSafe(stck);
2790 catch(INTERP_KERNEL::Exception& e)
2792 std::ostringstream oss; oss << "For tuple # " << i << " component # " << iComp << " with value (";
2794 oss << ") : Evaluation of function failed !" << e.what();
2795 throw INTERP_KERNEL::Exception(oss.str().c_str());
2797 *ptrToFill=stck.back();
2802 return newArr.retn();
2806 * This method is a non const method that modify the array in \a this.
2807 * This method only works on one component array. It means that function \a func must
2808 * contain at most one variable.
2809 * This method is a specialization of applyFunc method with one parameter on one component array.
2811 * \param [in] func - the expression defining how to transform a tuple of \a this array.
2812 * Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
2813 * \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
2814 * If false the computation is carried on without any notification. When false the evaluation is a little faster.
2818 void DataArrayDouble::applyFuncOnThis(const std::string& func, bool isSafe)
2820 int nbOfComp(getNumberOfComponents());
2822 throw INTERP_KERNEL::Exception("DataArrayDouble::applyFuncOnThis : output number of component must be > 0 !");
2824 int nbOfTuples(getNumberOfTuples());
2825 INTERP_KERNEL::ExprParser expr(func);
2827 std::set<std::string> vars;
2828 expr.getTrueSetOfVars(vars);
2829 if((int)vars.size()>1)
2831 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 : ";
2832 std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
2833 throw INTERP_KERNEL::Exception(oss.str().c_str());
2837 expr.prepareFastEvaluator();
2838 std::vector<std::string> compInfo(getInfoOnComponents());
2840 fillWithValue(expr.evaluateDouble());
2841 rearrange(nbOfComp);
2842 setInfoOnComponents(compInfo);
2845 std::vector<std::string> vars2(vars.begin(),vars.end());
2846 double buff,*ptrToFill(getPointer());
2847 const double *ptr(begin());
2848 std::vector<double> stck;
2849 expr.prepareExprEvaluationDouble(vars2,1,1,0,&buff,&buff+1);
2850 expr.prepareFastEvaluator();
2853 for(int i=0;i<nbOfTuples;i++)
2855 for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
2858 expr.evaluateDoubleInternal(stck);
2859 *ptrToFill=stck.back();
2866 for(int i=0;i<nbOfTuples;i++)
2868 for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
2873 expr.evaluateDoubleInternalSafe(stck);
2875 catch(INTERP_KERNEL::Exception& e)
2877 std::ostringstream oss; oss << "For tuple # " << i << " component # " << iComp << " with value (";
2879 oss << ") : Evaluation of function failed !" << e.what();
2880 throw INTERP_KERNEL::Exception(oss.str().c_str());
2882 *ptrToFill=stck.back();
2890 * Returns a new DataArrayDouble created from \a this one by applying a function to every
2891 * tuple of \a this array. Textual data is not copied.
2892 * For more info see \ref MEDCouplingArrayApplyFunc2.
2893 * \param [in] nbOfComp - number of components in the result array.
2894 * \param [in] func - the expression defining how to transform a tuple of \a this array.
2895 * Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
2896 * \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
2897 * If false the computation is carried on without any notification. When false the evaluation is a little faster.
2898 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2899 * same number of tuples as \a this array.
2900 * The caller is to delete this result array using decrRef() as it is no more
2902 * \throw If \a this is not allocated.
2903 * \throw If \a func contains vars that are not in \a this->getInfoOnComponent().
2904 * \throw If computing \a func fails.
2906 DataArrayDouble *DataArrayDouble::applyFuncCompo(int nbOfComp, const std::string& func, bool isSafe) const
2908 return applyFuncNamedCompo(nbOfComp,getVarsOnComponent(),func,isSafe);
2912 * Returns a new DataArrayDouble created from \a this one by applying a function to every
2913 * tuple of \a this array. Textual data is not copied.
2914 * For more info see \ref MEDCouplingArrayApplyFunc3.
2915 * \param [in] nbOfComp - number of components in the result array.
2916 * \param [in] varsOrder - sequence of vars defining their order.
2917 * \param [in] func - the expression defining how to transform a tuple of \a this array.
2918 * Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
2919 * \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
2920 * If false the computation is carried on without any notification. When false the evaluation is a little faster.
2921 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2922 * same number of tuples as \a this array.
2923 * The caller is to delete this result array using decrRef() as it is no more
2925 * \throw If \a this is not allocated.
2926 * \throw If \a func contains vars not in \a varsOrder.
2927 * \throw If computing \a func fails.
2929 DataArrayDouble *DataArrayDouble::applyFuncNamedCompo(int nbOfComp, const std::vector<std::string>& varsOrder, const std::string& func, bool isSafe) const
2932 throw INTERP_KERNEL::Exception("DataArrayDouble::applyFuncNamedCompo : output number of component must be > 0 !");
2933 std::vector<std::string> varsOrder2(varsOrder);
2934 int oldNbOfComp(getNumberOfComponents());
2935 for(int i=(int)varsOrder.size();i<oldNbOfComp;i++)
2936 varsOrder2.push_back(std::string());
2938 int nbOfTuples(getNumberOfTuples());
2939 INTERP_KERNEL::ExprParser expr(func);
2941 std::set<std::string> vars;
2942 expr.getTrueSetOfVars(vars);
2943 if((int)vars.size()>oldNbOfComp)
2945 std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
2946 oss << vars.size() << " variables : ";
2947 std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
2948 throw INTERP_KERNEL::Exception(oss.str().c_str());
2950 MCAuto<DataArrayDouble> newArr(DataArrayDouble::New());
2951 newArr->alloc(nbOfTuples,nbOfComp);
2952 INTERP_KERNEL::AutoPtr<double> buff(new double[oldNbOfComp]);
2953 double *buffPtr(buff),*ptrToFill;
2954 std::vector<double> stck;
2955 for(int iComp=0;iComp<nbOfComp;iComp++)
2957 expr.prepareExprEvaluationDouble(varsOrder2,oldNbOfComp,nbOfComp,iComp,buffPtr,buffPtr+oldNbOfComp);
2958 expr.prepareFastEvaluator();
2959 const double *ptr(getConstPointer());
2960 ptrToFill=newArr->getPointer()+iComp;
2963 for(int i=0;i<nbOfTuples;i++,ptrToFill+=nbOfComp,ptr+=oldNbOfComp)
2965 std::copy(ptr,ptr+oldNbOfComp,buffPtr);
2966 expr.evaluateDoubleInternal(stck);
2967 *ptrToFill=stck.back();
2973 for(int i=0;i<nbOfTuples;i++,ptrToFill+=nbOfComp,ptr+=oldNbOfComp)
2975 std::copy(ptr,ptr+oldNbOfComp,buffPtr);
2978 expr.evaluateDoubleInternalSafe(stck);
2979 *ptrToFill=stck.back();
2982 catch(INTERP_KERNEL::Exception& e)
2984 std::ostringstream oss; oss << "For tuple # " << i << " with value (";
2985 std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
2986 oss << ") : Evaluation of function failed !" << e.what();
2987 throw INTERP_KERNEL::Exception(oss.str().c_str());
2992 return newArr.retn();
2995 void DataArrayDouble::applyFuncFast32(const std::string& func)
2998 INTERP_KERNEL::ExprParser expr(func);
3000 char *funcStr=expr.compileX86();
3002 *((void **)&funcPtr)=funcStr;//he he...
3004 double *ptr=getPointer();
3005 int nbOfComp=getNumberOfComponents();
3006 int nbOfTuples=getNumberOfTuples();
3007 int nbOfElems=nbOfTuples*nbOfComp;
3008 for(int i=0;i<nbOfElems;i++,ptr++)
3013 void DataArrayDouble::applyFuncFast64(const std::string& func)
3016 INTERP_KERNEL::ExprParser expr(func);
3018 char *funcStr=expr.compileX86_64();
3020 *((void **)&funcPtr)=funcStr;//he he...
3022 double *ptr=getPointer();
3023 int nbOfComp=getNumberOfComponents();
3024 int nbOfTuples=getNumberOfTuples();
3025 int nbOfElems=nbOfTuples*nbOfComp;
3026 for(int i=0;i<nbOfElems;i++,ptr++)
3032 * \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.
3034 MCAuto<DataArrayDouble> DataArrayDouble::symmetry3DPlane(const double point[3], const double normalVector[3]) const
3037 if(getNumberOfComponents()!=3)
3038 throw INTERP_KERNEL::Exception("DataArrayDouble::symmetry3DPlane : this is excepted to have 3 components !");
3039 int nbTuples(getNumberOfTuples());
3040 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
3041 ret->alloc(nbTuples,3);
3042 Symmetry3DPlane(point,normalVector,nbTuples,begin(),ret->getPointer());
3046 DataArrayDoubleIterator *DataArrayDouble::iterator()
3048 return new DataArrayDoubleIterator(this);
3052 * Returns a new DataArrayInt containing indices of tuples of \a this one-dimensional
3053 * array whose values are within a given range. Textual data is not copied.
3054 * \param [in] vmin - a lowest acceptable value (included).
3055 * \param [in] vmax - a greatest acceptable value (included).
3056 * \return DataArrayInt * - the new instance of DataArrayInt.
3057 * The caller is to delete this result array using decrRef() as it is no more
3059 * \throw If \a this->getNumberOfComponents() != 1.
3061 * \sa DataArrayDouble::findIdsNotInRange
3063 * \if ENABLE_EXAMPLES
3064 * \ref cpp_mcdataarraydouble_getidsinrange "Here is a C++ example".<br>
3065 * \ref py_mcdataarraydouble_getidsinrange "Here is a Python example".
3068 DataArrayInt *DataArrayDouble::findIdsInRange(double vmin, double vmax) const
3071 if(getNumberOfComponents()!=1)
3072 throw INTERP_KERNEL::Exception("DataArrayDouble::findIdsInRange : this must have exactly one component !");
3073 const double *cptr(begin());
3074 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
3075 int nbOfTuples(getNumberOfTuples());
3076 for(int i=0;i<nbOfTuples;i++,cptr++)
3077 if(*cptr>=vmin && *cptr<=vmax)
3078 ret->pushBackSilent(i);
3083 * Returns a new DataArrayInt containing indices of tuples of \a this one-dimensional
3084 * array whose values are not within a given range. Textual data is not copied.
3085 * \param [in] vmin - a lowest not acceptable value (excluded).
3086 * \param [in] vmax - a greatest not acceptable value (excluded).
3087 * \return DataArrayInt * - the new instance of DataArrayInt.
3088 * The caller is to delete this result array using decrRef() as it is no more
3090 * \throw If \a this->getNumberOfComponents() != 1.
3092 * \sa DataArrayDouble::findIdsInRange
3094 DataArrayInt *DataArrayDouble::findIdsNotInRange(double vmin, double vmax) const
3097 if(getNumberOfComponents()!=1)
3098 throw INTERP_KERNEL::Exception("DataArrayDouble::findIdsNotInRange : this must have exactly one component !");
3099 const double *cptr(begin());
3100 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
3101 int nbOfTuples(getNumberOfTuples());
3102 for(int i=0;i<nbOfTuples;i++,cptr++)
3103 if(*cptr<vmin || *cptr>vmax)
3104 ret->pushBackSilent(i);
3109 * Returns a new DataArrayDouble by concatenating two given arrays, so that (1) the number
3110 * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
3111 * the number of component in the result array is same as that of each of given arrays.
3112 * Info on components is copied from the first of the given arrays. Number of components
3113 * in the given arrays must be the same.
3114 * \param [in] a1 - an array to include in the result array.
3115 * \param [in] a2 - another array to include in the result array.
3116 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3117 * The caller is to delete this result array using decrRef() as it is no more
3119 * \throw If both \a a1 and \a a2 are NULL.
3120 * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
3122 DataArrayDouble *DataArrayDouble::Aggregate(const DataArrayDouble *a1, const DataArrayDouble *a2)
3124 std::vector<const DataArrayDouble *> tmp(2);
3125 tmp[0]=a1; tmp[1]=a2;
3126 return Aggregate(tmp);
3130 * Returns a new DataArrayDouble by concatenating all given arrays, so that (1) the number
3131 * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
3132 * the number of component in the result array is same as that of each of given arrays.
3133 * Info on components is copied from the first of the given arrays. Number of components
3134 * in the given arrays must be the same.
3135 * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it
3136 * not the object itself.
3137 * \param [in] arr - a sequence of arrays to include in the result array.
3138 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3139 * The caller is to delete this result array using decrRef() as it is no more
3141 * \throw If all arrays within \a arr are NULL.
3142 * \throw If getNumberOfComponents() of arrays within \a arr.
3144 DataArrayDouble *DataArrayDouble::Aggregate(const std::vector<const DataArrayDouble *>& arr)
3146 std::vector<const DataArrayDouble *> a;
3147 for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
3151 throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : input list must contain at least one NON EMPTY DataArrayDouble !");
3152 std::vector<const DataArrayDouble *>::const_iterator it=a.begin();
3153 std::size_t nbOfComp((*it)->getNumberOfComponents());
3154 int nbt=(*it++)->getNumberOfTuples();
3155 for(int i=1;it!=a.end();it++,i++)
3157 if((*it)->getNumberOfComponents()!=nbOfComp)
3158 throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : Nb of components mismatch for array aggregation !");
3159 nbt+=(*it)->getNumberOfTuples();
3161 MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
3162 ret->alloc(nbt,nbOfComp);
3163 double *pt=ret->getPointer();
3164 for(it=a.begin();it!=a.end();it++)
3165 pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
3166 ret->copyStringInfoFrom(*(a[0]));
3171 * Returns a new DataArrayDouble containing a dot product of two given arrays, so that
3172 * the i-th tuple of the result array is a sum of products of j-th components of i-th
3173 * tuples of given arrays (\f$ a_i = \sum_{j=1}^n a1_j * a2_j \f$).
3174 * Info on components and name is copied from the first of the given arrays.
3175 * Number of tuples and components in the given arrays must be the same.
3176 * \param [in] a1 - a given array.
3177 * \param [in] a2 - another given array.
3178 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3179 * The caller is to delete this result array using decrRef() as it is no more
3181 * \throw If either \a a1 or \a a2 is NULL.
3182 * \throw If any given array is not allocated.
3183 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3184 * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
3186 DataArrayDouble *DataArrayDouble::Dot(const DataArrayDouble *a1, const DataArrayDouble *a2)
3189 throw INTERP_KERNEL::Exception("DataArrayDouble::Dot : input DataArrayDouble instance is NULL !");
3190 a1->checkAllocated();
3191 a2->checkAllocated();
3192 std::size_t nbOfComp(a1->getNumberOfComponents());
3193 if(nbOfComp!=a2->getNumberOfComponents())
3194 throw INTERP_KERNEL::Exception("Nb of components mismatch for array Dot !");
3195 std::size_t nbOfTuple(a1->getNumberOfTuples());
3196 if(nbOfTuple!=a2->getNumberOfTuples())
3197 throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Dot !");
3198 DataArrayDouble *ret=DataArrayDouble::New();
3199 ret->alloc(nbOfTuple,1);
3200 double *retPtr=ret->getPointer();
3201 const double *a1Ptr=a1->begin(),*a2Ptr(a2->begin());
3202 for(std::size_t i=0;i<nbOfTuple;i++)
3205 for(std::size_t j=0;j<nbOfComp;j++)
3206 sum+=a1Ptr[i*nbOfComp+j]*a2Ptr[i*nbOfComp+j];
3209 ret->setInfoOnComponent(0,a1->getInfoOnComponent(0));
3210 ret->setName(a1->getName());
3215 * Returns a new DataArrayDouble containing a cross product of two given arrays, so that
3216 * the i-th tuple of the result array contains 3 components of a vector which is a cross
3217 * product of two vectors defined by the i-th tuples of given arrays.
3218 * Info on components is copied from the first of the given arrays.
3219 * Number of tuples in the given arrays must be the same.
3220 * Number of components in the given arrays must be 3.
3221 * \param [in] a1 - a given array.
3222 * \param [in] a2 - another given array.
3223 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3224 * The caller is to delete this result array using decrRef() as it is no more
3226 * \throw If either \a a1 or \a a2 is NULL.
3227 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3228 * \throw If \a a1->getNumberOfComponents() != 3
3229 * \throw If \a a2->getNumberOfComponents() != 3
3231 DataArrayDouble *DataArrayDouble::CrossProduct(const DataArrayDouble *a1, const DataArrayDouble *a2)
3234 throw INTERP_KERNEL::Exception("DataArrayDouble::CrossProduct : input DataArrayDouble instance is NULL !");
3235 std::size_t nbOfComp(a1->getNumberOfComponents());
3236 if(nbOfComp!=a2->getNumberOfComponents())
3237 throw INTERP_KERNEL::Exception("Nb of components mismatch for array crossProduct !");
3239 throw INTERP_KERNEL::Exception("Nb of components must be equal to 3 for array crossProduct !");
3240 std::size_t nbOfTuple(a1->getNumberOfTuples());
3241 if(nbOfTuple!=a2->getNumberOfTuples())
3242 throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array crossProduct !");
3243 DataArrayDouble *ret=DataArrayDouble::New();
3244 ret->alloc(nbOfTuple,3);
3245 double *retPtr=ret->getPointer();
3246 const double *a1Ptr(a1->begin()),*a2Ptr(a2->begin());
3247 for(std::size_t i=0;i<nbOfTuple;i++)
3249 retPtr[3*i]=a1Ptr[3*i+1]*a2Ptr[3*i+2]-a1Ptr[3*i+2]*a2Ptr[3*i+1];
3250 retPtr[3*i+1]=a1Ptr[3*i+2]*a2Ptr[3*i]-a1Ptr[3*i]*a2Ptr[3*i+2];
3251 retPtr[3*i+2]=a1Ptr[3*i]*a2Ptr[3*i+1]-a1Ptr[3*i+1]*a2Ptr[3*i];
3253 ret->copyStringInfoFrom(*a1);
3258 * Returns a new DataArrayDouble containing maximal values of two given arrays.
3259 * Info on components is copied from the first of the given arrays.
3260 * Number of tuples and components in the given arrays must be the same.
3261 * \param [in] a1 - an array to compare values with another one.
3262 * \param [in] a2 - another array to compare values with the first one.
3263 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3264 * The caller is to delete this result array using decrRef() as it is no more
3266 * \throw If either \a a1 or \a a2 is NULL.
3267 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3268 * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
3270 DataArrayDouble *DataArrayDouble::Max(const DataArrayDouble *a1, const DataArrayDouble *a2)
3273 throw INTERP_KERNEL::Exception("DataArrayDouble::Max : input DataArrayDouble instance is NULL !");
3274 std::size_t nbOfComp(a1->getNumberOfComponents());
3275 if(nbOfComp!=a2->getNumberOfComponents())
3276 throw INTERP_KERNEL::Exception("Nb of components mismatch for array Max !");
3277 std::size_t nbOfTuple(a1->getNumberOfTuples());
3278 if(nbOfTuple!=a2->getNumberOfTuples())
3279 throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Max !");
3280 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
3281 ret->alloc(nbOfTuple,nbOfComp);
3282 double *retPtr(ret->getPointer());
3283 const double *a1Ptr(a1->begin()),*a2Ptr(a2->begin());
3284 std::size_t nbElem(nbOfTuple*nbOfComp);
3285 for(std::size_t i=0;i<nbElem;i++)
3286 retPtr[i]=std::max(a1Ptr[i],a2Ptr[i]);
3287 ret->copyStringInfoFrom(*a1);
3292 * Returns a new DataArrayDouble containing minimal values of two given arrays.
3293 * Info on components is copied from the first of the given arrays.
3294 * Number of tuples and components in the given arrays must be the same.
3295 * \param [in] a1 - an array to compare values with another one.
3296 * \param [in] a2 - another array to compare values with the first one.
3297 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3298 * The caller is to delete this result array using decrRef() as it is no more
3300 * \throw If either \a a1 or \a a2 is NULL.
3301 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3302 * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
3304 DataArrayDouble *DataArrayDouble::Min(const DataArrayDouble *a1, const DataArrayDouble *a2)
3307 throw INTERP_KERNEL::Exception("DataArrayDouble::Min : input DataArrayDouble instance is NULL !");
3308 std::size_t nbOfComp(a1->getNumberOfComponents());
3309 if(nbOfComp!=a2->getNumberOfComponents())
3310 throw INTERP_KERNEL::Exception("Nb of components mismatch for array min !");
3311 std::size_t nbOfTuple(a1->getNumberOfTuples());
3312 if(nbOfTuple!=a2->getNumberOfTuples())
3313 throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array min !");
3314 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
3315 ret->alloc(nbOfTuple,nbOfComp);
3316 double *retPtr(ret->getPointer());
3317 const double *a1Ptr(a1->begin()),*a2Ptr(a2->begin());
3318 std::size_t nbElem(nbOfTuple*nbOfComp);
3319 for(std::size_t i=0;i<nbElem;i++)
3320 retPtr[i]=std::min(a1Ptr[i],a2Ptr[i]);
3321 ret->copyStringInfoFrom(*a1);
3326 * Returns a new DataArrayDouble that is the result of pow of two given arrays. There are 3
3329 * \param [in] a1 - an array to pow up.
3330 * \param [in] a2 - another array to sum up.
3331 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3332 * The caller is to delete this result array using decrRef() as it is no more
3334 * \throw If either \a a1 or \a a2 is NULL.
3335 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3336 * \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
3337 * \throw If there is a negative value in \a a1.
3339 DataArrayDouble *DataArrayDouble::Pow(const DataArrayDouble *a1, const DataArrayDouble *a2)
3342 throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : at least one of input instances is null !");
3343 int nbOfTuple=a1->getNumberOfTuples();
3344 int nbOfTuple2=a2->getNumberOfTuples();
3345 int nbOfComp=a1->getNumberOfComponents();
3346 int nbOfComp2=a2->getNumberOfComponents();
3347 if(nbOfTuple!=nbOfTuple2)
3348 throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of tuples mismatches !");
3349 if(nbOfComp!=1 || nbOfComp2!=1)
3350 throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of components of both arrays must be equal to 1 !");
3351 MCAuto<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbOfTuple,1);
3352 const double *ptr1(a1->begin()),*ptr2(a2->begin());
3353 double *ptr=ret->getPointer();
3354 for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
3358 *ptr=pow(*ptr1,*ptr2);
3362 std::ostringstream oss; oss << "DataArrayDouble::Pow : on tuple #" << i << " of a1 value is < 0 (" << *ptr1 << ") !";
3363 throw INTERP_KERNEL::Exception(oss.str().c_str());
3370 * Apply pow on values of another DataArrayDouble to values of \a this one.
3372 * \param [in] other - an array to pow to \a this one.
3373 * \throw If \a other is NULL.
3374 * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
3375 * \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
3376 * \throw If there is a negative value in \a this.
3378 void DataArrayDouble::powEqual(const DataArrayDouble *other)
3381 throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : input instance is null !");
3382 int nbOfTuple=getNumberOfTuples();
3383 int nbOfTuple2=other->getNumberOfTuples();
3384 int nbOfComp=getNumberOfComponents();
3385 int nbOfComp2=other->getNumberOfComponents();
3386 if(nbOfTuple!=nbOfTuple2)
3387 throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of tuples mismatches !");
3388 if(nbOfComp!=1 || nbOfComp2!=1)
3389 throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of components of both arrays must be equal to 1 !");
3390 double *ptr=getPointer();
3391 const double *ptrc=other->begin();
3392 for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
3395 *ptr=pow(*ptr,*ptrc);
3398 std::ostringstream oss; oss << "DataArrayDouble::powEqual : on tuple #" << i << " of this value is < 0 (" << *ptr << ") !";
3399 throw INTERP_KERNEL::Exception(oss.str().c_str());
3406 * This method is \b NOT wrapped into python because it can be useful only for performance reasons in C++ context.
3407 * All values in \a this must be 0. or 1. within eps error. 0 means false, 1 means true.
3408 * If an another value than 0 or 1 appear (within eps precision) an INTERP_KERNEL::Exception will be thrown.
3410 * \throw if \a this is not allocated.
3411 * \throw if \a this has not exactly one component.
3413 std::vector<bool> DataArrayDouble::toVectorOfBool(double eps) const
3416 if(getNumberOfComponents()!=1)
3417 throw INTERP_KERNEL::Exception("DataArrayDouble::toVectorOfBool : must be applied on single component array !");
3418 int nbt(getNumberOfTuples());
3419 std::vector<bool> ret(nbt);
3420 const double *pt(begin());
3421 for(int i=0;i<nbt;i++)
3425 else if(fabs(pt[i]-1.)<eps)
3429 std::ostringstream oss; oss << "DataArrayDouble::toVectorOfBool : the tuple #" << i << " has value " << pt[i] << " is invalid ! must be 0. or 1. !";
3430 throw INTERP_KERNEL::Exception(oss.str().c_str());
3437 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
3440 void DataArrayDouble::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
3445 tinyInfo[0]=getNumberOfTuples();
3446 tinyInfo[1]=getNumberOfComponents();
3456 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
3459 void DataArrayDouble::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
3463 int nbOfCompo=getNumberOfComponents();
3464 tinyInfo.resize(nbOfCompo+1);
3465 tinyInfo[0]=getName();
3466 for(int i=0;i<nbOfCompo;i++)
3467 tinyInfo[i+1]=getInfoOnComponent(i);
3472 tinyInfo[0]=getName();
3477 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
3478 * This method returns if a feeding is needed.
3480 bool DataArrayDouble::resizeForUnserialization(const std::vector<int>& tinyInfoI)
3482 int nbOfTuple=tinyInfoI[0];
3483 int nbOfComp=tinyInfoI[1];
3484 if(nbOfTuple!=-1 || nbOfComp!=-1)
3486 alloc(nbOfTuple,nbOfComp);
3493 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
3495 void DataArrayDouble::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
3497 setName(tinyInfoS[0]);
3500 int nbOfCompo=getNumberOfComponents();
3501 for(int i=0;i<nbOfCompo;i++)
3502 setInfoOnComponent(i,tinyInfoS[i+1]);
3507 * Low static method that operates 3D rotation of 'nbNodes' 3D nodes whose coordinates are arranged in \a coordsIn
3508 * around an axe ( \a center, \a vect) and with angle \a angle.
3510 void DataArrayDouble::Rotate3DAlg(const double *center, const double *vect, double angle, int nbNodes, const double *coordsIn, double *coordsOut)
3512 if(!center || !vect)
3513 throw INTERP_KERNEL::Exception("DataArrayDouble::Rotate3DAlg : null vector in input !");
3514 double sina(sin(angle));
3515 double cosa(cos(angle));
3516 double vectorNorm[3];
3518 double matrixTmp[9];
3519 double norm(sqrt(vect[0]*vect[0]+vect[1]*vect[1]+vect[2]*vect[2]));
3520 if(norm<std::numeric_limits<double>::min())
3521 throw INTERP_KERNEL::Exception("DataArrayDouble::Rotate3DAlg : magnitude of input vector is too close of 0. !");
3522 std::transform(vect,vect+3,vectorNorm,std::bind2nd(std::multiplies<double>(),1/norm));
3523 //rotation matrix computation
3524 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;
3525 matrixTmp[0]=vectorNorm[0]*vectorNorm[0]; matrixTmp[1]=vectorNorm[0]*vectorNorm[1]; matrixTmp[2]=vectorNorm[0]*vectorNorm[2];
3526 matrixTmp[3]=vectorNorm[1]*vectorNorm[0]; matrixTmp[4]=vectorNorm[1]*vectorNorm[1]; matrixTmp[5]=vectorNorm[1]*vectorNorm[2];
3527 matrixTmp[6]=vectorNorm[2]*vectorNorm[0]; matrixTmp[7]=vectorNorm[2]*vectorNorm[1]; matrixTmp[8]=vectorNorm[2]*vectorNorm[2];
3528 std::transform(matrixTmp,matrixTmp+9,matrixTmp,std::bind2nd(std::multiplies<double>(),1-cosa));
3529 std::transform(matrix,matrix+9,matrixTmp,matrix,std::plus<double>());
3530 matrixTmp[0]=0.; matrixTmp[1]=-vectorNorm[2]; matrixTmp[2]=vectorNorm[1];
3531 matrixTmp[3]=vectorNorm[2]; matrixTmp[4]=0.; matrixTmp[5]=-vectorNorm[0];
3532 matrixTmp[6]=-vectorNorm[1]; matrixTmp[7]=vectorNorm[0]; matrixTmp[8]=0.;
3533 std::transform(matrixTmp,matrixTmp+9,matrixTmp,std::bind2nd(std::multiplies<double>(),sina));
3534 std::transform(matrix,matrix+9,matrixTmp,matrix,std::plus<double>());
3535 //rotation matrix computed.
3537 for(int i=0; i<nbNodes; i++)
3539 std::transform(coordsIn+i*3,coordsIn+(i+1)*3,center,tmp,std::minus<double>());
3540 coordsOut[i*3]=matrix[0]*tmp[0]+matrix[1]*tmp[1]+matrix[2]*tmp[2]+center[0];
3541 coordsOut[i*3+1]=matrix[3]*tmp[0]+matrix[4]*tmp[1]+matrix[5]*tmp[2]+center[1];
3542 coordsOut[i*3+2]=matrix[6]*tmp[0]+matrix[7]*tmp[1]+matrix[8]*tmp[2]+center[2];
3546 void DataArrayDouble::Symmetry3DPlane(const double point[3], const double normalVector[3], int nbNodes, const double *coordsIn, double *coordsOut)
3548 double matrix[9],matrix2[9],matrix3[9];
3549 double vect[3],crossVect[3];
3550 INTERP_KERNEL::orthogonalVect3(normalVector,vect);
3551 crossVect[0]=normalVector[1]*vect[2]-normalVector[2]*vect[1];
3552 crossVect[1]=normalVector[2]*vect[0]-normalVector[0]*vect[2];
3553 crossVect[2]=normalVector[0]*vect[1]-normalVector[1]*vect[0];
3554 double nv(INTERP_KERNEL::norm<3>(vect)),ni(INTERP_KERNEL::norm<3>(normalVector)),nc(INTERP_KERNEL::norm<3>(crossVect));
3555 matrix[0]=vect[0]/nv; matrix[1]=crossVect[0]/nc; matrix[2]=-normalVector[0]/ni;
3556 matrix[3]=vect[1]/nv; matrix[4]=crossVect[1]/nc; matrix[5]=-normalVector[1]/ni;
3557 matrix[6]=vect[2]/nv; matrix[7]=crossVect[2]/nc; matrix[8]=-normalVector[2]/ni;
3558 matrix2[0]=vect[0]/nv; matrix2[1]=vect[1]/nv; matrix2[2]=vect[2]/nv;
3559 matrix2[3]=crossVect[0]/nc; matrix2[4]=crossVect[1]/nc; matrix2[5]=crossVect[2]/nc;
3560 matrix2[6]=normalVector[0]/ni; matrix2[7]=normalVector[1]/ni; matrix2[8]=normalVector[2]/ni;
3561 for(int i=0;i<3;i++)
3562 for(int j=0;j<3;j++)
3565 for(int k=0;k<3;k++)
3566 val+=matrix[3*i+k]*matrix2[3*k+j];
3569 //rotation matrix computed.
3571 for(int i=0; i<nbNodes; i++)
3573 std::transform(coordsIn+i*3,coordsIn+(i+1)*3,point,tmp,std::minus<double>());
3574 coordsOut[i*3]=matrix3[0]*tmp[0]+matrix3[1]*tmp[1]+matrix3[2]*tmp[2]+point[0];
3575 coordsOut[i*3+1]=matrix3[3]*tmp[0]+matrix3[4]*tmp[1]+matrix3[5]*tmp[2]+point[1];
3576 coordsOut[i*3+2]=matrix3[6]*tmp[0]+matrix3[7]*tmp[1]+matrix3[8]*tmp[2]+point[2];
3580 void DataArrayDouble::GiveBaseForPlane(const double normalVector[3], double baseOfPlane[9])
3582 double vect[3],crossVect[3];
3583 INTERP_KERNEL::orthogonalVect3(normalVector,vect);
3584 crossVect[0]=normalVector[1]*vect[2]-normalVector[2]*vect[1];
3585 crossVect[1]=normalVector[2]*vect[0]-normalVector[0]*vect[2];
3586 crossVect[2]=normalVector[0]*vect[1]-normalVector[1]*vect[0];
3587 double nv(INTERP_KERNEL::norm<3>(vect)),ni(INTERP_KERNEL::norm<3>(normalVector)),nc(INTERP_KERNEL::norm<3>(crossVect));
3588 baseOfPlane[0]=vect[0]/nv; baseOfPlane[1]=vect[1]/nv; baseOfPlane[2]=vect[2]/nv;
3589 baseOfPlane[3]=crossVect[0]/nc; baseOfPlane[4]=crossVect[1]/nc; baseOfPlane[5]=crossVect[2]/nc;
3590 baseOfPlane[6]=normalVector[0]/ni; baseOfPlane[7]=normalVector[1]/ni; baseOfPlane[8]=normalVector[2]/ni;
3594 * Low static method that operates 3D rotation of \a nbNodes 3D nodes whose coordinates are arranged in \a coords
3595 * around the center point \a center and with angle \a angle.
3597 void DataArrayDouble::Rotate2DAlg(const double *center, double angle, int nbNodes, const double *coordsIn, double *coordsOut)
3599 double cosa=cos(angle);
3600 double sina=sin(angle);
3602 matrix[0]=cosa; matrix[1]=-sina; matrix[2]=sina; matrix[3]=cosa;
3604 for(int i=0; i<nbNodes; i++)
3606 std::transform(coordsIn+i*2,coordsIn+(i+1)*2,center,tmp,std::minus<double>());
3607 coordsOut[i*2]=matrix[0]*tmp[0]+matrix[1]*tmp[1]+center[0];
3608 coordsOut[i*2+1]=matrix[2]*tmp[0]+matrix[3]*tmp[1]+center[1];
3612 DataArrayDoubleIterator::DataArrayDoubleIterator(DataArrayDouble *da):DataArrayIterator<double>(da)
3616 DataArrayDoubleTuple::DataArrayDoubleTuple(double *pt, int nbOfComp):DataArrayTuple<double>(pt,nbOfComp)
3621 std::string DataArrayDoubleTuple::repr() const
3623 std::ostringstream oss; oss.precision(17); oss << "(";
3624 for(int i=0;i<_nb_of_compo-1;i++)
3625 oss << _pt[i] << ", ";
3626 oss << _pt[_nb_of_compo-1] << ")";
3630 double DataArrayDoubleTuple::doubleValue() const
3632 return this->zeValue();
3636 * This method returns a newly allocated instance the caller should dealed with by a MEDCoupling::DataArrayDouble::decrRef.
3637 * This method performs \b no copy of data. The content is only referenced using MEDCoupling::DataArrayDouble::useArray with ownership set to \b false.
3638 * 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
3639 * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
3641 DataArrayDouble *DataArrayDoubleTuple::buildDADouble(int nbOfTuples, int nbOfCompo) const
3643 return this->buildDA(nbOfTuples,nbOfCompo);
3647 * Returns a new instance of DataArrayInt. The caller is to delete this array
3648 * using decrRef() as it is no more needed.
3650 DataArrayInt *DataArrayInt::New()
3652 return new DataArrayInt;
3656 * Returns the only one value in \a this, if and only if number of elements
3657 * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
3658 * \return double - the sole value stored in \a this array.
3659 * \throw If at least one of conditions stated above is not fulfilled.
3661 int DataArrayInt::intValue() const
3665 if(getNbOfElems()==1)
3667 return *getConstPointer();
3670 throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is allocated but number of elements is not equal to 1 !");
3673 throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is not allocated !");
3677 * Returns an integer value characterizing \a this array, which is useful for a quick
3678 * comparison of many instances of DataArrayInt.
3679 * \return int - the hash value.
3680 * \throw If \a this is not allocated.
3682 int DataArrayInt::getHashCode() const
3685 std::size_t nbOfElems=getNbOfElems();
3686 int ret=nbOfElems*65536;
3691 const int *pt=begin();
3692 for(std::size_t i=0;i<nbOfElems;i+=delta)
3693 ret0+=pt[i] & 0x1FFF;
3698 * Returns a full copy of \a this. For more info on copying data arrays see
3699 * \ref MEDCouplingArrayBasicsCopyDeep.
3700 * \return DataArrayInt * - a new instance of DataArrayInt.
3702 DataArrayInt32 *DataArrayInt32::deepCopy() const
3704 return new DataArrayInt32(*this);
3708 * Returns a textual and human readable representation of \a this instance of
3709 * DataArrayInt. This text is shown when a DataArrayInt is printed in Python.
3710 * \return std::string - text describing \a this DataArrayInt.
3712 * \sa reprNotTooLong, reprZip
3714 std::string DataArrayInt::repr() const
3716 std::ostringstream ret;
3721 std::string DataArrayInt::reprZip() const
3723 std::ostringstream ret;
3728 void DataArrayInt::writeVTK(std::ostream& ofs, int indent, const std::string& type, const std::string& nameInFile, DataArrayByte *byteArr) const
3730 static const char SPACE[4]={' ',' ',' ',' '};
3732 std::string idt(indent,' ');
3733 ofs << idt << "<DataArray type=\"" << type << "\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
3736 ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
3737 if(std::string(type)=="Int32")
3739 const char *data(reinterpret_cast<const char *>(begin()));
3740 std::size_t sz(getNbOfElems()*sizeof(int));
3741 byteArr->insertAtTheEnd(data,data+sz);
3742 byteArr->insertAtTheEnd(SPACE,SPACE+4);
3744 else if(std::string(type)=="Int8")
3746 INTERP_KERNEL::AutoPtr<char> tmp(new char[getNbOfElems()]);
3747 std::copy(begin(),end(),(char *)tmp);
3748 byteArr->insertAtTheEnd((char *)tmp,(char *)tmp+getNbOfElems());
3749 byteArr->insertAtTheEnd(SPACE,SPACE+4);
3751 else if(std::string(type)=="UInt8")
3753 INTERP_KERNEL::AutoPtr<unsigned char> tmp(new unsigned char[getNbOfElems()]);
3754 std::copy(begin(),end(),(unsigned char *)tmp);
3755 byteArr->insertAtTheEnd((unsigned char *)tmp,(unsigned char *)tmp+getNbOfElems());
3756 byteArr->insertAtTheEnd(SPACE,SPACE+4);
3759 throw INTERP_KERNEL::Exception("DataArrayInt::writeVTK : Only Int32, Int8 and UInt8 supported !");
3763 ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
3764 std::copy(begin(),end(),std::ostream_iterator<int>(ofs," "));
3766 ofs << std::endl << idt << "</DataArray>\n";
3769 void DataArrayInt::reprCppStream(const std::string& varName, std::ostream& stream) const
3771 int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
3772 const int *data=getConstPointer();
3773 stream << "DataArrayInt *" << varName << "=DataArrayInt::New();" << std::endl;
3774 if(nbTuples*nbComp>=1)
3776 stream << "const int " << varName << "Data[" << nbTuples*nbComp << "]={";
3777 std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<int>(stream,","));
3778 stream << data[nbTuples*nbComp-1] << "};" << std::endl;
3779 stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
3782 stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
3783 stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
3787 * Method that gives a quick overvien of \a this for python.
3789 void DataArrayInt::reprQuickOverview(std::ostream& stream) const
3791 static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
3792 stream << "DataArrayInt C++ instance at " << this << ". ";
3795 int nbOfCompo=(int)_info_on_compo.size();
3798 int nbOfTuples=getNumberOfTuples();
3799 stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
3800 reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
3803 stream << "Number of components : 0.";
3806 stream << "*** No data allocated ****";
3809 void DataArrayInt::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
3811 const int *data=begin();
3812 int nbOfTuples=getNumberOfTuples();
3813 int nbOfCompo=(int)_info_on_compo.size();
3814 std::ostringstream oss2; oss2 << "[";
3815 std::string oss2Str(oss2.str());
3816 bool isFinished=true;
3817 for(int i=0;i<nbOfTuples && isFinished;i++)
3822 for(int j=0;j<nbOfCompo;j++,data++)
3825 if(j!=nbOfCompo-1) oss2 << ", ";
3831 if(i!=nbOfTuples-1) oss2 << ", ";
3832 std::string oss3Str(oss2.str());
3833 if(oss3Str.length()<maxNbOfByteInRepr)
3845 * Computes distribution of values of \a this one-dimensional array between given value
3846 * ranges (casts). This method is typically useful for entity number splitting by types,
3848 * \warning The values contained in \a arrBg should be sorted ascendently. No
3849 * check of this is be done. If not, the result is not warranted.
3850 * \param [in] arrBg - the array of ascending values defining the value ranges. The i-th
3851 * value of \a arrBg (\a arrBg[ i ]) gives the lowest value of the i-th range,
3852 * and the greatest value of the i-th range equals to \a arrBg[ i+1 ] - 1. \a
3853 * arrBg containing \a n values defines \a n-1 ranges. The last value of \a arrBg
3854 * should be more than every value in \a this array.
3855 * \param [in] arrEnd - specifies the end of the array \a arrBg, so that
3856 * the last value of \a arrBg is \a arrEnd[ -1 ].
3857 * \param [out] castArr - a new instance of DataArrayInt, of same size as \a this array
3858 * (same number of tuples and components), the caller is to delete
3859 * using decrRef() as it is no more needed.
3860 * This array contains indices of ranges for every value of \a this array. I.e.
3861 * the i-th value of \a castArr gives the index of range the i-th value of \a this
3862 * belongs to. Or, in other words, this parameter contains for each tuple in \a
3863 * this in which cast it holds.
3864 * \param [out] rankInsideCast - a new instance of DataArrayInt, of same size as \a this
3865 * array, the caller is to delete using decrRef() as it is no more needed.
3866 * This array contains ranks of values of \a this array within ranges
3867 * they belongs to. I.e. the i-th value of \a rankInsideCast gives the rank of
3868 * the i-th value of \a this array within the \a castArr[ i ]-th range, to which
3869 * the i-th value of \a this belongs to. Or, in other words, this param contains
3870 * for each tuple its rank inside its cast. The rank is computed as difference
3871 * between the value and the lowest value of range.
3872 * \param [out] castsPresent - a new instance of DataArrayInt, containing indices of
3873 * ranges (casts) to which at least one value of \a this array belongs.
3874 * Or, in other words, this param contains the casts that \a this contains.
3875 * The caller is to delete this array using decrRef() as it is no more needed.
3877 * \b Example: If \a this contains [6,5,0,3,2,7,8,1,4] and \a arrBg contains [0,4,9] then
3878 * the output of this method will be :
3879 * - \a castArr : [1,1,0,0,0,1,1,0,1]
3880 * - \a rankInsideCast: [2,1,0,3,2,3,4,1,0]
3881 * - \a castsPresent : [0,1]
3883 * I.e. values of \a this array belong to 2 ranges: #0 and #1. Value 6 belongs to the
3884 * range #1 and its rank within this range is 2; etc.
3886 * \throw If \a this->getNumberOfComponents() != 1.
3887 * \throw If \a arrEnd - arrBg < 2.
3888 * \throw If any value of \a this is not less than \a arrEnd[-1].
3890 void DataArrayInt::splitByValueRange(const int *arrBg, const int *arrEnd,
3891 DataArrayInt *& castArr, DataArrayInt *& rankInsideCast, DataArrayInt *& castsPresent) const
3894 if(getNumberOfComponents()!=1)
3895 throw INTERP_KERNEL::Exception("Call splitByValueRange method on DataArrayInt with only one component, you can call 'rearrange' method before !");
3896 int nbOfTuples=getNumberOfTuples();
3897 std::size_t nbOfCast=std::distance(arrBg,arrEnd);
3899 throw INTERP_KERNEL::Exception("DataArrayInt::splitByValueRange : The input array giving the cast range values should be of size >=2 !");
3901 const int *work=getConstPointer();
3902 typedef std::reverse_iterator<const int *> rintstart;
3903 rintstart bg(arrEnd);//OK no problem because size of 'arr' is greater or equal 2
3904 rintstart end2(arrBg);
3905 MCAuto<DataArrayInt> ret1=DataArrayInt::New();
3906 MCAuto<DataArrayInt> ret2=DataArrayInt::New();
3907 MCAuto<DataArrayInt> ret3=DataArrayInt::New();
3908 ret1->alloc(nbOfTuples,1);
3909 ret2->alloc(nbOfTuples,1);
3910 int *ret1Ptr=ret1->getPointer();
3911 int *ret2Ptr=ret2->getPointer();
3912 std::set<std::size_t> castsDetected;
3913 for(int i=0;i<nbOfTuples;i++)
3915 rintstart res=std::find_if(bg,end2,std::bind2nd(std::less_equal<int>(), work[i]));
3916 std::size_t pos=std::distance(bg,res);
3917 std::size_t pos2=nbOfCast-pos;
3920 ret1Ptr[i]=(int)pos2;
3921 ret2Ptr[i]=work[i]-arrBg[pos2];
3922 castsDetected.insert(pos2);
3926 std::ostringstream oss; oss << "DataArrayInt::splitByValueRange : At rank #" << i << " the value is " << work[i] << " should be in [0," << *bg << ") !";
3927 throw INTERP_KERNEL::Exception(oss.str().c_str());
3930 ret3->alloc((int)castsDetected.size(),1);
3931 std::copy(castsDetected.begin(),castsDetected.end(),ret3->getPointer());
3932 castArr=ret1.retn();
3933 rankInsideCast=ret2.retn();
3934 castsPresent=ret3.retn();
3938 * 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 ).
3939 * 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 ).
3940 * This method works only if \a this is allocated and single component. If not an exception will be thrown.
3942 * \param [out] strt - the start of the range (included) if true is returned.
3943 * \param [out] sttoopp - the end of the range (not included) if true is returned.
3944 * \param [out] stteepp - the step of the range if true is returned.
3945 * \return the verdict of the check.
3947 * \sa DataArray::GetNumberOfItemGivenBES
3949 bool DataArrayInt::isRange(int& strt, int& sttoopp, int& stteepp) const
3952 if(getNumberOfComponents()!=1)
3953 throw INTERP_KERNEL::Exception("DataArrayInt::isRange : this must be single component array !");
3954 int nbTuples(getNumberOfTuples());
3956 { strt=0; sttoopp=0; stteepp=1; return true; }
3957 const int *pt(begin());
3960 { sttoopp=strt+1; stteepp=1; return true; }
3961 strt=*pt; sttoopp=pt[nbTuples-1];
3967 int a(sttoopp-1-strt),tmp(strt);
3968 if(a%(nbTuples-1)!=0)
3970 stteepp=a/(nbTuples-1);
3971 for(int i=0;i<nbTuples;i++,tmp+=stteepp)
3979 int a(strt-sttoopp-1),tmp(strt);
3980 if(a%(nbTuples-1)!=0)
3982 stteepp=-(a/(nbTuples-1));
3983 for(int i=0;i<nbTuples;i++,tmp+=stteepp)
3992 * Modifies in place \a this one-dimensional array so that each value \a v = \a indArrBg[ \a v ],
3993 * i.e. a current value is used as in index to get a new value from \a indArrBg.
3994 * \param [in] indArrBg - pointer to the first element of array of new values to assign
3996 * \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
3997 * the last value of \a indArrBg is \a indArrEnd[ -1 ].
3998 * \throw If \a this->getNumberOfComponents() != 1
3999 * \throw If any value of \a this can't be used as a valid index for
4000 * [\a indArrBg, \a indArrEnd).
4002 * \sa changeValue, findIdForEach
4004 void DataArrayInt::transformWithIndArr(const int *indArrBg, const int *indArrEnd)
4006 this->checkAllocated();
4007 if(this->getNumberOfComponents()!=1)
4008 throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
4009 int nbElemsIn((int)std::distance(indArrBg,indArrEnd)),nbOfTuples(getNumberOfTuples()),*pt(getPointer());
4010 for(int i=0;i<nbOfTuples;i++,pt++)
4012 if(*pt>=0 && *pt<nbElemsIn)
4016 std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " of this value is " << *pt << ", should be in [0," << nbElemsIn << ") !";
4017 throw INTERP_KERNEL::Exception(oss.str());
4020 this->declareAsNew();
4023 void DataArrayInt::transformWithIndArr(const MapKeyVal<int>& m)
4025 this->checkAllocated();
4026 if(this->getNumberOfComponents()!=1)
4027 throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
4028 const std::map<int,int>& dat(m.data());
4029 int nbOfTuples(getNumberOfTuples()),*pt(getPointer());
4030 for(int i=0;i<nbOfTuples;i++,pt++)
4032 std::map<int,int>::const_iterator it(dat.find(*pt));
4037 std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " of this value is " << *pt << " not in map !";
4038 throw INTERP_KERNEL::Exception(oss.str());
4041 this->declareAsNew();
4045 * Creates a one-dimensional DataArrayInt (\a res) whose contents are computed from
4046 * values of \a this (\a a) and the given (\a indArr) arrays as follows:
4047 * \a res[ \a indArr[ \a a[ i ]]] = i. I.e. for each value in place i \a v = \a a[ i ],
4048 * new value in place \a indArr[ \a v ] is i.
4049 * \param [in] indArrBg - the array holding indices within the result array to assign
4050 * indices of values of \a this array pointing to values of \a indArrBg.
4051 * \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
4052 * the last value of \a indArrBg is \a indArrEnd[ -1 ].
4053 * \return DataArrayInt * - the new instance of DataArrayInt.
4054 * The caller is to delete this result array using decrRef() as it is no more
4056 * \throw If \a this->getNumberOfComponents() != 1.
4057 * \throw If any value of \a this array is not a valid index for \a indArrBg array.
4058 * \throw If any value of \a indArrBg is not a valid index for \a this array.
4060 DataArrayInt *DataArrayInt::transformWithIndArrR(const int *indArrBg, const int *indArrEnd) const
4063 if(getNumberOfComponents()!=1)
4064 throw INTERP_KERNEL::Exception("Call transformWithIndArrR method on DataArrayInt with only one component, you can call 'rearrange' method before !");
4065 int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
4066 int nbOfTuples=getNumberOfTuples();
4067 const int *pt=getConstPointer();
4068 MCAuto<DataArrayInt> ret=DataArrayInt::New();
4069 ret->alloc(nbOfTuples,1);
4070 ret->fillWithValue(-1);
4071 int *tmp=ret->getPointer();
4072 for(int i=0;i<nbOfTuples;i++,pt++)
4074 if(*pt>=0 && *pt<nbElemsIn)
4076 int pos=indArrBg[*pt];
4077 if(pos>=0 && pos<nbOfTuples)
4081 std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value of new pos is " << pos << " ( indArrBg[" << *pt << "]) ! Should be in [0," << nbOfTuples << ") !";
4082 throw INTERP_KERNEL::Exception(oss.str().c_str());
4087 std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn << " !";
4088 throw INTERP_KERNEL::Exception(oss.str().c_str());
4095 * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
4096 * from values of \a this array, which is supposed to contain a renumbering map in
4097 * "Old to New" mode. The result array contains a renumbering map in "New to Old" mode.
4098 * To know how to use the renumbering maps see \ref numbering.
4099 * \param [in] newNbOfElem - the number of tuples in the result array.
4100 * \return DataArrayInt * - the new instance of DataArrayInt.
4101 * The caller is to delete this result array using decrRef() as it is no more
4104 * \if ENABLE_EXAMPLES
4105 * \ref cpp_mcdataarrayint_invertarrayo2n2n2o "Here is a C++ example".<br>
4106 * \ref py_mcdataarrayint_invertarrayo2n2n2o "Here is a Python example".
4109 DataArrayInt *DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const
4111 MCAuto<DataArrayInt> ret(DataArrayInt::New());
4112 ret->alloc(newNbOfElem,1);
4113 int nbOfOldNodes(this->getNumberOfTuples());
4114 const int *old2New(begin());
4115 int *pt(ret->getPointer());
4116 for(int i=0;i!=nbOfOldNodes;i++)
4118 int newp(old2New[i]);
4121 if(newp>=0 && newp<newNbOfElem)
4125 std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2O : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
4126 throw INTERP_KERNEL::Exception(oss.str().c_str());
4134 * This method is similar to DataArrayInt::invertArrayO2N2N2O except that
4135 * 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]
4137 DataArrayInt *DataArrayInt::invertArrayO2N2N2OBis(int newNbOfElem) const
4139 MCAuto<DataArrayInt> ret=DataArrayInt::New();
4140 ret->alloc(newNbOfElem,1);
4141 int nbOfOldNodes=getNumberOfTuples();
4142 const int *old2New=getConstPointer();
4143 int *pt=ret->getPointer();
4144 for(int i=nbOfOldNodes-1;i>=0;i--)
4146 int newp(old2New[i]);
4149 if(newp>=0 && newp<newNbOfElem)
4153 std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2OBis : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
4154 throw INTERP_KERNEL::Exception(oss.str().c_str());
4162 * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
4163 * from values of \a this array, which is supposed to contain a renumbering map in
4164 * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
4165 * To know how to use the renumbering maps see \ref numbering.
4166 * \param [in] newNbOfElem - the number of tuples in the result array.
4167 * \return DataArrayInt * - the new instance of DataArrayInt.
4168 * The caller is to delete this result array using decrRef() as it is no more
4171 * \if ENABLE_EXAMPLES
4172 * \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
4174 * \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
4175 * \sa invertArrayN2O2O2NOptimized
4178 DataArrayInt *DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const
4181 MCAuto<DataArrayInt> ret=DataArrayInt::New();
4182 ret->alloc(oldNbOfElem,1);
4183 const int *new2Old=getConstPointer();
4184 int *pt=ret->getPointer();
4185 std::fill(pt,pt+oldNbOfElem,-1);
4186 int nbOfNewElems=getNumberOfTuples();
4187 for(int i=0;i<nbOfNewElems;i++)
4190 if(v>=0 && v<oldNbOfElem)
4194 std::ostringstream oss; oss << "DataArrayInt::invertArrayN2O2O2N : in new id #" << i << " old value is " << v << " expected to be in [0," << oldNbOfElem << ") !";
4195 throw INTERP_KERNEL::Exception(oss.str().c_str());
4202 * Creates a map, whose contents are computed
4203 * from values of \a this array, which is supposed to contain a renumbering map in
4204 * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
4205 * To know how to use the renumbering maps see \ref numbering.
4206 * \param [in] newNbOfElem - the number of tuples in the result array.
4207 * \return MapII - the new instance of Map.
4209 * \if ENABLE_EXAMPLES
4210 * \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
4212 * \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
4213 * \sa invertArrayN2O2O2N
4216 MCAuto< MapKeyVal<int> > DataArrayInt32::invertArrayN2O2O2NOptimized() const
4219 if(getNumberOfComponents()!=1)
4220 throw INTERP_KERNEL::Exception("DataArrayInt32::invertArrayN2O2O2NOptimized : single component expected !");
4221 MCAuto< MapKeyVal<int> > ret(MapKeyVal<int>::New());
4222 std::map<int,int>& m(ret->data());
4223 const int *new2Old(begin());
4224 std::size_t nbOfNewElems(this->getNumberOfTuples());
4225 for(std::size_t i=0;i<nbOfNewElems;i++)
4234 * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode.
4235 * This map, if applied to \a this array, would make it sorted. For example, if
4236 * \a this array contents are [9,10,0,6,4,11,3,7] then the contents of the result array
4237 * are [5,6,0,3,2,7,1,4]; if this result array (\a res) is used as an argument in call
4238 * \a this->renumber(\a res) then the returned array contains [0,3,4,6,7,9,10,11].
4239 * This method is useful for renumbering (in MED file for example). For more info
4240 * on renumbering see \ref numbering.
4241 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4242 * array using decrRef() as it is no more needed.
4243 * \throw If \a this is not allocated.
4244 * \throw If \a this->getNumberOfComponents() != 1.
4245 * \throw If there are equal values in \a this array.
4247 DataArrayInt *DataArrayInt::checkAndPreparePermutation() const
4250 if(getNumberOfComponents()!=1)
4251 throw INTERP_KERNEL::Exception("DataArrayInt::checkAndPreparePermutation : number of components must == 1 !");
4252 int nbTuples=getNumberOfTuples();
4253 const int *pt=getConstPointer();
4254 int *pt2=CheckAndPreparePermutation(pt,pt+nbTuples);
4255 DataArrayInt *ret=DataArrayInt::New();
4256 ret->useArray(pt2,true,C_DEALLOC,nbTuples,1);
4261 * 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
4262 * input array \a ids2.
4263 * \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.
4264 * 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
4266 * In case of success both assertion will be true (no throw) :
4267 * \c ids1->renumber(ret)->isEqual(ids2) where \a ret is the return of this method.
4268 * \c ret->transformWithIndArr(ids2)->isEqual(ids1)
4271 * - \a ids1 : [3,1,103,4,6,10,-7,205]
4272 * - \a ids2 : [-7,1,205,10,6,3,103,4]
4273 * - \a return is : [5,1,6,7,4,3,0,2] because ids2[5]==ids1[0], ids2[1]==ids1[1], ids2[6]==ids1[2]...
4275 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4276 * array using decrRef() as it is no more needed.
4277 * \throw If either ids1 or ids2 is null not allocated or not with one components.
4279 * \sa DataArrayInt32::findIdForEach
4281 DataArrayInt *DataArrayInt::FindPermutationFromFirstToSecond(const DataArrayInt *ids1, const DataArrayInt *ids2)
4284 throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be not null !");
4285 if(!ids1->isAllocated() || !ids2->isAllocated())
4286 throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be allocated !");
4287 if(ids1->getNumberOfComponents()!=1 || ids2->getNumberOfComponents()!=1)
4288 throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays have exactly one component !");
4289 if(ids1->getNumberOfTuples()!=ids2->getNumberOfTuples())
4291 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 !";
4292 throw INTERP_KERNEL::Exception(oss.str().c_str());
4294 MCAuto<DataArrayInt> p1(ids1->deepCopy());
4295 MCAuto<DataArrayInt> p2(ids2->deepCopy());
4296 p1->sort(true); p2->sort(true);
4297 if(!p1->isEqualWithoutConsideringStr(*p2))
4298 throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two arrays are not lying on same ids ! Impossible to find a permutation between the 2 arrays !");
4299 p1=ids1->checkAndPreparePermutation();
4300 p2=ids2->checkAndPreparePermutation();
4301 p2=p2->invertArrayO2N2N2O(p2->getNumberOfTuples());
4302 p2=p2->selectByTupleIdSafe(p1->begin(),p1->end());
4307 * Returns two arrays describing a surjective mapping from \a this set of values (\a A)
4308 * onto a set of values of size \a targetNb (\a B). The surjective function is
4309 * \a B[ \a A[ i ]] = i. That is to say that for each \a id in [0,\a targetNb), where \a
4310 * targetNb < \a this->getNumberOfTuples(), there exists at least one tupleId (\a tid) so
4311 * that <em> this->getIJ( tid, 0 ) == id</em>. <br>
4312 * The first of out arrays returns indices of elements of \a this array, grouped by their
4313 * place in the set \a B. The second out array is the index of the first one; it shows how
4314 * many elements of \a A are mapped into each element of \a B. <br>
4316 * mapping and its usage in renumbering see \ref numbering. <br>
4318 * - \a this: [0,3,2,3,2,2,1,2]
4320 * - \a arr: [0, 6, 2,4,5,7, 1,3]
4321 * - \a arrI: [0,1,2,6,8]
4323 * This result means: <br>
4324 * the element of \a B 0 encounters within \a A once (\a arrI[ 0+1 ] - \a arrI[ 0 ]) and
4325 * its index within \a A is 0 ( \a arr[ 0:1 ] == \a arr[ \a arrI[ 0 ] : \a arrI[ 0+1 ]]);<br>
4326 * the element of \a B 2 encounters within \a A 4 times (\a arrI[ 2+1 ] - \a arrI[ 2 ]) and
4327 * its indices within \a A are [2,4,5,7] ( \a arr[ 2:6 ] == \a arr[ \a arrI[ 2 ] :
4328 * \a arrI[ 2+1 ]]); <br> etc.
4329 * \param [in] targetNb - the size of the set \a B. \a targetNb must be equal or more
4330 * than the maximal value of \a A.
4331 * \param [out] arr - a new instance of DataArrayInt returning indices of
4332 * elements of \a this, grouped by their place in the set \a B. The caller is to delete
4333 * this array using decrRef() as it is no more needed.
4334 * \param [out] arrI - a new instance of DataArrayInt returning size of groups of equal
4335 * elements of \a this. The caller is to delete this array using decrRef() as it
4336 * is no more needed.
4337 * \throw If \a this is not allocated.
4338 * \throw If \a this->getNumberOfComponents() != 1.
4339 * \throw If any value in \a this is more or equal to \a targetNb.
4341 void DataArrayInt::changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, DataArrayInt *&arrI) const
4344 if(getNumberOfComponents()!=1)
4345 throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : number of components must == 1 !");
4346 int nbOfTuples=getNumberOfTuples();
4347 MCAuto<DataArrayInt> ret(DataArrayInt::New());
4348 MCAuto<DataArrayInt> retI(DataArrayInt::New());
4349 retI->alloc(targetNb+1,1);
4350 const int *input=getConstPointer();
4351 std::vector< std::vector<int> > tmp(targetNb);
4352 for(int i=0;i<nbOfTuples;i++)
4355 if(tmp2>=0 && tmp2<targetNb)
4356 tmp[tmp2].push_back(i);
4359 std::ostringstream oss; oss << "DataArrayInt::changeSurjectiveFormat : At pos " << i << " presence of element " << tmp2 << " ! should be in [0," << targetNb << ") !";
4360 throw INTERP_KERNEL::Exception(oss.str().c_str());
4363 int *retIPtr=retI->getPointer();
4365 for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++,retIPtr++)
4366 retIPtr[1]=retIPtr[0]+(int)((*it1).size());
4367 if(nbOfTuples!=retI->getIJ(targetNb,0))
4368 throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : big problem should never happen !");
4369 ret->alloc(nbOfTuples,1);
4370 int *retPtr=ret->getPointer();
4371 for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++)
4372 retPtr=std::copy((*it1).begin(),(*it1).end(),retPtr);
4379 * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode computed
4380 * from a zip representation of a surjective format (returned e.g. by
4381 * \ref MEDCoupling::DataArrayDouble::findCommonTuples() "DataArrayDouble::findCommonTuples()"
4382 * for example). The result array minimizes the permutation. <br>
4383 * For more info on renumbering see \ref numbering. <br>
4385 * - \a nbOfOldTuples: 10
4386 * - \a arr : [0,3, 5,7,9]
4387 * - \a arrIBg : [0,2,5]
4388 * - \a newNbOfTuples: 7
4389 * - result array : [0,1,2,0,3,4,5,4,6,4]
4391 * \param [in] nbOfOldTuples - number of tuples in the initial array \a arr.
4392 * \param [in] arr - the array of tuple indices grouped by \a arrIBg array.
4393 * \param [in] arrIBg - the array dividing all indices stored in \a arr into groups of
4394 * (indices of) equal values. Its every element (except the last one) points to
4395 * the first element of a group of equal values.
4396 * \param [in] arrIEnd - specifies the end of \a arrIBg, so that the last element of \a
4397 * arrIBg is \a arrIEnd[ -1 ].
4398 * \param [out] newNbOfTuples - number of tuples after surjection application.
4399 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4400 * array using decrRef() as it is no more needed.
4401 * \throw If any value of \a arr breaks condition ( 0 <= \a arr[ i ] < \a nbOfOldTuples ).
4403 DataArrayInt *DataArrayInt::ConvertIndexArrayToO2N(int nbOfOldTuples, const int *arr, const int *arrIBg, const int *arrIEnd, int &newNbOfTuples)
4405 MCAuto<DataArrayInt> ret=DataArrayInt::New();
4406 ret->alloc(nbOfOldTuples,1);
4407 int *pt=ret->getPointer();
4408 std::fill(pt,pt+nbOfOldTuples,-1);
4409 int nbOfGrps=((int)std::distance(arrIBg,arrIEnd))-1;
4410 const int *cIPtr=arrIBg;
4411 for(int i=0;i<nbOfGrps;i++)
4412 pt[arr[cIPtr[i]]]=-(i+2);
4414 for(int iNode=0;iNode<nbOfOldTuples;iNode++)
4422 int grpId=-(pt[iNode]+2);
4423 for(int j=cIPtr[grpId];j<cIPtr[grpId+1];j++)
4425 if(arr[j]>=0 && arr[j]<nbOfOldTuples)
4429 std::ostringstream oss; oss << "DataArrayInt::ConvertIndexArrayToO2N : With element #" << j << " value is " << arr[j] << " should be in [0," << nbOfOldTuples << ") !";
4430 throw INTERP_KERNEL::Exception(oss.str().c_str());
4437 newNbOfTuples=newNb;
4442 * Returns a new DataArrayInt containing a renumbering map in "New to Old" mode,
4443 * which if applied to \a this array would make it sorted ascendingly.
4444 * For more info on renumbering see \ref numbering. <br>
4446 * - \a this: [2,0,1,1,0,1,2,0,1,1,0,0]
4447 * - result: [10,0,5,6,1,7,11,2,8,9,3,4]
4448 * - after applying result to \a this: [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2]
4450 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4451 * array using decrRef() as it is no more needed.
4452 * \throw If \a this is not allocated.
4453 * \throw If \a this->getNumberOfComponents() != 1.
4455 DataArrayInt *DataArrayInt::buildPermArrPerLevel() const
4458 if(getNumberOfComponents()!=1)
4459 throw INTERP_KERNEL::Exception("DataArrayInt::buildPermArrPerLevel : number of components must == 1 !");
4460 int nbOfTuples=getNumberOfTuples();
4461 const int *pt=getConstPointer();
4462 std::map<int,int> m;
4463 MCAuto<DataArrayInt> ret=DataArrayInt::New();
4464 ret->alloc(nbOfTuples,1);
4465 int *opt=ret->getPointer();
4466 for(int i=0;i<nbOfTuples;i++,pt++,opt++)
4469 std::map<int,int>::iterator it=m.find(val);
4478 m.insert(std::pair<int,int>(val,1));
4482 for(std::map<int,int>::iterator it=m.begin();it!=m.end();it++)
4484 int vt=(*it).second;
4488 pt=getConstPointer();
4489 opt=ret->getPointer();
4490 for(int i=0;i<nbOfTuples;i++,pt++,opt++)
4497 * Checks if \a this array has the given size, and if its contents is equal to an array filled with
4498 * iota(). This method is particularly useful for DataArrayInt instances that represent
4499 * a renumbering array, to check if there is a real need in renumbering.
4500 * This method checks than \a this can be considered as an identity mapping
4501 * of a set having \a sizeExpected elements into itself.
4503 * \param [in] sizeExpected - The number of elements expected.
4504 * \return bool - \a true if \a this array contents == \a range( \a this->getNumberOfTuples())
4505 * \throw If \a this is not allocated.
4506 * \throw If \a this->getNumberOfComponents() != 1.
4508 bool DataArrayInt::isIota(int sizeExpected) const
4511 if(getNumberOfComponents()!=1)
4513 int nbOfTuples(getNumberOfTuples());
4514 if(nbOfTuples!=sizeExpected)
4516 const int *pt=getConstPointer();
4517 for(int i=0;i<nbOfTuples;i++,pt++)
4524 * Checks if all values in \a this array are equal to \a val.
4525 * \param [in] val - value to check equality of array values to.
4526 * \return bool - \a true if all values are \a val.
4527 * \throw If \a this is not allocated.
4528 * \throw If \a this->getNumberOfComponents() != 1
4529 * \sa DataArrayInt::checkUniformAndGuess
4531 bool DataArrayInt::isUniform(int val) const
4534 if(getNumberOfComponents()!=1)
4535 throw INTERP_KERNEL::Exception("DataArrayInt::isUniform : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
4536 const int *w(begin()),*end2(end());
4544 * This method checks that \a this is uniform. If not and exception will be thrown.
4545 * In case of uniformity the corresponding value is returned.
4547 * \return int - the unique value contained in this
4548 * \throw If \a this is not allocated.
4549 * \throw If \a this->getNumberOfComponents() != 1
4550 * \throw If \a this is not uniform.
4551 * \sa DataArrayInt::isUniform
4553 int DataArrayInt::checkUniformAndGuess() const
4556 if(getNumberOfComponents()!=1)
4557 throw INTERP_KERNEL::Exception("DataArrayInt::checkUniformAndGuess : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
4559 throw INTERP_KERNEL::Exception("DataArrayInt::checkUniformAndGuess : this is empty !");
4560 const int *w(begin()),*end2(end());
4564 throw INTERP_KERNEL::Exception("DataArrayInt::checkUniformAndGuess : this is not uniform !");
4569 * Checks if all values in \a this array are unique.
4570 * \return bool - \a true if condition above is true
4571 * \throw If \a this is not allocated.
4572 * \throw If \a this->getNumberOfComponents() != 1
4574 bool DataArrayInt::hasUniqueValues() const
4577 if(getNumberOfComponents()!=1)
4578 throw INTERP_KERNEL::Exception("DataArrayInt::hasOnlyUniqueValues: must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
4579 std::size_t nbOfTuples(getNumberOfTuples());
4580 std::set<int> s(begin(),end()); // in C++11, should use unordered_set (O(1) complexity)
4581 if (s.size() != nbOfTuples)
4587 * Copy all components in a specified order from another DataArrayInt.
4588 * The specified components become the first ones in \a this array.
4589 * Both numerical and textual data is copied. The number of tuples in \a this and
4590 * the other array can be different.
4591 * \param [in] a - the array to copy data from.
4592 * \param [in] compoIds - sequence of zero based indices of components, data of which is
4594 * \throw If \a a is NULL.
4595 * \throw If \a compoIds.size() != \a a->getNumberOfComponents().
4596 * \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
4598 * \if ENABLE_EXAMPLES
4599 * \ref py_mcdataarrayint_setselectedcomponents "Here is a Python example".
4602 void DataArrayInt::setSelectedComponents(const DataArrayInt *a, const std::vector<int>& compoIds)
4605 throw INTERP_KERNEL::Exception("DataArrayInt::setSelectedComponents : input DataArrayInt is NULL !");
4607 a->checkAllocated();
4608 copyPartOfStringInfoFrom2(compoIds,*a);
4609 std::size_t partOfCompoSz=compoIds.size();
4610 int nbOfCompo=getNumberOfComponents();
4611 int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
4612 const int *ac=a->getConstPointer();
4613 int *nc=getPointer();
4614 for(int i=0;i<nbOfTuples;i++)
4615 for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
4616 nc[nbOfCompo*i+compoIds[j]]=*ac;
4619 DataArrayIntIterator *DataArrayInt::iterator()
4621 return new DataArrayIntIterator(this);
4625 * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to a
4626 * given one. The ids are sorted in the ascending order.
4627 * \param [in] val - the value to find within \a this.
4628 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4629 * array using decrRef() as it is no more needed.
4630 * \throw If \a this is not allocated.
4631 * \throw If \a this->getNumberOfComponents() != 1.
4632 * \sa DataArrayInt::findIdsEqualTuple
4634 DataArrayInt *DataArrayInt::findIdsEqual(int val) const
4637 if(getNumberOfComponents()!=1)
4638 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqual : the array must have only one component, you can call 'rearrange' method before !");
4639 const int *cptr(getConstPointer());
4640 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4641 int nbOfTuples=getNumberOfTuples();
4642 for(int i=0;i<nbOfTuples;i++,cptr++)
4644 ret->pushBackSilent(i);
4649 * Creates a new DataArrayInt containing IDs (indices) of tuples holding value \b not
4650 * equal to a given one.
4651 * \param [in] val - the value to ignore within \a this.
4652 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4653 * array using decrRef() as it is no more needed.
4654 * \throw If \a this is not allocated.
4655 * \throw If \a this->getNumberOfComponents() != 1.
4657 DataArrayInt *DataArrayInt::findIdsNotEqual(int val) const
4660 if(getNumberOfComponents()!=1)
4661 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotEqual : the array must have only one component, you can call 'rearrange' method before !");
4662 const int *cptr(getConstPointer());
4663 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4664 int nbOfTuples=getNumberOfTuples();
4665 for(int i=0;i<nbOfTuples;i++,cptr++)
4667 ret->pushBackSilent(i);
4672 * Creates a new DataArrayInt containing IDs (indices) of tuples holding tuple equal to those defined by [ \a tupleBg , \a tupleEnd )
4673 * This method is an extension of DataArrayInt::findIdsEqual method.
4675 * \param [in] tupleBg - the begin (included) of the input tuple to find within \a this.
4676 * \param [in] tupleEnd - the end (excluded) of the input tuple to find within \a this.
4677 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4678 * array using decrRef() as it is no more needed.
4679 * \throw If \a this is not allocated.
4680 * \throw If \a this->getNumberOfComponents() != std::distance(tupleBg,tupleEnd).
4681 * \throw If \a this->getNumberOfComponents() is equal to 0.
4682 * \sa DataArrayInt::findIdsEqual
4684 DataArrayInt *DataArrayInt::findIdsEqualTuple(const int *tupleBg, const int *tupleEnd) const
4686 std::size_t nbOfCompoExp(std::distance(tupleBg,tupleEnd));
4688 if(getNumberOfComponents()!=nbOfCompoExp)
4690 std::ostringstream oss; oss << "DataArrayInt::findIdsEqualTuple : mismatch of number of components. Input tuple has " << nbOfCompoExp << " whereas this array has " << getNumberOfComponents() << " components !";
4691 throw INTERP_KERNEL::Exception(oss.str().c_str());
4694 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqualTuple : number of components should be > 0 !");
4695 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4696 const int *bg(begin()),*end2(end()),*work(begin());
4699 work=std::search(work,end2,tupleBg,tupleEnd);
4702 std::size_t pos(std::distance(bg,work));
4703 if(pos%nbOfCompoExp==0)
4704 ret->pushBackSilent(pos/nbOfCompoExp);
4712 * This method finds for each element \a ELT in [valsBg,valsEnd) elements in \a this equal to it. Associated to ELT
4713 * this method will return the tuple id of last element found. If there is no element in \a this equal to ELT
4714 * an exception will be thrown.
4716 * In case of success this[ret]==vals. Samely ret->transformWithIndArr(this->begin(),this->end())==vals.
4717 * Where \a vals is the [valsBg,valsEnd) array and \a ret the array returned by this method.
4718 * This method can be seen as an extension of FindPermutationFromFirstToSecond.
4721 * - \a this: [17,27,2,10,-4,3,12,27,16]
4722 * - \a val : [3,16,-4,27,17]
4723 * - result: [5,8,4,7,0]
4725 * \return - An array of size std::distance(valsBg,valsEnd)
4727 * \sa DataArrayInt32::FindPermutationFromFirstToSecond
4729 MCAuto<DataArrayInt32> DataArrayInt32::findIdForEach(const int *valsBg, const int *valsEnd) const
4731 MCAuto<DataArrayInt32> ret(DataArrayInt32::New());
4732 std::size_t nbOfTuplesOut(std::distance(valsBg,valsEnd));
4733 ret->alloc(nbOfTuplesOut,1);
4734 MCAuto< MapKeyVal<int> > zeMap(invertArrayN2O2O2NOptimized());
4735 const std::map<int,int>& dat(zeMap->data());
4736 int *ptToFeed(ret->getPointer());
4737 for(const int *pt=valsBg;pt!=valsEnd;pt++)
4739 std::map<int,int>::const_iterator it(dat.find(*pt));
4741 *ptToFeed++=(*it).second;
4744 std::ostringstream oss; oss << "DataArrayInt32::findIdForEach : error for element at place " << std::distance(valsBg,pt);
4745 oss << " of input array value is " << *pt << " which is not in this !";
4746 throw INTERP_KERNEL::Exception(oss.str());
4753 * Assigns \a newValue to all elements holding \a oldValue within \a this
4754 * one-dimensional array.
4755 * \param [in] oldValue - the value to replace.
4756 * \param [in] newValue - the value to assign.
4757 * \return int - number of replacements performed.
4758 * \throw If \a this is not allocated.
4759 * \throw If \a this->getNumberOfComponents() != 1.
4761 int DataArrayInt::changeValue(int oldValue, int newValue)
4764 if(getNumberOfComponents()!=1)
4765 throw INTERP_KERNEL::Exception("DataArrayInt::changeValue : the array must have only one component, you can call 'rearrange' method before !");
4766 if(oldValue==newValue)
4768 int *start(getPointer()),*end2(start+getNbOfElems());
4770 for(int *val=start;val!=end2;val++)
4784 * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to
4785 * one of given values.
4786 * \param [in] valsBg - an array of values to find within \a this array.
4787 * \param [in] valsEnd - specifies the end of the array \a valsBg, so that
4788 * the last value of \a valsBg is \a valsEnd[ -1 ].
4789 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4790 * array using decrRef() as it is no more needed.
4791 * \throw If \a this->getNumberOfComponents() != 1.
4793 DataArrayInt *DataArrayInt::findIdsEqualList(const int *valsBg, const int *valsEnd) const
4795 if(getNumberOfComponents()!=1)
4796 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqualList : the array must have only one component, you can call 'rearrange' method before !");
4797 std::set<int> vals2(valsBg,valsEnd);
4798 const int *cptr(getConstPointer());
4799 std::vector<int> res;
4800 int nbOfTuples(getNumberOfTuples());
4801 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4802 for(int i=0;i<nbOfTuples;i++,cptr++)
4803 if(vals2.find(*cptr)!=vals2.end())
4804 ret->pushBackSilent(i);
4809 * Creates a new DataArrayInt containing IDs (indices) of tuples holding values \b not
4810 * equal to any of given values.
4811 * \param [in] valsBg - an array of values to ignore within \a this array.
4812 * \param [in] valsEnd - specifies the end of the array \a valsBg, so that
4813 * the last value of \a valsBg is \a valsEnd[ -1 ].
4814 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4815 * array using decrRef() as it is no more needed.
4816 * \throw If \a this->getNumberOfComponents() != 1.
4818 DataArrayInt *DataArrayInt::findIdsNotEqualList(const int *valsBg, const int *valsEnd) const
4820 if(getNumberOfComponents()!=1)
4821 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotEqualList : the array must have only one component, you can call 'rearrange' method before !");
4822 std::set<int> vals2(valsBg,valsEnd);
4823 const int *cptr=getConstPointer();
4824 std::vector<int> res;
4825 int nbOfTuples=getNumberOfTuples();
4826 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4827 for(int i=0;i<nbOfTuples;i++,cptr++)
4828 if(vals2.find(*cptr)==vals2.end())
4829 ret->pushBackSilent(i);
4834 * This method is an extension of DataArrayInt::findIdFirstEqual method because this method works for DataArrayInt with
4835 * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
4836 * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
4837 * If any the tuple id is returned. If not -1 is returned.
4839 * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
4840 * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
4842 * \return tuple id where \b tupl is. -1 if no such tuple exists in \b this.
4843 * \sa DataArrayInt::findIdSequence, DataArrayInt::presenceOfTuple.
4845 int DataArrayInt::findIdFirstEqualTuple(const std::vector<int>& tupl) const
4848 int nbOfCompo=getNumberOfComponents();
4850 throw INTERP_KERNEL::Exception("DataArrayInt::findIdFirstEqualTuple : 0 components in 'this' !");
4851 if(nbOfCompo!=(int)tupl.size())
4853 std::ostringstream oss; oss << "DataArrayInt::findIdFirstEqualTuple : 'this' contains " << nbOfCompo << " components and searching for a tuple of length " << tupl.size() << " !";
4854 throw INTERP_KERNEL::Exception(oss.str().c_str());
4856 const int *cptr=getConstPointer();
4857 std::size_t nbOfVals=getNbOfElems();
4858 for(const int *work=cptr;work!=cptr+nbOfVals;)
4860 work=std::search(work,cptr+nbOfVals,tupl.begin(),tupl.end());
4861 if(work!=cptr+nbOfVals)
4863 if(std::distance(cptr,work)%nbOfCompo!=0)
4866 return std::distance(cptr,work)/nbOfCompo;
4873 * This method searches the sequence specified in input parameter \b vals in \b this.
4874 * This works only for DataArrayInt having number of components equal to one (if not an INTERP_KERNEL::Exception will be thrown).
4875 * This method differs from DataArrayInt::findIdFirstEqualTuple in that the position is internal raw data is not considered here contrary to DataArrayInt::findIdFirstEqualTuple.
4876 * \sa DataArrayInt::findIdFirstEqualTuple
4878 int DataArrayInt::findIdSequence(const std::vector<int>& vals) const
4881 int nbOfCompo=getNumberOfComponents();
4883 throw INTERP_KERNEL::Exception("DataArrayInt::findIdSequence : works only for DataArrayInt instance with one component !");
4884 const int *cptr=getConstPointer();
4885 std::size_t nbOfVals=getNbOfElems();
4886 const int *loc=std::search(cptr,cptr+nbOfVals,vals.begin(),vals.end());
4887 if(loc!=cptr+nbOfVals)
4888 return std::distance(cptr,loc);
4893 * This method expects to be called when number of components of this is equal to one.
4894 * This method returns the tuple id, if it exists, of the first tuple equal to \b value.
4895 * If not any tuple contains \b value -1 is returned.
4896 * \sa DataArrayInt::presenceOfValue
4898 int DataArrayInt::findIdFirstEqual(int value) const
4901 if(getNumberOfComponents()!=1)
4902 throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
4903 const int *cptr=getConstPointer();
4904 int nbOfTuples=getNumberOfTuples();
4905 const int *ret=std::find(cptr,cptr+nbOfTuples,value);
4906 if(ret!=cptr+nbOfTuples)
4907 return std::distance(cptr,ret);
4912 * This method expects to be called when number of components of this is equal to one.
4913 * This method returns the tuple id, if it exists, of the first tuple so that the value is contained in \b vals.
4914 * If not any tuple contains one of the values contained in 'vals' -1 is returned.
4915 * \sa DataArrayInt::presenceOfValue
4917 int DataArrayInt::findIdFirstEqual(const std::vector<int>& vals) const
4920 if(getNumberOfComponents()!=1)
4921 throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
4922 std::set<int> vals2(vals.begin(),vals.end());
4923 const int *cptr=getConstPointer();
4924 int nbOfTuples=getNumberOfTuples();
4925 for(const int *w=cptr;w!=cptr+nbOfTuples;w++)
4926 if(vals2.find(*w)!=vals2.end())
4927 return std::distance(cptr,w);
4932 * This method returns the number of values in \a this that are equals to input parameter \a value.
4933 * This method only works for single component array.
4935 * \return a value in [ 0, \c this->getNumberOfTuples() )
4937 * \throw If \a this is not allocated
4940 int DataArrayInt::count(int value) const
4944 if(getNumberOfComponents()!=1)
4945 throw INTERP_KERNEL::Exception("DataArrayInt::count : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
4946 const int *vals=begin();
4947 int nbOfTuples=getNumberOfTuples();
4948 for(int i=0;i<nbOfTuples;i++,vals++)
4955 * This method is an extension of DataArrayInt::presenceOfValue method because this method works for DataArrayInt with
4956 * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
4957 * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
4958 * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
4959 * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
4960 * \sa DataArrayInt::findIdFirstEqualTuple
4962 bool DataArrayInt::presenceOfTuple(const std::vector<int>& tupl) const
4964 return findIdFirstEqualTuple(tupl)!=-1;
4969 * Returns \a true if a given value is present within \a this one-dimensional array.
4970 * \param [in] value - the value to find within \a this array.
4971 * \return bool - \a true in case if \a value is present within \a this array.
4972 * \throw If \a this is not allocated.
4973 * \throw If \a this->getNumberOfComponents() != 1.
4974 * \sa findIdFirstEqual()
4976 bool DataArrayInt::presenceOfValue(int value) const
4978 return findIdFirstEqual(value)!=-1;
4982 * This method expects to be called when number of components of this is equal to one.
4983 * This method returns true if it exists a tuple so that the value is contained in \b vals.
4984 * If not any tuple contains one of the values contained in 'vals' false is returned.
4985 * \sa DataArrayInt::findIdFirstEqual
4987 bool DataArrayInt::presenceOfValue(const std::vector<int>& vals) const
4989 return findIdFirstEqual(vals)!=-1;
4993 * Accumulates values of each component of \a this array.
4994 * \param [out] res - an array of length \a this->getNumberOfComponents(), allocated
4995 * by the caller, that is filled by this method with sum value for each
4997 * \throw If \a this is not allocated.
4999 void DataArrayInt::accumulate(int *res) const
5002 const int *ptr=getConstPointer();
5003 int nbTuple=getNumberOfTuples();
5004 int nbComps=getNumberOfComponents();
5005 std::fill(res,res+nbComps,0);
5006 for(int i=0;i<nbTuple;i++)
5007 std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<int>());
5010 int DataArrayInt::accumulate(int compId) const
5013 const int *ptr=getConstPointer();
5014 int nbTuple=getNumberOfTuples();
5015 int nbComps=getNumberOfComponents();
5016 if(compId<0 || compId>=nbComps)
5017 throw INTERP_KERNEL::Exception("DataArrayInt::accumulate : Invalid compId specified : No such nb of components !");
5019 for(int i=0;i<nbTuple;i++)
5020 ret+=ptr[i*nbComps+compId];
5025 * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
5026 * The returned array will have same number of components than \a this and number of tuples equal to
5027 * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
5029 * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
5031 * \param [in] bgOfIndex - begin (included) of the input index array.
5032 * \param [in] endOfIndex - end (excluded) of the input index array.
5033 * \return DataArrayInt * - the new instance having the same number of components than \a this.
5035 * \throw If bgOfIndex or end is NULL.
5036 * \throw If input index array is not ascendingly sorted.
5037 * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
5038 * \throw If std::distance(bgOfIndex,endOfIndex)==0.
5040 DataArrayInt *DataArrayInt::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
5042 if(!bgOfIndex || !endOfIndex)
5043 throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : input pointer NULL !");
5045 int nbCompo=getNumberOfComponents();
5046 int nbOfTuples=getNumberOfTuples();
5047 int sz=(int)std::distance(bgOfIndex,endOfIndex);
5049 throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : invalid size of input index array !");
5051 MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(sz,nbCompo);
5052 const int *w=bgOfIndex;
5053 if(*w<0 || *w>=nbOfTuples)
5054 throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
5055 const int *srcPt=begin()+(*w)*nbCompo;
5056 int *tmp=ret->getPointer();
5057 for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
5059 std::fill(tmp,tmp+nbCompo,0);
5062 for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
5064 if(j>=0 && j<nbOfTuples)
5065 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<int>());
5068 std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
5069 throw INTERP_KERNEL::Exception(oss.str().c_str());
5075 std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
5076 throw INTERP_KERNEL::Exception(oss.str().c_str());
5079 ret->copyStringInfoFrom(*this);
5084 * Returns a new DataArrayInt by concatenating two given arrays, so that (1) the number
5085 * of tuples in the result array is <em> a1->getNumberOfTuples() + a2->getNumberOfTuples() -
5086 * offsetA2</em> and (2)
5087 * the number of component in the result array is same as that of each of given arrays.
5088 * First \a offsetA2 tuples of \a a2 are skipped and thus are missing from the result array.
5089 * Info on components is copied from the first of the given arrays. Number of components
5090 * in the given arrays must be the same.
5091 * \param [in] a1 - an array to include in the result array.
5092 * \param [in] a2 - another array to include in the result array.
5093 * \param [in] offsetA2 - number of tuples of \a a2 to skip.
5094 * \return DataArrayInt * - the new instance of DataArrayInt.
5095 * The caller is to delete this result array using decrRef() as it is no more
5097 * \throw If either \a a1 or \a a2 is NULL.
5098 * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
5100 DataArrayInt *DataArrayInt::Aggregate(const DataArrayInt *a1, const DataArrayInt *a2, int offsetA2)
5103 throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input DataArrayInt instance is NULL !");
5104 std::size_t nbOfComp(a1->getNumberOfComponents());
5105 if(nbOfComp!=a2->getNumberOfComponents())
5106 throw INTERP_KERNEL::Exception("Nb of components mismatch for array Aggregation !");
5107 std::size_t nbOfTuple1(a1->getNumberOfTuples()),nbOfTuple2(a2->getNumberOfTuples());
5108 MCAuto<DataArrayInt> ret(DataArrayInt::New());
5109 ret->alloc(nbOfTuple1+nbOfTuple2-offsetA2,nbOfComp);
5110 int *pt=std::copy(a1->begin(),a1->end(),ret->getPointer());
5111 std::copy(a2->getConstPointer()+offsetA2*nbOfComp,a2->getConstPointer()+nbOfTuple2*nbOfComp,pt);
5112 ret->copyStringInfoFrom(*a1);
5117 * Returns a new DataArrayInt by concatenating all given arrays, so that (1) the number
5118 * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
5119 * the number of component in the result array is same as that of each of given arrays.
5120 * Info on components is copied from the first of the given arrays. Number of components
5121 * in the given arrays must be the same.
5122 * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it
5123 * not the object itself.
5124 * \param [in] arr - a sequence of arrays to include in the result array.
5125 * \return DataArrayInt * - the new instance of DataArrayInt.
5126 * The caller is to delete this result array using decrRef() as it is no more
5128 * \throw If all arrays within \a arr are NULL.
5129 * \throw If getNumberOfComponents() of arrays within \a arr.
5131 DataArrayInt *DataArrayInt::Aggregate(const std::vector<const DataArrayInt *>& arr)
5133 std::vector<const DataArrayInt *> a;
5134 for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
5138 throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input list must be NON EMPTY !");
5139 std::vector<const DataArrayInt *>::const_iterator it=a.begin();
5140 std::size_t nbOfComp((*it)->getNumberOfComponents()),nbt((*it++)->getNumberOfTuples());
5141 for(int i=1;it!=a.end();it++,i++)
5143 if((*it)->getNumberOfComponents()!=nbOfComp)
5144 throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : Nb of components mismatch for array aggregation !");
5145 nbt+=(*it)->getNumberOfTuples();
5147 MCAuto<DataArrayInt> ret=DataArrayInt::New();
5148 ret->alloc(nbt,nbOfComp);
5149 int *pt=ret->getPointer();
5150 for(it=a.begin();it!=a.end();it++)
5151 pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
5152 ret->copyStringInfoFrom(*(a[0]));
5157 * This method takes as input a list of DataArrayInt instances \a arrs that represent each a packed index arrays.
5158 * A packed index array is an allocated array with one component, and at least one tuple. The first element
5159 * of each array in \a arrs must be 0. Each array in \a arrs is expected to be increasingly monotonic.
5160 * 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.
5162 * \return DataArrayInt * - a new object to be managed by the caller.
5164 DataArrayInt *DataArrayInt::AggregateIndexes(const std::vector<const DataArrayInt *>& arrs)
5167 for(std::vector<const DataArrayInt *>::const_iterator it4=arrs.begin();it4!=arrs.end();it4++)
5171 (*it4)->checkAllocated();
5172 if((*it4)->getNumberOfComponents()!=1)
5174 std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of compo != 1 at pos " << std::distance(arrs.begin(),it4) << " !";
5175 throw INTERP_KERNEL::Exception(oss.str().c_str());
5177 int nbTupl=(*it4)->getNumberOfTuples();
5180 std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of tuples < 1 at pos " << std::distance(arrs.begin(),it4) << " !";
5181 throw INTERP_KERNEL::Exception(oss.str().c_str());
5183 if((*it4)->front()!=0)
5185 std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with front value != 0 at pos " << std::distance(arrs.begin(),it4) << " !";
5186 throw INTERP_KERNEL::Exception(oss.str().c_str());
5192 std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a null instance at pos " << std::distance(arrs.begin(),it4) << " !";
5193 throw INTERP_KERNEL::Exception(oss.str().c_str());
5197 throw INTERP_KERNEL::Exception("DataArrayInt::AggregateIndexes : input list must be NON EMPTY !");
5198 MCAuto<DataArrayInt> ret=DataArrayInt::New();
5199 ret->alloc(retSz,1);
5200 int *pt=ret->getPointer(); *pt++=0;
5201 for(std::vector<const DataArrayInt *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
5202 pt=std::transform((*it)->begin()+1,(*it)->end(),pt,std::bind2nd(std::plus<int>(),pt[-1]));
5203 ret->copyStringInfoFrom(*(arrs[0]));
5208 * Returns in a single walk in \a this the min value and the max value in \a this.
5209 * \a this is expected to be single component array.
5211 * \param [out] minValue - the min value in \a this.
5212 * \param [out] maxValue - the max value in \a this.
5214 * \sa getMinValueInArray, getMinValue, getMaxValueInArray, getMaxValue
5216 void DataArrayInt::getMinMaxValues(int& minValue, int& maxValue) const
5219 if(getNumberOfComponents()!=1)
5220 throw INTERP_KERNEL::Exception("DataArrayInt::getMinMaxValues : must be applied on DataArrayInt with only one component !");
5221 int nbTuples(getNumberOfTuples());
5222 const int *pt(begin());
5223 minValue=std::numeric_limits<int>::max(); maxValue=-std::numeric_limits<int>::max();
5224 for(int i=0;i<nbTuples;i++,pt++)
5234 * Modify all elements of \a this array, so that
5235 * an element _x_ becomes \f$ numerator / x \f$.
5236 * \warning If an exception is thrown because of presence of 0 element in \a this
5237 * array, all elements processed before detection of the zero element remain
5239 * \param [in] numerator - the numerator used to modify array elements.
5240 * \throw If \a this is not allocated.
5241 * \throw If there is an element equal to 0 in \a this array.
5243 void DataArrayInt::applyInv(int numerator)
5246 int *ptr=getPointer();
5247 std::size_t nbOfElems=getNbOfElems();
5248 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
5252 *ptr=numerator/(*ptr);
5256 std::ostringstream oss; oss << "DataArrayInt::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
5258 throw INTERP_KERNEL::Exception(oss.str().c_str());
5265 * Modify all elements of \a this array, so that
5266 * an element _x_ becomes \f$ x / val \f$.
5267 * \param [in] val - the denominator used to modify array elements.
5268 * \throw If \a this is not allocated.
5269 * \throw If \a val == 0.
5271 void DataArrayInt::applyDivideBy(int val)
5274 throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to divide by 0 !");
5276 int *ptr=getPointer();
5277 std::size_t nbOfElems=getNbOfElems();
5278 std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::divides<int>(),val));
5283 * Modify all elements of \a this array, so that
5284 * an element _x_ becomes <em> x % val </em>.
5285 * \param [in] val - the divisor used to modify array elements.
5286 * \throw If \a this is not allocated.
5287 * \throw If \a val <= 0.
5289 void DataArrayInt::applyModulus(int val)
5292 throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to operate modulus on value <= 0 !");
5294 int *ptr=getPointer();
5295 std::size_t nbOfElems=getNbOfElems();
5296 std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::modulus<int>(),val));
5301 * This method works only on data array with one component.
5302 * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
5303 * this[*id] in [\b vmin,\b vmax)
5305 * \param [in] vmin begin of range. This value is included in range (included).
5306 * \param [in] vmax end of range. This value is \b not included in range (excluded).
5307 * \return a newly allocated data array that the caller should deal with.
5309 * \sa DataArrayInt::findIdsNotInRange , DataArrayInt::findIdsStricltyNegative
5311 DataArrayInt *DataArrayInt::findIdsInRange(int vmin, int vmax) const
5313 InRange<int> ir(vmin,vmax);
5314 MCAuto<DataArrayInt> ret(findIdsAdv(ir));
5319 * This method works only on data array with one component.
5320 * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
5321 * this[*id] \b not in [\b vmin,\b vmax)
5323 * \param [in] vmin begin of range. This value is \b not included in range (excluded).
5324 * \param [in] vmax end of range. This value is included in range (included).
5325 * \return a newly allocated data array that the caller should deal with.
5327 * \sa DataArrayInt::findIdsInRange , DataArrayInt::findIdsStricltyNegative
5329 DataArrayInt *DataArrayInt::findIdsNotInRange(int vmin, int vmax) const
5331 NotInRange<int> nir(vmin,vmax);
5332 MCAuto<DataArrayInt> ret(findIdsAdv(nir));
5337 * This method works only on data array with one component.
5338 * 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.
5340 * \param [in] vmin begin of range. This value is included in range (included).
5341 * \param [in] vmax end of range. This value is \b not included in range (excluded).
5342 * \return if all ids in \a this are so that (*this)[i]==i for all i in [ 0, \c this->getNumberOfTuples() ). */
5343 bool DataArrayInt::checkAllIdsInRange(int vmin, int vmax) const
5346 if(getNumberOfComponents()!=1)
5347 throw INTERP_KERNEL::Exception("DataArrayInt::checkAllIdsInRange : this must have exactly one component !");
5348 int nbOfTuples=getNumberOfTuples();
5350 const int *cptr=getConstPointer();
5351 for(int i=0;i<nbOfTuples;i++,cptr++)
5353 if(*cptr>=vmin && *cptr<vmax)
5354 { ret=ret && *cptr==i; }
5357 std::ostringstream oss; oss << "DataArrayInt::checkAllIdsInRange : tuple #" << i << " has value " << *cptr << " should be in [" << vmin << "," << vmax << ") !";
5358 throw INTERP_KERNEL::Exception(oss.str().c_str());
5365 * Modify all elements of \a this array, so that
5366 * an element _x_ becomes <em> val % x </em>.
5367 * \warning If an exception is thrown because of presence of an element <= 0 in \a this
5368 * array, all elements processed before detection of the zero element remain
5370 * \param [in] val - the divident used to modify array elements.
5371 * \throw If \a this is not allocated.
5372 * \throw If there is an element equal to or less than 0 in \a this array.
5374 void DataArrayInt::applyRModulus(int val)
5377 int *ptr=getPointer();
5378 std::size_t nbOfElems=getNbOfElems();
5379 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
5387 std::ostringstream oss; oss << "DataArrayInt::applyRModulus : presence of value <=0 in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
5389 throw INTERP_KERNEL::Exception(oss.str().c_str());
5396 * Modify all elements of \a this array, so that
5397 * an element _x_ becomes <em> val ^ x </em>.
5398 * \param [in] val - the value used to apply pow on all array elements.
5399 * \throw If \a this is not allocated.
5400 * \throw If \a val < 0.
5402 void DataArrayInt::applyPow(int val)
5406 throw INTERP_KERNEL::Exception("DataArrayInt::applyPow : input pow in < 0 !");
5407 int *ptr=getPointer();
5408 std::size_t nbOfElems=getNbOfElems();
5411 std::fill(ptr,ptr+nbOfElems,1);
5414 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
5417 for(int j=0;j<val;j++)
5425 * Modify all elements of \a this array, so that
5426 * an element _x_ becomes \f$ val ^ x \f$.
5427 * \param [in] val - the value used to apply pow on all array elements.
5428 * \throw If \a this is not allocated.
5429 * \throw If there is an element < 0 in \a this array.
5430 * \warning If an exception is thrown because of presence of 0 element in \a this
5431 * array, all elements processed before detection of the zero element remain
5434 void DataArrayInt::applyRPow(int val)
5437 int *ptr=getPointer();
5438 std::size_t nbOfElems=getNbOfElems();
5439 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
5444 for(int j=0;j<*ptr;j++)
5450 std::ostringstream oss; oss << "DataArrayInt::applyRPow : presence of negative value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
5452 throw INTERP_KERNEL::Exception(oss.str().c_str());
5459 * Returns a new DataArrayInt which is a minimal partition of elements of \a groups.
5460 * The i-th item of the result array is an ID of a set of elements belonging to a
5461 * unique set of groups, which the i-th element is a part of. This set of elements
5462 * belonging to a unique set of groups is called \a family, so the result array contains
5463 * IDs of families each element belongs to.
5465 * \b Example: if we have two groups of elements: \a group1 [0,4] and \a group2 [ 0,1,2 ],
5466 * then there are 3 families:
5467 * - \a family1 (with ID 1) contains element [0] belonging to ( \a group1 + \a group2 ),
5468 * - \a family2 (with ID 2) contains elements [4] belonging to ( \a group1 ),
5469 * - \a family3 (with ID 3) contains element [1,2] belonging to ( \a group2 ), <br>
5470 * and the result array contains IDs of families [ 1,3,3,0,2 ]. <br> Note a family ID 0 which
5471 * stands for the element #3 which is in none of groups.
5473 * \param [in] groups - sequence of groups of element IDs.
5474 * \param [in] newNb - total number of elements; it must be more than max ID of element
5476 * \param [out] fidsOfGroups - IDs of families the elements of each group belong to.
5477 * \return DataArrayInt * - a new instance of DataArrayInt containing IDs of families
5478 * each element with ID from range [0, \a newNb ) belongs to. The caller is to
5479 * delete this array using decrRef() as it is no more needed.
5480 * \throw If any element ID in \a groups violates condition ( 0 <= ID < \a newNb ).
5482 DataArrayInt *DataArrayInt::MakePartition(const std::vector<const DataArrayInt *>& groups, int newNb, std::vector< std::vector<int> >& fidsOfGroups)
5484 std::vector<const DataArrayInt *> groups2;
5485 for(std::vector<const DataArrayInt *>::const_iterator it4=groups.begin();it4!=groups.end();it4++)
5487 groups2.push_back(*it4);
5488 MCAuto<DataArrayInt> ret=DataArrayInt::New();
5489 ret->alloc(newNb,1);
5490 int *retPtr=ret->getPointer();
5491 std::fill(retPtr,retPtr+newNb,0);
5493 for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++)
5495 const int *ptr=(*iter)->getConstPointer();
5496 std::size_t nbOfElem=(*iter)->getNbOfElems();
5498 for(int j=0;j<sfid;j++)
5501 for(std::size_t i=0;i<nbOfElem;i++)
5503 if(ptr[i]>=0 && ptr[i]<newNb)
5505 if(retPtr[ptr[i]]==j)
5513 std::ostringstream oss; oss << "DataArrayInt::MakePartition : In group \"" << (*iter)->getName() << "\" in tuple #" << i << " value = " << ptr[i] << " ! Should be in [0," << newNb;
5515 throw INTERP_KERNEL::Exception(oss.str().c_str());
5522 fidsOfGroups.clear();
5523 fidsOfGroups.resize(groups2.size());
5525 for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++,grId++)
5528 const int *ptr=(*iter)->getConstPointer();
5529 std::size_t nbOfElem=(*iter)->getNbOfElems();
5530 for(const int *p=ptr;p!=ptr+nbOfElem;p++)
5531 tmp.insert(retPtr[*p]);
5532 fidsOfGroups[grId].insert(fidsOfGroups[grId].end(),tmp.begin(),tmp.end());
5538 * Returns a new DataArrayInt which contains all elements of given one-dimensional
5539 * arrays. The result array does not contain any duplicates and its values
5540 * are sorted in ascending order.
5541 * \param [in] arr - sequence of DataArrayInt's to unite.
5542 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5543 * array using decrRef() as it is no more needed.
5544 * \throw If any \a arr[i] is not allocated.
5545 * \throw If \a arr[i]->getNumberOfComponents() != 1.
5547 DataArrayInt *DataArrayInt::BuildUnion(const std::vector<const DataArrayInt *>& arr)
5549 std::vector<const DataArrayInt *> a;
5550 for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
5553 for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
5555 (*it)->checkAllocated();
5556 if((*it)->getNumberOfComponents()!=1)
5557 throw INTERP_KERNEL::Exception("DataArrayInt::BuildUnion : only single component allowed !");
5561 for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
5563 const int *pt=(*it)->getConstPointer();
5564 int nbOfTuples=(*it)->getNumberOfTuples();
5565 r.insert(pt,pt+nbOfTuples);
5567 DataArrayInt *ret=DataArrayInt::New();
5568 ret->alloc((int)r.size(),1);
5569 std::copy(r.begin(),r.end(),ret->getPointer());
5574 * Returns a new DataArrayInt which contains elements present in each of given one-dimensional
5575 * arrays. The result array does not contain any duplicates and its values
5576 * are sorted in ascending order.
5577 * \param [in] arr - sequence of DataArrayInt's to intersect.
5578 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5579 * array using decrRef() as it is no more needed.
5580 * \throw If any \a arr[i] is not allocated.
5581 * \throw If \a arr[i]->getNumberOfComponents() != 1.
5583 DataArrayInt *DataArrayInt::BuildIntersection(const std::vector<const DataArrayInt *>& arr)
5585 std::vector<const DataArrayInt *> a;
5586 for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
5589 for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
5591 (*it)->checkAllocated();
5592 if((*it)->getNumberOfComponents()!=1)
5593 throw INTERP_KERNEL::Exception("DataArrayInt::BuildIntersection : only single component allowed !");
5597 for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
5599 const int *pt=(*it)->getConstPointer();
5600 int nbOfTuples=(*it)->getNumberOfTuples();
5601 std::set<int> s1(pt,pt+nbOfTuples);
5605 std::set_intersection(r.begin(),r.end(),s1.begin(),s1.end(),inserter(r2,r2.end()));
5611 DataArrayInt *ret(DataArrayInt::New());
5612 ret->alloc((int)r.size(),1);
5613 std::copy(r.begin(),r.end(),ret->getPointer());
5618 namespace MEDCouplingImpl
5623 OpSwitchedOn(int *pt):_pt(pt),_cnt(0) { }
5624 void operator()(const bool& b) { if(b) *_pt++=_cnt; _cnt++; }
5633 OpSwitchedOff(int *pt):_pt(pt),_cnt(0) { }
5634 void operator()(const bool& b) { if(!b) *_pt++=_cnt; _cnt++; }
5643 * This method returns the list of ids in ascending mode so that v[id]==true.
5645 DataArrayInt *DataArrayInt::BuildListOfSwitchedOn(const std::vector<bool>& v)
5647 int sz((int)std::count(v.begin(),v.end(),true));
5648 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
5649 std::for_each(v.begin(),v.end(),MEDCouplingImpl::OpSwitchedOn(ret->getPointer()));
5654 * This method returns the list of ids in ascending mode so that v[id]==false.
5656 DataArrayInt *DataArrayInt::BuildListOfSwitchedOff(const std::vector<bool>& v)
5658 int sz((int)std::count(v.begin(),v.end(),false));
5659 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
5660 std::for_each(v.begin(),v.end(),MEDCouplingImpl::OpSwitchedOff(ret->getPointer()));
5665 * This method allows to put a vector of vector of integer into a more compact data structure (skyline).
5666 * This method is not available into python because no available optimized data structure available to map std::vector< std::vector<int> >.
5668 * \param [in] v the input data structure to be translate into skyline format.
5669 * \param [out] data the first element of the skyline format. The user is expected to deal with newly allocated array.
5670 * \param [out] dataIndex the second element of the skyline format.
5672 void DataArrayInt::PutIntoToSkylineFrmt(const std::vector< std::vector<int> >& v, DataArrayInt *& data, DataArrayInt *& dataIndex)
5674 int sz((int)v.size());
5675 MCAuto<DataArrayInt> ret0(DataArrayInt::New()),ret1(DataArrayInt::New());
5676 ret1->alloc(sz+1,1);
5677 int *pt(ret1->getPointer()); *pt=0;
5678 for(int i=0;i<sz;i++,pt++)
5679 pt[1]=pt[0]+(int)v[i].size();
5680 ret0->alloc(ret1->back(),1);
5681 pt=ret0->getPointer();
5682 for(int i=0;i<sz;i++)
5683 pt=std::copy(v[i].begin(),v[i].end(),pt);
5684 data=ret0.retn(); dataIndex=ret1.retn();
5688 * Returns a new DataArrayInt which contains a complement of elements of \a this
5689 * one-dimensional array. I.e. the result array contains all elements from the range [0,
5690 * \a nbOfElement) not present in \a this array.
5691 * \param [in] nbOfElement - maximal size of the result array.
5692 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5693 * array using decrRef() as it is no more needed.
5694 * \throw If \a this is not allocated.
5695 * \throw If \a this->getNumberOfComponents() != 1.
5696 * \throw If any element \a x of \a this array violates condition ( 0 <= \a x < \a
5699 DataArrayInt *DataArrayInt::buildComplement(int nbOfElement) const
5702 if(getNumberOfComponents()!=1)
5703 throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : only single component allowed !");
5704 std::vector<bool> tmp(nbOfElement);
5705 const int *pt=getConstPointer();
5706 int nbOfTuples=getNumberOfTuples();
5707 for(const int *w=pt;w!=pt+nbOfTuples;w++)
5708 if(*w>=0 && *w<nbOfElement)
5711 throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : an element is not in valid range : [0,nbOfElement) !");
5712 int nbOfRetVal=(int)std::count(tmp.begin(),tmp.end(),false);
5713 DataArrayInt *ret=DataArrayInt::New();
5714 ret->alloc(nbOfRetVal,1);
5716 int *retPtr=ret->getPointer();
5717 for(int i=0;i<nbOfElement;i++)
5724 * Returns a new DataArrayInt containing elements of \a this one-dimensional missing
5725 * from an \a other one-dimensional array.
5726 * \param [in] other - a DataArrayInt containing elements not to include in the result array.
5727 * \return DataArrayInt * - a new instance of DataArrayInt with one component. The
5728 * caller is to delete this array using decrRef() as it is no more needed.
5729 * \throw If \a other is NULL.
5730 * \throw If \a other is not allocated.
5731 * \throw If \a other->getNumberOfComponents() != 1.
5732 * \throw If \a this is not allocated.
5733 * \throw If \a this->getNumberOfComponents() != 1.
5734 * \sa DataArrayInt::buildSubstractionOptimized()
5736 DataArrayInt *DataArrayInt::buildSubstraction(const DataArrayInt *other) const
5739 throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : DataArrayInt pointer in input is NULL !");
5741 other->checkAllocated();
5742 if(getNumberOfComponents()!=1)
5743 throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed !");
5744 if(other->getNumberOfComponents()!=1)
5745 throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed for other type !");
5746 const int *pt=getConstPointer();
5747 int nbOfTuples=getNumberOfTuples();
5748 std::set<int> s1(pt,pt+nbOfTuples);
5749 pt=other->getConstPointer();
5750 nbOfTuples=other->getNumberOfTuples();
5751 std::set<int> s2(pt,pt+nbOfTuples);
5753 std::set_difference(s1.begin(),s1.end(),s2.begin(),s2.end(),std::back_insert_iterator< std::vector<int> >(r));
5754 DataArrayInt *ret=DataArrayInt::New();
5755 ret->alloc((int)r.size(),1);
5756 std::copy(r.begin(),r.end(),ret->getPointer());
5761 * \a this is expected to have one component and to be sorted ascendingly (as for \a other).
5762 * \a other is expected to be a part of \a this. If not DataArrayInt::buildSubstraction should be called instead.
5764 * \param [in] other an array with one component and expected to be sorted ascendingly.
5765 * \ret list of ids in \a this but not in \a other.
5766 * \sa DataArrayInt::buildSubstraction
5768 DataArrayInt *DataArrayInt::buildSubstractionOptimized(const DataArrayInt *other) const
5770 static const char *MSG="DataArrayInt::buildSubstractionOptimized : only single component allowed !";
5771 if(!other) throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstractionOptimized : NULL input array !");
5772 checkAllocated(); other->checkAllocated();
5773 if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
5774 if(other->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
5775 const int *pt1Bg(begin()),*pt1End(end()),*pt2Bg(other->begin()),*pt2End(other->end());
5776 const int *work1(pt1Bg),*work2(pt2Bg);
5777 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
5778 for(;work1!=pt1End;work1++)
5780 if(work2!=pt2End && *work1==*work2)
5783 ret->pushBackSilent(*work1);
5790 * Returns a new DataArrayInt which contains all elements of \a this and a given
5791 * one-dimensional arrays. The result array does not contain any duplicates
5792 * and its values are sorted in ascending order.
5793 * \param [in] other - an array to unite with \a this one.
5794 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5795 * array using decrRef() as it is no more needed.
5796 * \throw If \a this or \a other is not allocated.
5797 * \throw If \a this->getNumberOfComponents() != 1.
5798 * \throw If \a other->getNumberOfComponents() != 1.
5800 DataArrayInt *DataArrayInt::buildUnion(const DataArrayInt *other) const
5802 std::vector<const DataArrayInt *>arrs(2);
5803 arrs[0]=this; arrs[1]=other;
5804 return BuildUnion(arrs);
5809 * Returns a new DataArrayInt which contains elements present in both \a this and a given
5810 * one-dimensional arrays. The result array does not contain any duplicates
5811 * and its values are sorted in ascending order.
5812 * \param [in] other - an array to intersect with \a this one.
5813 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5814 * array using decrRef() as it is no more needed.
5815 * \throw If \a this or \a other is not allocated.
5816 * \throw If \a this->getNumberOfComponents() != 1.
5817 * \throw If \a other->getNumberOfComponents() != 1.
5819 DataArrayInt *DataArrayInt::buildIntersection(const DataArrayInt *other) const
5821 std::vector<const DataArrayInt *>arrs(2);
5822 arrs[0]=this; arrs[1]=other;
5823 return BuildIntersection(arrs);
5827 * This method can be applied on allocated with one component DataArrayInt instance.
5828 * This method is typically relevant for sorted arrays. All consecutive duplicated items in \a this will appear only once in returned DataArrayInt instance.
5829 * 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]
5831 * \return a newly allocated array that contain the result of the unique operation applied on \a this.
5832 * \throw if \a this is not allocated or if \a this has not exactly one component.
5833 * \sa DataArrayInt::buildUniqueNotSorted
5835 DataArrayInt *DataArrayInt::buildUnique() const
5838 if(getNumberOfComponents()!=1)
5839 throw INTERP_KERNEL::Exception("DataArrayInt::buildUnique : only single component allowed !");
5840 int nbOfTuples=getNumberOfTuples();
5841 MCAuto<DataArrayInt> tmp=deepCopy();
5842 int *data=tmp->getPointer();
5843 int *last=std::unique(data,data+nbOfTuples);
5844 MCAuto<DataArrayInt> ret=DataArrayInt::New();
5845 ret->alloc(std::distance(data,last),1);
5846 std::copy(data,last,ret->getPointer());
5851 * This method can be applied on allocated with one component DataArrayInt instance.
5852 * This method keep elements only once by keeping the same order in \a this that is not expected to be sorted.
5854 * \return a newly allocated array that contain the result of the unique operation applied on \a this.
5856 * \throw if \a this is not allocated or if \a this has not exactly one component.
5858 * \sa DataArrayInt::buildUnique
5860 DataArrayInt *DataArrayInt::buildUniqueNotSorted() const
5863 if(getNumberOfComponents()!=1)
5864 throw INTERP_KERNEL::Exception("DataArrayInt::buildUniqueNotSorted : only single component allowed !");
5866 getMinMaxValues(minVal,maxVal);
5867 std::vector<bool> b(maxVal-minVal+1,false);
5868 const int *ptBg(begin()),*endBg(end());
5869 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
5870 for(const int *pt=ptBg;pt!=endBg;pt++)
5874 ret->pushBackSilent(*pt);
5878 ret->copyStringInfoFrom(*this);
5883 * Returns a new DataArrayInt which contains size of every of groups described by \a this
5884 * "index" array. Such "index" array is returned for example by
5885 * \ref MEDCoupling::MEDCouplingUMesh::buildDescendingConnectivity
5886 * "MEDCouplingUMesh::buildDescendingConnectivity" and
5887 * \ref MEDCoupling::MEDCouplingUMesh::getNodalConnectivityIndex
5888 * "MEDCouplingUMesh::getNodalConnectivityIndex" etc.
5889 * This method performs the reverse operation of DataArrayInt::computeOffsetsFull.
5890 * \return DataArrayInt * - a new instance of DataArrayInt, whose number of tuples
5891 * equals to \a this->getNumberOfComponents() - 1, and number of components is 1.
5892 * The caller is to delete this array using decrRef() as it is no more needed.
5893 * \throw If \a this is not allocated.
5894 * \throw If \a this->getNumberOfComponents() != 1.
5895 * \throw If \a this->getNumberOfTuples() < 2.
5898 * - this contains [1,3,6,7,7,9,15]
5899 * - result array contains [2,3,1,0,2,6],
5900 * where 2 = 3 - 1, 3 = 6 - 3, 1 = 7 - 6 etc.
5902 * \sa DataArrayInt::computeOffsetsFull
5904 DataArrayInt *DataArrayInt::deltaShiftIndex() const
5907 if(getNumberOfComponents()!=1)
5908 throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : only single component allowed !");
5909 int nbOfTuples=getNumberOfTuples();
5911 throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : 1 tuple at least must be present in 'this' !");
5912 const int *ptr=getConstPointer();
5913 DataArrayInt *ret=DataArrayInt::New();
5914 ret->alloc(nbOfTuples-1,1);
5915 int *out=ret->getPointer();
5916 std::transform(ptr+1,ptr+nbOfTuples,ptr,out,std::minus<int>());
5921 * Modifies \a this one-dimensional array so that value of each element \a x
5922 * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
5923 * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number of tuples
5924 * and components remains the same.<br>
5925 * This method is useful for allToAllV in MPI with contiguous policy. This method
5926 * differs from computeOffsetsFull() in that the number of tuples is \b not changed by
5928 * \throw If \a this is not allocated.
5929 * \throw If \a this->getNumberOfComponents() != 1.
5932 * - Before \a this contains [3,5,1,2,0,8]
5933 * - After \a this contains [0,3,8,9,11,11]<br>
5934 * Note that the last element 19 = 11 + 8 is missing because size of \a this
5935 * array is retained and thus there is no space to store the last element.
5937 void DataArrayInt::computeOffsets()
5940 if(getNumberOfComponents()!=1)
5941 throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets : only single component allowed !");
5942 int nbOfTuples=getNumberOfTuples();
5945 int *work=getPointer();
5948 for(int i=1;i<nbOfTuples;i++)
5951 work[i]=work[i-1]+tmp;
5959 * Modifies \a this one-dimensional array so that value of each element \a x
5960 * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
5961 * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number
5962 * components remains the same and number of tuples is inceamented by one.<br>
5963 * This method is useful for allToAllV in MPI with contiguous policy. This method
5964 * differs from computeOffsets() in that the number of tuples is changed by this one.
5965 * This method performs the reverse operation of DataArrayInt::deltaShiftIndex.
5966 * \throw If \a this is not allocated.
5967 * \throw If \a this->getNumberOfComponents() != 1.
5970 * - Before \a this contains [3,5,1,2,0,8]
5971 * - After \a this contains [0,3,8,9,11,11,19]<br>
5972 * \sa DataArrayInt::deltaShiftIndex
5974 void DataArrayInt::computeOffsetsFull()
5977 if(getNumberOfComponents()!=1)
5978 throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsetsFull : only single component allowed !");
5979 int nbOfTuples=getNumberOfTuples();
5980 int *ret=(int *)malloc((nbOfTuples+1)*sizeof(int));
5981 const int *work=getConstPointer();
5983 for(int i=0;i<nbOfTuples;i++)
5984 ret[i+1]=work[i]+ret[i];
5985 useArray(ret,true,C_DEALLOC,nbOfTuples+1,1);
5990 * Returns two new DataArrayInt instances whose contents is computed from that of \a this and \a listOfIds arrays as follows.
5991 * \a this is expected to be an offset format ( as returned by DataArrayInt::computeOffsetsFull ) that is to say with one component
5992 * and ** sorted strictly increasingly **. \a listOfIds is expected to be sorted ascendingly (not strictly needed for \a listOfIds).
5993 * This methods searches in \a this, considered as a set of contiguous \c this->getNumberOfComponents() ranges, all ids in \a listOfIds
5994 * filling completely one of the ranges in \a this.
5996 * \param [in] listOfIds a list of ids that has to be sorted ascendingly.
5997 * \param [out] rangeIdsFetched the range ids fetched
5998 * \param [out] idsInInputListThatFetch contains the list of ids in \a listOfIds that are \b fully included in a range in \a this. So
5999 * \a idsInInputListThatFetch is a part of input \a listOfIds.
6001 * \sa DataArrayInt::computeOffsetsFull
6004 * - \a this : [0,3,7,9,15,18]
6005 * - \a listOfIds contains [0,1,2,3,7,8,15,16,17]
6006 * - \a rangeIdsFetched result array: [0,2,4]
6007 * - \a idsInInputListThatFetch result array: [0,1,2,7,8,15,16,17]
6008 * In this example id 3 in input \a listOfIds is alone so it do not appear in output \a idsInInputListThatFetch.
6011 void DataArrayInt::findIdsRangesInListOfIds(const DataArrayInt *listOfIds, DataArrayInt *& rangeIdsFetched, DataArrayInt *& idsInInputListThatFetch) const
6014 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : input list of ids is null !");
6015 listOfIds->checkAllocated(); checkAllocated();
6016 if(listOfIds->getNumberOfComponents()!=1)
6017 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : input list of ids must have exactly one component !");
6018 if(getNumberOfComponents()!=1)
6019 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : this must have exactly one component !");
6020 MCAuto<DataArrayInt> ret0=DataArrayInt::New(); ret0->alloc(0,1);
6021 MCAuto<DataArrayInt> ret1=DataArrayInt::New(); ret1->alloc(0,1);
6022 const int *tupEnd(listOfIds->end()),*offBg(begin()),*offEnd(end()-1);
6023 const int *tupPtr(listOfIds->begin()),*offPtr(offBg);
6024 while(tupPtr!=tupEnd && offPtr!=offEnd)
6026 if(*tupPtr==*offPtr)
6029 while(i<offPtr[1] && *tupPtr==i && tupPtr!=tupEnd) { i++; tupPtr++; }
6032 ret0->pushBackSilent((int)std::distance(offBg,offPtr));
6033 ret1->pushBackValsSilent(tupPtr-(offPtr[1]-offPtr[0]),tupPtr);
6038 { if(*tupPtr<*offPtr) tupPtr++; else offPtr++; }
6040 rangeIdsFetched=ret0.retn();
6041 idsInInputListThatFetch=ret1.retn();
6045 * Returns a new DataArrayInt whose contents is computed from that of \a this and \a
6046 * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
6047 * "index" array of a "iota" array, thus, whose each element gives an index of a group
6048 * beginning within the "iota" array. And \a this is a one-dimensional array
6049 * considered as a selector of groups described by \a offsets to include into the result array.
6050 * \throw If \a offsets is NULL.
6051 * \throw If \a offsets is not allocated.
6052 * \throw If \a offsets->getNumberOfComponents() != 1.
6053 * \throw If \a offsets is not monotonically increasing.
6054 * \throw If \a this is not allocated.
6055 * \throw If \a this->getNumberOfComponents() != 1.
6056 * \throw If any element of \a this is not a valid index for \a offsets array.
6059 * - \a this: [0,2,3]
6060 * - \a offsets: [0,3,6,10,14,20]
6061 * - result array: [0,1,2,6,7,8,9,10,11,12,13] == <br>
6062 * \c range(0,3) + \c range(6,10) + \c range(10,14) ==<br>
6063 * \c range( \a offsets[ \a this[0] ], offsets[ \a this[0]+1 ]) +
6064 * \c range( \a offsets[ \a this[1] ], offsets[ \a this[1]+1 ]) +
6065 * \c range( \a offsets[ \a this[2] ], offsets[ \a this[2]+1 ])
6067 DataArrayInt *DataArrayInt::buildExplicitArrByRanges(const DataArrayInt *offsets) const
6070 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : DataArrayInt pointer in input is NULL !");
6072 if(getNumberOfComponents()!=1)
6073 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : only single component allowed !");
6074 offsets->checkAllocated();
6075 if(offsets->getNumberOfComponents()!=1)
6076 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : input array should have only single component !");
6077 int othNbTuples=offsets->getNumberOfTuples()-1;
6078 int nbOfTuples=getNumberOfTuples();
6079 int retNbOftuples=0;
6080 const int *work=getConstPointer();
6081 const int *offPtr=offsets->getConstPointer();
6082 for(int i=0;i<nbOfTuples;i++)
6085 if(val>=0 && val<othNbTuples)
6087 int delta=offPtr[val+1]-offPtr[val];
6089 retNbOftuples+=delta;
6092 std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << val << " of offset array has a delta < 0 !";
6093 throw INTERP_KERNEL::Exception(oss.str().c_str());
6098 std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << i << " in this contains " << val;
6099 oss << " whereas offsets array is of size " << othNbTuples+1 << " !";
6100 throw INTERP_KERNEL::Exception(oss.str().c_str());
6103 MCAuto<DataArrayInt> ret=DataArrayInt::New();
6104 ret->alloc(retNbOftuples,1);
6105 int *retPtr=ret->getPointer();
6106 for(int i=0;i<nbOfTuples;i++)
6109 int start=offPtr[val];
6110 int off=offPtr[val+1]-start;
6111 for(int j=0;j<off;j++,retPtr++)
6118 * Returns a new DataArrayInt whose contents is computed using \a this that must be a
6119 * scaled array (monotonically increasing).
6120 from that of \a this and \a
6121 * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
6122 * "index" array of a "iota" array, thus, whose each element gives an index of a group
6123 * beginning within the "iota" array. And \a this is a one-dimensional array
6124 * considered as a selector of groups described by \a offsets to include into the result array.
6125 * \throw If \a is NULL.
6126 * \throw If \a this is not allocated.
6127 * \throw If \a this->getNumberOfComponents() != 1.
6128 * \throw If \a this->getNumberOfTuples() == 0.
6129 * \throw If \a this is not monotonically increasing.
6130 * \throw If any element of ids in ( \a bg \a stop \a step ) points outside the scale in \a this.
6133 * - \a bg , \a stop and \a step : (0,5,2)
6134 * - \a this: [0,3,6,10,14,20]
6135 * - result array: [0,0,0, 2,2,2,2, 4,4,4,4,4,4] == <br>
6137 DataArrayInt *DataArrayInt::buildExplicitArrOfSliceOnScaledArr(int bg, int stop, int step) const
6140 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : not allocated array !");
6141 if(getNumberOfComponents()!=1)
6142 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of components is expected to be equal to one !");
6143 int nbOfTuples(getNumberOfTuples());
6145 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of tuples must be != 0 !");
6146 const int *ids(begin());
6147 int nbOfEltsInSlc(GetNumberOfItemGivenBESRelative(bg,stop,step,"DataArrayInt::buildExplicitArrOfSliceOnScaledArr")),sz(0),pos(bg);
6148 for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
6150 if(pos>=0 && pos<nbOfTuples-1)
6152 int delta(ids[pos+1]-ids[pos]);
6156 std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " and at this pos this is not monotonically increasing !";
6157 throw INTERP_KERNEL::Exception(oss.str().c_str());
6162 std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " should be in [0," << nbOfTuples-1 << ") !";
6163 throw INTERP_KERNEL::Exception(oss.str().c_str());
6166 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
6167 int *retPtr(ret->getPointer());
6169 for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
6171 int delta(ids[pos+1]-ids[pos]);
6172 for(int j=0;j<delta;j++,retPtr++)
6179 * 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.
6180 * 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
6181 * in tuple **i** of returned DataArrayInt.
6182 * If ranges overlapped (in theory it should not) this method do not detect it and always returns the first range.
6184 * 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)]
6185 * The return DataArrayInt will contain : **[0,4,1,2,2,3]**
6187 * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
6188 * for lower value included and 2nd component is the upper value of corresponding range **excluded**.
6189 * \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
6190 * is thrown if no ranges in \a ranges contains value in \a this.
6192 * \sa DataArrayInt::findIdInRangeForEachTuple
6194 DataArrayInt *DataArrayInt::findRangeIdForEachTuple(const DataArrayInt *ranges) const
6197 throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : null input pointer !");
6198 if(ranges->getNumberOfComponents()!=2)
6199 throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : input DataArrayInt instance should have 2 components !");
6201 if(getNumberOfComponents()!=1)
6202 throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : this should have only one component !");
6203 int nbTuples=getNumberOfTuples();
6204 MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
6205 int nbOfRanges=ranges->getNumberOfTuples();
6206 const int *rangesPtr=ranges->getConstPointer();
6207 int *retPtr=ret->getPointer();
6208 const int *inPtr=getConstPointer();
6209 for(int i=0;i<nbTuples;i++,retPtr++)
6213 for(int j=0;j<nbOfRanges && !found;j++)
6214 if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
6215 { *retPtr=j; found=true; }
6220 std::ostringstream oss; oss << "DataArrayInt::findRangeIdForEachTuple : tuple #" << i << " not found by any ranges !";
6221 throw INTERP_KERNEL::Exception(oss.str().c_str());
6228 * 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.
6229 * 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
6230 * in tuple **i** of returned DataArrayInt.
6231 * If ranges overlapped (in theory it should not) this method do not detect it and always returns the sub position of the first range.
6233 * 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)]
6234 * The return DataArrayInt will contain : **[1,2,4,0,2,2]**
6235 * This method is often called in pair with DataArrayInt::findRangeIdForEachTuple method.
6237 * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
6238 * for lower value included and 2nd component is the upper value of corresponding range **excluded**.
6239 * \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
6240 * is thrown if no ranges in \a ranges contains value in \a this.
6241 * \sa DataArrayInt::findRangeIdForEachTuple
6243 DataArrayInt *DataArrayInt::findIdInRangeForEachTuple(const DataArrayInt *ranges) const
6246 throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : null input pointer !");
6247 if(ranges->getNumberOfComponents()!=2)
6248 throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : input DataArrayInt instance should have 2 components !");
6250 if(getNumberOfComponents()!=1)
6251 throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : this should have only one component !");
6252 int nbTuples=getNumberOfTuples();
6253 MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
6254 int nbOfRanges=ranges->getNumberOfTuples();
6255 const int *rangesPtr=ranges->getConstPointer();
6256 int *retPtr=ret->getPointer();
6257 const int *inPtr=getConstPointer();
6258 for(int i=0;i<nbTuples;i++,retPtr++)
6262 for(int j=0;j<nbOfRanges && !found;j++)
6263 if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
6264 { *retPtr=val-rangesPtr[2*j]; found=true; }
6269 std::ostringstream oss; oss << "DataArrayInt::findIdInRangeForEachTuple : tuple #" << i << " not found by any ranges !";
6270 throw INTERP_KERNEL::Exception(oss.str().c_str());
6277 * \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).
6278 * 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).
6279 * 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 !
6280 * If this method has correctly worked, \a this will be able to be considered as a linked list.
6281 * This method does nothing if number of tuples is lower of equal to 1.
6283 * This method is useful for users having an unstructured mesh having only SEG2 to rearrange internally the connectibity without any coordinates consideration.
6285 * \sa MEDCouplingUMesh::orderConsecutiveCells1D, DataArrayInt::fromLinkedListOfPairToList
6287 void DataArrayInt::sortEachPairToMakeALinkedList()
6290 if(getNumberOfComponents()!=2)
6291 throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : Only works on DataArrayInt instance with nb of components equal to 2 !");
6292 int nbOfTuples(getNumberOfTuples());
6295 int *conn(getPointer());
6296 for(int i=1;i<nbOfTuples;i++,conn+=2)
6300 if(conn[2]==conn[3])
6302 std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " presence of a pair filled with same ids !";
6303 throw INTERP_KERNEL::Exception(oss.str().c_str());
6305 if(conn[2]!=conn[1] && conn[3]==conn[1] && conn[2]!=conn[0])
6306 std::swap(conn[2],conn[3]);
6307 //not(conn[2]==conn[1] && conn[3]!=conn[1] && conn[3]!=conn[0])
6308 if(conn[2]!=conn[1] || conn[3]==conn[1] || conn[3]==conn[0])
6310 std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " something is invalid !";
6311 throw INTERP_KERNEL::Exception(oss.str().c_str());
6316 if(conn[0]==conn[1] || conn[2]==conn[3])
6317 throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : In the 2 first tuples presence of a pair filled with same ids !");
6320 s.insert(conn,conn+4);
6322 throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : This can't be considered as a linked list regarding 2 first tuples !");
6323 if(std::count(conn,conn+4,conn[0])==2)
6328 if(conn[2]==conn[0])
6332 std::copy(tmp,tmp+4,conn);
6335 {//here we are sure to have (std::count(conn,conn+4,conn[1])==2)
6336 if(conn[1]==conn[3])
6337 std::swap(conn[2],conn[3]);
6344 * \a this is expected to be a correctly linked list of pairs.
6346 * \sa DataArrayInt::sortEachPairToMakeALinkedList
6348 MCAuto<DataArrayInt> DataArrayInt::fromLinkedListOfPairToList() const
6351 checkNbOfComps(2,"DataArrayInt::fromLinkedListOfPairToList : this is expected to have 2 components");
6352 int nbTuples(getNumberOfTuples());
6354 throw INTERP_KERNEL::Exception("DataArrayInt::fromLinkedListOfPairToList : no tuples in this ! Not a linked list !");
6355 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbTuples+1,1);
6356 const int *thisPtr(begin());
6357 int *retPtr(ret->getPointer());
6358 retPtr[0]=thisPtr[0];
6359 for(int i=0;i<nbTuples;i++)
6361 retPtr[i+1]=thisPtr[2*i+1];
6363 if(thisPtr[2*i+1]!=thisPtr[2*(i+1)+0])
6365 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 ?";
6366 throw INTERP_KERNEL::Exception(oss.str());
6373 * This method returns all different values found in \a this. This method throws if \a this has not been allocated.
6374 * But the number of components can be different from one.
6375 * \return a newly allocated array (that should be dealt by the caller) containing different values in \a this.
6377 DataArrayInt *DataArrayInt::getDifferentValues() const
6381 ret.insert(begin(),end());
6382 MCAuto<DataArrayInt> ret2=DataArrayInt::New(); ret2->alloc((int)ret.size(),1);
6383 std::copy(ret.begin(),ret.end(),ret2->getPointer());
6388 * This method is a refinement of DataArrayInt::getDifferentValues because it returns not only different values in \a this but also, for each of
6389 * them it tells which tuple id have this id.
6390 * This method works only on arrays with one component (if it is not the case call DataArrayInt::rearrange(1) ).
6391 * This method returns two arrays having same size.
6392 * 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.
6393 * 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]]
6395 std::vector<DataArrayInt *> DataArrayInt::partitionByDifferentValues(std::vector<int>& differentIds) const
6398 if(getNumberOfComponents()!=1)
6399 throw INTERP_KERNEL::Exception("DataArrayInt::partitionByDifferentValues : this should have only one component !");
6401 std::map<int,int> m,m2,m3;
6402 for(const int *w=begin();w!=end();w++)
6404 differentIds.resize(m.size());
6405 std::vector<DataArrayInt *> ret(m.size());
6406 std::vector<int *> retPtr(m.size());
6407 for(std::map<int,int>::const_iterator it=m.begin();it!=m.end();it++,id++)
6410 ret[id]=DataArrayInt::New();
6411 ret[id]->alloc((*it).second,1);
6412 retPtr[id]=ret[id]->getPointer();
6413 differentIds[id]=(*it).first;
6416 for(const int *w=begin();w!=end();w++,id++)
6418 retPtr[m2[*w]][m3[*w]++]=id;
6424 * This method split ids in [0, \c this->getNumberOfTuples() ) using \a this array as a field of weight (>=0 each).
6425 * The aim of this method is to return a set of \a nbOfSlices chunk of contiguous ids as balanced as possible.
6427 * \param [in] nbOfSlices - number of slices expected.
6428 * \return - a vector having a size equal to \a nbOfSlices giving the start (included) and the stop (excluded) of each chunks.
6430 * \sa DataArray::GetSlice
6431 * \throw If \a this is not allocated or not with exactly one component.
6432 * \throw If an element in \a this if < 0.
6434 std::vector< std::pair<int,int> > DataArrayInt::splitInBalancedSlices(int nbOfSlices) const
6436 if(!isAllocated() || getNumberOfComponents()!=1)
6437 throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : this array should have number of components equal to one and must be allocated !");
6439 throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : number of slices must be >= 1 !");
6440 int sum(accumulate(0)),nbOfTuples(getNumberOfTuples());
6441 int sumPerSlc(sum/nbOfSlices),pos(0);
6442 const int *w(begin());
6443 std::vector< std::pair<int,int> > ret(nbOfSlices);
6444 for(int i=0;i<nbOfSlices;i++)
6446 std::pair<int,int> p(pos,-1);
6448 while(locSum<sumPerSlc && pos<nbOfTuples) { pos++; locSum+=*w++; }
6452 p.second=nbOfTuples;
6459 * Returns a new DataArrayInt that is a modulus of two given arrays. There are 3
6461 * 1. The arrays have same number of tuples and components. Then each value of
6462 * the result array (_a_) is a division of the corresponding values of \a a1 and
6463 * \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, j ].
6464 * 2. The arrays have same number of tuples and one array, say _a2_, has one
6466 * _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, 0 ].
6467 * 3. The arrays have same number of components and one array, say _a2_, has one
6469 * _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ 0, j ].
6471 * Info on components is copied either from the first array (in the first case) or from
6472 * the array with maximal number of elements (getNbOfElems()).
6473 * \warning No check of division by zero is performed!
6474 * \param [in] a1 - a dividend array.
6475 * \param [in] a2 - a divisor array.
6476 * \return DataArrayInt * - the new instance of DataArrayInt.
6477 * The caller is to delete this result array using decrRef() as it is no more
6479 * \throw If either \a a1 or \a a2 is NULL.
6480 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
6481 * \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
6482 * none of them has number of tuples or components equal to 1.
6484 DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt *a2)
6487 throw INTERP_KERNEL::Exception("DataArrayInt::Modulus : input DataArrayInt instance is NULL !");
6488 int nbOfTuple1=a1->getNumberOfTuples();
6489 int nbOfTuple2=a2->getNumberOfTuples();
6490 int nbOfComp1=a1->getNumberOfComponents();
6491 int nbOfComp2=a2->getNumberOfComponents();
6492 if(nbOfTuple2==nbOfTuple1)
6494 if(nbOfComp1==nbOfComp2)
6496 MCAuto<DataArrayInt> ret=DataArrayInt::New();
6497 ret->alloc(nbOfTuple2,nbOfComp1);
6498 std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::modulus<int>());
6499 ret->copyStringInfoFrom(*a1);
6502 else if(nbOfComp2==1)
6504 MCAuto<DataArrayInt> ret=DataArrayInt::New();
6505 ret->alloc(nbOfTuple1,nbOfComp1);
6506 const int *a2Ptr=a2->getConstPointer();
6507 const int *a1Ptr=a1->getConstPointer();
6508 int *res=ret->getPointer();
6509 for(int i=0;i<nbOfTuple1;i++)
6510 res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::modulus<int>(),a2Ptr[i]));
6511 ret->copyStringInfoFrom(*a1);
6516 a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
6520 else if(nbOfTuple2==1)
6522 a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
6523 MCAuto<DataArrayInt> ret=DataArrayInt::New();
6524 ret->alloc(nbOfTuple1,nbOfComp1);
6525 const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
6526 int *pt=ret->getPointer();
6527 for(int i=0;i<nbOfTuple1;i++)
6528 pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::modulus<int>());
6529 ret->copyStringInfoFrom(*a1);
6534 a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Modulus !");//will always throw an exception
6540 * Modify \a this array so that each value becomes a modulus of division of this value by
6541 * a value of another DataArrayInt. There are 3 valid cases.
6542 * 1. The arrays have same number of tuples and components. Then each value of
6543 * \a this array is divided by the corresponding value of \a other one, i.e.:
6544 * _a_ [ i, j ] %= _other_ [ i, j ].
6545 * 2. The arrays have same number of tuples and \a other array has one component. Then
6546 * _a_ [ i, j ] %= _other_ [ i, 0 ].
6547 * 3. The arrays have same number of components and \a other array has one tuple. Then
6548 * _a_ [ i, j ] %= _a2_ [ 0, j ].
6550 * \warning No check of division by zero is performed!
6551 * \param [in] other - a divisor array.
6552 * \throw If \a other is NULL.
6553 * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
6554 * \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
6555 * \a other has number of both tuples and components not equal to 1.
6557 void DataArrayInt::modulusEqual(const DataArrayInt *other)
6560 throw INTERP_KERNEL::Exception("DataArrayInt::modulusEqual : input DataArrayInt instance is NULL !");
6561 const char *msg="Nb of tuples mismatch for DataArrayInt::modulusEqual !";
6562 checkAllocated(); other->checkAllocated();
6563 int nbOfTuple=getNumberOfTuples();
6564 int nbOfTuple2=other->getNumberOfTuples();
6565 int nbOfComp=getNumberOfComponents();
6566 int nbOfComp2=other->getNumberOfComponents();
6567 if(nbOfTuple==nbOfTuple2)
6569 if(nbOfComp==nbOfComp2)
6571 std::transform(begin(),end(),other->begin(),getPointer(),std::modulus<int>());
6573 else if(nbOfComp2==1)
6575 if(nbOfComp2==nbOfComp)
6577 int *ptr=getPointer();
6578 const int *ptrc=other->getConstPointer();
6579 for(int i=0;i<nbOfTuple;i++)
6580 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::modulus<int>(),*ptrc++));
6583 throw INTERP_KERNEL::Exception(msg);
6586 throw INTERP_KERNEL::Exception(msg);
6588 else if(nbOfTuple2==1)
6590 int *ptr=getPointer();
6591 const int *ptrc=other->getConstPointer();
6592 for(int i=0;i<nbOfTuple;i++)
6593 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::modulus<int>());
6596 throw INTERP_KERNEL::Exception(msg);
6601 * Returns a new DataArrayInt that is the result of pow of two given arrays. There are 3
6604 * \param [in] a1 - an array to pow up.
6605 * \param [in] a2 - another array to sum up.
6606 * \return DataArrayInt * - the new instance of DataArrayInt.
6607 * The caller is to delete this result array using decrRef() as it is no more
6609 * \throw If either \a a1 or \a a2 is NULL.
6610 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
6611 * \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
6612 * \throw If there is a negative value in \a a2.
6614 DataArrayInt *DataArrayInt::Pow(const DataArrayInt *a1, const DataArrayInt *a2)
6617 throw INTERP_KERNEL::Exception("DataArrayInt::Pow : at least one of input instances is null !");
6618 int nbOfTuple=a1->getNumberOfTuples();
6619 int nbOfTuple2=a2->getNumberOfTuples();
6620 int nbOfComp=a1->getNumberOfComponents();
6621 int nbOfComp2=a2->getNumberOfComponents();
6622 if(nbOfTuple!=nbOfTuple2)
6623 throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of tuples mismatches !");
6624 if(nbOfComp!=1 || nbOfComp2!=1)
6625 throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of components of both arrays must be equal to 1 !");
6626 MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuple,1);
6627 const int *ptr1(a1->begin()),*ptr2(a2->begin());
6628 int *ptr=ret->getPointer();
6629 for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
6634 for(int j=0;j<*ptr2;j++)
6640 std::ostringstream oss; oss << "DataArrayInt::Pow : on tuple #" << i << " of a2 value is < 0 (" << *ptr2 << ") !";
6641 throw INTERP_KERNEL::Exception(oss.str().c_str());
6648 * Apply pow on values of another DataArrayInt to values of \a this one.
6650 * \param [in] other - an array to pow to \a this one.
6651 * \throw If \a other is NULL.
6652 * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
6653 * \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
6654 * \throw If there is a negative value in \a other.
6656 void DataArrayInt::powEqual(const DataArrayInt *other)
6659 throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : input instance is null !");
6660 int nbOfTuple=getNumberOfTuples();
6661 int nbOfTuple2=other->getNumberOfTuples();
6662 int nbOfComp=getNumberOfComponents();
6663 int nbOfComp2=other->getNumberOfComponents();
6664 if(nbOfTuple!=nbOfTuple2)
6665 throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of tuples mismatches !");
6666 if(nbOfComp!=1 || nbOfComp2!=1)
6667 throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of components of both arrays must be equal to 1 !");
6668 int *ptr=getPointer();
6669 const int *ptrc=other->begin();
6670 for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
6675 for(int j=0;j<*ptrc;j++)
6681 std::ostringstream oss; oss << "DataArrayInt::powEqual : on tuple #" << i << " of other value is < 0 (" << *ptrc << ") !";
6682 throw INTERP_KERNEL::Exception(oss.str().c_str());
6689 * Returns a C array which is a renumbering map in "Old to New" mode for the input array.
6690 * This map, if applied to \a start array, would make it sorted. For example, if
6691 * \a start array contents are [9,10,0,6,4,11,3,7] then the contents of the result array is
6692 * [5,6,0,3,2,7,1,4].
6693 * \param [in] start - pointer to the first element of the array for which the
6694 * permutation map is computed.
6695 * \param [in] end - pointer specifying the end of the array \a start, so that
6696 * the last value of \a start is \a end[ -1 ].
6697 * \return int * - the result permutation array that the caller is to delete as it is no
6699 * \throw If there are equal values in the input array.
6701 int *DataArrayInt::CheckAndPreparePermutation(const int *start, const int *end)
6703 std::size_t sz=std::distance(start,end);
6704 int *ret=(int *)malloc(sz*sizeof(int));
6705 int *work=new int[sz];
6706 std::copy(start,end,work);
6707 std::sort(work,work+sz);
6708 if(std::unique(work,work+sz)!=work+sz)
6712 throw INTERP_KERNEL::Exception("Some elements are equals in the specified array !");
6714 std::map<int,int> m;
6715 for(int *workPt=work;workPt!=work+sz;workPt++)
6716 m[*workPt]=(int)std::distance(work,workPt);
6718 for(const int *iter=start;iter!=end;iter++,iter2++)
6725 * Returns a new DataArrayInt containing an arithmetic progression
6726 * that is equal to the sequence returned by Python \c range(\a begin,\a end,\a step )
6728 * \param [in] begin - the start value of the result sequence.
6729 * \param [in] end - limiting value, so that every value of the result array is less than
6731 * \param [in] step - specifies the increment or decrement.
6732 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6733 * array using decrRef() as it is no more needed.
6734 * \throw If \a step == 0.
6735 * \throw If \a end < \a begin && \a step > 0.
6736 * \throw If \a end > \a begin && \a step < 0.
6738 DataArrayInt *DataArrayInt::Range(int begin, int end, int step)
6740 int nbOfTuples=GetNumberOfItemGivenBESRelative(begin,end,step,"DataArrayInt::Range");
6741 MCAuto<DataArrayInt> ret=DataArrayInt::New();
6742 ret->alloc(nbOfTuples,1);
6743 int *ptr=ret->getPointer();
6746 for(int i=begin;i<end;i+=step,ptr++)
6751 for(int i=begin;i>end;i+=step,ptr++)
6758 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
6761 void DataArrayInt::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
6766 tinyInfo[0]=getNumberOfTuples();
6767 tinyInfo[1]=getNumberOfComponents();
6777 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
6780 void DataArrayInt::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
6784 int nbOfCompo=getNumberOfComponents();
6785 tinyInfo.resize(nbOfCompo+1);
6786 tinyInfo[0]=getName();
6787 for(int i=0;i<nbOfCompo;i++)
6788 tinyInfo[i+1]=getInfoOnComponent(i);
6793 tinyInfo[0]=getName();
6798 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
6799 * This method returns if a feeding is needed.
6801 bool DataArrayInt::resizeForUnserialization(const std::vector<int>& tinyInfoI)
6803 int nbOfTuple=tinyInfoI[0];
6804 int nbOfComp=tinyInfoI[1];
6805 if(nbOfTuple!=-1 || nbOfComp!=-1)
6807 alloc(nbOfTuple,nbOfComp);
6814 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
6815 * This method returns if a feeding is needed.
6817 void DataArrayInt::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
6819 setName(tinyInfoS[0]);
6822 int nbOfCompo=tinyInfoI[1];
6823 for(int i=0;i<nbOfCompo;i++)
6824 setInfoOnComponent(i,tinyInfoS[i+1]);
6828 DataArrayIntIterator::DataArrayIntIterator(DataArrayInt *da):DataArrayIterator<int>(da)
6832 DataArrayInt32Tuple::DataArrayInt32Tuple(int *pt, int nbOfComp):DataArrayTuple<int>(pt,nbOfComp)
6836 std::string DataArrayIntTuple::repr() const
6838 std::ostringstream oss; oss << "(";
6839 for(int i=0;i<_nb_of_compo-1;i++)
6840 oss << _pt[i] << ", ";
6841 oss << _pt[_nb_of_compo-1] << ")";
6845 int DataArrayIntTuple::intValue() const
6847 return this->zeValue();
6851 * This method returns a newly allocated instance the caller should dealed with by a MEDCoupling::DataArrayInt::decrRef.
6852 * This method performs \b no copy of data. The content is only referenced using MEDCoupling::DataArrayInt::useArray with ownership set to \b false.
6853 * 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
6854 * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
6856 DataArrayInt *DataArrayIntTuple::buildDAInt(int nbOfTuples, int nbOfCompo) const
6858 return this->buildDA(nbOfTuples,nbOfCompo);