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 (CEA/DEN)
21 #include "MEDCouplingMemArray.txx"
24 #include "GenMathFormulae.hxx"
25 #include "InterpKernelAutoPtr.hxx"
26 #include "InterpKernelExprParser.hxx"
35 typedef double (*MYFUNCPTR)(double);
37 using namespace MEDCoupling;
39 template class MEDCoupling::MemArray<int>;
40 template class MEDCoupling::MemArray<double>;
41 template class MEDCoupling::DataArrayTemplate<int>;
42 template class MEDCoupling::DataArrayTemplate<double>;
43 template class MEDCoupling::DataArrayTemplateClassic<int>;
44 template class MEDCoupling::DataArrayTemplateClassic<double>;
45 template class MEDCoupling::DataArrayTemplateFP<double>;
46 template class MEDCoupling::DataArrayIterator<double>;
47 template class MEDCoupling::DataArrayIterator<int>;
49 template<int SPACEDIM>
50 void DataArrayDouble::findCommonTuplesAlg(const double *bbox, int nbNodes, int limitNodeId, double prec, DataArrayInt *c, DataArrayInt *cI) const
52 const double *coordsPtr=getConstPointer();
53 BBTreePts<SPACEDIM,int> myTree(bbox,0,0,nbNodes,prec);
54 std::vector<bool> isDone(nbNodes);
55 for(int i=0;i<nbNodes;i++)
59 std::vector<int> intersectingElems;
60 myTree.getElementsAroundPoint(coordsPtr+i*SPACEDIM,intersectingElems);
61 if(intersectingElems.size()>1)
63 std::vector<int> commonNodes;
64 for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
68 commonNodes.push_back(*it);
71 if(!commonNodes.empty())
73 cI->pushBackSilent(cI->back()+(int)commonNodes.size()+1);
75 c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
82 template<int SPACEDIM>
83 void DataArrayDouble::FindTupleIdsNearTuplesAlg(const BBTreePts<SPACEDIM,int>& myTree, const double *pos, int nbOfTuples, double eps,
84 DataArrayInt *c, DataArrayInt *cI)
86 for(int i=0;i<nbOfTuples;i++)
88 std::vector<int> intersectingElems;
89 myTree.getElementsAroundPoint(pos+i*SPACEDIM,intersectingElems);
90 std::vector<int> commonNodes;
91 for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
92 commonNodes.push_back(*it);
93 cI->pushBackSilent(cI->back()+(int)commonNodes.size());
94 c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
98 template<int SPACEDIM>
99 void DataArrayDouble::FindClosestTupleIdAlg(const BBTreePts<SPACEDIM,int>& myTree, double dist, const double *pos, int nbOfTuples, const double *thisPt, int thisNbOfTuples, int *res)
101 double distOpt(dist);
102 const double *p(pos);
104 for(int i=0;i<nbOfTuples;i++,p+=SPACEDIM,r++)
109 double ret=myTree.getElementsAroundPoint2(p,distOpt,elem);
110 if(ret!=std::numeric_limits<double>::max())
112 distOpt=std::max(ret,1e-4);
117 { distOpt=2*distOpt; continue; }
122 int DataArray::EffectiveCircPerm(int nbOfShift, int nbOfTuples)
125 throw INTERP_KERNEL::Exception("DataArray::EffectiveCircPerm : number of tuples is expected to be > 0 !");
128 return nbOfShift%nbOfTuples;
134 return nbOfTuples-tmp;
138 std::size_t DataArray::getHeapMemorySizeWithoutChildren() const
140 std::size_t sz1=_name.capacity();
141 std::size_t sz2=_info_on_compo.capacity();
143 for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
144 sz3+=(*it).capacity();
148 std::vector<const BigMemoryObject *> DataArray::getDirectChildrenWithNull() const
150 return std::vector<const BigMemoryObject *>();
154 * Sets the attribute \a _name of \a this array.
155 * See \ref MEDCouplingArrayBasicsName "DataArrays infos" for more information.
156 * \param [in] name - new array name
158 void DataArray::setName(const std::string& name)
164 * Copies textual data from an \a other DataArray. The copied data are
165 * - the name attribute,
166 * - the information of components.
168 * For more information on these data see \ref MEDCouplingArrayBasicsName "DataArrays infos".
170 * \param [in] other - another instance of DataArray to copy the textual data from.
171 * \throw If number of components of \a this array differs from that of the \a other.
173 void DataArray::copyStringInfoFrom(const DataArray& other)
175 if(_info_on_compo.size()!=other._info_on_compo.size())
176 throw INTERP_KERNEL::Exception("Size of arrays mismatches on copyStringInfoFrom !");
178 _info_on_compo=other._info_on_compo;
181 void DataArray::copyPartOfStringInfoFrom(const DataArray& other, const std::vector<int>& compoIds)
183 int nbOfCompoOth=other.getNumberOfComponents();
184 std::size_t newNbOfCompo=compoIds.size();
185 for(std::size_t i=0;i<newNbOfCompo;i++)
186 if(compoIds[i]>=nbOfCompoOth || compoIds[i]<0)
188 std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompoOth << ")";
189 throw INTERP_KERNEL::Exception(oss.str().c_str());
191 for(std::size_t i=0;i<newNbOfCompo;i++)
192 setInfoOnComponent((int)i,other.getInfoOnComponent(compoIds[i]));
195 void DataArray::copyPartOfStringInfoFrom2(const std::vector<int>& compoIds, const DataArray& other)
197 int nbOfCompo=getNumberOfComponents();
198 std::size_t partOfCompoToSet=compoIds.size();
199 if((int)partOfCompoToSet!=other.getNumberOfComponents())
200 throw INTERP_KERNEL::Exception("Given compoIds has not the same size as number of components of given array !");
201 for(std::size_t i=0;i<partOfCompoToSet;i++)
202 if(compoIds[i]>=nbOfCompo || compoIds[i]<0)
204 std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompo << ")";
205 throw INTERP_KERNEL::Exception(oss.str().c_str());
207 for(std::size_t i=0;i<partOfCompoToSet;i++)
208 setInfoOnComponent(compoIds[i],other.getInfoOnComponent((int)i));
211 bool DataArray::areInfoEqualsIfNotWhy(const DataArray& other, std::string& reason) const
213 std::ostringstream oss;
214 if(_name!=other._name)
216 oss << "Names DataArray mismatch : this name=\"" << _name << " other name=\"" << other._name << "\" !";
220 if(_info_on_compo!=other._info_on_compo)
222 oss << "Components DataArray mismatch : \nThis components=";
223 for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
224 oss << "\"" << *it << "\",";
225 oss << "\nOther components=";
226 for(std::vector<std::string>::const_iterator it=other._info_on_compo.begin();it!=other._info_on_compo.end();it++)
227 oss << "\"" << *it << "\",";
235 * Compares textual information of \a this DataArray with that of an \a other one.
236 * The compared data are
237 * - the name attribute,
238 * - the information of components.
240 * For more information on these data see \ref MEDCouplingArrayBasicsName "DataArrays infos".
241 * \param [in] other - another instance of DataArray to compare the textual data of.
242 * \return bool - \a true if the textual information is same, \a false else.
244 bool DataArray::areInfoEquals(const DataArray& other) const
247 return areInfoEqualsIfNotWhy(other,tmp);
250 void DataArray::reprWithoutNameStream(std::ostream& stream) const
252 stream << "Number of components : "<< getNumberOfComponents() << "\n";
253 stream << "Info of these components : ";
254 for(std::vector<std::string>::const_iterator iter=_info_on_compo.begin();iter!=_info_on_compo.end();iter++)
255 stream << "\"" << *iter << "\" ";
259 std::string DataArray::cppRepr(const std::string& varName) const
261 std::ostringstream ret;
262 reprCppStream(varName,ret);
267 * Sets information on all components. To know more on format of this information
268 * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
269 * \param [in] info - a vector of strings.
270 * \throw If size of \a info differs from the number of components of \a this.
272 void DataArray::setInfoOnComponents(const std::vector<std::string>& info)
274 if(getNumberOfComponents()!=(int)info.size())
276 std::ostringstream oss; oss << "DataArray::setInfoOnComponents : input is of size " << info.size() << " whereas number of components is equal to " << getNumberOfComponents() << " !";
277 throw INTERP_KERNEL::Exception(oss.str().c_str());
283 * This method is only a dispatcher towards DataArrayDouble::setPartOfValues3, DataArrayInt::setPartOfValues3, DataArrayChar::setPartOfValues3 depending on the true
284 * type of \a this and \a aBase.
286 * \throw If \a aBase and \a this do not have the same type.
288 * \sa DataArrayDouble::setPartOfValues3, DataArrayInt::setPartOfValues3, DataArrayChar::setPartOfValues3.
290 void DataArray::setPartOfValuesBase3(const DataArray *aBase, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
293 throw INTERP_KERNEL::Exception("DataArray::setPartOfValuesBase3 : input aBase object is NULL !");
294 DataArrayDouble *this1(dynamic_cast<DataArrayDouble *>(this));
295 DataArrayInt *this2(dynamic_cast<DataArrayInt *>(this));
296 DataArrayChar *this3(dynamic_cast<DataArrayChar *>(this));
297 const DataArrayDouble *a1(dynamic_cast<const DataArrayDouble *>(aBase));
298 const DataArrayInt *a2(dynamic_cast<const DataArrayInt *>(aBase));
299 const DataArrayChar *a3(dynamic_cast<const DataArrayChar *>(aBase));
302 this1->setPartOfValues3(a1,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
307 this2->setPartOfValues3(a2,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
312 this3->setPartOfValues3(a3,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
315 throw INTERP_KERNEL::Exception("DataArray::setPartOfValuesBase3 : input aBase object and this do not have the same type !");
318 std::vector<std::string> DataArray::getVarsOnComponent() const
320 int nbOfCompo=(int)_info_on_compo.size();
321 std::vector<std::string> ret(nbOfCompo);
322 for(int i=0;i<nbOfCompo;i++)
323 ret[i]=getVarOnComponent(i);
327 std::vector<std::string> DataArray::getUnitsOnComponent() const
329 int nbOfCompo=(int)_info_on_compo.size();
330 std::vector<std::string> ret(nbOfCompo);
331 for(int i=0;i<nbOfCompo;i++)
332 ret[i]=getUnitOnComponent(i);
337 * Returns information on a component specified by an index.
338 * To know more on format of this information
339 * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
340 * \param [in] i - the index (zero based) of the component of interest.
341 * \return std::string - a string containing the information on \a i-th component.
342 * \throw If \a i is not a valid component index.
344 std::string DataArray::getInfoOnComponent(int i) const
346 if(i<(int)_info_on_compo.size() && i>=0)
347 return _info_on_compo[i];
350 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();
351 throw INTERP_KERNEL::Exception(oss.str().c_str());
356 * Returns the var part of the full information of the \a i-th component.
357 * For example, if \c getInfoOnComponent(0) returns "SIGXY [N/m^2]", then
358 * \c getVarOnComponent(0) returns "SIGXY".
359 * If a unit part of information is not detected by presence of
360 * two square brackets, then the full information is returned.
361 * To read more about the component information format, see
362 * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
363 * \param [in] i - the index (zero based) of the component of interest.
364 * \return std::string - a string containing the var information, or the full info.
365 * \throw If \a i is not a valid component index.
367 std::string DataArray::getVarOnComponent(int i) const
369 if(i<(int)_info_on_compo.size() && i>=0)
371 return GetVarNameFromInfo(_info_on_compo[i]);
375 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();
376 throw INTERP_KERNEL::Exception(oss.str().c_str());
381 * Returns the unit part of the full information of the \a i-th component.
382 * For example, if \c getInfoOnComponent(0) returns "SIGXY [ N/m^2]", then
383 * \c getUnitOnComponent(0) returns " N/m^2".
384 * If a unit part of information is not detected by presence of
385 * two square brackets, then an empty string is returned.
386 * To read more about the component information format, see
387 * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
388 * \param [in] i - the index (zero based) of the component of interest.
389 * \return std::string - a string containing the unit information, if any, or "".
390 * \throw If \a i is not a valid component index.
392 std::string DataArray::getUnitOnComponent(int i) const
394 if(i<(int)_info_on_compo.size() && i>=0)
396 return GetUnitFromInfo(_info_on_compo[i]);
400 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();
401 throw INTERP_KERNEL::Exception(oss.str().c_str());
406 * Returns the var part of the full component information.
407 * For example, if \a info == "SIGXY [N/m^2]", then this method returns "SIGXY".
408 * If a unit part of information is not detected by presence of
409 * two square brackets, then the whole \a info is returned.
410 * To read more about the component information format, see
411 * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
412 * \param [in] info - the full component information.
413 * \return std::string - a string containing only var information, or the \a info.
415 std::string DataArray::GetVarNameFromInfo(const std::string& info)
417 std::size_t p1=info.find_last_of('[');
418 std::size_t p2=info.find_last_of(']');
419 if(p1==std::string::npos || p2==std::string::npos)
424 return std::string();
425 std::size_t p3=info.find_last_not_of(' ',p1-1);
426 return info.substr(0,p3+1);
430 * Returns the unit part of the full component information.
431 * For example, if \a info == "SIGXY [ N/m^2]", then this method returns " N/m^2".
432 * If a unit part of information is not detected by presence of
433 * two square brackets, then an empty string is returned.
434 * To read more about the component information format, see
435 * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
436 * \param [in] info - the full component information.
437 * \return std::string - a string containing only unit information, if any, or "".
439 std::string DataArray::GetUnitFromInfo(const std::string& info)
441 std::size_t p1=info.find_last_of('[');
442 std::size_t p2=info.find_last_of(']');
443 if(p1==std::string::npos || p2==std::string::npos)
444 return std::string();
446 return std::string();
447 return info.substr(p1+1,p2-p1-1);
451 * This method put in info format the result of the merge of \a var and \a unit.
452 * The standard format for that is "var [unit]".
453 * Inversely you can retrieve the var part or the unit part of info string using resp. GetVarNameFromInfo and GetUnitFromInfo.
455 std::string DataArray::BuildInfoFromVarAndUnit(const std::string& var, const std::string& unit)
457 std::ostringstream oss;
458 oss << var << " [" << unit << "]";
462 std::string DataArray::GetAxisTypeRepr(MEDCouplingAxisType at)
467 return std::string("AX_CART");
469 return std::string("AX_CYL");
471 return std::string("AX_SPHER");
473 throw INTERP_KERNEL::Exception("DataArray::GetAxisTypeRepr : unrecognized axis type enum !");
478 * Returns a new DataArray by concatenating all given arrays, so that (1) the number
479 * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
480 * the number of component in the result array is same as that of each of given arrays.
481 * Info on components is copied from the first of the given arrays. Number of components
482 * in the given arrays must be the same.
483 * \param [in] arrs - a sequence of arrays to include in the result array. All arrays must have the same type.
484 * \return DataArray * - the new instance of DataArray (that can be either DataArrayInt, DataArrayDouble, DataArrayChar).
485 * The caller is to delete this result array using decrRef() as it is no more
487 * \throw If all arrays within \a arrs are NULL.
488 * \throw If all not null arrays in \a arrs have not the same type.
489 * \throw If getNumberOfComponents() of arrays within \a arrs.
491 DataArray *DataArray::Aggregate(const std::vector<const DataArray *>& arrs)
493 std::vector<const DataArray *> arr2;
494 for(std::vector<const DataArray *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
498 throw INTERP_KERNEL::Exception("DataArray::Aggregate : only null instance in input vector !");
499 std::vector<const DataArrayDouble *> arrd;
500 std::vector<const DataArrayInt *> arri;
501 std::vector<const DataArrayChar *> arrc;
502 for(std::vector<const DataArray *>::const_iterator it=arr2.begin();it!=arr2.end();it++)
504 const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(*it);
506 { arrd.push_back(a); continue; }
507 const DataArrayInt *b=dynamic_cast<const DataArrayInt *>(*it);
509 { arri.push_back(b); continue; }
510 const DataArrayChar *c=dynamic_cast<const DataArrayChar *>(*it);
512 { arrc.push_back(c); continue; }
513 throw INTERP_KERNEL::Exception("DataArray::Aggregate : presence of not null instance in inuput that is not in [DataArrayDouble, DataArrayInt, DataArrayChar] !");
515 if(arr2.size()==arrd.size())
516 return DataArrayDouble::Aggregate(arrd);
517 if(arr2.size()==arri.size())
518 return DataArrayInt::Aggregate(arri);
519 if(arr2.size()==arrc.size())
520 return DataArrayChar::Aggregate(arrc);
521 throw INTERP_KERNEL::Exception("DataArray::Aggregate : all input arrays must have the same type !");
525 * Sets information on a component specified by an index.
526 * To know more on format of this information
527 * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
528 * \warning Don't pass NULL as \a info!
529 * \param [in] i - the index (zero based) of the component of interest.
530 * \param [in] info - the string containing the information.
531 * \throw If \a i is not a valid component index.
533 void DataArray::setInfoOnComponent(int i, const std::string& info)
535 if(i<(int)_info_on_compo.size() && i>=0)
536 _info_on_compo[i]=info;
539 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();
540 throw INTERP_KERNEL::Exception(oss.str().c_str());
545 * Sets information on all components. This method can change number of components
546 * at certain conditions; if the conditions are not respected, an exception is thrown.
547 * The number of components can be changed in \a this only if \a this is not allocated.
548 * The condition of number of components must not be changed.
550 * To know more on format of the component information see
551 * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
552 * \param [in] info - a vector of component infos.
553 * \throw If \a this->getNumberOfComponents() != \a info.size() && \a this->isAllocated()
555 void DataArray::setInfoAndChangeNbOfCompo(const std::vector<std::string>& info)
557 if(getNumberOfComponents()!=(int)info.size())
563 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 !";
564 throw INTERP_KERNEL::Exception(oss.str().c_str());
571 void DataArray::checkNbOfTuples(int nbOfTuples, const std::string& msg) const
573 if(getNumberOfTuples()!=nbOfTuples)
575 std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " << nbOfTuples << " having " << getNumberOfTuples() << " !";
576 throw INTERP_KERNEL::Exception(oss.str().c_str());
580 void DataArray::checkNbOfComps(int nbOfCompo, const std::string& msg) const
582 if(getNumberOfComponents()!=nbOfCompo)
584 std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << nbOfCompo << " having " << getNumberOfComponents() << " !";
585 throw INTERP_KERNEL::Exception(oss.str().c_str());
589 void DataArray::checkNbOfElems(std::size_t nbOfElems, const std::string& msg) const
591 if(getNbOfElems()!=nbOfElems)
593 std::ostringstream oss; oss << msg << " : mismatch number of elems : Expected " << nbOfElems << " having " << getNbOfElems() << " !";
594 throw INTERP_KERNEL::Exception(oss.str().c_str());
598 void DataArray::checkNbOfTuplesAndComp(const DataArray& other, const std::string& msg) const
600 if(getNumberOfTuples()!=other.getNumberOfTuples())
602 std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " << other.getNumberOfTuples() << " having " << getNumberOfTuples() << " !";
603 throw INTERP_KERNEL::Exception(oss.str().c_str());
605 if(getNumberOfComponents()!=other.getNumberOfComponents())
607 std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << other.getNumberOfComponents() << " having " << getNumberOfComponents() << " !";
608 throw INTERP_KERNEL::Exception(oss.str().c_str());
612 void DataArray::checkNbOfTuplesAndComp(int nbOfTuples, int nbOfCompo, const std::string& msg) const
614 checkNbOfTuples(nbOfTuples,msg);
615 checkNbOfComps(nbOfCompo,msg);
619 * Simply this method checks that \b value is in [0,\b ref).
621 void DataArray::CheckValueInRange(int ref, int value, const std::string& msg)
623 if(value<0 || value>=ref)
625 std::ostringstream oss; oss << "DataArray::CheckValueInRange : " << msg << " ! Expected in range [0," << ref << "[ having " << value << " !";
626 throw INTERP_KERNEL::Exception(oss.str().c_str());
631 * This method checks that [\b start, \b end) is compliant with ref length \b value.
632 * typicaly start in [0,\b value) and end in [0,\b value). If value==start and start==end, it is supported.
634 void DataArray::CheckValueInRangeEx(int value, int start, int end, const std::string& msg)
636 if(start<0 || start>=value)
638 if(value!=start || end!=start)
640 std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg << " ! Expected start " << start << " of input range, in [0," << value << "[ !";
641 throw INTERP_KERNEL::Exception(oss.str().c_str());
644 if(end<0 || end>value)
646 std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg << " ! Expected end " << end << " of input range, in [0," << value << "] !";
647 throw INTERP_KERNEL::Exception(oss.str().c_str());
651 void DataArray::CheckClosingParInRange(int ref, int value, const std::string& msg)
653 if(value<0 || value>ref)
655 std::ostringstream oss; oss << "DataArray::CheckClosingParInRange : " << msg << " ! Expected input range in [0," << ref << "] having closing open parenthesis " << value << " !";
656 throw INTERP_KERNEL::Exception(oss.str().c_str());
661 * 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,
662 * typically it is a whole slice of tuples of DataArray or cells, nodes of a mesh...
664 * The input \a sliceId should be an id in [0, \a nbOfSlices) that specifies the slice of work.
666 * \param [in] start - the start of the input slice of the whole work to perform splitted into slices.
667 * \param [in] stop - the stop of the input slice of the whole work to perform splitted into slices.
668 * \param [in] step - the step (that can be <0) of the input slice of the whole work to perform splitted into slices.
669 * \param [in] sliceId - the slice id considered
670 * \param [in] nbOfSlices - the number of slices (typically the number of cores on which the work is expected to be sliced)
671 * \param [out] startSlice - the start of the slice considered
672 * \param [out] stopSlice - the stop of the slice consided
674 * \throw If \a step == 0
675 * \throw If \a nbOfSlices not > 0
676 * \throw If \a sliceId not in [0,nbOfSlices)
678 void DataArray::GetSlice(int start, int stop, int step, int sliceId, int nbOfSlices, int& startSlice, int& stopSlice)
682 std::ostringstream oss; oss << "DataArray::GetSlice : nbOfSlices (" << nbOfSlices << ") must be > 0 !";
683 throw INTERP_KERNEL::Exception(oss.str().c_str());
685 if(sliceId<0 || sliceId>=nbOfSlices)
687 std::ostringstream oss; oss << "DataArray::GetSlice : sliceId (" << nbOfSlices << ") must be in [0 , nbOfSlices (" << nbOfSlices << ") ) !";
688 throw INTERP_KERNEL::Exception(oss.str().c_str());
690 int nbElems=GetNumberOfItemGivenBESRelative(start,stop,step,"DataArray::GetSlice");
691 int minNbOfElemsPerSlice=nbElems/nbOfSlices;
692 startSlice=start+minNbOfElemsPerSlice*step*sliceId;
693 if(sliceId<nbOfSlices-1)
694 stopSlice=start+minNbOfElemsPerSlice*step*(sliceId+1);
699 int DataArray::GetNumberOfItemGivenBES(int begin, int end, int step, const std::string& msg)
703 std::ostringstream oss; oss << msg << " : end before begin !";
704 throw INTERP_KERNEL::Exception(oss.str().c_str());
710 std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
711 throw INTERP_KERNEL::Exception(oss.str().c_str());
713 return (end-1-begin)/step+1;
716 int DataArray::GetNumberOfItemGivenBESRelative(int begin, int end, int step, const std::string& msg)
719 throw INTERP_KERNEL::Exception("DataArray::GetNumberOfItemGivenBES : step=0 is not allowed !");
720 if(end<begin && step>0)
722 std::ostringstream oss; oss << msg << " : end before begin whereas step is positive !";
723 throw INTERP_KERNEL::Exception(oss.str().c_str());
725 if(begin<end && step<0)
727 std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
728 throw INTERP_KERNEL::Exception(oss.str().c_str());
731 return (std::max(begin,end)-1-std::min(begin,end))/std::abs(step)+1;
736 int DataArray::GetPosOfItemGivenBESRelativeNoThrow(int value, int begin, int end, int step)
742 if(begin<=value && value<end)
744 if((value-begin)%step==0)
745 return (value-begin)/step;
754 if(begin>=value && value>end)
756 if((begin-value)%(-step)==0)
757 return (begin-value)/(-step);
770 * Returns a new instance of DataArrayDouble. The caller is to delete this array
771 * using decrRef() as it is no more needed.
773 DataArrayDouble *DataArrayDouble::New()
775 return new DataArrayDouble;
779 * Returns the only one value in \a this, if and only if number of elements
780 * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
781 * \return double - the sole value stored in \a this array.
782 * \throw If at least one of conditions stated above is not fulfilled.
784 double DataArrayDouble::doubleValue() const
788 if(getNbOfElems()==1)
790 return *getConstPointer();
793 throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is allocated but number of elements is not equal to 1 !");
796 throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is not allocated !");
800 * Returns a full copy of \a this. For more info on copying data arrays see
801 * \ref MEDCouplingArrayBasicsCopyDeep.
802 * \return DataArrayDouble * - a new instance of DataArrayDouble. The caller is to
803 * delete this array using decrRef() as it is no more needed.
805 DataArrayDouble *DataArrayDouble::deepCopy() const
807 return new DataArrayDouble(*this);
811 * Assign zero to all values in \a this array. To know more on filling arrays see
812 * \ref MEDCouplingArrayFill.
813 * \throw If \a this is not allocated.
815 void DataArrayDouble::fillWithZero()
821 * Checks that \a this array is consistently **increasing** or **decreasing** in value,
822 * with at least absolute difference value of |\a eps| at each step.
823 * If not an exception is thrown.
824 * \param [in] increasing - if \a true, the array values should be increasing.
825 * \param [in] eps - minimal absolute difference between the neighbor values at which
826 * the values are considered different.
827 * \throw If sequence of values is not strictly monotonic in agreement with \a
829 * \throw If \a this->getNumberOfComponents() != 1.
830 * \throw If \a this is not allocated.
832 void DataArrayDouble::checkMonotonic(bool increasing, double eps) const
834 if(!isMonotonic(increasing,eps))
837 throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not INCREASING monotonic !");
839 throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not DECREASING monotonic !");
844 * Checks that \a this array is consistently **increasing** or **decreasing** in value,
845 * with at least absolute difference value of |\a eps| at each step.
846 * \param [in] increasing - if \a true, array values should be increasing.
847 * \param [in] eps - minimal absolute difference between the neighbor values at which
848 * the values are considered different.
849 * \return bool - \a true if values change in accordance with \a increasing arg.
850 * \throw If \a this->getNumberOfComponents() != 1.
851 * \throw If \a this is not allocated.
853 bool DataArrayDouble::isMonotonic(bool increasing, double eps) const
856 if(getNumberOfComponents()!=1)
857 throw INTERP_KERNEL::Exception("DataArrayDouble::isMonotonic : only supported with 'this' array with ONE component !");
858 int nbOfElements=getNumberOfTuples();
859 const double *ptr=getConstPointer();
863 double absEps=fabs(eps);
866 for(int i=1;i<nbOfElements;i++)
868 if(ptr[i]<(ref+absEps))
876 for(int i=1;i<nbOfElements;i++)
878 if(ptr[i]>(ref-absEps))
887 * Returns a textual and human readable representation of \a this instance of
888 * DataArrayDouble. This text is shown when a DataArrayDouble is printed in Python.
889 * \return std::string - text describing \a this DataArrayDouble.
891 * \sa reprNotTooLong, reprZip
893 std::string DataArrayDouble::repr() const
895 std::ostringstream ret;
900 std::string DataArrayDouble::reprZip() const
902 std::ostringstream ret;
908 * This method is close to repr method except that when \a this has more than 1000 tuples, all tuples are not
909 * printed out to avoid to consume too much space in interpretor.
912 std::string DataArrayDouble::reprNotTooLong() const
914 std::ostringstream ret;
915 reprNotTooLongStream(ret);
919 void DataArrayDouble::writeVTK(std::ostream& ofs, int indent, const std::string& nameInFile, DataArrayByte *byteArr) const
921 static const char SPACE[4]={' ',' ',' ',' '};
923 std::string idt(indent,' ');
925 ofs << idt << "<DataArray type=\"Float32\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
927 bool areAllEmpty(true);
928 for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
932 for(std::size_t i=0;i<_info_on_compo.size();i++)
933 ofs << " ComponentName" << i << "=\"" << _info_on_compo[i] << "\"";
937 ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
938 INTERP_KERNEL::AutoPtr<float> tmp(new float[getNbOfElems()]);
940 // to make Visual C++ happy : instead of std::copy(begin(),end(),(float *)tmp);
941 for(const double *src=begin();src!=end();src++,pt++)
943 const char *data(reinterpret_cast<const char *>((float *)tmp));
944 std::size_t sz(getNbOfElems()*sizeof(float));
945 byteArr->insertAtTheEnd(data,data+sz);
946 byteArr->insertAtTheEnd(SPACE,SPACE+4);
950 ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
951 std::copy(begin(),end(),std::ostream_iterator<double>(ofs," "));
953 ofs << std::endl << idt << "</DataArray>\n";
956 void DataArrayDouble::reprStream(std::ostream& stream) const
958 stream << "Name of double array : \"" << _name << "\"\n";
959 reprWithoutNameStream(stream);
962 void DataArrayDouble::reprZipStream(std::ostream& stream) const
964 stream << "Name of double array : \"" << _name << "\"\n";
965 reprZipWithoutNameStream(stream);
968 void DataArrayDouble::reprNotTooLongStream(std::ostream& stream) const
970 stream << "Name of double array : \"" << _name << "\"\n";
971 reprNotTooLongWithoutNameStream(stream);
974 void DataArrayDouble::reprWithoutNameStream(std::ostream& stream) const
976 DataArray::reprWithoutNameStream(stream);
977 stream.precision(17);
978 _mem.repr(getNumberOfComponents(),stream);
981 void DataArrayDouble::reprZipWithoutNameStream(std::ostream& stream) const
983 DataArray::reprWithoutNameStream(stream);
984 stream.precision(17);
985 _mem.reprZip(getNumberOfComponents(),stream);
988 void DataArrayDouble::reprNotTooLongWithoutNameStream(std::ostream& stream) const
990 DataArray::reprWithoutNameStream(stream);
991 stream.precision(17);
992 _mem.reprNotTooLong(getNumberOfComponents(),stream);
995 void DataArrayDouble::reprCppStream(const std::string& varName, std::ostream& stream) const
997 int nbTuples(getNumberOfTuples()),nbComp(getNumberOfComponents());
998 const double *data(getConstPointer());
999 stream.precision(17);
1000 stream << "DataArrayDouble *" << varName << "=DataArrayDouble::New();" << std::endl;
1001 if(nbTuples*nbComp>=1)
1003 stream << "const double " << varName << "Data[" << nbTuples*nbComp << "]={";
1004 std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<double>(stream,","));
1005 stream << data[nbTuples*nbComp-1] << "};" << std::endl;
1006 stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
1009 stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
1010 stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
1014 * Method that gives a quick overvien of \a this for python.
1016 void DataArrayDouble::reprQuickOverview(std::ostream& stream) const
1018 static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
1019 stream << "DataArrayDouble C++ instance at " << this << ". ";
1022 int nbOfCompo=(int)_info_on_compo.size();
1025 int nbOfTuples=getNumberOfTuples();
1026 stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
1027 reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
1030 stream << "Number of components : 0.";
1033 stream << "*** No data allocated ****";
1036 void DataArrayDouble::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
1038 const double *data=begin();
1039 int nbOfTuples=getNumberOfTuples();
1040 int nbOfCompo=(int)_info_on_compo.size();
1041 std::ostringstream oss2; oss2 << "[";
1043 std::string oss2Str(oss2.str());
1044 bool isFinished=true;
1045 for(int i=0;i<nbOfTuples && isFinished;i++)
1050 for(int j=0;j<nbOfCompo;j++,data++)
1053 if(j!=nbOfCompo-1) oss2 << ", ";
1059 if(i!=nbOfTuples-1) oss2 << ", ";
1060 std::string oss3Str(oss2.str());
1061 if(oss3Str.length()<maxNbOfByteInRepr)
1073 * Equivalent to DataArrayDouble::isEqual except that if false the reason of
1074 * mismatch is given.
1076 * \param [in] other the instance to be compared with \a this
1077 * \param [in] prec the precision to compare numeric data of the arrays.
1078 * \param [out] reason In case of inequality returns the reason.
1079 * \sa DataArrayDouble::isEqual
1081 bool DataArrayDouble::isEqualIfNotWhy(const DataArrayDouble& other, double prec, std::string& reason) const
1083 if(!areInfoEqualsIfNotWhy(other,reason))
1085 return _mem.isEqual(other._mem,prec,reason);
1089 * Checks if \a this and another DataArrayDouble are fully equal. For more info see
1090 * \ref MEDCouplingArrayBasicsCompare.
1091 * \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1092 * \param [in] prec - precision value to compare numeric data of the arrays.
1093 * \return bool - \a true if the two arrays are equal, \a false else.
1095 bool DataArrayDouble::isEqual(const DataArrayDouble& other, double prec) const
1098 return isEqualIfNotWhy(other,prec,tmp);
1102 * Checks if values of \a this and another DataArrayDouble are equal. For more info see
1103 * \ref MEDCouplingArrayBasicsCompare.
1104 * \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1105 * \param [in] prec - precision value to compare numeric data of the arrays.
1106 * \return bool - \a true if the values of two arrays are equal, \a false else.
1108 bool DataArrayDouble::isEqualWithoutConsideringStr(const DataArrayDouble& other, double prec) const
1111 return _mem.isEqual(other._mem,prec,tmp);
1115 * This method checks that all tuples in \a other are in \a this.
1116 * If true, the output param \a tupleIds contains the tuples ids of \a this that correspond to tupes in \a this.
1117 * 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.
1119 * \param [in] other - the array having the same number of components than \a this.
1120 * \param [out] tupleIds - the tuple ids containing the same number of tuples than \a other has.
1121 * \sa DataArrayDouble::findCommonTuples
1123 bool DataArrayDouble::areIncludedInMe(const DataArrayDouble *other, double prec, DataArrayInt *&tupleIds) const
1126 throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : input array is NULL !");
1127 checkAllocated(); other->checkAllocated();
1128 if(getNumberOfComponents()!=other->getNumberOfComponents())
1129 throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : the number of components does not match !");
1130 MCAuto<DataArrayDouble> a=DataArrayDouble::Aggregate(this,other);
1131 DataArrayInt *c=0,*ci=0;
1132 a->findCommonTuples(prec,getNumberOfTuples(),c,ci);
1133 MCAuto<DataArrayInt> cSafe(c),ciSafe(ci);
1134 int newNbOfTuples=-1;
1135 MCAuto<DataArrayInt> ids=DataArrayInt::ConvertIndexArrayToO2N(a->getNumberOfTuples(),c->begin(),ci->begin(),ci->end(),newNbOfTuples);
1136 MCAuto<DataArrayInt> ret1=ids->selectByTupleIdSafeSlice(getNumberOfTuples(),a->getNumberOfTuples(),1);
1137 tupleIds=ret1.retn();
1138 return newNbOfTuples==getNumberOfTuples();
1142 * Searches for tuples coincident within \a prec tolerance. Each tuple is considered
1143 * as coordinates of a point in getNumberOfComponents()-dimensional space. The
1144 * distance separating two points is computed with the infinite norm.
1146 * Indices of coincident tuples are stored in output arrays.
1147 * A pair of arrays (\a comm, \a commIndex) is called "Surjective Format 2".
1149 * This method is typically used by MEDCouplingPointSet::findCommonNodes() and
1150 * MEDCouplingUMesh::mergeNodes().
1151 * \param [in] prec - minimal absolute distance between two tuples (infinite norm) at which they are
1152 * considered not coincident.
1153 * \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
1154 * tuples have id strictly lower than \a limitTupleId then they are not returned.
1155 * \param [out] comm - the array holding ids (== indices) of coincident tuples.
1156 * \a comm->getNumberOfComponents() == 1.
1157 * \a comm->getNumberOfTuples() == \a commIndex->back().
1158 * \param [out] commIndex - the array dividing all indices stored in \a comm into
1159 * groups of (indices of) coincident tuples. Its every value is a tuple
1160 * index where a next group of tuples begins. For example the second
1161 * group of tuples in \a comm is described by following range of indices:
1162 * [ \a commIndex[1], \a commIndex[2] ). \a commIndex->getNumberOfTuples()-1
1163 * gives the number of groups of coincident tuples.
1164 * \throw If \a this is not allocated.
1165 * \throw If the number of components is not in [1,2,3,4].
1167 * \if ENABLE_EXAMPLES
1168 * \ref cpp_mcdataarraydouble_findcommontuples "Here is a C++ example".
1170 * \ref py_mcdataarraydouble_findcommontuples "Here is a Python example".
1172 * \sa DataArrayInt::ConvertIndexArrayToO2N(), DataArrayDouble::areIncludedInMe
1174 void DataArrayDouble::findCommonTuples(double prec, int limitTupleId, DataArrayInt *&comm, DataArrayInt *&commIndex) const
1177 int nbOfCompo=getNumberOfComponents();
1178 if ((nbOfCompo<1) || (nbOfCompo>4)) //test before work
1179 throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : Unexpected spacedim of coords. Must be 1, 2, 3 or 4.");
1181 int nbOfTuples=getNumberOfTuples();
1183 MCAuto<DataArrayInt> c(DataArrayInt::New()),cI(DataArrayInt::New()); c->alloc(0,1); cI->pushBackSilent(0);
1187 findCommonTuplesAlg<4>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1190 findCommonTuplesAlg<3>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1193 findCommonTuplesAlg<2>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1196 findCommonTuplesAlg<1>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1199 throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : nb of components managed are 1,2,3 and 4 ! not implemented for other number of components !");
1202 commIndex=cI.retn();
1206 * This methods returns the minimal distance between the two set of points \a this and \a other.
1207 * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
1208 * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
1210 * \param [out] thisTupleId the tuple id in \a this corresponding to the returned minimal distance
1211 * \param [out] otherTupleId the tuple id in \a other corresponding to the returned minimal distance
1212 * \return the minimal distance between the two set of points \a this and \a other.
1213 * \sa DataArrayDouble::findClosestTupleId
1215 double DataArrayDouble::minimalDistanceTo(const DataArrayDouble *other, int& thisTupleId, int& otherTupleId) const
1217 MCAuto<DataArrayInt> part1=findClosestTupleId(other);
1218 int nbOfCompo(getNumberOfComponents());
1219 int otherNbTuples(other->getNumberOfTuples());
1220 const double *thisPt(begin()),*otherPt(other->begin());
1221 const int *part1Pt(part1->begin());
1222 double ret=std::numeric_limits<double>::max();
1223 for(int i=0;i<otherNbTuples;i++,part1Pt++,otherPt+=nbOfCompo)
1226 for(int j=0;j<nbOfCompo;j++)
1227 tmp+=(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j])*(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j]);
1229 { ret=tmp; thisTupleId=*part1Pt; otherTupleId=i; }
1235 * This methods returns for each tuple in \a other which tuple in \a this is the closest.
1236 * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
1237 * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
1239 * \return a newly allocated (new object to be dealt by the caller) DataArrayInt having \c other->getNumberOfTuples() tuples and one components.
1240 * \sa DataArrayDouble::minimalDistanceTo
1242 DataArrayInt *DataArrayDouble::findClosestTupleId(const DataArrayDouble *other) const
1245 throw INTERP_KERNEL::Exception("DataArrayDouble::findClosestTupleId : other instance is NULL !");
1246 checkAllocated(); other->checkAllocated();
1247 int nbOfCompo=getNumberOfComponents();
1248 if(nbOfCompo!=other->getNumberOfComponents())
1250 std::ostringstream oss; oss << "DataArrayDouble::findClosestTupleId : number of components in this is " << nbOfCompo;
1251 oss << ", whereas number of components in other is " << other->getNumberOfComponents() << "! Should be equal !";
1252 throw INTERP_KERNEL::Exception(oss.str().c_str());
1254 int nbOfTuples=other->getNumberOfTuples();
1255 int thisNbOfTuples=getNumberOfTuples();
1256 MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuples,1);
1258 getMinMaxPerComponent(bounds);
1263 double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2])),zDelta(fabs(bounds[5]-bounds[4]));
1264 double delta=std::max(xDelta,yDelta); delta=std::max(delta,zDelta);
1265 double characSize=pow((delta*delta*delta)/((double)thisNbOfTuples),1./3.);
1266 BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1267 FindClosestTupleIdAlg<3>(myTree,3.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1272 double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2]));
1273 double delta=std::max(xDelta,yDelta);
1274 double characSize=sqrt(delta/(double)thisNbOfTuples);
1275 BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1276 FindClosestTupleIdAlg<2>(myTree,2.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1281 double characSize=fabs(bounds[1]-bounds[0])/thisNbOfTuples;
1282 BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1283 FindClosestTupleIdAlg<1>(myTree,1.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1287 throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for findClosestTupleId. Must be 1, 2 or 3.");
1293 * This method expects that \a this and \a otherBBoxFrmt arrays are bounding box arrays ( as the output of MEDCouplingPointSet::getBoundingBoxForBBTree method ).
1294 * 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
1295 * how many bounding boxes in \a otherBBoxFrmt.
1296 * So, this method expects that \a this and \a otherBBoxFrmt have the same number of components.
1298 * \param [in] otherBBoxFrmt - It is an array .
1299 * \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.
1300 * \sa MEDCouplingPointSet::getBoundingBoxForBBTree
1301 * \throw If \a this and \a otherBBoxFrmt have not the same number of components.
1302 * \throw If \a this and \a otherBBoxFrmt number of components is not even (BBox format).
1304 DataArrayInt *DataArrayDouble::computeNbOfInteractionsWith(const DataArrayDouble *otherBBoxFrmt, double eps) const
1307 throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : input array is NULL !");
1308 if(!isAllocated() || !otherBBoxFrmt->isAllocated())
1309 throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : this and input array must be allocated !");
1310 int nbOfComp(getNumberOfComponents()),nbOfTuples(getNumberOfTuples());
1311 if(nbOfComp!=otherBBoxFrmt->getNumberOfComponents())
1313 std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : this number of components (" << nbOfComp << ") must be equal to the number of components of input array (" << otherBBoxFrmt->getNumberOfComponents() << ") !";
1314 throw INTERP_KERNEL::Exception(oss.str().c_str());
1318 std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : Number of components (" << nbOfComp << ") is not even ! It should be to be compatible with bbox format !";
1319 throw INTERP_KERNEL::Exception(oss.str().c_str());
1321 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbOfTuples,1);
1322 const double *thisBBPtr(begin());
1323 int *retPtr(ret->getPointer());
1328 BBTree<3,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
1329 for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
1330 *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
1335 BBTree<2,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
1336 for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
1337 *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
1342 BBTree<1,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
1343 for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
1344 *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
1348 throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : space dimension supported are [1,2,3] !");
1355 * Returns a copy of \a this array by excluding coincident tuples. Each tuple is
1356 * considered as coordinates of a point in getNumberOfComponents()-dimensional
1357 * space. The distance between tuples is computed using norm2. If several tuples are
1358 * not far each from other than \a prec, only one of them remains in the result
1359 * array. The order of tuples in the result array is same as in \a this one except
1360 * that coincident tuples are excluded.
1361 * \param [in] prec - minimal absolute distance between two tuples at which they are
1362 * considered not coincident.
1363 * \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
1364 * tuples have id strictly lower than \a limitTupleId then they are not excluded.
1365 * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1366 * is to delete using decrRef() as it is no more needed.
1367 * \throw If \a this is not allocated.
1368 * \throw If the number of components is not in [1,2,3,4].
1370 * \if ENABLE_EXAMPLES
1371 * \ref py_mcdataarraydouble_getdifferentvalues "Here is a Python example".
1374 DataArrayDouble *DataArrayDouble::getDifferentValues(double prec, int limitTupleId) const
1377 DataArrayInt *c0=0,*cI0=0;
1378 findCommonTuples(prec,limitTupleId,c0,cI0);
1379 MCAuto<DataArrayInt> c(c0),cI(cI0);
1380 int newNbOfTuples=-1;
1381 MCAuto<DataArrayInt> o2n=DataArrayInt::ConvertIndexArrayToO2N(getNumberOfTuples(),c0->begin(),cI0->begin(),cI0->end(),newNbOfTuples);
1382 return renumberAndReduce(o2n->getConstPointer(),newNbOfTuples);
1386 * Copy all components in a specified order from another DataArrayDouble.
1387 * Both numerical and textual data is copied. The number of tuples in \a this and
1388 * the other array can be different.
1389 * \param [in] a - the array to copy data from.
1390 * \param [in] compoIds - sequence of zero based indices of components, data of which is
1392 * \throw If \a a is NULL.
1393 * \throw If \a compoIds.size() != \a a->getNumberOfComponents().
1394 * \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
1396 * \if ENABLE_EXAMPLES
1397 * \ref py_mcdataarraydouble_setselectedcomponents "Here is a Python example".
1400 void DataArrayDouble::setSelectedComponents(const DataArrayDouble *a, const std::vector<int>& compoIds)
1403 throw INTERP_KERNEL::Exception("DataArrayDouble::setSelectedComponents : input DataArrayDouble is NULL !");
1405 copyPartOfStringInfoFrom2(compoIds,*a);
1406 std::size_t partOfCompoSz=compoIds.size();
1407 int nbOfCompo=getNumberOfComponents();
1408 int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
1409 const double *ac=a->getConstPointer();
1410 double *nc=getPointer();
1411 for(int i=0;i<nbOfTuples;i++)
1412 for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
1413 nc[nbOfCompo*i+compoIds[j]]=*ac;
1417 * Checks if 0.0 value is present in \a this array. If it is the case, an exception
1419 * \throw If zero is found in \a this array.
1421 void DataArrayDouble::checkNoNullValues() const
1423 const double *tmp=getConstPointer();
1424 std::size_t nbOfElems=getNbOfElems();
1425 const double *where=std::find(tmp,tmp+nbOfElems,0.);
1426 if(where!=tmp+nbOfElems)
1427 throw INTERP_KERNEL::Exception("A value 0.0 have been detected !");
1431 * Computes minimal and maximal value in each component. An output array is filled
1432 * with \c 2 * \a this->getNumberOfComponents() values, so the caller is to allocate
1433 * enough memory before calling this method.
1434 * \param [out] bounds - array of size at least 2 *\a this->getNumberOfComponents().
1435 * It is filled as follows:<br>
1436 * \a bounds[0] = \c min_of_component_0 <br>
1437 * \a bounds[1] = \c max_of_component_0 <br>
1438 * \a bounds[2] = \c min_of_component_1 <br>
1439 * \a bounds[3] = \c max_of_component_1 <br>
1442 void DataArrayDouble::getMinMaxPerComponent(double *bounds) const
1445 int dim=getNumberOfComponents();
1446 for (int idim=0; idim<dim; idim++)
1448 bounds[idim*2]=std::numeric_limits<double>::max();
1449 bounds[idim*2+1]=-std::numeric_limits<double>::max();
1451 const double *ptr=getConstPointer();
1452 int nbOfTuples=getNumberOfTuples();
1453 for(int i=0;i<nbOfTuples;i++)
1455 for(int idim=0;idim<dim;idim++)
1457 if(bounds[idim*2]>ptr[i*dim+idim])
1459 bounds[idim*2]=ptr[i*dim+idim];
1461 if(bounds[idim*2+1]<ptr[i*dim+idim])
1463 bounds[idim*2+1]=ptr[i*dim+idim];
1470 * This method retrieves a newly allocated DataArrayDouble instance having same number of tuples than \a this and twice number of components than \a this
1471 * to store both the min and max per component of each tuples.
1472 * \param [in] epsilon the width of the bbox (identical in each direction) - 0.0 by default
1474 * \return a newly created DataArrayDouble instance having \c this->getNumberOfTuples() tuples and 2 * \c this->getNumberOfComponent() components
1476 * \throw If \a this is not allocated yet.
1478 DataArrayDouble *DataArrayDouble::computeBBoxPerTuple(double epsilon) const
1481 const double *dataPtr=getConstPointer();
1482 int nbOfCompo=getNumberOfComponents();
1483 int nbTuples=getNumberOfTuples();
1484 MCAuto<DataArrayDouble> bbox=DataArrayDouble::New();
1485 bbox->alloc(nbTuples,2*nbOfCompo);
1486 double *bboxPtr=bbox->getPointer();
1487 for(int i=0;i<nbTuples;i++)
1489 for(int j=0;j<nbOfCompo;j++)
1491 bboxPtr[2*nbOfCompo*i+2*j]=dataPtr[nbOfCompo*i+j]-epsilon;
1492 bboxPtr[2*nbOfCompo*i+2*j+1]=dataPtr[nbOfCompo*i+j]+epsilon;
1499 * For each tuples **t** in \a other, this method retrieves tuples in \a this that are equal to **t**.
1500 * Two tuples are considered equal if the euclidian distance between the two tuples is lower than \a eps.
1502 * \param [in] other a DataArrayDouble having same number of components than \a this.
1503 * \param [in] eps absolute precision representing distance (using infinite norm) between 2 tuples behind which 2 tuples are considered equal.
1504 * \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.
1505 * \a cI allows to extract information in \a c.
1506 * \param [out] cI is an indirection array that allows to extract the data contained in \a c.
1508 * \throw In case of:
1509 * - \a this is not allocated
1510 * - \a other is not allocated or null
1511 * - \a this and \a other do not have the same number of components
1512 * - if number of components of \a this is not in [1,2,3]
1514 * \sa MEDCouplingPointSet::getNodeIdsNearPoints, DataArrayDouble::getDifferentValues
1516 void DataArrayDouble::computeTupleIdsNearTuples(const DataArrayDouble *other, double eps, DataArrayInt *& c, DataArrayInt *& cI) const
1519 throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : input pointer other is null !");
1521 other->checkAllocated();
1522 int nbOfCompo=getNumberOfComponents();
1523 int otherNbOfCompo=other->getNumberOfComponents();
1524 if(nbOfCompo!=otherNbOfCompo)
1525 throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : number of components should be equal between this and other !");
1526 int nbOfTuplesOther=other->getNumberOfTuples();
1527 MCAuto<DataArrayInt> cArr(DataArrayInt::New()),cIArr(DataArrayInt::New()); cArr->alloc(0,1); cIArr->pushBackSilent(0);
1532 BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
1533 FindTupleIdsNearTuplesAlg<3>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
1538 BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
1539 FindTupleIdsNearTuplesAlg<2>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
1544 BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
1545 FindTupleIdsNearTuplesAlg<1>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
1549 throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for computeTupleIdsNearTuples. Must be 1, 2 or 3.");
1551 c=cArr.retn(); cI=cIArr.retn();
1555 * 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
1556 * around origin of 'radius' 1.
1558 * \param [in] eps absolute epsilon. under that value of delta between max and min no scale is performed.
1560 void DataArrayDouble::recenterForMaxPrecision(double eps)
1563 int dim=getNumberOfComponents();
1564 std::vector<double> bounds(2*dim);
1565 getMinMaxPerComponent(&bounds[0]);
1566 for(int i=0;i<dim;i++)
1568 double delta=bounds[2*i+1]-bounds[2*i];
1569 double offset=(bounds[2*i]+bounds[2*i+1])/2.;
1571 applyLin(1./delta,-offset/delta,i);
1573 applyLin(1.,-offset,i);
1578 * Returns the maximal value and all its locations within \a this one-dimensional array.
1579 * \param [out] tupleIds - a new instance of DataArrayInt containg indices of
1580 * tuples holding the maximal value. The caller is to delete it using
1581 * decrRef() as it is no more needed.
1582 * \return double - the maximal value among all values of \a this array.
1583 * \throw If \a this->getNumberOfComponents() != 1
1584 * \throw If \a this->getNumberOfTuples() < 1
1586 double DataArrayDouble::getMaxValue2(DataArrayInt*& tupleIds) const
1590 double ret=getMaxValue(tmp);
1591 tupleIds=findIdsInRange(ret,ret);
1596 * Returns the minimal value and all its locations within \a this one-dimensional array.
1597 * \param [out] tupleIds - a new instance of DataArrayInt containg indices of
1598 * tuples holding the minimal value. The caller is to delete it using
1599 * decrRef() as it is no more needed.
1600 * \return double - the minimal value among all values of \a this array.
1601 * \throw If \a this->getNumberOfComponents() != 1
1602 * \throw If \a this->getNumberOfTuples() < 1
1604 double DataArrayDouble::getMinValue2(DataArrayInt*& tupleIds) const
1608 double ret=getMinValue(tmp);
1609 tupleIds=findIdsInRange(ret,ret);
1614 * 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.
1615 * This method only works for single component array.
1617 * \return a value in [ 0, \c this->getNumberOfTuples() )
1619 * \throw If \a this is not allocated
1622 int DataArrayDouble::count(double value, double eps) const
1626 if(getNumberOfComponents()!=1)
1627 throw INTERP_KERNEL::Exception("DataArrayDouble::count : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
1628 const double *vals=begin();
1629 int nbOfTuples=getNumberOfTuples();
1630 for(int i=0;i<nbOfTuples;i++,vals++)
1631 if(fabs(*vals-value)<=eps)
1637 * Returns the average value of \a this one-dimensional array.
1638 * \return double - the average value over all values of \a this array.
1639 * \throw If \a this->getNumberOfComponents() != 1
1640 * \throw If \a this->getNumberOfTuples() < 1
1642 double DataArrayDouble::getAverageValue() const
1644 if(getNumberOfComponents()!=1)
1645 throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
1646 int nbOfTuples=getNumberOfTuples();
1648 throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : array exists but number of tuples must be > 0 !");
1649 const double *vals=getConstPointer();
1650 double ret=std::accumulate(vals,vals+nbOfTuples,0.);
1651 return ret/nbOfTuples;
1655 * Returns the Euclidean norm of the vector defined by \a this array.
1656 * \return double - the value of the Euclidean norm, i.e.
1657 * the square root of the inner product of vector.
1658 * \throw If \a this is not allocated.
1660 double DataArrayDouble::norm2() const
1664 std::size_t nbOfElems=getNbOfElems();
1665 const double *pt=getConstPointer();
1666 for(std::size_t i=0;i<nbOfElems;i++,pt++)
1672 * Returns the maximum norm of the vector defined by \a this array.
1673 * This method works even if the number of components is diferent from one.
1674 * If the number of elements in \a this is 0, -1. is returned.
1675 * \return double - the value of the maximum norm, i.e.
1676 * the maximal absolute value among values of \a this array (whatever its number of components).
1677 * \throw If \a this is not allocated.
1679 double DataArrayDouble::normMax() const
1683 std::size_t nbOfElems(getNbOfElems());
1684 const double *pt(getConstPointer());
1685 for(std::size_t i=0;i<nbOfElems;i++,pt++)
1687 double val(std::abs(*pt));
1695 * Returns the minimum norm (absolute value) of the vector defined by \a this array.
1696 * This method works even if the number of components is diferent from one.
1697 * If the number of elements in \a this is 0, std::numeric_limits<double>::max() is returned.
1698 * \return double - the value of the minimum norm, i.e.
1699 * the minimal absolute value among values of \a this array (whatever its number of components).
1700 * \throw If \a this is not allocated.
1702 double DataArrayDouble::normMin() const
1705 double ret(std::numeric_limits<double>::max());
1706 std::size_t nbOfElems(getNbOfElems());
1707 const double *pt(getConstPointer());
1708 for(std::size_t i=0;i<nbOfElems;i++,pt++)
1710 double val(std::abs(*pt));
1718 * Accumulates values of each component of \a this array.
1719 * \param [out] res - an array of length \a this->getNumberOfComponents(), allocated
1720 * by the caller, that is filled by this method with sum value for each
1722 * \throw If \a this is not allocated.
1724 void DataArrayDouble::accumulate(double *res) const
1727 const double *ptr=getConstPointer();
1728 int nbTuple=getNumberOfTuples();
1729 int nbComps=getNumberOfComponents();
1730 std::fill(res,res+nbComps,0.);
1731 for(int i=0;i<nbTuple;i++)
1732 std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<double>());
1736 * This method returns the min distance from an external tuple defined by [ \a tupleBg , \a tupleEnd ) to \a this and
1737 * the first tuple in \a this that matches the returned distance. If there is no tuples in \a this an exception will be thrown.
1740 * \a this is expected to be allocated and expected to have a number of components equal to the distance from \a tupleBg to
1741 * \a tupleEnd. If not an exception will be thrown.
1743 * \param [in] tupleBg start pointer (included) of input external tuple
1744 * \param [in] tupleEnd end pointer (not included) of input external tuple
1745 * \param [out] tupleId the tuple id in \a this that matches the min of distance between \a this and input external tuple
1746 * \return the min distance.
1747 * \sa MEDCouplingUMesh::distanceToPoint
1749 double DataArrayDouble::distanceToTuple(const double *tupleBg, const double *tupleEnd, int& tupleId) const
1752 int nbTuple=getNumberOfTuples();
1753 int nbComps=getNumberOfComponents();
1754 if(nbComps!=(int)std::distance(tupleBg,tupleEnd))
1755 { 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()); }
1757 throw INTERP_KERNEL::Exception("DataArrayDouble::distanceToTuple : no tuple in this ! No distance to compute !");
1758 double ret0=std::numeric_limits<double>::max();
1760 const double *work=getConstPointer();
1761 for(int i=0;i<nbTuple;i++)
1764 for(int j=0;j<nbComps;j++,work++)
1765 val+=(*work-tupleBg[j])*((*work-tupleBg[j]));
1769 { ret0=val; tupleId=i; }
1775 * Accumulate values of the given component of \a this array.
1776 * \param [in] compId - the index of the component of interest.
1777 * \return double - a sum value of \a compId-th component.
1778 * \throw If \a this is not allocated.
1779 * \throw If \a the condition ( 0 <= \a compId < \a this->getNumberOfComponents() ) is
1782 double DataArrayDouble::accumulate(int compId) const
1785 const double *ptr=getConstPointer();
1786 int nbTuple=getNumberOfTuples();
1787 int nbComps=getNumberOfComponents();
1788 if(compId<0 || compId>=nbComps)
1789 throw INTERP_KERNEL::Exception("DataArrayDouble::accumulate : Invalid compId specified : No such nb of components !");
1791 for(int i=0;i<nbTuple;i++)
1792 ret+=ptr[i*nbComps+compId];
1797 * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
1798 * The returned array will have same number of components than \a this and number of tuples equal to
1799 * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
1801 * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
1802 * 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.
1804 * \param [in] bgOfIndex - begin (included) of the input index array.
1805 * \param [in] endOfIndex - end (excluded) of the input index array.
1806 * \return DataArrayDouble * - the new instance having the same number of components than \a this.
1808 * \throw If bgOfIndex or end is NULL.
1809 * \throw If input index array is not ascendingly sorted.
1810 * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
1811 * \throw If std::distance(bgOfIndex,endOfIndex)==0.
1813 DataArrayDouble *DataArrayDouble::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
1815 if(!bgOfIndex || !endOfIndex)
1816 throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : input pointer NULL !");
1818 int nbCompo=getNumberOfComponents();
1819 int nbOfTuples=getNumberOfTuples();
1820 int sz=(int)std::distance(bgOfIndex,endOfIndex);
1822 throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : invalid size of input index array !");
1824 MCAuto<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(sz,nbCompo);
1825 const int *w=bgOfIndex;
1826 if(*w<0 || *w>=nbOfTuples)
1827 throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
1828 const double *srcPt=begin()+(*w)*nbCompo;
1829 double *tmp=ret->getPointer();
1830 for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
1832 std::fill(tmp,tmp+nbCompo,0.);
1835 for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
1837 if(j>=0 && j<nbOfTuples)
1838 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<double>());
1841 std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
1842 throw INTERP_KERNEL::Exception(oss.str().c_str());
1848 std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
1849 throw INTERP_KERNEL::Exception(oss.str().c_str());
1852 ret->copyStringInfoFrom(*this);
1857 * 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.
1858 * This method expects that \a this as only one component. The returned array will have \a this->getNumberOfTuples()+1 tuple with also one component.
1859 * The ith element of returned array is equal to the sum of elements in \a this with rank strictly lower than i.
1861 * \return DataArrayDouble - A newly built array containing cum sum of \a this.
1863 MCAuto<DataArrayDouble> DataArrayDouble::cumSum() const
1866 checkNbOfComps(1,"DataArrayDouble::cumSum : this is expected to be single component");
1867 int nbOfTuple(getNumberOfTuples());
1868 MCAuto<DataArrayDouble> ret(DataArrayDouble::New()); ret->alloc(nbOfTuple+1,1);
1869 double *ptr(ret->getPointer());
1871 const double *thisPtr(begin());
1872 for(int i=0;i<nbOfTuple;i++)
1873 ptr[i+1]=ptr[i]+thisPtr[i];
1878 * Converts each 2D point defined by the tuple of \a this array from the Polar to the
1879 * Cartesian coordinate system. The two components of the tuple of \a this array are
1880 * considered to contain (1) radius and (2) angle of the point in the Polar CS.
1881 * \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
1882 * contains X and Y coordinates of the point in the Cartesian CS. The caller
1883 * is to delete this array using decrRef() as it is no more needed. The array
1884 * does not contain any textual info on components.
1885 * \throw If \a this->getNumberOfComponents() != 2.
1886 * \sa fromCartToPolar
1888 DataArrayDouble *DataArrayDouble::fromPolarToCart() const
1891 int nbOfComp(getNumberOfComponents());
1893 throw INTERP_KERNEL::Exception("DataArrayDouble::fromPolarToCart : must be an array with exactly 2 components !");
1894 int nbOfTuple(getNumberOfTuples());
1895 DataArrayDouble *ret(DataArrayDouble::New());
1896 ret->alloc(nbOfTuple,2);
1897 double *w(ret->getPointer());
1898 const double *wIn(getConstPointer());
1899 for(int i=0;i<nbOfTuple;i++,w+=2,wIn+=2)
1901 w[0]=wIn[0]*cos(wIn[1]);
1902 w[1]=wIn[0]*sin(wIn[1]);
1908 * Converts each 3D point defined by the tuple of \a this array from the Cylindrical to
1909 * the Cartesian coordinate system. The three components of the tuple of \a this array
1910 * are considered to contain (1) radius, (2) azimuth and (3) altitude of the point in
1911 * the Cylindrical CS.
1912 * \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
1913 * contains X, Y and Z coordinates of the point in the Cartesian CS. The info
1914 * on the third component is copied from \a this array. The caller
1915 * is to delete this array using decrRef() as it is no more needed.
1916 * \throw If \a this->getNumberOfComponents() != 3.
1919 DataArrayDouble *DataArrayDouble::fromCylToCart() const
1922 int nbOfComp(getNumberOfComponents());
1924 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCylToCart : must be an array with exactly 3 components !");
1925 int nbOfTuple(getNumberOfTuples());
1926 DataArrayDouble *ret(DataArrayDouble::New());
1927 ret->alloc(getNumberOfTuples(),3);
1928 double *w(ret->getPointer());
1929 const double *wIn(getConstPointer());
1930 for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
1932 w[0]=wIn[0]*cos(wIn[1]);
1933 w[1]=wIn[0]*sin(wIn[1]);
1936 ret->setInfoOnComponent(2,getInfoOnComponent(2));
1941 * Converts each 3D point defined by the tuple of \a this array from the Spherical to
1942 * the Cartesian coordinate system. The three components of the tuple of \a this array
1943 * are considered to contain (1) radius, (2) polar angle and (3) azimuthal angle of the
1944 * point in the Cylindrical CS.
1945 * \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
1946 * contains X, Y and Z coordinates of the point in the Cartesian CS. The info
1947 * on the third component is copied from \a this array. The caller
1948 * is to delete this array using decrRef() as it is no more needed.
1949 * \throw If \a this->getNumberOfComponents() != 3.
1950 * \sa fromCartToSpher
1952 DataArrayDouble *DataArrayDouble::fromSpherToCart() const
1955 int nbOfComp(getNumberOfComponents());
1957 throw INTERP_KERNEL::Exception("DataArrayDouble::fromSpherToCart : must be an array with exactly 3 components !");
1958 int nbOfTuple(getNumberOfTuples());
1959 DataArrayDouble *ret(DataArrayDouble::New());
1960 ret->alloc(getNumberOfTuples(),3);
1961 double *w(ret->getPointer());
1962 const double *wIn(getConstPointer());
1963 for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
1965 w[0]=wIn[0]*cos(wIn[2])*sin(wIn[1]);
1966 w[1]=wIn[0]*sin(wIn[2])*sin(wIn[1]);
1967 w[2]=wIn[0]*cos(wIn[1]);
1973 * 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.
1974 * 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.
1975 * If \a at equals to AX_CYL the returned array will be the result of operation cylindric to cartesian of \a this...
1977 * \param [in] atOfThis - The axis type of \a this.
1978 * \return DataArrayDouble * - the new instance of DataArrayDouble (that must be dealed by caller) containing the result of the cartesianizification of \a this.
1980 DataArrayDouble *DataArrayDouble::cartesianize(MEDCouplingAxisType atOfThis) const
1983 int nbOfComp(getNumberOfComponents());
1984 MCAuto<DataArrayDouble> ret;
1992 ret=fromCylToCart();
1997 ret=fromPolarToCart();
2001 throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : For AX_CYL, number of components must be in [2,3] !");
2005 ret=fromSpherToCart();
2010 ret=fromPolarToCart();
2014 throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : For AX_CYL, number of components must be in [2,3] !");
2016 throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : not recognized axis type ! Only AX_CART, AX_CYL and AX_SPHER supported !");
2018 ret->copyStringInfoFrom(*this);
2023 * This method returns a newly created array to be deallocated that contains the result of conversion from cartesian to polar.
2024 * This method expects that \a this has exactly 2 components.
2025 * \sa fromPolarToCart
2027 DataArrayDouble *DataArrayDouble::fromCartToPolar() const
2029 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2031 int nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2033 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToPolar : must be an array with exactly 2 components !");
2034 ret->alloc(nbTuples,2);
2035 double *retPtr(ret->getPointer());
2036 const double *ptr(begin());
2037 for(int i=0;i<nbTuples;i++,ptr+=2,retPtr+=2)
2039 retPtr[0]=sqrt(ptr[0]*ptr[0]+ptr[1]*ptr[1]);
2040 retPtr[1]=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.
2047 * This method expects that \a this has exactly 3 components.
2050 DataArrayDouble *DataArrayDouble::fromCartToCyl() const
2052 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2054 int nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2056 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCyl : must be an array with exactly 3 components !");
2057 ret->alloc(nbTuples,3);
2058 double *retPtr(ret->getPointer());
2059 const double *ptr(begin());
2060 for(int i=0;i<nbTuples;i++,ptr+=3,retPtr+=3)
2062 retPtr[0]=sqrt(ptr[0]*ptr[0]+ptr[1]*ptr[1]);
2063 retPtr[1]=atan2(ptr[1],ptr[0]);
2070 * This method returns a newly created array to be deallocated that contains the result of conversion from cartesian to spherical coordinates.
2071 * \sa fromSpherToCart
2073 DataArrayDouble *DataArrayDouble::fromCartToSpher() const
2075 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2077 int nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2079 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToSpher : must be an array with exactly 3 components !");
2080 ret->alloc(nbTuples,3);
2081 double *retPtr(ret->getPointer());
2082 const double *ptr(begin());
2083 for(int i=0;i<nbTuples;i++,ptr+=3,retPtr+=3)
2085 retPtr[0]=sqrt(ptr[0]*ptr[0]+ptr[1]*ptr[1]+ptr[2]*ptr[2]);
2086 retPtr[1]=acos(ptr[2]/retPtr[0]);
2087 retPtr[2]=atan2(ptr[1],ptr[0]);
2093 * 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.
2094 * This method expects that \a this has exactly 3 components.
2095 * \sa MEDCouplingFieldDouble::computeVectorFieldCyl
2097 DataArrayDouble *DataArrayDouble::fromCartToCylGiven(const DataArrayDouble *coords, const double center[3], const double vect[3]) const
2100 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : input coords are NULL !");
2101 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2102 checkAllocated(); coords->checkAllocated();
2103 int nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2105 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : must be an array with exactly 3 components !");
2106 if(coords->getNumberOfComponents()!=3)
2107 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : coords array must have exactly 3 components !");
2108 if(coords->getNumberOfTuples()!=nbTuples)
2109 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : coords array must have the same number of tuples !");
2110 ret->alloc(nbTuples,nbOfComp);
2111 double magOfVect(sqrt(vect[0]*vect[0]+vect[1]*vect[1]+vect[2]*vect[2]));
2113 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : magnitude of vect is too low !");
2114 double Ur[3],Uteta[3],Uz[3],*retPtr(ret->getPointer());
2115 const double *coo(coords->begin()),*vectField(begin());
2116 std::transform(vect,vect+3,Uz,std::bind2nd(std::multiplies<double>(),1./magOfVect));
2117 for(int i=0;i<nbTuples;i++,vectField+=3,retPtr+=3,coo+=3)
2119 std::transform(coo,coo+3,center,Ur,std::minus<double>());
2120 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];
2121 double magOfTeta(sqrt(Uteta[0]*Uteta[0]+Uteta[1]*Uteta[1]+Uteta[2]*Uteta[2]));
2122 std::transform(Uteta,Uteta+3,Uteta,std::bind2nd(std::multiplies<double>(),1./magOfTeta));
2123 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];
2124 retPtr[0]=Ur[0]*vectField[0]+Ur[1]*vectField[1]+Ur[2]*vectField[2];
2125 retPtr[1]=Uteta[0]*vectField[0]+Uteta[1]*vectField[1]+Uteta[2]*vectField[2];
2126 retPtr[2]=Uz[0]*vectField[0]+Uz[1]*vectField[1]+Uz[2]*vectField[2];
2128 ret->copyStringInfoFrom(*this);
2133 * Computes the doubly contracted product of every tensor defined by the tuple of \a this
2134 * array contating 6 components.
2135 * \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
2136 * is calculated from the tuple <em>(t)</em> of \a this array as follows:
2137 * \f$ t[0]^2+t[1]^2+t[2]^2+2*t[3]^2+2*t[4]^2+2*t[5]^2\f$.
2138 * The caller is to delete this result array using decrRef() as it is no more needed.
2139 * \throw If \a this->getNumberOfComponents() != 6.
2141 DataArrayDouble *DataArrayDouble::doublyContractedProduct() const
2144 int nbOfComp(getNumberOfComponents());
2146 throw INTERP_KERNEL::Exception("DataArrayDouble::doublyContractedProduct : must be an array with exactly 6 components !");
2147 DataArrayDouble *ret=DataArrayDouble::New();
2148 int nbOfTuple=getNumberOfTuples();
2149 ret->alloc(nbOfTuple,1);
2150 const double *src=getConstPointer();
2151 double *dest=ret->getPointer();
2152 for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
2153 *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];
2158 * Computes the determinant of every square matrix defined by the tuple of \a this
2159 * array, which contains either 4, 6 or 9 components. The case of 6 components
2160 * corresponds to that of the upper triangular matrix.
2161 * \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
2162 * is the determinant of matrix of the corresponding tuple of \a this array.
2163 * The caller is to delete this result array using decrRef() as it is no more
2165 * \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2167 DataArrayDouble *DataArrayDouble::determinant() const
2170 DataArrayDouble *ret=DataArrayDouble::New();
2171 int nbOfTuple=getNumberOfTuples();
2172 ret->alloc(nbOfTuple,1);
2173 const double *src=getConstPointer();
2174 double *dest=ret->getPointer();
2175 switch(getNumberOfComponents())
2178 for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
2179 *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];
2182 for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
2183 *dest=src[0]*src[3]-src[1]*src[2];
2186 for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
2187 *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];
2191 throw INTERP_KERNEL::Exception("DataArrayDouble::determinant : Invalid number of components ! must be in 4,6,9 !");
2196 * Computes 3 eigenvalues of every upper triangular matrix defined by the tuple of
2197 * \a this array, which contains 6 components.
2198 * \return DataArrayDouble * - the new instance of DataArrayDouble containing 3
2199 * components, whose each tuple contains the eigenvalues of the matrix of
2200 * corresponding tuple of \a this array.
2201 * The caller is to delete this result array using decrRef() as it is no more
2203 * \throw If \a this->getNumberOfComponents() != 6.
2205 DataArrayDouble *DataArrayDouble::eigenValues() const
2208 int nbOfComp=getNumberOfComponents();
2210 throw INTERP_KERNEL::Exception("DataArrayDouble::eigenValues : must be an array with exactly 6 components !");
2211 DataArrayDouble *ret=DataArrayDouble::New();
2212 int nbOfTuple=getNumberOfTuples();
2213 ret->alloc(nbOfTuple,3);
2214 const double *src=getConstPointer();
2215 double *dest=ret->getPointer();
2216 for(int i=0;i<nbOfTuple;i++,dest+=3,src+=6)
2217 INTERP_KERNEL::computeEigenValues6(src,dest);
2222 * Computes 3 eigenvectors of every upper triangular matrix defined by the tuple of
2223 * \a this array, which contains 6 components.
2224 * \return DataArrayDouble * - the new instance of DataArrayDouble containing 9
2225 * components, whose each tuple contains 3 eigenvectors of the matrix of
2226 * corresponding tuple of \a this array.
2227 * The caller is to delete this result array using decrRef() as it is no more
2229 * \throw If \a this->getNumberOfComponents() != 6.
2231 DataArrayDouble *DataArrayDouble::eigenVectors() const
2234 int nbOfComp=getNumberOfComponents();
2236 throw INTERP_KERNEL::Exception("DataArrayDouble::eigenVectors : must be an array with exactly 6 components !");
2237 DataArrayDouble *ret=DataArrayDouble::New();
2238 int nbOfTuple=getNumberOfTuples();
2239 ret->alloc(nbOfTuple,9);
2240 const double *src=getConstPointer();
2241 double *dest=ret->getPointer();
2242 for(int i=0;i<nbOfTuple;i++,src+=6)
2245 INTERP_KERNEL::computeEigenValues6(src,tmp);
2246 for(int j=0;j<3;j++,dest+=3)
2247 INTERP_KERNEL::computeEigenVectorForEigenValue6(src,tmp[j],1e-12,dest);
2253 * Computes the inverse matrix of every matrix defined by the tuple of \a this
2254 * array, which contains either 4, 6 or 9 components. The case of 6 components
2255 * corresponds to that of the upper triangular matrix.
2256 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2257 * same number of components as \a this one, whose each tuple is the inverse
2258 * matrix of the matrix of corresponding tuple of \a this array.
2259 * The caller is to delete this result array using decrRef() as it is no more
2261 * \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2263 DataArrayDouble *DataArrayDouble::inverse() const
2266 int nbOfComp=getNumberOfComponents();
2267 if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
2268 throw INTERP_KERNEL::Exception("DataArrayDouble::inversion : must be an array with 4,6 or 9 components !");
2269 DataArrayDouble *ret=DataArrayDouble::New();
2270 int nbOfTuple=getNumberOfTuples();
2271 ret->alloc(nbOfTuple,nbOfComp);
2272 const double *src=getConstPointer();
2273 double *dest=ret->getPointer();
2275 for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
2277 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];
2278 dest[0]=(src[1]*src[2]-src[4]*src[4])/det;
2279 dest[1]=(src[0]*src[2]-src[5]*src[5])/det;
2280 dest[2]=(src[0]*src[1]-src[3]*src[3])/det;
2281 dest[3]=(src[5]*src[4]-src[3]*src[2])/det;
2282 dest[4]=(src[5]*src[3]-src[0]*src[4])/det;
2283 dest[5]=(src[3]*src[4]-src[1]*src[5])/det;
2285 else if(nbOfComp==4)
2286 for(int i=0;i<nbOfTuple;i++,dest+=4,src+=4)
2288 double det=src[0]*src[3]-src[1]*src[2];
2290 dest[1]=-src[1]/det;
2291 dest[2]=-src[2]/det;
2295 for(int i=0;i<nbOfTuple;i++,dest+=9,src+=9)
2297 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];
2298 dest[0]=(src[4]*src[8]-src[7]*src[5])/det;
2299 dest[1]=(src[7]*src[2]-src[1]*src[8])/det;
2300 dest[2]=(src[1]*src[5]-src[4]*src[2])/det;
2301 dest[3]=(src[6]*src[5]-src[3]*src[8])/det;
2302 dest[4]=(src[0]*src[8]-src[6]*src[2])/det;
2303 dest[5]=(src[2]*src[3]-src[0]*src[5])/det;
2304 dest[6]=(src[3]*src[7]-src[6]*src[4])/det;
2305 dest[7]=(src[6]*src[1]-src[0]*src[7])/det;
2306 dest[8]=(src[0]*src[4]-src[1]*src[3])/det;
2312 * Computes the trace of every matrix defined by the tuple of \a this
2313 * array, which contains either 4, 6 or 9 components. The case of 6 components
2314 * corresponds to that of the upper triangular matrix.
2315 * \return DataArrayDouble * - the new instance of DataArrayDouble containing
2316 * 1 component, whose each tuple is the trace of
2317 * the matrix of corresponding tuple of \a this array.
2318 * The caller is to delete this result array using decrRef() as it is no more
2320 * \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2322 DataArrayDouble *DataArrayDouble::trace() const
2325 int nbOfComp=getNumberOfComponents();
2326 if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
2327 throw INTERP_KERNEL::Exception("DataArrayDouble::trace : must be an array with 4,6 or 9 components !");
2328 DataArrayDouble *ret=DataArrayDouble::New();
2329 int nbOfTuple=getNumberOfTuples();
2330 ret->alloc(nbOfTuple,1);
2331 const double *src=getConstPointer();
2332 double *dest=ret->getPointer();
2334 for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
2335 *dest=src[0]+src[1]+src[2];
2336 else if(nbOfComp==4)
2337 for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
2338 *dest=src[0]+src[3];
2340 for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
2341 *dest=src[0]+src[4]+src[8];
2346 * Computes the stress deviator tensor of every stress tensor defined by the tuple of
2347 * \a this array, which contains 6 components.
2348 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2349 * same number of components and tuples as \a this array.
2350 * The caller is to delete this result array using decrRef() as it is no more
2352 * \throw If \a this->getNumberOfComponents() != 6.
2354 DataArrayDouble *DataArrayDouble::deviator() const
2357 int nbOfComp=getNumberOfComponents();
2359 throw INTERP_KERNEL::Exception("DataArrayDouble::deviator : must be an array with exactly 6 components !");
2360 DataArrayDouble *ret=DataArrayDouble::New();
2361 int nbOfTuple=getNumberOfTuples();
2362 ret->alloc(nbOfTuple,6);
2363 const double *src=getConstPointer();
2364 double *dest=ret->getPointer();
2365 for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
2367 double tr=(src[0]+src[1]+src[2])/3.;
2379 * Computes the magnitude of every vector defined by the tuple of
2381 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2382 * same number of tuples as \a this array and one component.
2383 * The caller is to delete this result array using decrRef() as it is no more
2385 * \throw If \a this is not allocated.
2387 DataArrayDouble *DataArrayDouble::magnitude() const
2390 int nbOfComp=getNumberOfComponents();
2391 DataArrayDouble *ret=DataArrayDouble::New();
2392 int nbOfTuple=getNumberOfTuples();
2393 ret->alloc(nbOfTuple,1);
2394 const double *src=getConstPointer();
2395 double *dest=ret->getPointer();
2396 for(int i=0;i<nbOfTuple;i++,dest++)
2399 for(int j=0;j<nbOfComp;j++,src++)
2407 * Computes for each tuple the sum of number of components values in the tuple and return it.
2409 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2410 * same number of tuples as \a this array and one component.
2411 * The caller is to delete this result array using decrRef() as it is no more
2413 * \throw If \a this is not allocated.
2415 DataArrayDouble *DataArrayDouble::sumPerTuple() const
2418 int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
2419 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2420 ret->alloc(nbOfTuple,1);
2421 const double *src(getConstPointer());
2422 double *dest(ret->getPointer());
2423 for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
2424 *dest=std::accumulate(src,src+nbOfComp,0.);
2429 * Computes the maximal value within every tuple of \a this array.
2430 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2431 * same number of tuples as \a this array and one component.
2432 * The caller is to delete this result array using decrRef() as it is no more
2434 * \throw If \a this is not allocated.
2435 * \sa DataArrayDouble::maxPerTupleWithCompoId
2437 DataArrayDouble *DataArrayDouble::maxPerTuple() const
2440 int nbOfComp=getNumberOfComponents();
2441 MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
2442 int nbOfTuple=getNumberOfTuples();
2443 ret->alloc(nbOfTuple,1);
2444 const double *src=getConstPointer();
2445 double *dest=ret->getPointer();
2446 for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
2447 *dest=*std::max_element(src,src+nbOfComp);
2452 * Computes the maximal value within every tuple of \a this array and it returns the first component
2453 * id for each tuple that corresponds to the maximal value within the tuple.
2455 * \param [out] compoIdOfMaxPerTuple - the new new instance of DataArrayInt containing the
2456 * same number of tuples and only one component.
2457 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2458 * same number of tuples as \a this array and one component.
2459 * The caller is to delete this result array using decrRef() as it is no more
2461 * \throw If \a this is not allocated.
2462 * \sa DataArrayDouble::maxPerTuple
2464 DataArrayDouble *DataArrayDouble::maxPerTupleWithCompoId(DataArrayInt* &compoIdOfMaxPerTuple) const
2467 int nbOfComp=getNumberOfComponents();
2468 MCAuto<DataArrayDouble> ret0=DataArrayDouble::New();
2469 MCAuto<DataArrayInt> ret1=DataArrayInt::New();
2470 int nbOfTuple=getNumberOfTuples();
2471 ret0->alloc(nbOfTuple,1); ret1->alloc(nbOfTuple,1);
2472 const double *src=getConstPointer();
2473 double *dest=ret0->getPointer(); int *dest1=ret1->getPointer();
2474 for(int i=0;i<nbOfTuple;i++,dest++,dest1++,src+=nbOfComp)
2476 const double *loc=std::max_element(src,src+nbOfComp);
2478 *dest1=(int)std::distance(src,loc);
2480 compoIdOfMaxPerTuple=ret1.retn();
2485 * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c this->getNumberOfTuples() tuples.
2486 * \n This returned array contains the euclidian distance for each tuple in \a this.
2487 * \n So the returned array can be seen as a dense symmetrical matrix whose diagonal elements are equal to 0.
2488 * \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)
2490 * \warning use this method with care because it can leads to big amount of consumed memory !
2492 * \return A newly allocated (huge) MEDCoupling::DataArrayDouble instance that the caller should deal with.
2494 * \throw If \a this is not allocated.
2496 * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrixWith
2498 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrix() const
2501 int nbOfComp=getNumberOfComponents();
2502 int nbOfTuples=getNumberOfTuples();
2503 const double *inData=getConstPointer();
2504 MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
2505 ret->alloc(nbOfTuples*nbOfTuples,1);
2506 double *outData=ret->getPointer();
2507 for(int i=0;i<nbOfTuples;i++)
2509 outData[i*nbOfTuples+i]=0.;
2510 for(int j=i+1;j<nbOfTuples;j++)
2513 for(int k=0;k<nbOfComp;k++)
2514 { double delta=inData[i*nbOfComp+k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
2516 outData[i*nbOfTuples+j]=dist;
2517 outData[j*nbOfTuples+i]=dist;
2524 * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c other->getNumberOfTuples() tuples.
2525 * \n This returned array contains the euclidian distance for each tuple in \a other with each tuple in \a this.
2526 * \n So the returned array can be seen as a dense rectangular matrix with \c other->getNumberOfTuples() rows and \c this->getNumberOfTuples() columns.
2527 * \n Output rectangular matrix is sorted along rows.
2528 * \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)
2530 * \warning use this method with care because it can leads to big amount of consumed memory !
2532 * \param [in] other DataArrayDouble instance having same number of components than \a this.
2533 * \return A newly allocated (huge) MEDCoupling::DataArrayDouble instance that the caller should deal with.
2535 * \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.
2537 * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrix
2539 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrixWith(const DataArrayDouble *other) const
2542 throw INTERP_KERNEL::Exception("DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : input parameter is null !");
2544 other->checkAllocated();
2545 int nbOfComp=getNumberOfComponents();
2546 int otherNbOfComp=other->getNumberOfComponents();
2547 if(nbOfComp!=otherNbOfComp)
2549 std::ostringstream oss; oss << "DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : this nb of compo=" << nbOfComp << " and other nb of compo=" << otherNbOfComp << ". It should match !";
2550 throw INTERP_KERNEL::Exception(oss.str().c_str());
2552 int nbOfTuples=getNumberOfTuples();
2553 int otherNbOfTuples=other->getNumberOfTuples();
2554 const double *inData=getConstPointer();
2555 const double *inDataOther=other->getConstPointer();
2556 MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
2557 ret->alloc(otherNbOfTuples*nbOfTuples,1);
2558 double *outData=ret->getPointer();
2559 for(int i=0;i<otherNbOfTuples;i++,inDataOther+=nbOfComp)
2561 for(int j=0;j<nbOfTuples;j++)
2564 for(int k=0;k<nbOfComp;k++)
2565 { double delta=inDataOther[k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
2567 outData[i*nbOfTuples+j]=dist;
2574 * Sorts value within every tuple of \a this array.
2575 * \param [in] asc - if \a true, the values are sorted in ascending order, else,
2576 * in descending order.
2577 * \throw If \a this is not allocated.
2579 void DataArrayDouble::sortPerTuple(bool asc)
2582 double *pt=getPointer();
2583 int nbOfTuple=getNumberOfTuples();
2584 int nbOfComp=getNumberOfComponents();
2586 for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
2587 std::sort(pt,pt+nbOfComp);
2589 for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
2590 std::sort(pt,pt+nbOfComp,std::greater<double>());
2595 * Modify all elements of \a this array, so that
2596 * an element _x_ becomes \f$ numerator / x \f$.
2597 * \warning If an exception is thrown because of presence of 0.0 element in \a this
2598 * array, all elements processed before detection of the zero element remain
2600 * \param [in] numerator - the numerator used to modify array elements.
2601 * \throw If \a this is not allocated.
2602 * \throw If there is an element equal to 0.0 in \a this array.
2604 void DataArrayDouble::applyInv(double numerator)
2607 double *ptr=getPointer();
2608 std::size_t nbOfElems=getNbOfElems();
2609 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2611 if(std::abs(*ptr)>std::numeric_limits<double>::min())
2613 *ptr=numerator/(*ptr);
2617 std::ostringstream oss; oss << "DataArrayDouble::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
2619 throw INTERP_KERNEL::Exception(oss.str().c_str());
2626 * Modify all elements of \a this array, so that
2627 * an element _x_ becomes <em> val ^ x </em>. Contrary to DataArrayInt::applyPow
2628 * all values in \a this have to be >= 0 if val is \b not integer.
2629 * \param [in] val - the value used to apply pow on all array elements.
2630 * \throw If \a this is not allocated.
2631 * \warning If an exception is thrown because of presence of 0 element in \a this
2632 * array and \a val is \b not integer, all elements processed before detection of the zero element remain
2635 void DataArrayDouble::applyPow(double val)
2638 double *ptr=getPointer();
2639 std::size_t nbOfElems=getNbOfElems();
2641 bool isInt=((double)val2)==val;
2644 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2650 std::ostringstream oss; oss << "DataArrayDouble::applyPow (double) : At elem # " << i << " value is " << *ptr << " ! must be >=0. !";
2651 throw INTERP_KERNEL::Exception(oss.str().c_str());
2657 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2658 *ptr=pow(*ptr,val2);
2664 * Modify all elements of \a this array, so that
2665 * an element _x_ becomes \f$ val ^ x \f$.
2666 * \param [in] val - the value used to apply pow on all array elements.
2667 * \throw If \a this is not allocated.
2668 * \throw If \a val < 0.
2669 * \warning If an exception is thrown because of presence of 0 element in \a this
2670 * array, all elements processed before detection of the zero element remain
2673 void DataArrayDouble::applyRPow(double val)
2677 throw INTERP_KERNEL::Exception("DataArrayDouble::applyRPow : the input value has to be >= 0 !");
2678 double *ptr=getPointer();
2679 std::size_t nbOfElems=getNbOfElems();
2680 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2686 * Returns a new DataArrayDouble created from \a this one by applying \a
2687 * FunctionToEvaluate to every tuple of \a this array. Textual data is not copied.
2688 * For more info see \ref MEDCouplingArrayApplyFunc
2689 * \param [in] nbOfComp - number of components in the result array.
2690 * \param [in] func - the \a FunctionToEvaluate declared as
2691 * \c bool (*\a func)(\c const \c double *\a pos, \c double *\a res),
2692 * where \a pos points to the first component of a tuple of \a this array
2693 * and \a res points to the first component of a tuple of the result array.
2694 * Note that length (number of components) of \a pos can differ from
2696 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2697 * same number of tuples as \a this array.
2698 * The caller is to delete this result array using decrRef() as it is no more
2700 * \throw If \a this is not allocated.
2701 * \throw If \a func returns \a false.
2703 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, FunctionToEvaluate func) const
2706 DataArrayDouble *newArr=DataArrayDouble::New();
2707 int nbOfTuples=getNumberOfTuples();
2708 int oldNbOfComp=getNumberOfComponents();
2709 newArr->alloc(nbOfTuples,nbOfComp);
2710 const double *ptr=getConstPointer();
2711 double *ptrToFill=newArr->getPointer();
2712 for(int i=0;i<nbOfTuples;i++)
2714 if(!func(ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp))
2716 std::ostringstream oss; oss << "For tuple # " << i << " with value (";
2717 std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
2718 oss << ") : Evaluation of function failed !";
2720 throw INTERP_KERNEL::Exception(oss.str().c_str());
2727 * Returns a new DataArrayDouble created from \a this one by applying a function to every
2728 * tuple of \a this array. Textual data is not copied.
2729 * For more info see \ref MEDCouplingArrayApplyFunc1.
2730 * \param [in] nbOfComp - number of components in the result array.
2731 * \param [in] func - the expression defining how to transform a tuple of \a this array.
2732 * Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
2733 * \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
2734 * If false the computation is carried on without any notification. When false the evaluation is a little faster.
2735 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2736 * same number of tuples as \a this array and \a nbOfComp components.
2737 * The caller is to delete this result array using decrRef() as it is no more
2739 * \throw If \a this is not allocated.
2740 * \throw If computing \a func fails.
2742 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, const std::string& func, bool isSafe) const
2744 INTERP_KERNEL::ExprParser expr(func);
2746 std::set<std::string> vars;
2747 expr.getTrueSetOfVars(vars);
2748 std::vector<std::string> varsV(vars.begin(),vars.end());
2749 return applyFuncNamedCompo(nbOfComp,varsV,func,isSafe);
2753 * Returns a new DataArrayDouble created from \a this one by applying a function to every
2754 * tuple of \a this array. Textual data is not copied. This method works by tuples (whatever its size).
2755 * If \a this is a one component array, call applyFuncOnThis instead that performs the same work faster.
2757 * For more info see \ref MEDCouplingArrayApplyFunc0.
2758 * \param [in] func - the expression defining how to transform a tuple of \a this array.
2759 * Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
2760 * \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
2761 * If false the computation is carried on without any notification. When false the evaluation is a little faster.
2762 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2763 * same number of tuples and components as \a this array.
2764 * The caller is to delete this result array using decrRef() as it is no more
2766 * \sa applyFuncOnThis
2767 * \throw If \a this is not allocated.
2768 * \throw If computing \a func fails.
2770 DataArrayDouble *DataArrayDouble::applyFunc(const std::string& func, bool isSafe) const
2772 int nbOfComp(getNumberOfComponents());
2774 throw INTERP_KERNEL::Exception("DataArrayDouble::applyFunc : output number of component must be > 0 !");
2776 int nbOfTuples(getNumberOfTuples());
2777 MCAuto<DataArrayDouble> newArr(DataArrayDouble::New());
2778 newArr->alloc(nbOfTuples,nbOfComp);
2779 INTERP_KERNEL::ExprParser expr(func);
2781 std::set<std::string> vars;
2782 expr.getTrueSetOfVars(vars);
2783 if((int)vars.size()>1)
2785 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 : ";
2786 std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
2787 throw INTERP_KERNEL::Exception(oss.str().c_str());
2791 expr.prepareFastEvaluator();
2792 newArr->rearrange(1);
2793 newArr->fillWithValue(expr.evaluateDouble());
2794 newArr->rearrange(nbOfComp);
2795 return newArr.retn();
2797 std::vector<std::string> vars2(vars.begin(),vars.end());
2798 double buff,*ptrToFill(newArr->getPointer());
2799 const double *ptr(begin());
2800 std::vector<double> stck;
2801 expr.prepareExprEvaluationDouble(vars2,1,1,0,&buff,&buff+1);
2802 expr.prepareFastEvaluator();
2805 for(int i=0;i<nbOfTuples;i++)
2807 for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
2810 expr.evaluateDoubleInternal(stck);
2811 *ptrToFill=stck.back();
2818 for(int i=0;i<nbOfTuples;i++)
2820 for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
2825 expr.evaluateDoubleInternalSafe(stck);
2827 catch(INTERP_KERNEL::Exception& e)
2829 std::ostringstream oss; oss << "For tuple # " << i << " component # " << iComp << " with value (";
2831 oss << ") : Evaluation of function failed !" << e.what();
2832 throw INTERP_KERNEL::Exception(oss.str().c_str());
2834 *ptrToFill=stck.back();
2839 return newArr.retn();
2843 * This method is a non const method that modify the array in \a this.
2844 * This method only works on one component array. It means that function \a func must
2845 * contain at most one variable.
2846 * This method is a specialization of applyFunc method with one parameter on one component array.
2848 * \param [in] func - the expression defining how to transform a tuple of \a this array.
2849 * Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
2850 * \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
2851 * If false the computation is carried on without any notification. When false the evaluation is a little faster.
2855 void DataArrayDouble::applyFuncOnThis(const std::string& func, bool isSafe)
2857 int nbOfComp(getNumberOfComponents());
2859 throw INTERP_KERNEL::Exception("DataArrayDouble::applyFuncOnThis : output number of component must be > 0 !");
2861 int nbOfTuples(getNumberOfTuples());
2862 INTERP_KERNEL::ExprParser expr(func);
2864 std::set<std::string> vars;
2865 expr.getTrueSetOfVars(vars);
2866 if((int)vars.size()>1)
2868 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 : ";
2869 std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
2870 throw INTERP_KERNEL::Exception(oss.str().c_str());
2874 expr.prepareFastEvaluator();
2875 std::vector<std::string> compInfo(getInfoOnComponents());
2877 fillWithValue(expr.evaluateDouble());
2878 rearrange(nbOfComp);
2879 setInfoOnComponents(compInfo);
2882 std::vector<std::string> vars2(vars.begin(),vars.end());
2883 double buff,*ptrToFill(getPointer());
2884 const double *ptr(begin());
2885 std::vector<double> stck;
2886 expr.prepareExprEvaluationDouble(vars2,1,1,0,&buff,&buff+1);
2887 expr.prepareFastEvaluator();
2890 for(int i=0;i<nbOfTuples;i++)
2892 for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
2895 expr.evaluateDoubleInternal(stck);
2896 *ptrToFill=stck.back();
2903 for(int i=0;i<nbOfTuples;i++)
2905 for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
2910 expr.evaluateDoubleInternalSafe(stck);
2912 catch(INTERP_KERNEL::Exception& e)
2914 std::ostringstream oss; oss << "For tuple # " << i << " component # " << iComp << " with value (";
2916 oss << ") : Evaluation of function failed !" << e.what();
2917 throw INTERP_KERNEL::Exception(oss.str().c_str());
2919 *ptrToFill=stck.back();
2927 * Returns a new DataArrayDouble created from \a this one by applying a function to every
2928 * tuple of \a this array. Textual data is not copied.
2929 * For more info see \ref MEDCouplingArrayApplyFunc2.
2930 * \param [in] nbOfComp - number of components in the result array.
2931 * \param [in] func - the expression defining how to transform a tuple of \a this array.
2932 * Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
2933 * \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
2934 * If false the computation is carried on without any notification. When false the evaluation is a little faster.
2935 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2936 * same number of tuples as \a this array.
2937 * The caller is to delete this result array using decrRef() as it is no more
2939 * \throw If \a this is not allocated.
2940 * \throw If \a func contains vars that are not in \a this->getInfoOnComponent().
2941 * \throw If computing \a func fails.
2943 DataArrayDouble *DataArrayDouble::applyFuncCompo(int nbOfComp, const std::string& func, bool isSafe) const
2945 return applyFuncNamedCompo(nbOfComp,getVarsOnComponent(),func,isSafe);
2949 * Returns a new DataArrayDouble created from \a this one by applying a function to every
2950 * tuple of \a this array. Textual data is not copied.
2951 * For more info see \ref MEDCouplingArrayApplyFunc3.
2952 * \param [in] nbOfComp - number of components in the result array.
2953 * \param [in] varsOrder - sequence of vars defining their order.
2954 * \param [in] func - the expression defining how to transform a tuple of \a this array.
2955 * Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
2956 * \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
2957 * If false the computation is carried on without any notification. When false the evaluation is a little faster.
2958 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2959 * same number of tuples as \a this array.
2960 * The caller is to delete this result array using decrRef() as it is no more
2962 * \throw If \a this is not allocated.
2963 * \throw If \a func contains vars not in \a varsOrder.
2964 * \throw If computing \a func fails.
2966 DataArrayDouble *DataArrayDouble::applyFuncNamedCompo(int nbOfComp, const std::vector<std::string>& varsOrder, const std::string& func, bool isSafe) const
2969 throw INTERP_KERNEL::Exception("DataArrayDouble::applyFuncNamedCompo : output number of component must be > 0 !");
2970 std::vector<std::string> varsOrder2(varsOrder);
2971 int oldNbOfComp(getNumberOfComponents());
2972 for(int i=(int)varsOrder.size();i<oldNbOfComp;i++)
2973 varsOrder2.push_back(std::string());
2975 int nbOfTuples(getNumberOfTuples());
2976 INTERP_KERNEL::ExprParser expr(func);
2978 std::set<std::string> vars;
2979 expr.getTrueSetOfVars(vars);
2980 if((int)vars.size()>oldNbOfComp)
2982 std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
2983 oss << vars.size() << " variables : ";
2984 std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
2985 throw INTERP_KERNEL::Exception(oss.str().c_str());
2987 MCAuto<DataArrayDouble> newArr(DataArrayDouble::New());
2988 newArr->alloc(nbOfTuples,nbOfComp);
2989 INTERP_KERNEL::AutoPtr<double> buff(new double[oldNbOfComp]);
2990 double *buffPtr(buff),*ptrToFill;
2991 std::vector<double> stck;
2992 for(int iComp=0;iComp<nbOfComp;iComp++)
2994 expr.prepareExprEvaluationDouble(varsOrder2,oldNbOfComp,nbOfComp,iComp,buffPtr,buffPtr+oldNbOfComp);
2995 expr.prepareFastEvaluator();
2996 const double *ptr(getConstPointer());
2997 ptrToFill=newArr->getPointer()+iComp;
3000 for(int i=0;i<nbOfTuples;i++,ptrToFill+=nbOfComp,ptr+=oldNbOfComp)
3002 std::copy(ptr,ptr+oldNbOfComp,buffPtr);
3003 expr.evaluateDoubleInternal(stck);
3004 *ptrToFill=stck.back();
3010 for(int i=0;i<nbOfTuples;i++,ptrToFill+=nbOfComp,ptr+=oldNbOfComp)
3012 std::copy(ptr,ptr+oldNbOfComp,buffPtr);
3015 expr.evaluateDoubleInternalSafe(stck);
3016 *ptrToFill=stck.back();
3019 catch(INTERP_KERNEL::Exception& e)
3021 std::ostringstream oss; oss << "For tuple # " << i << " with value (";
3022 std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
3023 oss << ") : Evaluation of function failed !" << e.what();
3024 throw INTERP_KERNEL::Exception(oss.str().c_str());
3029 return newArr.retn();
3032 void DataArrayDouble::applyFuncFast32(const std::string& func)
3035 INTERP_KERNEL::ExprParser expr(func);
3037 char *funcStr=expr.compileX86();
3039 *((void **)&funcPtr)=funcStr;//he he...
3041 double *ptr=getPointer();
3042 int nbOfComp=getNumberOfComponents();
3043 int nbOfTuples=getNumberOfTuples();
3044 int nbOfElems=nbOfTuples*nbOfComp;
3045 for(int i=0;i<nbOfElems;i++,ptr++)
3050 void DataArrayDouble::applyFuncFast64(const std::string& func)
3053 INTERP_KERNEL::ExprParser expr(func);
3055 char *funcStr=expr.compileX86_64();
3057 *((void **)&funcPtr)=funcStr;//he he...
3059 double *ptr=getPointer();
3060 int nbOfComp=getNumberOfComponents();
3061 int nbOfTuples=getNumberOfTuples();
3062 int nbOfElems=nbOfTuples*nbOfComp;
3063 for(int i=0;i<nbOfElems;i++,ptr++)
3069 * \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.
3071 MCAuto<DataArrayDouble> DataArrayDouble::symmetry3DPlane(const double point[3], const double normalVector[3]) const
3074 if(getNumberOfComponents()!=3)
3075 throw INTERP_KERNEL::Exception("DataArrayDouble::symmetry3DPlane : this is excepted to have 3 components !");
3076 int nbTuples(getNumberOfTuples());
3077 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
3078 ret->alloc(nbTuples,3);
3079 Symmetry3DPlane(point,normalVector,nbTuples,begin(),ret->getPointer());
3083 DataArrayDoubleIterator *DataArrayDouble::iterator()
3085 return new DataArrayDoubleIterator(this);
3089 * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional
3090 * array whose values are within a given range. Textual data is not copied.
3091 * \param [in] vmin - a lowest acceptable value (included).
3092 * \param [in] vmax - a greatest acceptable value (included).
3093 * \return DataArrayInt * - the new instance of DataArrayInt.
3094 * The caller is to delete this result array using decrRef() as it is no more
3096 * \throw If \a this->getNumberOfComponents() != 1.
3098 * \sa DataArrayDouble::findIdsNotInRange
3100 * \if ENABLE_EXAMPLES
3101 * \ref cpp_mcdataarraydouble_getidsinrange "Here is a C++ example".<br>
3102 * \ref py_mcdataarraydouble_getidsinrange "Here is a Python example".
3105 DataArrayInt *DataArrayDouble::findIdsInRange(double vmin, double vmax) const
3108 if(getNumberOfComponents()!=1)
3109 throw INTERP_KERNEL::Exception("DataArrayDouble::findIdsInRange : this must have exactly one component !");
3110 const double *cptr(begin());
3111 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
3112 int nbOfTuples(getNumberOfTuples());
3113 for(int i=0;i<nbOfTuples;i++,cptr++)
3114 if(*cptr>=vmin && *cptr<=vmax)
3115 ret->pushBackSilent(i);
3120 * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional
3121 * array whose values are not within a given range. Textual data is not copied.
3122 * \param [in] vmin - a lowest not acceptable value (excluded).
3123 * \param [in] vmax - a greatest not acceptable value (excluded).
3124 * \return DataArrayInt * - the new instance of DataArrayInt.
3125 * The caller is to delete this result array using decrRef() as it is no more
3127 * \throw If \a this->getNumberOfComponents() != 1.
3129 * \sa DataArrayDouble::findIdsInRange
3131 DataArrayInt *DataArrayDouble::findIdsNotInRange(double vmin, double vmax) const
3134 if(getNumberOfComponents()!=1)
3135 throw INTERP_KERNEL::Exception("DataArrayDouble::findIdsNotInRange : this must have exactly one component !");
3136 const double *cptr(begin());
3137 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
3138 int nbOfTuples(getNumberOfTuples());
3139 for(int i=0;i<nbOfTuples;i++,cptr++)
3140 if(*cptr<vmin || *cptr>vmax)
3141 ret->pushBackSilent(i);
3146 * Returns a new DataArrayDouble by concatenating two given arrays, so that (1) the number
3147 * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
3148 * the number of component in the result array is same as that of each of given arrays.
3149 * Info on components is copied from the first of the given arrays. Number of components
3150 * in the given arrays must be the same.
3151 * \param [in] a1 - an array to include in the result array.
3152 * \param [in] a2 - another array to include in the result array.
3153 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3154 * The caller is to delete this result array using decrRef() as it is no more
3156 * \throw If both \a a1 and \a a2 are NULL.
3157 * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
3159 DataArrayDouble *DataArrayDouble::Aggregate(const DataArrayDouble *a1, const DataArrayDouble *a2)
3161 std::vector<const DataArrayDouble *> tmp(2);
3162 tmp[0]=a1; tmp[1]=a2;
3163 return Aggregate(tmp);
3167 * Returns a new DataArrayDouble by concatenating all given arrays, so that (1) the number
3168 * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
3169 * the number of component in the result array is same as that of each of given arrays.
3170 * Info on components is copied from the first of the given arrays. Number of components
3171 * in the given arrays must be the same.
3172 * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it
3173 * not the object itself.
3174 * \param [in] arr - a sequence of arrays to include in the result array.
3175 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3176 * The caller is to delete this result array using decrRef() as it is no more
3178 * \throw If all arrays within \a arr are NULL.
3179 * \throw If getNumberOfComponents() of arrays within \a arr.
3181 DataArrayDouble *DataArrayDouble::Aggregate(const std::vector<const DataArrayDouble *>& arr)
3183 std::vector<const DataArrayDouble *> a;
3184 for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
3188 throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : input list must contain at least one NON EMPTY DataArrayDouble !");
3189 std::vector<const DataArrayDouble *>::const_iterator it=a.begin();
3190 int nbOfComp=(*it)->getNumberOfComponents();
3191 int nbt=(*it++)->getNumberOfTuples();
3192 for(int i=1;it!=a.end();it++,i++)
3194 if((*it)->getNumberOfComponents()!=nbOfComp)
3195 throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : Nb of components mismatch for array aggregation !");
3196 nbt+=(*it)->getNumberOfTuples();
3198 MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
3199 ret->alloc(nbt,nbOfComp);
3200 double *pt=ret->getPointer();
3201 for(it=a.begin();it!=a.end();it++)
3202 pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
3203 ret->copyStringInfoFrom(*(a[0]));
3208 * Returns a new DataArrayDouble containing a dot product of two given arrays, so that
3209 * the i-th tuple of the result array is a sum of products of j-th components of i-th
3210 * tuples of given arrays (\f$ a_i = \sum_{j=1}^n a1_j * a2_j \f$).
3211 * Info on components and name is copied from the first of the given arrays.
3212 * Number of tuples and components in the given arrays must be the same.
3213 * \param [in] a1 - a given array.
3214 * \param [in] a2 - another given array.
3215 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3216 * The caller is to delete this result array using decrRef() as it is no more
3218 * \throw If either \a a1 or \a a2 is NULL.
3219 * \throw If any given array is not allocated.
3220 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3221 * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
3223 DataArrayDouble *DataArrayDouble::Dot(const DataArrayDouble *a1, const DataArrayDouble *a2)
3226 throw INTERP_KERNEL::Exception("DataArrayDouble::Dot : input DataArrayDouble instance is NULL !");
3227 a1->checkAllocated();
3228 a2->checkAllocated();
3229 int nbOfComp=a1->getNumberOfComponents();
3230 if(nbOfComp!=a2->getNumberOfComponents())
3231 throw INTERP_KERNEL::Exception("Nb of components mismatch for array Dot !");
3232 int nbOfTuple=a1->getNumberOfTuples();
3233 if(nbOfTuple!=a2->getNumberOfTuples())
3234 throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Dot !");
3235 DataArrayDouble *ret=DataArrayDouble::New();
3236 ret->alloc(nbOfTuple,1);
3237 double *retPtr=ret->getPointer();
3238 const double *a1Ptr=a1->getConstPointer();
3239 const double *a2Ptr=a2->getConstPointer();
3240 for(int i=0;i<nbOfTuple;i++)
3243 for(int j=0;j<nbOfComp;j++)
3244 sum+=a1Ptr[i*nbOfComp+j]*a2Ptr[i*nbOfComp+j];
3247 ret->setInfoOnComponent(0,a1->getInfoOnComponent(0));
3248 ret->setName(a1->getName());
3253 * Returns a new DataArrayDouble containing a cross product of two given arrays, so that
3254 * the i-th tuple of the result array contains 3 components of a vector which is a cross
3255 * product of two vectors defined by the i-th tuples of given arrays.
3256 * Info on components is copied from the first of the given arrays.
3257 * Number of tuples in the given arrays must be the same.
3258 * Number of components in the given arrays must be 3.
3259 * \param [in] a1 - a given array.
3260 * \param [in] a2 - another given array.
3261 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3262 * The caller is to delete this result array using decrRef() as it is no more
3264 * \throw If either \a a1 or \a a2 is NULL.
3265 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3266 * \throw If \a a1->getNumberOfComponents() != 3
3267 * \throw If \a a2->getNumberOfComponents() != 3
3269 DataArrayDouble *DataArrayDouble::CrossProduct(const DataArrayDouble *a1, const DataArrayDouble *a2)
3272 throw INTERP_KERNEL::Exception("DataArrayDouble::CrossProduct : input DataArrayDouble instance is NULL !");
3273 int nbOfComp=a1->getNumberOfComponents();
3274 if(nbOfComp!=a2->getNumberOfComponents())
3275 throw INTERP_KERNEL::Exception("Nb of components mismatch for array crossProduct !");
3277 throw INTERP_KERNEL::Exception("Nb of components must be equal to 3 for array crossProduct !");
3278 int nbOfTuple=a1->getNumberOfTuples();
3279 if(nbOfTuple!=a2->getNumberOfTuples())
3280 throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array crossProduct !");
3281 DataArrayDouble *ret=DataArrayDouble::New();
3282 ret->alloc(nbOfTuple,3);
3283 double *retPtr=ret->getPointer();
3284 const double *a1Ptr=a1->getConstPointer();
3285 const double *a2Ptr=a2->getConstPointer();
3286 for(int i=0;i<nbOfTuple;i++)
3288 retPtr[3*i]=a1Ptr[3*i+1]*a2Ptr[3*i+2]-a1Ptr[3*i+2]*a2Ptr[3*i+1];
3289 retPtr[3*i+1]=a1Ptr[3*i+2]*a2Ptr[3*i]-a1Ptr[3*i]*a2Ptr[3*i+2];
3290 retPtr[3*i+2]=a1Ptr[3*i]*a2Ptr[3*i+1]-a1Ptr[3*i+1]*a2Ptr[3*i];
3292 ret->copyStringInfoFrom(*a1);
3297 * Returns a new DataArrayDouble containing maximal values of two given arrays.
3298 * Info on components is copied from the first of the given arrays.
3299 * Number of tuples and components in the given arrays must be the same.
3300 * \param [in] a1 - an array to compare values with another one.
3301 * \param [in] a2 - another array to compare values with the first one.
3302 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3303 * The caller is to delete this result array using decrRef() as it is no more
3305 * \throw If either \a a1 or \a a2 is NULL.
3306 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3307 * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
3309 DataArrayDouble *DataArrayDouble::Max(const DataArrayDouble *a1, const DataArrayDouble *a2)
3312 throw INTERP_KERNEL::Exception("DataArrayDouble::Max : input DataArrayDouble instance is NULL !");
3313 int nbOfComp=a1->getNumberOfComponents();
3314 if(nbOfComp!=a2->getNumberOfComponents())
3315 throw INTERP_KERNEL::Exception("Nb of components mismatch for array Max !");
3316 int nbOfTuple=a1->getNumberOfTuples();
3317 if(nbOfTuple!=a2->getNumberOfTuples())
3318 throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Max !");
3319 DataArrayDouble *ret=DataArrayDouble::New();
3320 ret->alloc(nbOfTuple,nbOfComp);
3321 double *retPtr=ret->getPointer();
3322 const double *a1Ptr=a1->getConstPointer();
3323 const double *a2Ptr=a2->getConstPointer();
3324 int nbElem=nbOfTuple*nbOfComp;
3325 for(int i=0;i<nbElem;i++)
3326 retPtr[i]=std::max(a1Ptr[i],a2Ptr[i]);
3327 ret->copyStringInfoFrom(*a1);
3332 * Returns a new DataArrayDouble containing minimal values of two given arrays.
3333 * Info on components is copied from the first of the given arrays.
3334 * Number of tuples and components in the given arrays must be the same.
3335 * \param [in] a1 - an array to compare values with another one.
3336 * \param [in] a2 - another array to compare values with the first one.
3337 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3338 * The caller is to delete this result array using decrRef() as it is no more
3340 * \throw If either \a a1 or \a a2 is NULL.
3341 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3342 * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
3344 DataArrayDouble *DataArrayDouble::Min(const DataArrayDouble *a1, const DataArrayDouble *a2)
3347 throw INTERP_KERNEL::Exception("DataArrayDouble::Min : input DataArrayDouble instance is NULL !");
3348 int nbOfComp=a1->getNumberOfComponents();
3349 if(nbOfComp!=a2->getNumberOfComponents())
3350 throw INTERP_KERNEL::Exception("Nb of components mismatch for array min !");
3351 int nbOfTuple=a1->getNumberOfTuples();
3352 if(nbOfTuple!=a2->getNumberOfTuples())
3353 throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array min !");
3354 DataArrayDouble *ret=DataArrayDouble::New();
3355 ret->alloc(nbOfTuple,nbOfComp);
3356 double *retPtr=ret->getPointer();
3357 const double *a1Ptr=a1->getConstPointer();
3358 const double *a2Ptr=a2->getConstPointer();
3359 int nbElem=nbOfTuple*nbOfComp;
3360 for(int i=0;i<nbElem;i++)
3361 retPtr[i]=std::min(a1Ptr[i],a2Ptr[i]);
3362 ret->copyStringInfoFrom(*a1);
3367 * Returns a new DataArrayDouble that is the result of pow of two given arrays. There are 3
3370 * \param [in] a1 - an array to pow up.
3371 * \param [in] a2 - another array to sum up.
3372 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3373 * The caller is to delete this result array using decrRef() as it is no more
3375 * \throw If either \a a1 or \a a2 is NULL.
3376 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3377 * \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
3378 * \throw If there is a negative value in \a a1.
3380 DataArrayDouble *DataArrayDouble::Pow(const DataArrayDouble *a1, const DataArrayDouble *a2)
3383 throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : at least one of input instances is null !");
3384 int nbOfTuple=a1->getNumberOfTuples();
3385 int nbOfTuple2=a2->getNumberOfTuples();
3386 int nbOfComp=a1->getNumberOfComponents();
3387 int nbOfComp2=a2->getNumberOfComponents();
3388 if(nbOfTuple!=nbOfTuple2)
3389 throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of tuples mismatches !");
3390 if(nbOfComp!=1 || nbOfComp2!=1)
3391 throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of components of both arrays must be equal to 1 !");
3392 MCAuto<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbOfTuple,1);
3393 const double *ptr1(a1->begin()),*ptr2(a2->begin());
3394 double *ptr=ret->getPointer();
3395 for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
3399 *ptr=pow(*ptr1,*ptr2);
3403 std::ostringstream oss; oss << "DataArrayDouble::Pow : on tuple #" << i << " of a1 value is < 0 (" << *ptr1 << ") !";
3404 throw INTERP_KERNEL::Exception(oss.str().c_str());
3411 * Apply pow on values of another DataArrayDouble to values of \a this one.
3413 * \param [in] other - an array to pow to \a this one.
3414 * \throw If \a other is NULL.
3415 * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
3416 * \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
3417 * \throw If there is a negative value in \a this.
3419 void DataArrayDouble::powEqual(const DataArrayDouble *other)
3422 throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : input instance is null !");
3423 int nbOfTuple=getNumberOfTuples();
3424 int nbOfTuple2=other->getNumberOfTuples();
3425 int nbOfComp=getNumberOfComponents();
3426 int nbOfComp2=other->getNumberOfComponents();
3427 if(nbOfTuple!=nbOfTuple2)
3428 throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of tuples mismatches !");
3429 if(nbOfComp!=1 || nbOfComp2!=1)
3430 throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of components of both arrays must be equal to 1 !");
3431 double *ptr=getPointer();
3432 const double *ptrc=other->begin();
3433 for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
3436 *ptr=pow(*ptr,*ptrc);
3439 std::ostringstream oss; oss << "DataArrayDouble::powEqual : on tuple #" << i << " of this value is < 0 (" << *ptr << ") !";
3440 throw INTERP_KERNEL::Exception(oss.str().c_str());
3447 * This method is \b NOT wrapped into python because it can be useful only for performance reasons in C++ context.
3448 * All values in \a this must be 0. or 1. within eps error. 0 means false, 1 means true.
3449 * If an another value than 0 or 1 appear (within eps precision) an INTERP_KERNEL::Exception will be thrown.
3451 * \throw if \a this is not allocated.
3452 * \throw if \a this has not exactly one component.
3454 std::vector<bool> DataArrayDouble::toVectorOfBool(double eps) const
3457 if(getNumberOfComponents()!=1)
3458 throw INTERP_KERNEL::Exception("DataArrayDouble::toVectorOfBool : must be applied on single component array !");
3459 int nbt(getNumberOfTuples());
3460 std::vector<bool> ret(nbt);
3461 const double *pt(begin());
3462 for(int i=0;i<nbt;i++)
3466 else if(fabs(pt[i]-1.)<eps)
3470 std::ostringstream oss; oss << "DataArrayDouble::toVectorOfBool : the tuple #" << i << " has value " << pt[i] << " is invalid ! must be 0. or 1. !";
3471 throw INTERP_KERNEL::Exception(oss.str().c_str());
3478 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
3481 void DataArrayDouble::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
3486 tinyInfo[0]=getNumberOfTuples();
3487 tinyInfo[1]=getNumberOfComponents();
3497 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
3500 void DataArrayDouble::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
3504 int nbOfCompo=getNumberOfComponents();
3505 tinyInfo.resize(nbOfCompo+1);
3506 tinyInfo[0]=getName();
3507 for(int i=0;i<nbOfCompo;i++)
3508 tinyInfo[i+1]=getInfoOnComponent(i);
3513 tinyInfo[0]=getName();
3518 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
3519 * This method returns if a feeding is needed.
3521 bool DataArrayDouble::resizeForUnserialization(const std::vector<int>& tinyInfoI)
3523 int nbOfTuple=tinyInfoI[0];
3524 int nbOfComp=tinyInfoI[1];
3525 if(nbOfTuple!=-1 || nbOfComp!=-1)
3527 alloc(nbOfTuple,nbOfComp);
3534 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
3536 void DataArrayDouble::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
3538 setName(tinyInfoS[0]);
3541 int nbOfCompo=getNumberOfComponents();
3542 for(int i=0;i<nbOfCompo;i++)
3543 setInfoOnComponent(i,tinyInfoS[i+1]);
3548 * Low static method that operates 3D rotation of 'nbNodes' 3D nodes whose coordinates are arranged in \a coordsIn
3549 * around an axe ( \a center, \a vect) and with angle \a angle.
3551 void DataArrayDouble::Rotate3DAlg(const double *center, const double *vect, double angle, int nbNodes, const double *coordsIn, double *coordsOut)
3553 if(!center || !vect)
3554 throw INTERP_KERNEL::Exception("DataArrayDouble::Rotate3DAlg : null vector in input !");
3555 double sina(sin(angle));
3556 double cosa(cos(angle));
3557 double vectorNorm[3];
3559 double matrixTmp[9];
3560 double norm(sqrt(vect[0]*vect[0]+vect[1]*vect[1]+vect[2]*vect[2]));
3561 if(norm<std::numeric_limits<double>::min())
3562 throw INTERP_KERNEL::Exception("DataArrayDouble::Rotate3DAlg : magnitude of input vector is too close of 0. !");
3563 std::transform(vect,vect+3,vectorNorm,std::bind2nd(std::multiplies<double>(),1/norm));
3564 //rotation matrix computation
3565 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;
3566 matrixTmp[0]=vectorNorm[0]*vectorNorm[0]; matrixTmp[1]=vectorNorm[0]*vectorNorm[1]; matrixTmp[2]=vectorNorm[0]*vectorNorm[2];
3567 matrixTmp[3]=vectorNorm[1]*vectorNorm[0]; matrixTmp[4]=vectorNorm[1]*vectorNorm[1]; matrixTmp[5]=vectorNorm[1]*vectorNorm[2];
3568 matrixTmp[6]=vectorNorm[2]*vectorNorm[0]; matrixTmp[7]=vectorNorm[2]*vectorNorm[1]; matrixTmp[8]=vectorNorm[2]*vectorNorm[2];
3569 std::transform(matrixTmp,matrixTmp+9,matrixTmp,std::bind2nd(std::multiplies<double>(),1-cosa));
3570 std::transform(matrix,matrix+9,matrixTmp,matrix,std::plus<double>());
3571 matrixTmp[0]=0.; matrixTmp[1]=-vectorNorm[2]; matrixTmp[2]=vectorNorm[1];
3572 matrixTmp[3]=vectorNorm[2]; matrixTmp[4]=0.; matrixTmp[5]=-vectorNorm[0];
3573 matrixTmp[6]=-vectorNorm[1]; matrixTmp[7]=vectorNorm[0]; matrixTmp[8]=0.;
3574 std::transform(matrixTmp,matrixTmp+9,matrixTmp,std::bind2nd(std::multiplies<double>(),sina));
3575 std::transform(matrix,matrix+9,matrixTmp,matrix,std::plus<double>());
3576 //rotation matrix computed.
3578 for(int i=0; i<nbNodes; i++)
3580 std::transform(coordsIn+i*3,coordsIn+(i+1)*3,center,tmp,std::minus<double>());
3581 coordsOut[i*3]=matrix[0]*tmp[0]+matrix[1]*tmp[1]+matrix[2]*tmp[2]+center[0];
3582 coordsOut[i*3+1]=matrix[3]*tmp[0]+matrix[4]*tmp[1]+matrix[5]*tmp[2]+center[1];
3583 coordsOut[i*3+2]=matrix[6]*tmp[0]+matrix[7]*tmp[1]+matrix[8]*tmp[2]+center[2];
3587 void DataArrayDouble::Symmetry3DPlane(const double point[3], const double normalVector[3], int nbNodes, const double *coordsIn, double *coordsOut)
3589 double matrix[9],matrix2[9],matrix3[9];
3590 double vect[3],crossVect[3];
3591 INTERP_KERNEL::orthogonalVect3(normalVector,vect);
3592 crossVect[0]=normalVector[1]*vect[2]-normalVector[2]*vect[1];
3593 crossVect[1]=normalVector[2]*vect[0]-normalVector[0]*vect[2];
3594 crossVect[2]=normalVector[0]*vect[1]-normalVector[1]*vect[0];
3595 double nv(INTERP_KERNEL::norm<3>(vect)),ni(INTERP_KERNEL::norm<3>(normalVector)),nc(INTERP_KERNEL::norm<3>(crossVect));
3596 matrix[0]=vect[0]/nv; matrix[1]=crossVect[0]/nc; matrix[2]=-normalVector[0]/ni;
3597 matrix[3]=vect[1]/nv; matrix[4]=crossVect[1]/nc; matrix[5]=-normalVector[1]/ni;
3598 matrix[6]=vect[2]/nv; matrix[7]=crossVect[2]/nc; matrix[8]=-normalVector[2]/ni;
3599 matrix2[0]=vect[0]/nv; matrix2[1]=vect[1]/nv; matrix2[2]=vect[2]/nv;
3600 matrix2[3]=crossVect[0]/nc; matrix2[4]=crossVect[1]/nc; matrix2[5]=crossVect[2]/nc;
3601 matrix2[6]=normalVector[0]/ni; matrix2[7]=normalVector[1]/ni; matrix2[8]=normalVector[2]/ni;
3602 for(int i=0;i<3;i++)
3603 for(int j=0;j<3;j++)
3606 for(int k=0;k<3;k++)
3607 val+=matrix[3*i+k]*matrix2[3*k+j];
3610 //rotation matrix computed.
3612 for(int i=0; i<nbNodes; i++)
3614 std::transform(coordsIn+i*3,coordsIn+(i+1)*3,point,tmp,std::minus<double>());
3615 coordsOut[i*3]=matrix3[0]*tmp[0]+matrix3[1]*tmp[1]+matrix3[2]*tmp[2]+point[0];
3616 coordsOut[i*3+1]=matrix3[3]*tmp[0]+matrix3[4]*tmp[1]+matrix3[5]*tmp[2]+point[1];
3617 coordsOut[i*3+2]=matrix3[6]*tmp[0]+matrix3[7]*tmp[1]+matrix3[8]*tmp[2]+point[2];
3621 void DataArrayDouble::GiveBaseForPlane(const double normalVector[3], double baseOfPlane[9])
3623 double vect[3],crossVect[3];
3624 INTERP_KERNEL::orthogonalVect3(normalVector,vect);
3625 crossVect[0]=normalVector[1]*vect[2]-normalVector[2]*vect[1];
3626 crossVect[1]=normalVector[2]*vect[0]-normalVector[0]*vect[2];
3627 crossVect[2]=normalVector[0]*vect[1]-normalVector[1]*vect[0];
3628 double nv(INTERP_KERNEL::norm<3>(vect)),ni(INTERP_KERNEL::norm<3>(normalVector)),nc(INTERP_KERNEL::norm<3>(crossVect));
3629 baseOfPlane[0]=vect[0]/nv; baseOfPlane[1]=vect[1]/nv; baseOfPlane[2]=vect[2]/nv;
3630 baseOfPlane[3]=crossVect[0]/nc; baseOfPlane[4]=crossVect[1]/nc; baseOfPlane[5]=crossVect[2]/nc;
3631 baseOfPlane[6]=normalVector[0]/ni; baseOfPlane[7]=normalVector[1]/ni; baseOfPlane[8]=normalVector[2]/ni;
3635 * Low static method that operates 3D rotation of \a nbNodes 3D nodes whose coordinates are arranged in \a coords
3636 * around the center point \a center and with angle \a angle.
3638 void DataArrayDouble::Rotate2DAlg(const double *center, double angle, int nbNodes, const double *coordsIn, double *coordsOut)
3640 double cosa=cos(angle);
3641 double sina=sin(angle);
3643 matrix[0]=cosa; matrix[1]=-sina; matrix[2]=sina; matrix[3]=cosa;
3645 for(int i=0; i<nbNodes; i++)
3647 std::transform(coordsIn+i*2,coordsIn+(i+1)*2,center,tmp,std::minus<double>());
3648 coordsOut[i*2]=matrix[0]*tmp[0]+matrix[1]*tmp[1]+center[0];
3649 coordsOut[i*2+1]=matrix[2]*tmp[0]+matrix[3]*tmp[1]+center[1];
3653 DataArrayDoubleIterator::DataArrayDoubleIterator(DataArrayDouble *da):DataArrayIterator<double>(da)
3657 DataArrayDoubleTuple::DataArrayDoubleTuple(double *pt, int nbOfComp):DataArrayTuple<double>(pt,nbOfComp)
3662 std::string DataArrayDoubleTuple::repr() const
3664 std::ostringstream oss; oss.precision(17); oss << "(";
3665 for(int i=0;i<_nb_of_compo-1;i++)
3666 oss << _pt[i] << ", ";
3667 oss << _pt[_nb_of_compo-1] << ")";
3671 double DataArrayDoubleTuple::doubleValue() const
3673 return this->zeValue();
3677 * This method returns a newly allocated instance the caller should dealed with by a MEDCoupling::DataArrayDouble::decrRef.
3678 * This method performs \b no copy of data. The content is only referenced using MEDCoupling::DataArrayDouble::useArray with ownership set to \b false.
3679 * 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
3680 * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
3682 DataArrayDouble *DataArrayDoubleTuple::buildDADouble(int nbOfTuples, int nbOfCompo) const
3684 return this->buildDA(nbOfTuples,nbOfCompo);
3688 * Returns a new instance of DataArrayInt. The caller is to delete this array
3689 * using decrRef() as it is no more needed.
3691 DataArrayInt *DataArrayInt::New()
3693 return new DataArrayInt;
3697 * Returns the only one value in \a this, if and only if number of elements
3698 * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
3699 * \return double - the sole value stored in \a this array.
3700 * \throw If at least one of conditions stated above is not fulfilled.
3702 int DataArrayInt::intValue() const
3706 if(getNbOfElems()==1)
3708 return *getConstPointer();
3711 throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is allocated but number of elements is not equal to 1 !");
3714 throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is not allocated !");
3718 * Returns an integer value characterizing \a this array, which is useful for a quick
3719 * comparison of many instances of DataArrayInt.
3720 * \return int - the hash value.
3721 * \throw If \a this is not allocated.
3723 int DataArrayInt::getHashCode() const
3726 std::size_t nbOfElems=getNbOfElems();
3727 int ret=nbOfElems*65536;
3732 const int *pt=begin();
3733 for(std::size_t i=0;i<nbOfElems;i+=delta)
3734 ret0+=pt[i] & 0x1FFF;
3739 * Returns a full copy of \a this. For more info on copying data arrays see
3740 * \ref MEDCouplingArrayBasicsCopyDeep.
3741 * \return DataArrayInt * - a new instance of DataArrayInt.
3743 DataArrayInt *DataArrayInt::deepCopy() const
3745 return new DataArrayInt(*this);
3749 * Assign zero to all values in \a this array. To know more on filling arrays see
3750 * \ref MEDCouplingArrayFill.
3751 * \throw If \a this is not allocated.
3753 void DataArrayInt::fillWithZero()
3759 * Set all values in \a this array so that the i-th element equals to \a init + i
3760 * (i starts from zero). To know more on filling arrays see \ref MEDCouplingArrayFill.
3761 * \param [in] init - value to assign to the first element of array.
3762 * \throw If \a this->getNumberOfComponents() != 1
3763 * \throw If \a this is not allocated.
3765 void DataArrayInt::iota(int init)
3768 if(getNumberOfComponents()!=1)
3769 throw INTERP_KERNEL::Exception("DataArrayInt::iota : works only for arrays with only one component, you can call 'rearrange' method before !");
3770 int *ptr=getPointer();
3771 int ntuples=getNumberOfTuples();
3772 for(int i=0;i<ntuples;i++)
3778 * Returns a textual and human readable representation of \a this instance of
3779 * DataArrayInt. This text is shown when a DataArrayInt is printed in Python.
3780 * \return std::string - text describing \a this DataArrayInt.
3782 * \sa reprNotTooLong, reprZip
3784 std::string DataArrayInt::repr() const
3786 std::ostringstream ret;
3791 std::string DataArrayInt::reprZip() const
3793 std::ostringstream ret;
3799 * This method is close to repr method except that when \a this has more than 1000 tuples, all tuples are not
3800 * printed out to avoid to consume too much space in interpretor.
3803 std::string DataArrayInt::reprNotTooLong() const
3805 std::ostringstream ret;
3806 reprNotTooLongStream(ret);
3810 void DataArrayInt::writeVTK(std::ostream& ofs, int indent, const std::string& type, const std::string& nameInFile, DataArrayByte *byteArr) const
3812 static const char SPACE[4]={' ',' ',' ',' '};
3814 std::string idt(indent,' ');
3815 ofs << idt << "<DataArray type=\"" << type << "\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
3818 ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
3819 if(std::string(type)=="Int32")
3821 const char *data(reinterpret_cast<const char *>(begin()));
3822 std::size_t sz(getNbOfElems()*sizeof(int));
3823 byteArr->insertAtTheEnd(data,data+sz);
3824 byteArr->insertAtTheEnd(SPACE,SPACE+4);
3826 else if(std::string(type)=="Int8")
3828 INTERP_KERNEL::AutoPtr<char> tmp(new char[getNbOfElems()]);
3829 std::copy(begin(),end(),(char *)tmp);
3830 byteArr->insertAtTheEnd((char *)tmp,(char *)tmp+getNbOfElems());
3831 byteArr->insertAtTheEnd(SPACE,SPACE+4);
3833 else if(std::string(type)=="UInt8")
3835 INTERP_KERNEL::AutoPtr<unsigned char> tmp(new unsigned char[getNbOfElems()]);
3836 std::copy(begin(),end(),(unsigned char *)tmp);
3837 byteArr->insertAtTheEnd((unsigned char *)tmp,(unsigned char *)tmp+getNbOfElems());
3838 byteArr->insertAtTheEnd(SPACE,SPACE+4);
3841 throw INTERP_KERNEL::Exception("DataArrayInt::writeVTK : Only Int32, Int8 and UInt8 supported !");
3845 ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
3846 std::copy(begin(),end(),std::ostream_iterator<int>(ofs," "));
3848 ofs << std::endl << idt << "</DataArray>\n";
3851 void DataArrayInt::reprStream(std::ostream& stream) const
3853 stream << "Name of int array : \"" << _name << "\"\n";
3854 reprWithoutNameStream(stream);
3857 void DataArrayInt::reprZipStream(std::ostream& stream) const
3859 stream << "Name of int array : \"" << _name << "\"\n";
3860 reprZipWithoutNameStream(stream);
3863 void DataArrayInt::reprNotTooLongStream(std::ostream& stream) const
3865 stream << "Name of int array : \"" << _name << "\"\n";
3866 reprNotTooLongWithoutNameStream(stream);
3869 void DataArrayInt::reprWithoutNameStream(std::ostream& stream) const
3871 DataArray::reprWithoutNameStream(stream);
3872 _mem.repr(getNumberOfComponents(),stream);
3875 void DataArrayInt::reprZipWithoutNameStream(std::ostream& stream) const
3877 DataArray::reprWithoutNameStream(stream);
3878 _mem.reprZip(getNumberOfComponents(),stream);
3881 void DataArrayInt::reprNotTooLongWithoutNameStream(std::ostream& stream) const
3883 DataArray::reprWithoutNameStream(stream);
3884 stream.precision(17);
3885 _mem.reprNotTooLong(getNumberOfComponents(),stream);
3888 void DataArrayInt::reprCppStream(const std::string& varName, std::ostream& stream) const
3890 int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
3891 const int *data=getConstPointer();
3892 stream << "DataArrayInt *" << varName << "=DataArrayInt::New();" << std::endl;
3893 if(nbTuples*nbComp>=1)
3895 stream << "const int " << varName << "Data[" << nbTuples*nbComp << "]={";
3896 std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<int>(stream,","));
3897 stream << data[nbTuples*nbComp-1] << "};" << std::endl;
3898 stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
3901 stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
3902 stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
3906 * Method that gives a quick overvien of \a this for python.
3908 void DataArrayInt::reprQuickOverview(std::ostream& stream) const
3910 static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
3911 stream << "DataArrayInt C++ instance at " << this << ". ";
3914 int nbOfCompo=(int)_info_on_compo.size();
3917 int nbOfTuples=getNumberOfTuples();
3918 stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
3919 reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
3922 stream << "Number of components : 0.";
3925 stream << "*** No data allocated ****";
3928 void DataArrayInt::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
3930 const int *data=begin();
3931 int nbOfTuples=getNumberOfTuples();
3932 int nbOfCompo=(int)_info_on_compo.size();
3933 std::ostringstream oss2; oss2 << "[";
3934 std::string oss2Str(oss2.str());
3935 bool isFinished=true;
3936 for(int i=0;i<nbOfTuples && isFinished;i++)
3941 for(int j=0;j<nbOfCompo;j++,data++)
3944 if(j!=nbOfCompo-1) oss2 << ", ";
3950 if(i!=nbOfTuples-1) oss2 << ", ";
3951 std::string oss3Str(oss2.str());
3952 if(oss3Str.length()<maxNbOfByteInRepr)
3964 * Computes distribution of values of \a this one-dimensional array between given value
3965 * ranges (casts). This method is typically useful for entity number spliting by types,
3967 * \warning The values contained in \a arrBg should be sorted ascendently. No
3968 * check of this is be done. If not, the result is not warranted.
3969 * \param [in] arrBg - the array of ascending values defining the value ranges. The i-th
3970 * value of \a arrBg (\a arrBg[ i ]) gives the lowest value of the i-th range,
3971 * and the greatest value of the i-th range equals to \a arrBg[ i+1 ] - 1. \a
3972 * arrBg containing \a n values defines \a n-1 ranges. The last value of \a arrBg
3973 * should be more than every value in \a this array.
3974 * \param [in] arrEnd - specifies the end of the array \a arrBg, so that
3975 * the last value of \a arrBg is \a arrEnd[ -1 ].
3976 * \param [out] castArr - a new instance of DataArrayInt, of same size as \a this array
3977 * (same number of tuples and components), the caller is to delete
3978 * using decrRef() as it is no more needed.
3979 * This array contains indices of ranges for every value of \a this array. I.e.
3980 * the i-th value of \a castArr gives the index of range the i-th value of \a this
3981 * belongs to. Or, in other words, this parameter contains for each tuple in \a
3982 * this in which cast it holds.
3983 * \param [out] rankInsideCast - a new instance of DataArrayInt, of same size as \a this
3984 * array, the caller is to delete using decrRef() as it is no more needed.
3985 * This array contains ranks of values of \a this array within ranges
3986 * they belongs to. I.e. the i-th value of \a rankInsideCast gives the rank of
3987 * the i-th value of \a this array within the \a castArr[ i ]-th range, to which
3988 * the i-th value of \a this belongs to. Or, in other words, this param contains
3989 * for each tuple its rank inside its cast. The rank is computed as difference
3990 * between the value and the lowest value of range.
3991 * \param [out] castsPresent - a new instance of DataArrayInt, containing indices of
3992 * ranges (casts) to which at least one value of \a this array belongs.
3993 * Or, in other words, this param contains the casts that \a this contains.
3994 * The caller is to delete this array using decrRef() as it is no more needed.
3996 * \b Example: If \a this contains [6,5,0,3,2,7,8,1,4] and \a arrBg contains [0,4,9] then
3997 * the output of this method will be :
3998 * - \a castArr : [1,1,0,0,0,1,1,0,1]
3999 * - \a rankInsideCast: [2,1,0,3,2,3,4,1,0]
4000 * - \a castsPresent : [0,1]
4002 * I.e. values of \a this array belong to 2 ranges: #0 and #1. Value 6 belongs to the
4003 * range #1 and its rank within this range is 2; etc.
4005 * \throw If \a this->getNumberOfComponents() != 1.
4006 * \throw If \a arrEnd - arrBg < 2.
4007 * \throw If any value of \a this is not less than \a arrEnd[-1].
4009 void DataArrayInt::splitByValueRange(const int *arrBg, const int *arrEnd,
4010 DataArrayInt *& castArr, DataArrayInt *& rankInsideCast, DataArrayInt *& castsPresent) const
4013 if(getNumberOfComponents()!=1)
4014 throw INTERP_KERNEL::Exception("Call splitByValueRange method on DataArrayInt with only one component, you can call 'rearrange' method before !");
4015 int nbOfTuples=getNumberOfTuples();
4016 std::size_t nbOfCast=std::distance(arrBg,arrEnd);
4018 throw INTERP_KERNEL::Exception("DataArrayInt::splitByValueRange : The input array giving the cast range values should be of size >=2 !");
4020 const int *work=getConstPointer();
4021 typedef std::reverse_iterator<const int *> rintstart;
4022 rintstart bg(arrEnd);//OK no problem because size of 'arr' is greater or equal 2
4023 rintstart end2(arrBg);
4024 MCAuto<DataArrayInt> ret1=DataArrayInt::New();
4025 MCAuto<DataArrayInt> ret2=DataArrayInt::New();
4026 MCAuto<DataArrayInt> ret3=DataArrayInt::New();
4027 ret1->alloc(nbOfTuples,1);
4028 ret2->alloc(nbOfTuples,1);
4029 int *ret1Ptr=ret1->getPointer();
4030 int *ret2Ptr=ret2->getPointer();
4031 std::set<std::size_t> castsDetected;
4032 for(int i=0;i<nbOfTuples;i++)
4034 rintstart res=std::find_if(bg,end2,std::bind2nd(std::less_equal<int>(), work[i]));
4035 std::size_t pos=std::distance(bg,res);
4036 std::size_t pos2=nbOfCast-pos;
4039 ret1Ptr[i]=(int)pos2;
4040 ret2Ptr[i]=work[i]-arrBg[pos2];
4041 castsDetected.insert(pos2);
4045 std::ostringstream oss; oss << "DataArrayInt::splitByValueRange : At rank #" << i << " the value is " << work[i] << " should be in [0," << *bg << ") !";
4046 throw INTERP_KERNEL::Exception(oss.str().c_str());
4049 ret3->alloc((int)castsDetected.size(),1);
4050 std::copy(castsDetected.begin(),castsDetected.end(),ret3->getPointer());
4051 castArr=ret1.retn();
4052 rankInsideCast=ret2.retn();
4053 castsPresent=ret3.retn();
4057 * 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 ).
4058 * 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 ).
4059 * This method works only if \a this is allocated and single component. If not an exception will be thrown.
4061 * \param [out] strt - the start of the range (included) if true is returned.
4062 * \param [out] sttoopp - the end of the range (not included) if true is returned.
4063 * \param [out] stteepp - the step of the range if true is returned.
4064 * \return the verdict of the check.
4066 * \sa DataArray::GetNumberOfItemGivenBES
4068 bool DataArrayInt::isRange(int& strt, int& sttoopp, int& stteepp) const
4071 if(getNumberOfComponents()!=1)
4072 throw INTERP_KERNEL::Exception("DataArrayInt::isRange : this must be single component array !");
4073 int nbTuples(getNumberOfTuples());
4075 { strt=0; sttoopp=0; stteepp=1; return true; }
4076 const int *pt(begin());
4079 { sttoopp=strt+1; stteepp=1; return true; }
4080 strt=*pt; sttoopp=pt[nbTuples-1];
4086 int a(sttoopp-1-strt),tmp(strt);
4087 if(a%(nbTuples-1)!=0)
4089 stteepp=a/(nbTuples-1);
4090 for(int i=0;i<nbTuples;i++,tmp+=stteepp)
4098 int a(strt-sttoopp-1),tmp(strt);
4099 if(a%(nbTuples-1)!=0)
4101 stteepp=-(a/(nbTuples-1));
4102 for(int i=0;i<nbTuples;i++,tmp+=stteepp)
4111 * Modifies in place \a this one-dimensional array so that each value \a v = \a indArrBg[ \a v ],
4112 * i.e. a current value is used as in index to get a new value from \a indArrBg.
4113 * \param [in] indArrBg - pointer to the first element of array of new values to assign
4115 * \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
4116 * the last value of \a indArrBg is \a indArrEnd[ -1 ].
4117 * \throw If \a this->getNumberOfComponents() != 1
4118 * \throw If any value of \a this can't be used as a valid index for
4119 * [\a indArrBg, \a indArrEnd).
4123 void DataArrayInt::transformWithIndArr(const int *indArrBg, const int *indArrEnd)
4125 this->checkAllocated();
4126 if(this->getNumberOfComponents()!=1)
4127 throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
4128 int nbElemsIn((int)std::distance(indArrBg,indArrEnd)),nbOfTuples(getNumberOfTuples()),*pt(getPointer());
4129 for(int i=0;i<nbOfTuples;i++,pt++)
4131 if(*pt>=0 && *pt<nbElemsIn)
4135 std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " of this value is " << *pt << ", should be in [0," << nbElemsIn << ") !";
4136 throw INTERP_KERNEL::Exception(oss.str().c_str());
4139 this->declareAsNew();
4142 void DataArrayInt::transformWithIndArr(const MapKeyVal<int>& m)
4144 this->checkAllocated();
4145 if(this->getNumberOfComponents()!=1)
4146 throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
4147 const std::map<int,int> dat(m.data());
4148 int nbOfTuples(getNumberOfTuples()),*pt(getPointer());
4149 for(int i=0;i<nbOfTuples;i++,pt++)
4151 std::map<int,int>::const_iterator it(dat.find(*pt));
4156 std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " of this value is " << *pt << " not in map !";
4157 throw INTERP_KERNEL::Exception(oss.str().c_str());
4160 this->declareAsNew();
4164 * Creates a one-dimensional DataArrayInt (\a res) whose contents are computed from
4165 * values of \a this (\a a) and the given (\a indArr) arrays as follows:
4166 * \a res[ \a indArr[ \a a[ i ]]] = i. I.e. for each value in place i \a v = \a a[ i ],
4167 * new value in place \a indArr[ \a v ] is i.
4168 * \param [in] indArrBg - the array holding indices within the result array to assign
4169 * indices of values of \a this array pointing to values of \a indArrBg.
4170 * \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
4171 * the last value of \a indArrBg is \a indArrEnd[ -1 ].
4172 * \return DataArrayInt * - the new instance of DataArrayInt.
4173 * The caller is to delete this result array using decrRef() as it is no more
4175 * \throw If \a this->getNumberOfComponents() != 1.
4176 * \throw If any value of \a this array is not a valid index for \a indArrBg array.
4177 * \throw If any value of \a indArrBg is not a valid index for \a this array.
4179 DataArrayInt *DataArrayInt::transformWithIndArrR(const int *indArrBg, const int *indArrEnd) const
4182 if(getNumberOfComponents()!=1)
4183 throw INTERP_KERNEL::Exception("Call transformWithIndArrR method on DataArrayInt with only one component, you can call 'rearrange' method before !");
4184 int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
4185 int nbOfTuples=getNumberOfTuples();
4186 const int *pt=getConstPointer();
4187 MCAuto<DataArrayInt> ret=DataArrayInt::New();
4188 ret->alloc(nbOfTuples,1);
4189 ret->fillWithValue(-1);
4190 int *tmp=ret->getPointer();
4191 for(int i=0;i<nbOfTuples;i++,pt++)
4193 if(*pt>=0 && *pt<nbElemsIn)
4195 int pos=indArrBg[*pt];
4196 if(pos>=0 && pos<nbOfTuples)
4200 std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value of new pos is " << pos << " ( indArrBg[" << *pt << "]) ! Should be in [0," << nbOfTuples << ") !";
4201 throw INTERP_KERNEL::Exception(oss.str().c_str());
4206 std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn << " !";
4207 throw INTERP_KERNEL::Exception(oss.str().c_str());
4214 * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
4215 * from values of \a this array, which is supposed to contain a renumbering map in
4216 * "Old to New" mode. The result array contains a renumbering map in "New to Old" mode.
4217 * To know how to use the renumbering maps see \ref numbering.
4218 * \param [in] newNbOfElem - the number of tuples in the result array.
4219 * \return DataArrayInt * - the new instance of DataArrayInt.
4220 * The caller is to delete this result array using decrRef() as it is no more
4223 * \if ENABLE_EXAMPLES
4224 * \ref cpp_mcdataarrayint_invertarrayo2n2n2o "Here is a C++ example".<br>
4225 * \ref py_mcdataarrayint_invertarrayo2n2n2o "Here is a Python example".
4228 DataArrayInt *DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const
4230 MCAuto<DataArrayInt> ret(DataArrayInt::New());
4231 ret->alloc(newNbOfElem,1);
4232 int nbOfOldNodes(this->getNumberOfTuples());
4233 const int *old2New(begin());
4234 int *pt(ret->getPointer());
4235 for(int i=0;i!=nbOfOldNodes;i++)
4237 int newp(old2New[i]);
4240 if(newp>=0 && newp<newNbOfElem)
4244 std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2O : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
4245 throw INTERP_KERNEL::Exception(oss.str().c_str());
4253 * This method is similar to DataArrayInt::invertArrayO2N2N2O except that
4254 * 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]
4256 DataArrayInt *DataArrayInt::invertArrayO2N2N2OBis(int newNbOfElem) const
4258 MCAuto<DataArrayInt> ret=DataArrayInt::New();
4259 ret->alloc(newNbOfElem,1);
4260 int nbOfOldNodes=getNumberOfTuples();
4261 const int *old2New=getConstPointer();
4262 int *pt=ret->getPointer();
4263 for(int i=nbOfOldNodes-1;i>=0;i--)
4265 int newp(old2New[i]);
4268 if(newp>=0 && newp<newNbOfElem)
4272 std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2OBis : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
4273 throw INTERP_KERNEL::Exception(oss.str().c_str());
4281 * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
4282 * from values of \a this array, which is supposed to contain a renumbering map in
4283 * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
4284 * To know how to use the renumbering maps see \ref numbering.
4285 * \param [in] newNbOfElem - the number of tuples in the result array.
4286 * \return DataArrayInt * - the new instance of DataArrayInt.
4287 * The caller is to delete this result array using decrRef() as it is no more
4290 * \if ENABLE_EXAMPLES
4291 * \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
4293 * \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
4294 * \sa invertArrayN2O2O2NOptimized
4297 DataArrayInt *DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const
4300 MCAuto<DataArrayInt> ret=DataArrayInt::New();
4301 ret->alloc(oldNbOfElem,1);
4302 const int *new2Old=getConstPointer();
4303 int *pt=ret->getPointer();
4304 std::fill(pt,pt+oldNbOfElem,-1);
4305 int nbOfNewElems=getNumberOfTuples();
4306 for(int i=0;i<nbOfNewElems;i++)
4309 if(v>=0 && v<oldNbOfElem)
4313 std::ostringstream oss; oss << "DataArrayInt::invertArrayN2O2O2N : in new id #" << i << " old value is " << v << " expected to be in [0," << oldNbOfElem << ") !";
4314 throw INTERP_KERNEL::Exception(oss.str().c_str());
4321 * Creates a map, whose contents are computed
4322 * from values of \a this array, which is supposed to contain a renumbering map in
4323 * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
4324 * To know how to use the renumbering maps see \ref numbering.
4325 * \param [in] newNbOfElem - the number of tuples in the result array.
4326 * \return MapII - the new instance of Map.
4328 * \if ENABLE_EXAMPLES
4329 * \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
4331 * \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
4332 * \sa invertArrayN2O2O2N
4335 MCAuto< MapKeyVal<int> > DataArrayInt::invertArrayN2O2O2NOptimized() const
4338 MCAuto< MapKeyVal<int> > ret(MapKeyVal<int>::New());
4339 std::map<int,int>& m(ret->data());
4340 const int *new2Old(begin());
4341 int nbOfNewElems(this->getNumberOfTuples());
4342 for(int i=0;i<nbOfNewElems;i++)
4351 * Equivalent to DataArrayInt::isEqual except that if false the reason of
4352 * mismatch is given.
4354 * \param [in] other the instance to be compared with \a this
4355 * \param [out] reason In case of inequality returns the reason.
4356 * \sa DataArrayInt::isEqual
4358 bool DataArrayInt::isEqualIfNotWhy(const DataArrayInt& other, std::string& reason) const
4360 if(!areInfoEqualsIfNotWhy(other,reason))
4362 return _mem.isEqual(other._mem,0,reason);
4366 * Checks if \a this and another DataArrayInt are fully equal. For more info see
4367 * \ref MEDCouplingArrayBasicsCompare.
4368 * \param [in] other - an instance of DataArrayInt to compare with \a this one.
4369 * \return bool - \a true if the two arrays are equal, \a false else.
4371 bool DataArrayInt::isEqual(const DataArrayInt& other) const
4374 return isEqualIfNotWhy(other,tmp);
4378 * Checks if values of \a this and another DataArrayInt are equal. For more info see
4379 * \ref MEDCouplingArrayBasicsCompare.
4380 * \param [in] other - an instance of DataArrayInt to compare with \a this one.
4381 * \return bool - \a true if the values of two arrays are equal, \a false else.
4383 bool DataArrayInt::isEqualWithoutConsideringStr(const DataArrayInt& other) const
4386 return _mem.isEqual(other._mem,0,tmp);
4390 * Checks if values of \a this and another DataArrayInt are equal. Comparison is
4391 * performed on sorted value sequences.
4392 * For more info see\ref MEDCouplingArrayBasicsCompare.
4393 * \param [in] other - an instance of DataArrayInt to compare with \a this one.
4394 * \return bool - \a true if the sorted values of two arrays are equal, \a false else.
4396 bool DataArrayInt::isEqualWithoutConsideringStrAndOrder(const DataArrayInt& other) const
4398 MCAuto<DataArrayInt> a=deepCopy();
4399 MCAuto<DataArrayInt> b=other.deepCopy();
4402 return a->isEqualWithoutConsideringStr(*b);
4406 * This method compares content of input vector \a v and \a this.
4407 * If for each id in \a this v[id]==True and for all other ids id2 not in \a this v[id2]==False, true is returned.
4408 * For performance reasons \a this is expected to be sorted ascendingly. If not an exception will be thrown.
4410 * \param [in] v - the vector of 'flags' to be compared with \a this.
4412 * \throw If \a this is not sorted ascendingly.
4413 * \throw If \a this has not exactly one component.
4414 * \throw If \a this is not allocated.
4416 bool DataArrayInt::isFittingWith(const std::vector<bool>& v) const
4419 if(getNumberOfComponents()!=1)
4420 throw INTERP_KERNEL::Exception("DataArrayInt::isFittingWith : number of components of this should be equal to one !");
4421 const int *w(begin()),*end2(end());
4422 int refVal=-std::numeric_limits<int>::max();
4424 std::vector<bool>::const_iterator it(v.begin());
4425 for(;it!=v.end();it++,i++)
4437 std::ostringstream oss; oss << "DataArrayInt::isFittingWith : At pos #" << std::distance(begin(),w-1) << " this is not sorted ascendingly !";
4438 throw INTERP_KERNEL::Exception(oss.str().c_str());
4452 * This method assumes that \a this has one component and is allocated. This method scans all tuples in \a this and for all tuple equal to \a val
4453 * put True to the corresponding entry in \a vec.
4454 * \a vec is expected to be with the same size than the number of tuples of \a this.
4456 * \sa DataArrayInt::switchOnTupleNotEqualTo.
4458 void DataArrayInt::switchOnTupleEqualTo(int val, std::vector<bool>& vec) const
4461 if(getNumberOfComponents()!=1)
4462 throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleEqualTo : number of components of this should be equal to one !");
4463 int nbOfTuples(getNumberOfTuples());
4464 if(nbOfTuples!=(int)vec.size())
4465 throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleEqualTo : number of tuples of this should be equal to size of input vector of bool !");
4466 const int *pt(begin());
4467 for(int i=0;i<nbOfTuples;i++)
4473 * This method assumes that \a this has one component and is allocated. This method scans all tuples in \a this and for all tuple different from \a val
4474 * put True to the corresponding entry in \a vec.
4475 * \a vec is expected to be with the same size than the number of tuples of \a this.
4477 * \sa DataArrayInt::switchOnTupleEqualTo.
4479 void DataArrayInt::switchOnTupleNotEqualTo(int val, std::vector<bool>& vec) const
4482 if(getNumberOfComponents()!=1)
4483 throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleNotEqualTo : number of components of this should be equal to one !");
4484 int nbOfTuples(getNumberOfTuples());
4485 if(nbOfTuples!=(int)vec.size())
4486 throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleNotEqualTo : number of tuples of this should be equal to size of input vector of bool !");
4487 const int *pt(begin());
4488 for(int i=0;i<nbOfTuples;i++)
4494 * Computes for each tuple the sum of number of components values in the tuple and return it.
4496 * \return DataArrayInt * - the new instance of DataArrayInt containing the
4497 * same number of tuples as \a this array and one component.
4498 * The caller is to delete this result array using decrRef() as it is no more
4500 * \throw If \a this is not allocated.
4502 DataArrayInt *DataArrayInt::sumPerTuple() const
4505 int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
4506 MCAuto<DataArrayInt> ret(DataArrayInt::New());
4507 ret->alloc(nbOfTuple,1);
4508 const int *src(getConstPointer());
4509 int *dest(ret->getPointer());
4510 for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
4511 *dest=std::accumulate(src,src+nbOfComp,0);
4516 * Checks that \a this array is consistently **increasing** or **decreasing** in value.
4517 * If not an exception is thrown.
4518 * \param [in] increasing - if \a true, the array values should be increasing.
4519 * \throw If sequence of values is not strictly monotonic in agreement with \a
4521 * \throw If \a this->getNumberOfComponents() != 1.
4522 * \throw If \a this is not allocated.
4524 void DataArrayInt::checkMonotonic(bool increasing) const
4526 if(!isMonotonic(increasing))
4529 throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not INCREASING monotonic !");
4531 throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not DECREASING monotonic !");
4536 * Checks that \a this array is consistently **increasing** or **decreasing** in value.
4537 * \param [in] increasing - if \a true, array values should be increasing.
4538 * \return bool - \a true if values change in accordance with \a increasing arg.
4539 * \throw If \a this->getNumberOfComponents() != 1.
4540 * \throw If \a this is not allocated.
4542 bool DataArrayInt::isMonotonic(bool increasing) const
4545 if(getNumberOfComponents()!=1)
4546 throw INTERP_KERNEL::Exception("DataArrayInt::isMonotonic : only supported with 'this' array with ONE component !");
4547 int nbOfElements=getNumberOfTuples();
4548 const int *ptr=getConstPointer();
4554 for(int i=1;i<nbOfElements;i++)
4564 for(int i=1;i<nbOfElements;i++)
4576 * This method check that array consistently INCREASING or DECREASING in value.
4578 bool DataArrayInt::isStrictlyMonotonic(bool increasing) const
4581 if(getNumberOfComponents()!=1)
4582 throw INTERP_KERNEL::Exception("DataArrayInt::isStrictlyMonotonic : only supported with 'this' array with ONE component !");
4583 int nbOfElements=getNumberOfTuples();
4584 const int *ptr=getConstPointer();
4590 for(int i=1;i<nbOfElements;i++)
4600 for(int i=1;i<nbOfElements;i++)
4612 * This method check that array consistently INCREASING or DECREASING in value.
4614 void DataArrayInt::checkStrictlyMonotonic(bool increasing) const
4616 if(!isStrictlyMonotonic(increasing))
4619 throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly INCREASING monotonic !");
4621 throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly DECREASING monotonic !");
4626 * Creates a new one-dimensional DataArrayInt of the same size as \a this and a given
4627 * one-dimensional arrays that must be of the same length. The result array describes
4628 * correspondence between \a this and \a other arrays, so that
4629 * <em> other.getIJ(i,0) == this->getIJ(ret->getIJ(i),0)</em>. If such a permutation is
4630 * not possible because some element in \a other is not in \a this, an exception is thrown.
4631 * \param [in] other - an array to compute permutation to.
4632 * \return DataArrayInt * - a new instance of DataArrayInt, which is a permutation array
4633 * from \a this to \a other. The caller is to delete this array using decrRef() as it is
4635 * \throw If \a this->getNumberOfComponents() != 1.
4636 * \throw If \a other->getNumberOfComponents() != 1.
4637 * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples().
4638 * \throw If \a other includes a value which is not in \a this array.
4640 * \if ENABLE_EXAMPLES
4641 * \ref cpp_mcdataarrayint_buildpermutationarr "Here is a C++ example".
4643 * \ref py_mcdataarrayint_buildpermutationarr "Here is a Python example".
4646 DataArrayInt *DataArrayInt::buildPermutationArr(const DataArrayInt& other) const
4649 if(getNumberOfComponents()!=1 || other.getNumberOfComponents()!=1)
4650 throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' have to have exactly ONE component !");
4651 int nbTuple=getNumberOfTuples();
4652 other.checkAllocated();
4653 if(nbTuple!=other.getNumberOfTuples())
4654 throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' must have the same number of tuple !");
4655 MCAuto<DataArrayInt> ret=DataArrayInt::New();
4656 ret->alloc(nbTuple,1);
4657 ret->fillWithValue(-1);
4658 const int *pt=getConstPointer();
4659 std::map<int,int> mm;
4660 for(int i=0;i<nbTuple;i++)
4662 pt=other.getConstPointer();
4663 int *retToFill=ret->getPointer();
4664 for(int i=0;i<nbTuple;i++)
4666 std::map<int,int>::const_iterator it=mm.find(pt[i]);
4669 std::ostringstream oss; oss << "DataArrayInt::buildPermutationArr : Arrays mismatch : element (" << pt[i] << ") in 'other' not findable in 'this' !";
4670 throw INTERP_KERNEL::Exception(oss.str().c_str());
4672 retToFill[i]=(*it).second;
4678 * Elements of \a partOfThis are expected to be included in \a this.
4679 * The returned array \a ret is so that this[ret]==partOfThis
4681 * For example, if \a this array contents are [9,10,0,6,4,11,3,8] and if \a partOfThis contains [6,0,11,8]
4682 * the return array will contain [3,2,5,7].
4684 * \a this is expected to be a 1 compo allocated array.
4685 * \param [in] partOfThis - A 1 compo allocated array
4686 * \return - A newly allocated array to be dealed by caller having the same number of tuples than \a partOfThis.
4687 * \throw if two same element is present twice in \a this
4688 * \throw if an element in \a partOfThis is \b NOT in \a this.
4690 DataArrayInt *DataArrayInt::indicesOfSubPart(const DataArrayInt& partOfThis) const
4692 if(getNumberOfComponents()!=1 || partOfThis.getNumberOfComponents()!=1)
4693 throw INTERP_KERNEL::Exception("DataArrayInt::indicesOfSubPart : this and input array must be one component array !");
4694 checkAllocated(); partOfThis.checkAllocated();
4695 int thisNbTuples(getNumberOfTuples()),nbTuples(partOfThis.getNumberOfTuples());
4696 const int *thisPt(begin()),*pt(partOfThis.begin());
4697 MCAuto<DataArrayInt> ret(DataArrayInt::New());
4698 ret->alloc(nbTuples,1);
4699 int *retPt(ret->getPointer());
4700 std::map<int,int> m;
4701 for(int i=0;i<thisNbTuples;i++,thisPt++)
4703 if(m.size()!=thisNbTuples)
4704 throw INTERP_KERNEL::Exception("DataArrayInt::indicesOfSubPart : some elements appears more than once !");
4705 for(int i=0;i<nbTuples;i++,retPt++,pt++)
4707 std::map<int,int>::const_iterator it(m.find(*pt));
4709 *retPt=(*it).second;
4712 std::ostringstream oss; oss << "DataArrayInt::indicesOfSubPart : At pos #" << i << " of input array value is " << *pt << " not in this !";
4713 throw INTERP_KERNEL::Exception(oss.str());
4720 * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode.
4721 * This map, if applied to \a this array, would make it sorted. For example, if
4722 * \a this array contents are [9,10,0,6,4,11,3,7] then the contents of the result array
4723 * are [5,6,0,3,2,7,1,4]; if this result array (\a res) is used as an argument in call
4724 * \a this->renumber(\a res) then the returned array contains [0,3,4,6,7,9,10,11].
4725 * This method is useful for renumbering (in MED file for example). For more info
4726 * on renumbering see \ref numbering.
4727 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4728 * array using decrRef() as it is no more needed.
4729 * \throw If \a this is not allocated.
4730 * \throw If \a this->getNumberOfComponents() != 1.
4731 * \throw If there are equal values in \a this array.
4733 DataArrayInt *DataArrayInt::checkAndPreparePermutation() const
4736 if(getNumberOfComponents()!=1)
4737 throw INTERP_KERNEL::Exception("DataArrayInt::checkAndPreparePermutation : number of components must == 1 !");
4738 int nbTuples=getNumberOfTuples();
4739 const int *pt=getConstPointer();
4740 int *pt2=CheckAndPreparePermutation(pt,pt+nbTuples);
4741 DataArrayInt *ret=DataArrayInt::New();
4742 ret->useArray(pt2,true,C_DEALLOC,nbTuples,1);
4747 * This method tries to find the permutation to apply to the first input \a ids1 to obtain the same array (without considering strings informations) the second
4748 * input array \a ids2.
4749 * \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.
4750 * 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
4752 * In case of success (no throw) : \c ids1->renumber(ret)->isEqual(ids2) where \a ret is the return of this method.
4754 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4755 * array using decrRef() as it is no more needed.
4756 * \throw If either ids1 or ids2 is null not allocated or not with one components.
4759 DataArrayInt *DataArrayInt::FindPermutationFromFirstToSecond(const DataArrayInt *ids1, const DataArrayInt *ids2)
4762 throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be not null !");
4763 if(!ids1->isAllocated() || !ids2->isAllocated())
4764 throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be allocated !");
4765 if(ids1->getNumberOfComponents()!=1 || ids2->getNumberOfComponents()!=1)
4766 throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays have exactly one component !");
4767 if(ids1->getNumberOfTuples()!=ids2->getNumberOfTuples())
4769 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 !";
4770 throw INTERP_KERNEL::Exception(oss.str().c_str());
4772 MCAuto<DataArrayInt> p1(ids1->deepCopy());
4773 MCAuto<DataArrayInt> p2(ids2->deepCopy());
4774 p1->sort(true); p2->sort(true);
4775 if(!p1->isEqualWithoutConsideringStr(*p2))
4776 throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two arrays are not lying on same ids ! Impossible to find a permutation between the 2 arrays !");
4777 p1=ids1->checkAndPreparePermutation();
4778 p2=ids2->checkAndPreparePermutation();
4779 p2=p2->invertArrayO2N2N2O(p2->getNumberOfTuples());
4780 p2=p2->selectByTupleIdSafe(p1->begin(),p1->end());
4785 * Returns two arrays describing a surjective mapping from \a this set of values (\a A)
4786 * onto a set of values of size \a targetNb (\a B). The surjective function is
4787 * \a B[ \a A[ i ]] = i. That is to say that for each \a id in [0,\a targetNb), where \a
4788 * targetNb < \a this->getNumberOfTuples(), there exists at least one tupleId (\a tid) so
4789 * that <em> this->getIJ( tid, 0 ) == id</em>. <br>
4790 * The first of out arrays returns indices of elements of \a this array, grouped by their
4791 * place in the set \a B. The second out array is the index of the first one; it shows how
4792 * many elements of \a A are mapped into each element of \a B. <br>
4794 * mapping and its usage in renumbering see \ref numbering. <br>
4796 * - \a this: [0,3,2,3,2,2,1,2]
4798 * - \a arr: [0, 6, 2,4,5,7, 1,3]
4799 * - \a arrI: [0,1,2,6,8]
4801 * This result means: <br>
4802 * the element of \a B 0 encounters within \a A once (\a arrI[ 0+1 ] - \a arrI[ 0 ]) and
4803 * its index within \a A is 0 ( \a arr[ 0:1 ] == \a arr[ \a arrI[ 0 ] : \a arrI[ 0+1 ]]);<br>
4804 * the element of \a B 2 encounters within \a A 4 times (\a arrI[ 2+1 ] - \a arrI[ 2 ]) and
4805 * its indices within \a A are [2,4,5,7] ( \a arr[ 2:6 ] == \a arr[ \a arrI[ 2 ] :
4806 * \a arrI[ 2+1 ]]); <br> etc.
4807 * \param [in] targetNb - the size of the set \a B. \a targetNb must be equal or more
4808 * than the maximal value of \a A.
4809 * \param [out] arr - a new instance of DataArrayInt returning indices of
4810 * elements of \a this, grouped by their place in the set \a B. The caller is to delete
4811 * this array using decrRef() as it is no more needed.
4812 * \param [out] arrI - a new instance of DataArrayInt returning size of groups of equal
4813 * elements of \a this. The caller is to delete this array using decrRef() as it
4814 * is no more needed.
4815 * \throw If \a this is not allocated.
4816 * \throw If \a this->getNumberOfComponents() != 1.
4817 * \throw If any value in \a this is more or equal to \a targetNb.
4819 void DataArrayInt::changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, DataArrayInt *&arrI) const
4822 if(getNumberOfComponents()!=1)
4823 throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : number of components must == 1 !");
4824 int nbOfTuples=getNumberOfTuples();
4825 MCAuto<DataArrayInt> ret(DataArrayInt::New());
4826 MCAuto<DataArrayInt> retI(DataArrayInt::New());
4827 retI->alloc(targetNb+1,1);
4828 const int *input=getConstPointer();
4829 std::vector< std::vector<int> > tmp(targetNb);
4830 for(int i=0;i<nbOfTuples;i++)
4833 if(tmp2>=0 && tmp2<targetNb)
4834 tmp[tmp2].push_back(i);
4837 std::ostringstream oss; oss << "DataArrayInt::changeSurjectiveFormat : At pos " << i << " presence of element " << tmp2 << " ! should be in [0," << targetNb << ") !";
4838 throw INTERP_KERNEL::Exception(oss.str().c_str());
4841 int *retIPtr=retI->getPointer();
4843 for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++,retIPtr++)
4844 retIPtr[1]=retIPtr[0]+(int)((*it1).size());
4845 if(nbOfTuples!=retI->getIJ(targetNb,0))
4846 throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : big problem should never happen !");
4847 ret->alloc(nbOfTuples,1);
4848 int *retPtr=ret->getPointer();
4849 for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++)
4850 retPtr=std::copy((*it1).begin(),(*it1).end(),retPtr);
4857 * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode computed
4858 * from a zip representation of a surjective format (returned e.g. by
4859 * \ref MEDCoupling::DataArrayDouble::findCommonTuples() "DataArrayDouble::findCommonTuples()"
4860 * for example). The result array minimizes the permutation. <br>
4861 * For more info on renumbering see \ref numbering. <br>
4863 * - \a nbOfOldTuples: 10
4864 * - \a arr : [0,3, 5,7,9]
4865 * - \a arrIBg : [0,2,5]
4866 * - \a newNbOfTuples: 7
4867 * - result array : [0,1,2,0,3,4,5,4,6,4]
4869 * \param [in] nbOfOldTuples - number of tuples in the initial array \a arr.
4870 * \param [in] arr - the array of tuple indices grouped by \a arrIBg array.
4871 * \param [in] arrIBg - the array dividing all indices stored in \a arr into groups of
4872 * (indices of) equal values. Its every element (except the last one) points to
4873 * the first element of a group of equal values.
4874 * \param [in] arrIEnd - specifies the end of \a arrIBg, so that the last element of \a
4875 * arrIBg is \a arrIEnd[ -1 ].
4876 * \param [out] newNbOfTuples - number of tuples after surjection application.
4877 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4878 * array using decrRef() as it is no more needed.
4879 * \throw If any value of \a arr breaks condition ( 0 <= \a arr[ i ] < \a nbOfOldTuples ).
4881 DataArrayInt *DataArrayInt::ConvertIndexArrayToO2N(int nbOfOldTuples, const int *arr, const int *arrIBg, const int *arrIEnd, int &newNbOfTuples)
4883 MCAuto<DataArrayInt> ret=DataArrayInt::New();
4884 ret->alloc(nbOfOldTuples,1);
4885 int *pt=ret->getPointer();
4886 std::fill(pt,pt+nbOfOldTuples,-1);
4887 int nbOfGrps=((int)std::distance(arrIBg,arrIEnd))-1;
4888 const int *cIPtr=arrIBg;
4889 for(int i=0;i<nbOfGrps;i++)
4890 pt[arr[cIPtr[i]]]=-(i+2);
4892 for(int iNode=0;iNode<nbOfOldTuples;iNode++)
4900 int grpId=-(pt[iNode]+2);
4901 for(int j=cIPtr[grpId];j<cIPtr[grpId+1];j++)
4903 if(arr[j]>=0 && arr[j]<nbOfOldTuples)
4907 std::ostringstream oss; oss << "DataArrayInt::ConvertIndexArrayToO2N : With element #" << j << " value is " << arr[j] << " should be in [0," << nbOfOldTuples << ") !";
4908 throw INTERP_KERNEL::Exception(oss.str().c_str());
4915 newNbOfTuples=newNb;
4920 * Returns a new DataArrayInt containing a renumbering map in "New to Old" mode,
4921 * which if applied to \a this array would make it sorted ascendingly.
4922 * For more info on renumbering see \ref numbering. <br>
4924 * - \a this: [2,0,1,1,0,1,2,0,1,1,0,0]
4925 * - result: [10,0,5,6,1,7,11,2,8,9,3,4]
4926 * - after applying result to \a this: [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2]
4928 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4929 * array using decrRef() as it is no more needed.
4930 * \throw If \a this is not allocated.
4931 * \throw If \a this->getNumberOfComponents() != 1.
4933 DataArrayInt *DataArrayInt::buildPermArrPerLevel() const
4936 if(getNumberOfComponents()!=1)
4937 throw INTERP_KERNEL::Exception("DataArrayInt::buildPermArrPerLevel : number of components must == 1 !");
4938 int nbOfTuples=getNumberOfTuples();
4939 const int *pt=getConstPointer();
4940 std::map<int,int> m;
4941 MCAuto<DataArrayInt> ret=DataArrayInt::New();
4942 ret->alloc(nbOfTuples,1);
4943 int *opt=ret->getPointer();
4944 for(int i=0;i<nbOfTuples;i++,pt++,opt++)
4947 std::map<int,int>::iterator it=m.find(val);
4956 m.insert(std::pair<int,int>(val,1));
4960 for(std::map<int,int>::iterator it=m.begin();it!=m.end();it++)
4962 int vt=(*it).second;
4966 pt=getConstPointer();
4967 opt=ret->getPointer();
4968 for(int i=0;i<nbOfTuples;i++,pt++,opt++)
4975 * Checks if \a this array has the given size, and if its contents is equal to an array filled with
4976 * iota(). This method is particularly useful for DataArrayInt instances that represent
4977 * a renumbering array, to check if there is a real need in renumbering.
4978 * This method checks than \a this can be considered as an identity mapping
4979 * of a set having \a sizeExpected elements into itself.
4981 * \param [in] sizeExpected - The number of elements expected.
4982 * \return bool - \a true if \a this array contents == \a range( \a this->getNumberOfTuples())
4983 * \throw If \a this is not allocated.
4984 * \throw If \a this->getNumberOfComponents() != 1.
4986 bool DataArrayInt::isIota(int sizeExpected) const
4989 if(getNumberOfComponents()!=1)
4991 int nbOfTuples(getNumberOfTuples());
4992 if(nbOfTuples!=sizeExpected)
4994 const int *pt=getConstPointer();
4995 for(int i=0;i<nbOfTuples;i++,pt++)
5002 * Checks if all values in \a this array are equal to \a val.
5003 * \param [in] val - value to check equality of array values to.
5004 * \return bool - \a true if all values are \a val.
5005 * \throw If \a this is not allocated.
5006 * \throw If \a this->getNumberOfComponents() != 1
5007 * \sa DataArrayInt::checkUniformAndGuess
5009 bool DataArrayInt::isUniform(int val) const
5012 if(getNumberOfComponents()!=1)
5013 throw INTERP_KERNEL::Exception("DataArrayInt::isUniform : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
5014 const int *w(begin()),*end2(end());
5022 * This method checks that \a this is uniform. If not and exception will be thrown.
5023 * In case of uniformity the corresponding value is returned.
5025 * \return int - the unique value contained in this
5026 * \throw If \a this is not allocated.
5027 * \throw If \a this->getNumberOfComponents() != 1
5028 * \throw If \a this is not uniform.
5029 * \sa DataArrayInt::isUniform
5031 int DataArrayInt::checkUniformAndGuess() const
5034 if(getNumberOfComponents()!=1)
5035 throw INTERP_KERNEL::Exception("DataArrayInt::checkUniformAndGuess : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
5037 throw INTERP_KERNEL::Exception("DataArrayInt::checkUniformAndGuess : this is empty !");
5038 const int *w(begin()),*end2(end());
5042 throw INTERP_KERNEL::Exception("DataArrayInt::checkUniformAndGuess : this is not uniform !");
5047 * Checks if all values in \a this array are unique.
5048 * \return bool - \a true if condition above is true
5049 * \throw If \a this is not allocated.
5050 * \throw If \a this->getNumberOfComponents() != 1
5052 bool DataArrayInt::hasUniqueValues() const
5055 if(getNumberOfComponents()!=1)
5056 throw INTERP_KERNEL::Exception("DataArrayInt::hasOnlyUniqueValues: must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
5057 int nbOfTuples(getNumberOfTuples());
5058 std::set<int> s(begin(),end()); // in C++11, should use unordered_set (O(1) complexity)
5059 if (s.size() != nbOfTuples)
5065 * Copy all components in a specified order from another DataArrayInt.
5066 * The specified components become the first ones in \a this array.
5067 * Both numerical and textual data is copied. The number of tuples in \a this and
5068 * the other array can be different.
5069 * \param [in] a - the array to copy data from.
5070 * \param [in] compoIds - sequence of zero based indices of components, data of which is
5072 * \throw If \a a is NULL.
5073 * \throw If \a compoIds.size() != \a a->getNumberOfComponents().
5074 * \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
5076 * \if ENABLE_EXAMPLES
5077 * \ref py_mcdataarrayint_setselectedcomponents "Here is a Python example".
5080 void DataArrayInt::setSelectedComponents(const DataArrayInt *a, const std::vector<int>& compoIds)
5083 throw INTERP_KERNEL::Exception("DataArrayInt::setSelectedComponents : input DataArrayInt is NULL !");
5085 a->checkAllocated();
5086 copyPartOfStringInfoFrom2(compoIds,*a);
5087 std::size_t partOfCompoSz=compoIds.size();
5088 int nbOfCompo=getNumberOfComponents();
5089 int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
5090 const int *ac=a->getConstPointer();
5091 int *nc=getPointer();
5092 for(int i=0;i<nbOfTuples;i++)
5093 for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
5094 nc[nbOfCompo*i+compoIds[j]]=*ac;
5097 DataArrayIntIterator *DataArrayInt::iterator()
5099 return new DataArrayIntIterator(this);
5103 * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to a
5104 * given one. The ids are sorted in the ascending order.
5105 * \param [in] val - the value to find within \a this.
5106 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5107 * array using decrRef() as it is no more needed.
5108 * \throw If \a this is not allocated.
5109 * \throw If \a this->getNumberOfComponents() != 1.
5110 * \sa DataArrayInt::findIdsEqualTuple
5112 DataArrayInt *DataArrayInt::findIdsEqual(int val) const
5115 if(getNumberOfComponents()!=1)
5116 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqual : the array must have only one component, you can call 'rearrange' method before !");
5117 const int *cptr(getConstPointer());
5118 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
5119 int nbOfTuples=getNumberOfTuples();
5120 for(int i=0;i<nbOfTuples;i++,cptr++)
5122 ret->pushBackSilent(i);
5127 * Creates a new DataArrayInt containing IDs (indices) of tuples holding value \b not
5128 * equal to a given one.
5129 * \param [in] val - the value to ignore within \a this.
5130 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5131 * array using decrRef() as it is no more needed.
5132 * \throw If \a this is not allocated.
5133 * \throw If \a this->getNumberOfComponents() != 1.
5135 DataArrayInt *DataArrayInt::findIdsNotEqual(int val) const
5138 if(getNumberOfComponents()!=1)
5139 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotEqual : the array must have only one component, you can call 'rearrange' method before !");
5140 const int *cptr(getConstPointer());
5141 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
5142 int nbOfTuples=getNumberOfTuples();
5143 for(int i=0;i<nbOfTuples;i++,cptr++)
5145 ret->pushBackSilent(i);
5150 * Creates a new DataArrayInt containing IDs (indices) of tuples holding tuple equal to those defined by [ \a tupleBg , \a tupleEnd )
5151 * This method is an extension of DataArrayInt::findIdsEqual method.
5153 * \param [in] tupleBg - the begin (included) of the input tuple to find within \a this.
5154 * \param [in] tupleEnd - the end (excluded) of the input tuple to find within \a this.
5155 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5156 * array using decrRef() as it is no more needed.
5157 * \throw If \a this is not allocated.
5158 * \throw If \a this->getNumberOfComponents() != std::distance(tupleBg,tupleEnd).
5159 * \throw If \a this->getNumberOfComponents() is equal to 0.
5160 * \sa DataArrayInt::findIdsEqual
5162 DataArrayInt *DataArrayInt::findIdsEqualTuple(const int *tupleBg, const int *tupleEnd) const
5164 std::size_t nbOfCompoExp(std::distance(tupleBg,tupleEnd));
5166 if(getNumberOfComponents()!=(int)nbOfCompoExp)
5168 std::ostringstream oss; oss << "DataArrayInt::findIdsEqualTuple : mismatch of number of components. Input tuple has " << nbOfCompoExp << " whereas this array has " << getNumberOfComponents() << " components !";
5169 throw INTERP_KERNEL::Exception(oss.str().c_str());
5172 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqualTuple : number of components should be > 0 !");
5173 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
5174 const int *bg(begin()),*end2(end()),*work(begin());
5177 work=std::search(work,end2,tupleBg,tupleEnd);
5180 std::size_t pos(std::distance(bg,work));
5181 if(pos%nbOfCompoExp==0)
5182 ret->pushBackSilent(pos/nbOfCompoExp);
5190 * Assigns \a newValue to all elements holding \a oldValue within \a this
5191 * one-dimensional array.
5192 * \param [in] oldValue - the value to replace.
5193 * \param [in] newValue - the value to assign.
5194 * \return int - number of replacements performed.
5195 * \throw If \a this is not allocated.
5196 * \throw If \a this->getNumberOfComponents() != 1.
5198 int DataArrayInt::changeValue(int oldValue, int newValue)
5201 if(getNumberOfComponents()!=1)
5202 throw INTERP_KERNEL::Exception("DataArrayInt::changeValue : the array must have only one component, you can call 'rearrange' method before !");
5203 if(oldValue==newValue)
5205 int *start(getPointer()),*end2(start+getNbOfElems());
5207 for(int *val=start;val!=end2;val++)
5221 * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to
5222 * one of given values.
5223 * \param [in] valsBg - an array of values to find within \a this array.
5224 * \param [in] valsEnd - specifies the end of the array \a valsBg, so that
5225 * the last value of \a valsBg is \a valsEnd[ -1 ].
5226 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5227 * array using decrRef() as it is no more needed.
5228 * \throw If \a this->getNumberOfComponents() != 1.
5230 DataArrayInt *DataArrayInt::findIdsEqualList(const int *valsBg, const int *valsEnd) const
5232 if(getNumberOfComponents()!=1)
5233 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqualList : the array must have only one component, you can call 'rearrange' method before !");
5234 std::set<int> vals2(valsBg,valsEnd);
5235 const int *cptr(getConstPointer());
5236 std::vector<int> res;
5237 int nbOfTuples(getNumberOfTuples());
5238 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
5239 for(int i=0;i<nbOfTuples;i++,cptr++)
5240 if(vals2.find(*cptr)!=vals2.end())
5241 ret->pushBackSilent(i);
5246 * Creates a new DataArrayInt containing IDs (indices) of tuples holding values \b not
5247 * equal to any of given values.
5248 * \param [in] valsBg - an array of values to ignore within \a this array.
5249 * \param [in] valsEnd - specifies the end of the array \a valsBg, so that
5250 * the last value of \a valsBg is \a valsEnd[ -1 ].
5251 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5252 * array using decrRef() as it is no more needed.
5253 * \throw If \a this->getNumberOfComponents() != 1.
5255 DataArrayInt *DataArrayInt::findIdsNotEqualList(const int *valsBg, const int *valsEnd) const
5257 if(getNumberOfComponents()!=1)
5258 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotEqualList : the array must have only one component, you can call 'rearrange' method before !");
5259 std::set<int> vals2(valsBg,valsEnd);
5260 const int *cptr=getConstPointer();
5261 std::vector<int> res;
5262 int nbOfTuples=getNumberOfTuples();
5263 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
5264 for(int i=0;i<nbOfTuples;i++,cptr++)
5265 if(vals2.find(*cptr)==vals2.end())
5266 ret->pushBackSilent(i);
5271 * This method is an extension of DataArrayInt::findIdFirstEqual method because this method works for DataArrayInt with
5272 * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
5273 * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
5274 * If any the tuple id is returned. If not -1 is returned.
5276 * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
5277 * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
5279 * \return tuple id where \b tupl is. -1 if no such tuple exists in \b this.
5280 * \sa DataArrayInt::findIdSequence, DataArrayInt::presenceOfTuple.
5282 int DataArrayInt::findIdFirstEqualTuple(const std::vector<int>& tupl) const
5285 int nbOfCompo=getNumberOfComponents();
5287 throw INTERP_KERNEL::Exception("DataArrayInt::findIdFirstEqualTuple : 0 components in 'this' !");
5288 if(nbOfCompo!=(int)tupl.size())
5290 std::ostringstream oss; oss << "DataArrayInt::findIdFirstEqualTuple : 'this' contains " << nbOfCompo << " components and searching for a tuple of length " << tupl.size() << " !";
5291 throw INTERP_KERNEL::Exception(oss.str().c_str());
5293 const int *cptr=getConstPointer();
5294 std::size_t nbOfVals=getNbOfElems();
5295 for(const int *work=cptr;work!=cptr+nbOfVals;)
5297 work=std::search(work,cptr+nbOfVals,tupl.begin(),tupl.end());
5298 if(work!=cptr+nbOfVals)
5300 if(std::distance(cptr,work)%nbOfCompo!=0)
5303 return std::distance(cptr,work)/nbOfCompo;
5310 * This method searches the sequence specified in input parameter \b vals in \b this.
5311 * This works only for DataArrayInt having number of components equal to one (if not an INTERP_KERNEL::Exception will be thrown).
5312 * This method differs from DataArrayInt::findIdFirstEqualTuple in that the position is internal raw data is not considered here contrary to DataArrayInt::findIdFirstEqualTuple.
5313 * \sa DataArrayInt::findIdFirstEqualTuple
5315 int DataArrayInt::findIdSequence(const std::vector<int>& vals) const
5318 int nbOfCompo=getNumberOfComponents();
5320 throw INTERP_KERNEL::Exception("DataArrayInt::findIdSequence : works only for DataArrayInt instance with one component !");
5321 const int *cptr=getConstPointer();
5322 std::size_t nbOfVals=getNbOfElems();
5323 const int *loc=std::search(cptr,cptr+nbOfVals,vals.begin(),vals.end());
5324 if(loc!=cptr+nbOfVals)
5325 return std::distance(cptr,loc);
5330 * This method expects to be called when number of components of this is equal to one.
5331 * This method returns the tuple id, if it exists, of the first tuple equal to \b value.
5332 * If not any tuple contains \b value -1 is returned.
5333 * \sa DataArrayInt::presenceOfValue
5335 int DataArrayInt::findIdFirstEqual(int value) const
5338 if(getNumberOfComponents()!=1)
5339 throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
5340 const int *cptr=getConstPointer();
5341 int nbOfTuples=getNumberOfTuples();
5342 const int *ret=std::find(cptr,cptr+nbOfTuples,value);
5343 if(ret!=cptr+nbOfTuples)
5344 return std::distance(cptr,ret);
5349 * This method expects to be called when number of components of this is equal to one.
5350 * This method returns the tuple id, if it exists, of the first tuple so that the value is contained in \b vals.
5351 * If not any tuple contains one of the values contained in 'vals' -1 is returned.
5352 * \sa DataArrayInt::presenceOfValue
5354 int DataArrayInt::findIdFirstEqual(const std::vector<int>& vals) const
5357 if(getNumberOfComponents()!=1)
5358 throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
5359 std::set<int> vals2(vals.begin(),vals.end());
5360 const int *cptr=getConstPointer();
5361 int nbOfTuples=getNumberOfTuples();
5362 for(const int *w=cptr;w!=cptr+nbOfTuples;w++)
5363 if(vals2.find(*w)!=vals2.end())
5364 return std::distance(cptr,w);
5369 * This method returns the number of values in \a this that are equals to input parameter \a value.
5370 * This method only works for single component array.
5372 * \return a value in [ 0, \c this->getNumberOfTuples() )
5374 * \throw If \a this is not allocated
5377 int DataArrayInt::count(int value) const
5381 if(getNumberOfComponents()!=1)
5382 throw INTERP_KERNEL::Exception("DataArrayInt::count : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
5383 const int *vals=begin();
5384 int nbOfTuples=getNumberOfTuples();
5385 for(int i=0;i<nbOfTuples;i++,vals++)
5392 * This method is an extension of DataArrayInt::presenceOfValue method because this method works for DataArrayInt with
5393 * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
5394 * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
5395 * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
5396 * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
5397 * \sa DataArrayInt::findIdFirstEqualTuple
5399 bool DataArrayInt::presenceOfTuple(const std::vector<int>& tupl) const
5401 return findIdFirstEqualTuple(tupl)!=-1;
5406 * Returns \a true if a given value is present within \a this one-dimensional array.
5407 * \param [in] value - the value to find within \a this array.
5408 * \return bool - \a true in case if \a value is present within \a this array.
5409 * \throw If \a this is not allocated.
5410 * \throw If \a this->getNumberOfComponents() != 1.
5411 * \sa findIdFirstEqual()
5413 bool DataArrayInt::presenceOfValue(int value) const
5415 return findIdFirstEqual(value)!=-1;
5419 * This method expects to be called when number of components of this is equal to one.
5420 * This method returns true if it exists a tuple so that the value is contained in \b vals.
5421 * If not any tuple contains one of the values contained in 'vals' false is returned.
5422 * \sa DataArrayInt::findIdFirstEqual
5424 bool DataArrayInt::presenceOfValue(const std::vector<int>& vals) const
5426 return findIdFirstEqual(vals)!=-1;
5430 * Accumulates values of each component of \a this array.
5431 * \param [out] res - an array of length \a this->getNumberOfComponents(), allocated
5432 * by the caller, that is filled by this method with sum value for each
5434 * \throw If \a this is not allocated.
5436 void DataArrayInt::accumulate(int *res) const
5439 const int *ptr=getConstPointer();
5440 int nbTuple=getNumberOfTuples();
5441 int nbComps=getNumberOfComponents();
5442 std::fill(res,res+nbComps,0);
5443 for(int i=0;i<nbTuple;i++)
5444 std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<int>());
5447 int DataArrayInt::accumulate(int compId) const
5450 const int *ptr=getConstPointer();
5451 int nbTuple=getNumberOfTuples();
5452 int nbComps=getNumberOfComponents();
5453 if(compId<0 || compId>=nbComps)
5454 throw INTERP_KERNEL::Exception("DataArrayInt::accumulate : Invalid compId specified : No such nb of components !");
5456 for(int i=0;i<nbTuple;i++)
5457 ret+=ptr[i*nbComps+compId];
5462 * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
5463 * The returned array will have same number of components than \a this and number of tuples equal to
5464 * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
5466 * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
5468 * \param [in] bgOfIndex - begin (included) of the input index array.
5469 * \param [in] endOfIndex - end (excluded) of the input index array.
5470 * \return DataArrayInt * - the new instance having the same number of components than \a this.
5472 * \throw If bgOfIndex or end is NULL.
5473 * \throw If input index array is not ascendingly sorted.
5474 * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
5475 * \throw If std::distance(bgOfIndex,endOfIndex)==0.
5477 DataArrayInt *DataArrayInt::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
5479 if(!bgOfIndex || !endOfIndex)
5480 throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : input pointer NULL !");
5482 int nbCompo=getNumberOfComponents();
5483 int nbOfTuples=getNumberOfTuples();
5484 int sz=(int)std::distance(bgOfIndex,endOfIndex);
5486 throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : invalid size of input index array !");
5488 MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(sz,nbCompo);
5489 const int *w=bgOfIndex;
5490 if(*w<0 || *w>=nbOfTuples)
5491 throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
5492 const int *srcPt=begin()+(*w)*nbCompo;
5493 int *tmp=ret->getPointer();
5494 for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
5496 std::fill(tmp,tmp+nbCompo,0);
5499 for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
5501 if(j>=0 && j<nbOfTuples)
5502 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<int>());
5505 std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
5506 throw INTERP_KERNEL::Exception(oss.str().c_str());
5512 std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
5513 throw INTERP_KERNEL::Exception(oss.str().c_str());
5516 ret->copyStringInfoFrom(*this);
5521 * Returns a new DataArrayInt by concatenating two given arrays, so that (1) the number
5522 * of tuples in the result array is <em> a1->getNumberOfTuples() + a2->getNumberOfTuples() -
5523 * offsetA2</em> and (2)
5524 * the number of component in the result array is same as that of each of given arrays.
5525 * First \a offsetA2 tuples of \a a2 are skipped and thus are missing from the result array.
5526 * Info on components is copied from the first of the given arrays. Number of components
5527 * in the given arrays must be the same.
5528 * \param [in] a1 - an array to include in the result array.
5529 * \param [in] a2 - another array to include in the result array.
5530 * \param [in] offsetA2 - number of tuples of \a a2 to skip.
5531 * \return DataArrayInt * - the new instance of DataArrayInt.
5532 * The caller is to delete this result array using decrRef() as it is no more
5534 * \throw If either \a a1 or \a a2 is NULL.
5535 * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
5537 DataArrayInt *DataArrayInt::Aggregate(const DataArrayInt *a1, const DataArrayInt *a2, int offsetA2)
5540 throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input DataArrayInt instance is NULL !");
5541 int nbOfComp=a1->getNumberOfComponents();
5542 if(nbOfComp!=a2->getNumberOfComponents())
5543 throw INTERP_KERNEL::Exception("Nb of components mismatch for array Aggregation !");
5544 int nbOfTuple1=a1->getNumberOfTuples();
5545 int nbOfTuple2=a2->getNumberOfTuples();
5546 DataArrayInt *ret=DataArrayInt::New();
5547 ret->alloc(nbOfTuple1+nbOfTuple2-offsetA2,nbOfComp);
5548 int *pt=std::copy(a1->getConstPointer(),a1->getConstPointer()+nbOfTuple1*nbOfComp,ret->getPointer());
5549 std::copy(a2->getConstPointer()+offsetA2*nbOfComp,a2->getConstPointer()+nbOfTuple2*nbOfComp,pt);
5550 ret->copyStringInfoFrom(*a1);
5555 * Returns a new DataArrayInt by concatenating all given arrays, so that (1) the number
5556 * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
5557 * the number of component in the result array is same as that of each of given arrays.
5558 * Info on components is copied from the first of the given arrays. Number of components
5559 * in the given arrays must be the same.
5560 * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it
5561 * not the object itself.
5562 * \param [in] arr - a sequence of arrays to include in the result array.
5563 * \return DataArrayInt * - the new instance of DataArrayInt.
5564 * The caller is to delete this result array using decrRef() as it is no more
5566 * \throw If all arrays within \a arr are NULL.
5567 * \throw If getNumberOfComponents() of arrays within \a arr.
5569 DataArrayInt *DataArrayInt::Aggregate(const std::vector<const DataArrayInt *>& arr)
5571 std::vector<const DataArrayInt *> a;
5572 for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
5576 throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input list must be NON EMPTY !");
5577 std::vector<const DataArrayInt *>::const_iterator it=a.begin();
5578 int nbOfComp=(*it)->getNumberOfComponents();
5579 int nbt=(*it++)->getNumberOfTuples();
5580 for(int i=1;it!=a.end();it++,i++)
5582 if((*it)->getNumberOfComponents()!=nbOfComp)
5583 throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : Nb of components mismatch for array aggregation !");
5584 nbt+=(*it)->getNumberOfTuples();
5586 MCAuto<DataArrayInt> ret=DataArrayInt::New();
5587 ret->alloc(nbt,nbOfComp);
5588 int *pt=ret->getPointer();
5589 for(it=a.begin();it!=a.end();it++)
5590 pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
5591 ret->copyStringInfoFrom(*(a[0]));
5596 * This method takes as input a list of DataArrayInt instances \a arrs that represent each a packed index arrays.
5597 * A packed index array is an allocated array with one component, and at least one tuple. The first element
5598 * of each array in \a arrs must be 0. Each array in \a arrs is expected to be increasingly monotonic.
5599 * 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.
5601 * \return DataArrayInt * - a new object to be managed by the caller.
5603 DataArrayInt *DataArrayInt::AggregateIndexes(const std::vector<const DataArrayInt *>& arrs)
5606 for(std::vector<const DataArrayInt *>::const_iterator it4=arrs.begin();it4!=arrs.end();it4++)
5610 (*it4)->checkAllocated();
5611 if((*it4)->getNumberOfComponents()!=1)
5613 std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of compo != 1 at pos " << std::distance(arrs.begin(),it4) << " !";
5614 throw INTERP_KERNEL::Exception(oss.str().c_str());
5616 int nbTupl=(*it4)->getNumberOfTuples();
5619 std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of tuples < 1 at pos " << std::distance(arrs.begin(),it4) << " !";
5620 throw INTERP_KERNEL::Exception(oss.str().c_str());
5622 if((*it4)->front()!=0)
5624 std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with front value != 0 at pos " << std::distance(arrs.begin(),it4) << " !";
5625 throw INTERP_KERNEL::Exception(oss.str().c_str());
5631 std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a null instance at pos " << std::distance(arrs.begin(),it4) << " !";
5632 throw INTERP_KERNEL::Exception(oss.str().c_str());
5636 throw INTERP_KERNEL::Exception("DataArrayInt::AggregateIndexes : input list must be NON EMPTY !");
5637 MCAuto<DataArrayInt> ret=DataArrayInt::New();
5638 ret->alloc(retSz,1);
5639 int *pt=ret->getPointer(); *pt++=0;
5640 for(std::vector<const DataArrayInt *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
5641 pt=std::transform((*it)->begin()+1,(*it)->end(),pt,std::bind2nd(std::plus<int>(),pt[-1]));
5642 ret->copyStringInfoFrom(*(arrs[0]));
5647 * Returns in a single walk in \a this the min value and the max value in \a this.
5648 * \a this is expected to be single component array.
5650 * \param [out] minValue - the min value in \a this.
5651 * \param [out] maxValue - the max value in \a this.
5653 * \sa getMinValueInArray, getMinValue, getMaxValueInArray, getMaxValue
5655 void DataArrayInt::getMinMaxValues(int& minValue, int& maxValue) const
5658 if(getNumberOfComponents()!=1)
5659 throw INTERP_KERNEL::Exception("DataArrayInt::getMinMaxValues : must be applied on DataArrayInt with only one component !");
5660 int nbTuples(getNumberOfTuples());
5661 const int *pt(begin());
5662 minValue=std::numeric_limits<int>::max(); maxValue=-std::numeric_limits<int>::max();
5663 for(int i=0;i<nbTuples;i++,pt++)
5673 * Modify all elements of \a this array, so that
5674 * an element _x_ becomes \f$ numerator / x \f$.
5675 * \warning If an exception is thrown because of presence of 0 element in \a this
5676 * array, all elements processed before detection of the zero element remain
5678 * \param [in] numerator - the numerator used to modify array elements.
5679 * \throw If \a this is not allocated.
5680 * \throw If there is an element equal to 0 in \a this array.
5682 void DataArrayInt::applyInv(int numerator)
5685 int *ptr=getPointer();
5686 std::size_t nbOfElems=getNbOfElems();
5687 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
5691 *ptr=numerator/(*ptr);
5695 std::ostringstream oss; oss << "DataArrayInt::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
5697 throw INTERP_KERNEL::Exception(oss.str().c_str());
5704 * Modify all elements of \a this array, so that
5705 * an element _x_ becomes \f$ x / val \f$.
5706 * \param [in] val - the denominator used to modify array elements.
5707 * \throw If \a this is not allocated.
5708 * \throw If \a val == 0.
5710 void DataArrayInt::applyDivideBy(int val)
5713 throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to divide by 0 !");
5715 int *ptr=getPointer();
5716 std::size_t nbOfElems=getNbOfElems();
5717 std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::divides<int>(),val));
5722 * Modify all elements of \a this array, so that
5723 * an element _x_ becomes <em> x % val </em>.
5724 * \param [in] val - the divisor used to modify array elements.
5725 * \throw If \a this is not allocated.
5726 * \throw If \a val <= 0.
5728 void DataArrayInt::applyModulus(int val)
5731 throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to operate modulus on value <= 0 !");
5733 int *ptr=getPointer();
5734 std::size_t nbOfElems=getNbOfElems();
5735 std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::modulus<int>(),val));
5740 * This method works only on data array with one component.
5741 * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
5742 * this[*id] in [\b vmin,\b vmax)
5744 * \param [in] vmin begin of range. This value is included in range (included).
5745 * \param [in] vmax end of range. This value is \b not included in range (excluded).
5746 * \return a newly allocated data array that the caller should deal with.
5748 * \sa DataArrayInt::findIdsNotInRange , DataArrayInt::findIdsStricltyNegative
5750 DataArrayInt *DataArrayInt::findIdsInRange(int vmin, int vmax) const
5752 InRange<int> ir(vmin,vmax);
5753 MCAuto<DataArrayInt> ret(findIdsAdv(ir));
5758 * This method works only on data array with one component.
5759 * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
5760 * this[*id] \b not in [\b vmin,\b vmax)
5762 * \param [in] vmin begin of range. This value is \b not included in range (excluded).
5763 * \param [in] vmax end of range. This value is included in range (included).
5764 * \return a newly allocated data array that the caller should deal with.
5766 * \sa DataArrayInt::findIdsInRange , DataArrayInt::findIdsStricltyNegative
5768 DataArrayInt *DataArrayInt::findIdsNotInRange(int vmin, int vmax) const
5770 NotInRange<int> nir(vmin,vmax);
5771 MCAuto<DataArrayInt> ret(findIdsAdv(nir));
5776 * This method works only on data array with one component.
5777 * 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.
5779 * \param [in] vmin begin of range. This value is included in range (included).
5780 * \param [in] vmax end of range. This value is \b not included in range (excluded).
5781 * \return if all ids in \a this are so that (*this)[i]==i for all i in [ 0, \c this->getNumberOfTuples() ). */
5782 bool DataArrayInt::checkAllIdsInRange(int vmin, int vmax) const
5785 if(getNumberOfComponents()!=1)
5786 throw INTERP_KERNEL::Exception("DataArrayInt::checkAllIdsInRange : this must have exactly one component !");
5787 int nbOfTuples=getNumberOfTuples();
5789 const int *cptr=getConstPointer();
5790 for(int i=0;i<nbOfTuples;i++,cptr++)
5792 if(*cptr>=vmin && *cptr<vmax)
5793 { ret=ret && *cptr==i; }
5796 std::ostringstream oss; oss << "DataArrayInt::checkAllIdsInRange : tuple #" << i << " has value " << *cptr << " should be in [" << vmin << "," << vmax << ") !";
5797 throw INTERP_KERNEL::Exception(oss.str().c_str());
5804 * Modify all elements of \a this array, so that
5805 * an element _x_ becomes <em> val % x </em>.
5806 * \warning If an exception is thrown because of presence of an element <= 0 in \a this
5807 * array, all elements processed before detection of the zero element remain
5809 * \param [in] val - the divident used to modify array elements.
5810 * \throw If \a this is not allocated.
5811 * \throw If there is an element equal to or less than 0 in \a this array.
5813 void DataArrayInt::applyRModulus(int val)
5816 int *ptr=getPointer();
5817 std::size_t nbOfElems=getNbOfElems();
5818 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
5826 std::ostringstream oss; oss << "DataArrayInt::applyRModulus : presence of value <=0 in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
5828 throw INTERP_KERNEL::Exception(oss.str().c_str());
5835 * Modify all elements of \a this array, so that
5836 * an element _x_ becomes <em> val ^ x </em>.
5837 * \param [in] val - the value used to apply pow on all array elements.
5838 * \throw If \a this is not allocated.
5839 * \throw If \a val < 0.
5841 void DataArrayInt::applyPow(int val)
5845 throw INTERP_KERNEL::Exception("DataArrayInt::applyPow : input pow in < 0 !");
5846 int *ptr=getPointer();
5847 std::size_t nbOfElems=getNbOfElems();
5850 std::fill(ptr,ptr+nbOfElems,1);
5853 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
5856 for(int j=0;j<val;j++)
5864 * Modify all elements of \a this array, so that
5865 * an element _x_ becomes \f$ val ^ x \f$.
5866 * \param [in] val - the value used to apply pow on all array elements.
5867 * \throw If \a this is not allocated.
5868 * \throw If there is an element < 0 in \a this array.
5869 * \warning If an exception is thrown because of presence of 0 element in \a this
5870 * array, all elements processed before detection of the zero element remain
5873 void DataArrayInt::applyRPow(int val)
5876 int *ptr=getPointer();
5877 std::size_t nbOfElems=getNbOfElems();
5878 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
5883 for(int j=0;j<*ptr;j++)
5889 std::ostringstream oss; oss << "DataArrayInt::applyRPow : presence of negative value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
5891 throw INTERP_KERNEL::Exception(oss.str().c_str());
5898 * Returns a new DataArrayInt which is a minimal partition of elements of \a groups.
5899 * The i-th item of the result array is an ID of a set of elements belonging to a
5900 * unique set of groups, which the i-th element is a part of. This set of elements
5901 * belonging to a unique set of groups is called \a family, so the result array contains
5902 * IDs of families each element belongs to.
5904 * \b Example: if we have two groups of elements: \a group1 [0,4] and \a group2 [ 0,1,2 ],
5905 * then there are 3 families:
5906 * - \a family1 (with ID 1) contains element [0] belonging to ( \a group1 + \a group2 ),
5907 * - \a family2 (with ID 2) contains elements [4] belonging to ( \a group1 ),
5908 * - \a family3 (with ID 3) contains element [1,2] belonging to ( \a group2 ), <br>
5909 * and the result array contains IDs of families [ 1,3,3,0,2 ]. <br> Note a family ID 0 which
5910 * stands for the element #3 which is in none of groups.
5912 * \param [in] groups - sequence of groups of element IDs.
5913 * \param [in] newNb - total number of elements; it must be more than max ID of element
5915 * \param [out] fidsOfGroups - IDs of families the elements of each group belong to.
5916 * \return DataArrayInt * - a new instance of DataArrayInt containing IDs of families
5917 * each element with ID from range [0, \a newNb ) belongs to. The caller is to
5918 * delete this array using decrRef() as it is no more needed.
5919 * \throw If any element ID in \a groups violates condition ( 0 <= ID < \a newNb ).
5921 DataArrayInt *DataArrayInt::MakePartition(const std::vector<const DataArrayInt *>& groups, int newNb, std::vector< std::vector<int> >& fidsOfGroups)
5923 std::vector<const DataArrayInt *> groups2;
5924 for(std::vector<const DataArrayInt *>::const_iterator it4=groups.begin();it4!=groups.end();it4++)
5926 groups2.push_back(*it4);
5927 MCAuto<DataArrayInt> ret=DataArrayInt::New();
5928 ret->alloc(newNb,1);
5929 int *retPtr=ret->getPointer();
5930 std::fill(retPtr,retPtr+newNb,0);
5932 for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++)
5934 const int *ptr=(*iter)->getConstPointer();
5935 std::size_t nbOfElem=(*iter)->getNbOfElems();
5937 for(int j=0;j<sfid;j++)
5940 for(std::size_t i=0;i<nbOfElem;i++)
5942 if(ptr[i]>=0 && ptr[i]<newNb)
5944 if(retPtr[ptr[i]]==j)
5952 std::ostringstream oss; oss << "DataArrayInt::MakePartition : In group \"" << (*iter)->getName() << "\" in tuple #" << i << " value = " << ptr[i] << " ! Should be in [0," << newNb;
5954 throw INTERP_KERNEL::Exception(oss.str().c_str());
5961 fidsOfGroups.clear();
5962 fidsOfGroups.resize(groups2.size());
5964 for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++,grId++)
5967 const int *ptr=(*iter)->getConstPointer();
5968 std::size_t nbOfElem=(*iter)->getNbOfElems();
5969 for(const int *p=ptr;p!=ptr+nbOfElem;p++)
5970 tmp.insert(retPtr[*p]);
5971 fidsOfGroups[grId].insert(fidsOfGroups[grId].end(),tmp.begin(),tmp.end());
5977 * Returns a new DataArrayInt which contains all elements of given one-dimensional
5978 * arrays. The result array does not contain any duplicates and its values
5979 * are sorted in ascending order.
5980 * \param [in] arr - sequence of DataArrayInt's to unite.
5981 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5982 * array using decrRef() as it is no more needed.
5983 * \throw If any \a arr[i] is not allocated.
5984 * \throw If \a arr[i]->getNumberOfComponents() != 1.
5986 DataArrayInt *DataArrayInt::BuildUnion(const std::vector<const DataArrayInt *>& arr)
5988 std::vector<const DataArrayInt *> a;
5989 for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
5992 for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
5994 (*it)->checkAllocated();
5995 if((*it)->getNumberOfComponents()!=1)
5996 throw INTERP_KERNEL::Exception("DataArrayInt::BuildUnion : only single component allowed !");
6000 for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
6002 const int *pt=(*it)->getConstPointer();
6003 int nbOfTuples=(*it)->getNumberOfTuples();
6004 r.insert(pt,pt+nbOfTuples);
6006 DataArrayInt *ret=DataArrayInt::New();
6007 ret->alloc((int)r.size(),1);
6008 std::copy(r.begin(),r.end(),ret->getPointer());
6013 * Returns a new DataArrayInt which contains elements present in each of given one-dimensional
6014 * arrays. The result array does not contain any duplicates and its values
6015 * are sorted in ascending order.
6016 * \param [in] arr - sequence of DataArrayInt's to intersect.
6017 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6018 * array using decrRef() as it is no more needed.
6019 * \throw If any \a arr[i] is not allocated.
6020 * \throw If \a arr[i]->getNumberOfComponents() != 1.
6022 DataArrayInt *DataArrayInt::BuildIntersection(const std::vector<const DataArrayInt *>& arr)
6024 std::vector<const DataArrayInt *> a;
6025 for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
6028 for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
6030 (*it)->checkAllocated();
6031 if((*it)->getNumberOfComponents()!=1)
6032 throw INTERP_KERNEL::Exception("DataArrayInt::BuildIntersection : only single component allowed !");
6036 for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
6038 const int *pt=(*it)->getConstPointer();
6039 int nbOfTuples=(*it)->getNumberOfTuples();
6040 std::set<int> s1(pt,pt+nbOfTuples);
6044 std::set_intersection(r.begin(),r.end(),s1.begin(),s1.end(),inserter(r2,r2.end()));
6050 DataArrayInt *ret(DataArrayInt::New());
6051 ret->alloc((int)r.size(),1);
6052 std::copy(r.begin(),r.end(),ret->getPointer());
6057 namespace MEDCouplingImpl
6062 OpSwitchedOn(int *pt):_pt(pt),_cnt(0) { }
6063 void operator()(const bool& b) { if(b) *_pt++=_cnt; _cnt++; }
6072 OpSwitchedOff(int *pt):_pt(pt),_cnt(0) { }
6073 void operator()(const bool& b) { if(!b) *_pt++=_cnt; _cnt++; }
6082 * This method returns the list of ids in ascending mode so that v[id]==true.
6084 DataArrayInt *DataArrayInt::BuildListOfSwitchedOn(const std::vector<bool>& v)
6086 int sz((int)std::count(v.begin(),v.end(),true));
6087 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
6088 std::for_each(v.begin(),v.end(),MEDCouplingImpl::OpSwitchedOn(ret->getPointer()));
6093 * This method returns the list of ids in ascending mode so that v[id]==false.
6095 DataArrayInt *DataArrayInt::BuildListOfSwitchedOff(const std::vector<bool>& v)
6097 int sz((int)std::count(v.begin(),v.end(),false));
6098 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
6099 std::for_each(v.begin(),v.end(),MEDCouplingImpl::OpSwitchedOff(ret->getPointer()));
6104 * This method allows to put a vector of vector of integer into a more compact data stucture (skyline).
6105 * This method is not available into python because no available optimized data structure available to map std::vector< std::vector<int> >.
6107 * \param [in] v the input data structure to be translate into skyline format.
6108 * \param [out] data the first element of the skyline format. The user is expected to deal with newly allocated array.
6109 * \param [out] dataIndex the second element of the skyline format.
6111 void DataArrayInt::PutIntoToSkylineFrmt(const std::vector< std::vector<int> >& v, DataArrayInt *& data, DataArrayInt *& dataIndex)
6113 int sz((int)v.size());
6114 MCAuto<DataArrayInt> ret0(DataArrayInt::New()),ret1(DataArrayInt::New());
6115 ret1->alloc(sz+1,1);
6116 int *pt(ret1->getPointer()); *pt=0;
6117 for(int i=0;i<sz;i++,pt++)
6118 pt[1]=pt[0]+(int)v[i].size();
6119 ret0->alloc(ret1->back(),1);
6120 pt=ret0->getPointer();
6121 for(int i=0;i<sz;i++)
6122 pt=std::copy(v[i].begin(),v[i].end(),pt);
6123 data=ret0.retn(); dataIndex=ret1.retn();
6127 * Returns a new DataArrayInt which contains a complement of elements of \a this
6128 * one-dimensional array. I.e. the result array contains all elements from the range [0,
6129 * \a nbOfElement) not present in \a this array.
6130 * \param [in] nbOfElement - maximal size of the result array.
6131 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6132 * array using decrRef() as it is no more needed.
6133 * \throw If \a this is not allocated.
6134 * \throw If \a this->getNumberOfComponents() != 1.
6135 * \throw If any element \a x of \a this array violates condition ( 0 <= \a x < \a
6138 DataArrayInt *DataArrayInt::buildComplement(int nbOfElement) const
6141 if(getNumberOfComponents()!=1)
6142 throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : only single component allowed !");
6143 std::vector<bool> tmp(nbOfElement);
6144 const int *pt=getConstPointer();
6145 int nbOfTuples=getNumberOfTuples();
6146 for(const int *w=pt;w!=pt+nbOfTuples;w++)
6147 if(*w>=0 && *w<nbOfElement)
6150 throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : an element is not in valid range : [0,nbOfElement) !");
6151 int nbOfRetVal=(int)std::count(tmp.begin(),tmp.end(),false);
6152 DataArrayInt *ret=DataArrayInt::New();
6153 ret->alloc(nbOfRetVal,1);
6155 int *retPtr=ret->getPointer();
6156 for(int i=0;i<nbOfElement;i++)
6163 * Returns a new DataArrayInt containing elements of \a this one-dimensional missing
6164 * from an \a other one-dimensional array.
6165 * \param [in] other - a DataArrayInt containing elements not to include in the result array.
6166 * \return DataArrayInt * - a new instance of DataArrayInt with one component. The
6167 * caller is to delete this array using decrRef() as it is no more needed.
6168 * \throw If \a other is NULL.
6169 * \throw If \a other is not allocated.
6170 * \throw If \a other->getNumberOfComponents() != 1.
6171 * \throw If \a this is not allocated.
6172 * \throw If \a this->getNumberOfComponents() != 1.
6173 * \sa DataArrayInt::buildSubstractionOptimized()
6175 DataArrayInt *DataArrayInt::buildSubstraction(const DataArrayInt *other) const
6178 throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : DataArrayInt pointer in input is NULL !");
6180 other->checkAllocated();
6181 if(getNumberOfComponents()!=1)
6182 throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed !");
6183 if(other->getNumberOfComponents()!=1)
6184 throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed for other type !");
6185 const int *pt=getConstPointer();
6186 int nbOfTuples=getNumberOfTuples();
6187 std::set<int> s1(pt,pt+nbOfTuples);
6188 pt=other->getConstPointer();
6189 nbOfTuples=other->getNumberOfTuples();
6190 std::set<int> s2(pt,pt+nbOfTuples);
6192 std::set_difference(s1.begin(),s1.end(),s2.begin(),s2.end(),std::back_insert_iterator< std::vector<int> >(r));
6193 DataArrayInt *ret=DataArrayInt::New();
6194 ret->alloc((int)r.size(),1);
6195 std::copy(r.begin(),r.end(),ret->getPointer());
6200 * \a this is expected to have one component and to be sorted ascendingly (as for \a other).
6201 * \a other is expected to be a part of \a this. If not DataArrayInt::buildSubstraction should be called instead.
6203 * \param [in] other an array with one component and expected to be sorted ascendingly.
6204 * \ret list of ids in \a this but not in \a other.
6205 * \sa DataArrayInt::buildSubstraction
6207 DataArrayInt *DataArrayInt::buildSubstractionOptimized(const DataArrayInt *other) const
6209 static const char *MSG="DataArrayInt::buildSubstractionOptimized : only single component allowed !";
6210 if(!other) throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstractionOptimized : NULL input array !");
6211 checkAllocated(); other->checkAllocated();
6212 if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
6213 if(other->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
6214 const int *pt1Bg(begin()),*pt1End(end()),*pt2Bg(other->begin()),*pt2End(other->end());
6215 const int *work1(pt1Bg),*work2(pt2Bg);
6216 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6217 for(;work1!=pt1End;work1++)
6219 if(work2!=pt2End && *work1==*work2)
6222 ret->pushBackSilent(*work1);
6229 * Returns a new DataArrayInt which contains all elements of \a this and a given
6230 * one-dimensional arrays. The result array does not contain any duplicates
6231 * and its values are sorted in ascending order.
6232 * \param [in] other - an array to unite with \a this one.
6233 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6234 * array using decrRef() as it is no more needed.
6235 * \throw If \a this or \a other is not allocated.
6236 * \throw If \a this->getNumberOfComponents() != 1.
6237 * \throw If \a other->getNumberOfComponents() != 1.
6239 DataArrayInt *DataArrayInt::buildUnion(const DataArrayInt *other) const
6241 std::vector<const DataArrayInt *>arrs(2);
6242 arrs[0]=this; arrs[1]=other;
6243 return BuildUnion(arrs);
6248 * Returns a new DataArrayInt which contains elements present in both \a this and a given
6249 * one-dimensional arrays. The result array does not contain any duplicates
6250 * and its values are sorted in ascending order.
6251 * \param [in] other - an array to intersect with \a this one.
6252 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6253 * array using decrRef() as it is no more needed.
6254 * \throw If \a this or \a other is not allocated.
6255 * \throw If \a this->getNumberOfComponents() != 1.
6256 * \throw If \a other->getNumberOfComponents() != 1.
6258 DataArrayInt *DataArrayInt::buildIntersection(const DataArrayInt *other) const
6260 std::vector<const DataArrayInt *>arrs(2);
6261 arrs[0]=this; arrs[1]=other;
6262 return BuildIntersection(arrs);
6266 * This method can be applied on allocated with one component DataArrayInt instance.
6267 * This method is typically relevant for sorted arrays. All consecutive duplicated items in \a this will appear only once in returned DataArrayInt instance.
6268 * 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]
6270 * \return a newly allocated array that contain the result of the unique operation applied on \a this.
6271 * \throw if \a this is not allocated or if \a this has not exactly one component.
6272 * \sa DataArrayInt::buildUniqueNotSorted
6274 DataArrayInt *DataArrayInt::buildUnique() const
6277 if(getNumberOfComponents()!=1)
6278 throw INTERP_KERNEL::Exception("DataArrayInt::buildUnique : only single component allowed !");
6279 int nbOfTuples=getNumberOfTuples();
6280 MCAuto<DataArrayInt> tmp=deepCopy();
6281 int *data=tmp->getPointer();
6282 int *last=std::unique(data,data+nbOfTuples);
6283 MCAuto<DataArrayInt> ret=DataArrayInt::New();
6284 ret->alloc(std::distance(data,last),1);
6285 std::copy(data,last,ret->getPointer());
6290 * This method can be applied on allocated with one component DataArrayInt instance.
6291 * This method keep elements only once by keeping the same order in \a this that is not expected to be sorted.
6293 * \return a newly allocated array that contain the result of the unique operation applied on \a this.
6295 * \throw if \a this is not allocated or if \a this has not exactly one component.
6297 * \sa DataArrayInt::buildUnique
6299 DataArrayInt *DataArrayInt::buildUniqueNotSorted() const
6302 if(getNumberOfComponents()!=1)
6303 throw INTERP_KERNEL::Exception("DataArrayInt::buildUniqueNotSorted : only single component allowed !");
6305 getMinMaxValues(minVal,maxVal);
6306 std::vector<bool> b(maxVal-minVal+1,false);
6307 const int *ptBg(begin()),*endBg(end());
6308 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6309 for(const int *pt=ptBg;pt!=endBg;pt++)
6313 ret->pushBackSilent(*pt);
6317 ret->copyStringInfoFrom(*this);
6322 * Returns a new DataArrayInt which contains size of every of groups described by \a this
6323 * "index" array. Such "index" array is returned for example by
6324 * \ref MEDCoupling::MEDCouplingUMesh::buildDescendingConnectivity
6325 * "MEDCouplingUMesh::buildDescendingConnectivity" and
6326 * \ref MEDCoupling::MEDCouplingUMesh::getNodalConnectivityIndex
6327 * "MEDCouplingUMesh::getNodalConnectivityIndex" etc.
6328 * This method preforms the reverse operation of DataArrayInt::computeOffsetsFull.
6329 * \return DataArrayInt * - a new instance of DataArrayInt, whose number of tuples
6330 * equals to \a this->getNumberOfComponents() - 1, and number of components is 1.
6331 * The caller is to delete this array using decrRef() as it is no more needed.
6332 * \throw If \a this is not allocated.
6333 * \throw If \a this->getNumberOfComponents() != 1.
6334 * \throw If \a this->getNumberOfTuples() < 2.
6337 * - this contains [1,3,6,7,7,9,15]
6338 * - result array contains [2,3,1,0,2,6],
6339 * where 2 = 3 - 1, 3 = 6 - 3, 1 = 7 - 6 etc.
6341 * \sa DataArrayInt::computeOffsetsFull
6343 DataArrayInt *DataArrayInt::deltaShiftIndex() const
6346 if(getNumberOfComponents()!=1)
6347 throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : only single component allowed !");
6348 int nbOfTuples=getNumberOfTuples();
6350 throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : 1 tuple at least must be present in 'this' !");
6351 const int *ptr=getConstPointer();
6352 DataArrayInt *ret=DataArrayInt::New();
6353 ret->alloc(nbOfTuples-1,1);
6354 int *out=ret->getPointer();
6355 std::transform(ptr+1,ptr+nbOfTuples,ptr,out,std::minus<int>());
6360 * Modifies \a this one-dimensional array so that value of each element \a x
6361 * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
6362 * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number of tuples
6363 * and components remains the same.<br>
6364 * This method is useful for allToAllV in MPI with contiguous policy. This method
6365 * differs from computeOffsetsFull() in that the number of tuples is \b not changed by
6367 * \throw If \a this is not allocated.
6368 * \throw If \a this->getNumberOfComponents() != 1.
6371 * - Before \a this contains [3,5,1,2,0,8]
6372 * - After \a this contains [0,3,8,9,11,11]<br>
6373 * Note that the last element 19 = 11 + 8 is missing because size of \a this
6374 * array is retained and thus there is no space to store the last element.
6376 void DataArrayInt::computeOffsets()
6379 if(getNumberOfComponents()!=1)
6380 throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets : only single component allowed !");
6381 int nbOfTuples=getNumberOfTuples();
6384 int *work=getPointer();
6387 for(int i=1;i<nbOfTuples;i++)
6390 work[i]=work[i-1]+tmp;
6398 * Modifies \a this one-dimensional array so that value of each element \a x
6399 * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
6400 * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number
6401 * components remains the same and number of tuples is inceamented by one.<br>
6402 * This method is useful for allToAllV in MPI with contiguous policy. This method
6403 * differs from computeOffsets() in that the number of tuples is changed by this one.
6404 * This method preforms the reverse operation of DataArrayInt::deltaShiftIndex.
6405 * \throw If \a this is not allocated.
6406 * \throw If \a this->getNumberOfComponents() != 1.
6409 * - Before \a this contains [3,5,1,2,0,8]
6410 * - After \a this contains [0,3,8,9,11,11,19]<br>
6411 * \sa DataArrayInt::deltaShiftIndex
6413 void DataArrayInt::computeOffsetsFull()
6416 if(getNumberOfComponents()!=1)
6417 throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsetsFull : only single component allowed !");
6418 int nbOfTuples=getNumberOfTuples();
6419 int *ret=(int *)malloc((nbOfTuples+1)*sizeof(int));
6420 const int *work=getConstPointer();
6422 for(int i=0;i<nbOfTuples;i++)
6423 ret[i+1]=work[i]+ret[i];
6424 useArray(ret,true,C_DEALLOC,nbOfTuples+1,1);
6429 * Returns two new DataArrayInt instances whose contents is computed from that of \a this and \a listOfIds arrays as follows.
6430 * \a this is expected to be an offset format ( as returned by DataArrayInt::computeOffsetsFull ) that is to say with one component
6431 * and ** sorted strictly increasingly **. \a listOfIds is expected to be sorted ascendingly (not strictly needed for \a listOfIds).
6432 * This methods searches in \a this, considered as a set of contiguous \c this->getNumberOfComponents() ranges, all ids in \a listOfIds
6433 * filling completely one of the ranges in \a this.
6435 * \param [in] listOfIds a list of ids that has to be sorted ascendingly.
6436 * \param [out] rangeIdsFetched the range ids fetched
6437 * \param [out] idsInInputListThatFetch contains the list of ids in \a listOfIds that are \b fully included in a range in \a this. So
6438 * \a idsInInputListThatFetch is a part of input \a listOfIds.
6440 * \sa DataArrayInt::computeOffsetsFull
6443 * - \a this : [0,3,7,9,15,18]
6444 * - \a listOfIds contains [0,1,2,3,7,8,15,16,17]
6445 * - \a rangeIdsFetched result array: [0,2,4]
6446 * - \a idsInInputListThatFetch result array: [0,1,2,7,8,15,16,17]
6447 * In this example id 3 in input \a listOfIds is alone so it do not appear in output \a idsInInputListThatFetch.
6450 void DataArrayInt::findIdsRangesInListOfIds(const DataArrayInt *listOfIds, DataArrayInt *& rangeIdsFetched, DataArrayInt *& idsInInputListThatFetch) const
6453 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : input list of ids is null !");
6454 listOfIds->checkAllocated(); checkAllocated();
6455 if(listOfIds->getNumberOfComponents()!=1)
6456 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : input list of ids must have exactly one component !");
6457 if(getNumberOfComponents()!=1)
6458 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : this must have exactly one component !");
6459 MCAuto<DataArrayInt> ret0=DataArrayInt::New(); ret0->alloc(0,1);
6460 MCAuto<DataArrayInt> ret1=DataArrayInt::New(); ret1->alloc(0,1);
6461 const int *tupEnd(listOfIds->end()),*offBg(begin()),*offEnd(end()-1);
6462 const int *tupPtr(listOfIds->begin()),*offPtr(offBg);
6463 while(tupPtr!=tupEnd && offPtr!=offEnd)
6465 if(*tupPtr==*offPtr)
6468 while(i<offPtr[1] && *tupPtr==i && tupPtr!=tupEnd) { i++; tupPtr++; }
6471 ret0->pushBackSilent((int)std::distance(offBg,offPtr));
6472 ret1->pushBackValsSilent(tupPtr-(offPtr[1]-offPtr[0]),tupPtr);
6477 { if(*tupPtr<*offPtr) tupPtr++; else offPtr++; }
6479 rangeIdsFetched=ret0.retn();
6480 idsInInputListThatFetch=ret1.retn();
6484 * Returns a new DataArrayInt whose contents is computed from that of \a this and \a
6485 * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
6486 * "index" array of a "iota" array, thus, whose each element gives an index of a group
6487 * beginning within the "iota" array. And \a this is a one-dimensional array
6488 * considered as a selector of groups described by \a offsets to include into the result array.
6489 * \throw If \a offsets is NULL.
6490 * \throw If \a offsets is not allocated.
6491 * \throw If \a offsets->getNumberOfComponents() != 1.
6492 * \throw If \a offsets is not monotonically increasing.
6493 * \throw If \a this is not allocated.
6494 * \throw If \a this->getNumberOfComponents() != 1.
6495 * \throw If any element of \a this is not a valid index for \a offsets array.
6498 * - \a this: [0,2,3]
6499 * - \a offsets: [0,3,6,10,14,20]
6500 * - result array: [0,1,2,6,7,8,9,10,11,12,13] == <br>
6501 * \c range(0,3) + \c range(6,10) + \c range(10,14) ==<br>
6502 * \c range( \a offsets[ \a this[0] ], offsets[ \a this[0]+1 ]) +
6503 * \c range( \a offsets[ \a this[1] ], offsets[ \a this[1]+1 ]) +
6504 * \c range( \a offsets[ \a this[2] ], offsets[ \a this[2]+1 ])
6506 DataArrayInt *DataArrayInt::buildExplicitArrByRanges(const DataArrayInt *offsets) const
6509 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : DataArrayInt pointer in input is NULL !");
6511 if(getNumberOfComponents()!=1)
6512 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : only single component allowed !");
6513 offsets->checkAllocated();
6514 if(offsets->getNumberOfComponents()!=1)
6515 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : input array should have only single component !");
6516 int othNbTuples=offsets->getNumberOfTuples()-1;
6517 int nbOfTuples=getNumberOfTuples();
6518 int retNbOftuples=0;
6519 const int *work=getConstPointer();
6520 const int *offPtr=offsets->getConstPointer();
6521 for(int i=0;i<nbOfTuples;i++)
6524 if(val>=0 && val<othNbTuples)
6526 int delta=offPtr[val+1]-offPtr[val];
6528 retNbOftuples+=delta;
6531 std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << val << " of offset array has a delta < 0 !";
6532 throw INTERP_KERNEL::Exception(oss.str().c_str());
6537 std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << i << " in this contains " << val;
6538 oss << " whereas offsets array is of size " << othNbTuples+1 << " !";
6539 throw INTERP_KERNEL::Exception(oss.str().c_str());
6542 MCAuto<DataArrayInt> ret=DataArrayInt::New();
6543 ret->alloc(retNbOftuples,1);
6544 int *retPtr=ret->getPointer();
6545 for(int i=0;i<nbOfTuples;i++)
6548 int start=offPtr[val];
6549 int off=offPtr[val+1]-start;
6550 for(int j=0;j<off;j++,retPtr++)
6557 * Returns a new DataArrayInt whose contents is computed using \a this that must be a
6558 * scaled array (monotonically increasing).
6559 from that of \a this and \a
6560 * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
6561 * "index" array of a "iota" array, thus, whose each element gives an index of a group
6562 * beginning within the "iota" array. And \a this is a one-dimensional array
6563 * considered as a selector of groups described by \a offsets to include into the result array.
6564 * \throw If \a is NULL.
6565 * \throw If \a this is not allocated.
6566 * \throw If \a this->getNumberOfComponents() != 1.
6567 * \throw If \a this->getNumberOfTuples() == 0.
6568 * \throw If \a this is not monotonically increasing.
6569 * \throw If any element of ids in ( \a bg \a stop \a step ) points outside the scale in \a this.
6572 * - \a bg , \a stop and \a step : (0,5,2)
6573 * - \a this: [0,3,6,10,14,20]
6574 * - result array: [0,0,0, 2,2,2,2, 4,4,4,4,4,4] == <br>
6576 DataArrayInt *DataArrayInt::buildExplicitArrOfSliceOnScaledArr(int bg, int stop, int step) const
6579 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : not allocated array !");
6580 if(getNumberOfComponents()!=1)
6581 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of components is expected to be equal to one !");
6582 int nbOfTuples(getNumberOfTuples());
6584 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of tuples must be != 0 !");
6585 const int *ids(begin());
6586 int nbOfEltsInSlc(GetNumberOfItemGivenBESRelative(bg,stop,step,"DataArrayInt::buildExplicitArrOfSliceOnScaledArr")),sz(0),pos(bg);
6587 for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
6589 if(pos>=0 && pos<nbOfTuples-1)
6591 int delta(ids[pos+1]-ids[pos]);
6595 std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " and at this pos this is not monotonically increasing !";
6596 throw INTERP_KERNEL::Exception(oss.str().c_str());
6601 std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " should be in [0," << nbOfTuples-1 << ") !";
6602 throw INTERP_KERNEL::Exception(oss.str().c_str());
6605 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
6606 int *retPtr(ret->getPointer());
6608 for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
6610 int delta(ids[pos+1]-ids[pos]);
6611 for(int j=0;j<delta;j++,retPtr++)
6618 * 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.
6619 * 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
6620 * in tuple **i** of returned DataArrayInt.
6621 * If ranges overlapped (in theory it should not) this method do not detect it and always returns the first range.
6623 * 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)]
6624 * The return DataArrayInt will contain : **[0,4,1,2,2,3]**
6626 * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
6627 * for lower value included and 2nd component is the upper value of corresponding range **excluded**.
6628 * \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
6629 * is thrown if no ranges in \a ranges contains value in \a this.
6631 * \sa DataArrayInt::findIdInRangeForEachTuple
6633 DataArrayInt *DataArrayInt::findRangeIdForEachTuple(const DataArrayInt *ranges) const
6636 throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : null input pointer !");
6637 if(ranges->getNumberOfComponents()!=2)
6638 throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : input DataArrayInt instance should have 2 components !");
6640 if(getNumberOfComponents()!=1)
6641 throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : this should have only one component !");
6642 int nbTuples=getNumberOfTuples();
6643 MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
6644 int nbOfRanges=ranges->getNumberOfTuples();
6645 const int *rangesPtr=ranges->getConstPointer();
6646 int *retPtr=ret->getPointer();
6647 const int *inPtr=getConstPointer();
6648 for(int i=0;i<nbTuples;i++,retPtr++)
6652 for(int j=0;j<nbOfRanges && !found;j++)
6653 if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
6654 { *retPtr=j; found=true; }
6659 std::ostringstream oss; oss << "DataArrayInt::findRangeIdForEachTuple : tuple #" << i << " not found by any ranges !";
6660 throw INTERP_KERNEL::Exception(oss.str().c_str());
6667 * 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.
6668 * 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
6669 * in tuple **i** of returned DataArrayInt.
6670 * If ranges overlapped (in theory it should not) this method do not detect it and always returns the sub position of the first range.
6672 * 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)]
6673 * The return DataArrayInt will contain : **[1,2,4,0,2,2]**
6674 * This method is often called in pair with DataArrayInt::findRangeIdForEachTuple method.
6676 * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
6677 * for lower value included and 2nd component is the upper value of corresponding range **excluded**.
6678 * \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
6679 * is thrown if no ranges in \a ranges contains value in \a this.
6680 * \sa DataArrayInt::findRangeIdForEachTuple
6682 DataArrayInt *DataArrayInt::findIdInRangeForEachTuple(const DataArrayInt *ranges) const
6685 throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : null input pointer !");
6686 if(ranges->getNumberOfComponents()!=2)
6687 throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : input DataArrayInt instance should have 2 components !");
6689 if(getNumberOfComponents()!=1)
6690 throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : this should have only one component !");
6691 int nbTuples=getNumberOfTuples();
6692 MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
6693 int nbOfRanges=ranges->getNumberOfTuples();
6694 const int *rangesPtr=ranges->getConstPointer();
6695 int *retPtr=ret->getPointer();
6696 const int *inPtr=getConstPointer();
6697 for(int i=0;i<nbTuples;i++,retPtr++)
6701 for(int j=0;j<nbOfRanges && !found;j++)
6702 if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
6703 { *retPtr=val-rangesPtr[2*j]; found=true; }
6708 std::ostringstream oss; oss << "DataArrayInt::findIdInRangeForEachTuple : tuple #" << i << " not found by any ranges !";
6709 throw INTERP_KERNEL::Exception(oss.str().c_str());
6716 * \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).
6717 * 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).
6718 * 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 !
6719 * If this method has correctly worked, \a this will be able to be considered as a linked list.
6720 * This method does nothing if number of tuples is lower of equal to 1.
6722 * This method is useful for users having an unstructured mesh having only SEG2 to rearrange internaly the connectibity without any coordinates consideration.
6724 * \sa MEDCouplingUMesh::orderConsecutiveCells1D, DataArrayInt::fromLinkedListOfPairToList
6726 void DataArrayInt::sortEachPairToMakeALinkedList()
6729 if(getNumberOfComponents()!=2)
6730 throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : Only works on DataArrayInt instance with nb of components equal to 2 !");
6731 int nbOfTuples(getNumberOfTuples());
6734 int *conn(getPointer());
6735 for(int i=1;i<nbOfTuples;i++,conn+=2)
6739 if(conn[2]==conn[3])
6741 std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " presence of a pair filled with same ids !";
6742 throw INTERP_KERNEL::Exception(oss.str().c_str());
6744 if(conn[2]!=conn[1] && conn[3]==conn[1] && conn[2]!=conn[0])
6745 std::swap(conn[2],conn[3]);
6746 //not(conn[2]==conn[1] && conn[3]!=conn[1] && conn[3]!=conn[0])
6747 if(conn[2]!=conn[1] || conn[3]==conn[1] || conn[3]==conn[0])
6749 std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " something is invalid !";
6750 throw INTERP_KERNEL::Exception(oss.str().c_str());
6755 if(conn[0]==conn[1] || conn[2]==conn[3])
6756 throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : In the 2 first tuples presence of a pair filled with same ids !");
6759 s.insert(conn,conn+4);
6761 throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : This can't be considered as a linked list regarding 2 first tuples !");
6762 if(std::count(conn,conn+4,conn[0])==2)
6767 if(conn[2]==conn[0])
6771 std::copy(tmp,tmp+4,conn);
6774 {//here we are sure to have (std::count(conn,conn+4,conn[1])==2)
6775 if(conn[1]==conn[3])
6776 std::swap(conn[2],conn[3]);
6783 * \a this is expected to be a correctly linked list of pairs.
6785 * \sa DataArrayInt::sortEachPairToMakeALinkedList
6787 MCAuto<DataArrayInt> DataArrayInt::fromLinkedListOfPairToList() const
6790 checkNbOfComps(2,"DataArrayInt::fromLinkedListOfPairToList : this is expected to have 2 components");
6791 int nbTuples(getNumberOfTuples());
6793 throw INTERP_KERNEL::Exception("DataArrayInt::fromLinkedListOfPairToList : no tuples in this ! Not a linked list !");
6794 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbTuples+1,1);
6795 const int *thisPtr(begin());
6796 int *retPtr(ret->getPointer());
6797 retPtr[0]=thisPtr[0];
6798 for(int i=0;i<nbTuples;i++)
6800 retPtr[i+1]=thisPtr[2*i+1];
6802 if(thisPtr[2*i+1]!=thisPtr[2*(i+1)+0])
6804 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 ?";
6805 throw INTERP_KERNEL::Exception(oss.str());
6812 * This method returns all different values found in \a this. This method throws if \a this has not been allocated.
6813 * But the number of components can be different from one.
6814 * \return a newly allocated array (that should be dealt by the caller) containing different values in \a this.
6816 DataArrayInt *DataArrayInt::getDifferentValues() const
6820 ret.insert(begin(),end());
6821 MCAuto<DataArrayInt> ret2=DataArrayInt::New(); ret2->alloc((int)ret.size(),1);
6822 std::copy(ret.begin(),ret.end(),ret2->getPointer());
6827 * This method is a refinement of DataArrayInt::getDifferentValues because it returns not only different values in \a this but also, for each of
6828 * them it tells which tuple id have this id.
6829 * This method works only on arrays with one component (if it is not the case call DataArrayInt::rearrange(1) ).
6830 * This method returns two arrays having same size.
6831 * 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.
6832 * 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]]
6834 std::vector<DataArrayInt *> DataArrayInt::partitionByDifferentValues(std::vector<int>& differentIds) const
6837 if(getNumberOfComponents()!=1)
6838 throw INTERP_KERNEL::Exception("DataArrayInt::partitionByDifferentValues : this should have only one component !");
6840 std::map<int,int> m,m2,m3;
6841 for(const int *w=begin();w!=end();w++)
6843 differentIds.resize(m.size());
6844 std::vector<DataArrayInt *> ret(m.size());
6845 std::vector<int *> retPtr(m.size());
6846 for(std::map<int,int>::const_iterator it=m.begin();it!=m.end();it++,id++)
6849 ret[id]=DataArrayInt::New();
6850 ret[id]->alloc((*it).second,1);
6851 retPtr[id]=ret[id]->getPointer();
6852 differentIds[id]=(*it).first;
6855 for(const int *w=begin();w!=end();w++,id++)
6857 retPtr[m2[*w]][m3[*w]++]=id;
6863 * This method split ids in [0, \c this->getNumberOfTuples() ) using \a this array as a field of weight (>=0 each).
6864 * The aim of this method is to return a set of \a nbOfSlices chunk of contiguous ids as balanced as possible.
6866 * \param [in] nbOfSlices - number of slices expected.
6867 * \return - a vector having a size equal to \a nbOfSlices giving the start (included) and the stop (excluded) of each chunks.
6869 * \sa DataArray::GetSlice
6870 * \throw If \a this is not allocated or not with exactly one component.
6871 * \throw If an element in \a this if < 0.
6873 std::vector< std::pair<int,int> > DataArrayInt::splitInBalancedSlices(int nbOfSlices) const
6875 if(!isAllocated() || getNumberOfComponents()!=1)
6876 throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : this array should have number of components equal to one and must be allocated !");
6878 throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : number of slices must be >= 1 !");
6879 int sum(accumulate(0)),nbOfTuples(getNumberOfTuples());
6880 int sumPerSlc(sum/nbOfSlices),pos(0);
6881 const int *w(begin());
6882 std::vector< std::pair<int,int> > ret(nbOfSlices);
6883 for(int i=0;i<nbOfSlices;i++)
6885 std::pair<int,int> p(pos,-1);
6887 while(locSum<sumPerSlc && pos<nbOfTuples) { pos++; locSum+=*w++; }
6891 p.second=nbOfTuples;
6898 * Returns a new DataArrayInt that is a modulus of two given arrays. There are 3
6900 * 1. The arrays have same number of tuples and components. Then each value of
6901 * the result array (_a_) is a division of the corresponding values of \a a1 and
6902 * \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, j ].
6903 * 2. The arrays have same number of tuples and one array, say _a2_, has one
6905 * _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, 0 ].
6906 * 3. The arrays have same number of components and one array, say _a2_, has one
6908 * _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ 0, j ].
6910 * Info on components is copied either from the first array (in the first case) or from
6911 * the array with maximal number of elements (getNbOfElems()).
6912 * \warning No check of division by zero is performed!
6913 * \param [in] a1 - a dividend array.
6914 * \param [in] a2 - a divisor array.
6915 * \return DataArrayInt * - the new instance of DataArrayInt.
6916 * The caller is to delete this result array using decrRef() as it is no more
6918 * \throw If either \a a1 or \a a2 is NULL.
6919 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
6920 * \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
6921 * none of them has number of tuples or components equal to 1.
6923 DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt *a2)
6926 throw INTERP_KERNEL::Exception("DataArrayInt::Modulus : input DataArrayInt instance is NULL !");
6927 int nbOfTuple1=a1->getNumberOfTuples();
6928 int nbOfTuple2=a2->getNumberOfTuples();
6929 int nbOfComp1=a1->getNumberOfComponents();
6930 int nbOfComp2=a2->getNumberOfComponents();
6931 if(nbOfTuple2==nbOfTuple1)
6933 if(nbOfComp1==nbOfComp2)
6935 MCAuto<DataArrayInt> ret=DataArrayInt::New();
6936 ret->alloc(nbOfTuple2,nbOfComp1);
6937 std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::modulus<int>());
6938 ret->copyStringInfoFrom(*a1);
6941 else if(nbOfComp2==1)
6943 MCAuto<DataArrayInt> ret=DataArrayInt::New();
6944 ret->alloc(nbOfTuple1,nbOfComp1);
6945 const int *a2Ptr=a2->getConstPointer();
6946 const int *a1Ptr=a1->getConstPointer();
6947 int *res=ret->getPointer();
6948 for(int i=0;i<nbOfTuple1;i++)
6949 res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::modulus<int>(),a2Ptr[i]));
6950 ret->copyStringInfoFrom(*a1);
6955 a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
6959 else if(nbOfTuple2==1)
6961 a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
6962 MCAuto<DataArrayInt> ret=DataArrayInt::New();
6963 ret->alloc(nbOfTuple1,nbOfComp1);
6964 const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
6965 int *pt=ret->getPointer();
6966 for(int i=0;i<nbOfTuple1;i++)
6967 pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::modulus<int>());
6968 ret->copyStringInfoFrom(*a1);
6973 a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Modulus !");//will always throw an exception
6979 * Modify \a this array so that each value becomes a modulus of division of this value by
6980 * a value of another DataArrayInt. There are 3 valid cases.
6981 * 1. The arrays have same number of tuples and components. Then each value of
6982 * \a this array is divided by the corresponding value of \a other one, i.e.:
6983 * _a_ [ i, j ] %= _other_ [ i, j ].
6984 * 2. The arrays have same number of tuples and \a other array has one component. Then
6985 * _a_ [ i, j ] %= _other_ [ i, 0 ].
6986 * 3. The arrays have same number of components and \a other array has one tuple. Then
6987 * _a_ [ i, j ] %= _a2_ [ 0, j ].
6989 * \warning No check of division by zero is performed!
6990 * \param [in] other - a divisor array.
6991 * \throw If \a other is NULL.
6992 * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
6993 * \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
6994 * \a other has number of both tuples and components not equal to 1.
6996 void DataArrayInt::modulusEqual(const DataArrayInt *other)
6999 throw INTERP_KERNEL::Exception("DataArrayInt::modulusEqual : input DataArrayInt instance is NULL !");
7000 const char *msg="Nb of tuples mismatch for DataArrayInt::modulusEqual !";
7001 checkAllocated(); other->checkAllocated();
7002 int nbOfTuple=getNumberOfTuples();
7003 int nbOfTuple2=other->getNumberOfTuples();
7004 int nbOfComp=getNumberOfComponents();
7005 int nbOfComp2=other->getNumberOfComponents();
7006 if(nbOfTuple==nbOfTuple2)
7008 if(nbOfComp==nbOfComp2)
7010 std::transform(begin(),end(),other->begin(),getPointer(),std::modulus<int>());
7012 else if(nbOfComp2==1)
7014 if(nbOfComp2==nbOfComp)
7016 int *ptr=getPointer();
7017 const int *ptrc=other->getConstPointer();
7018 for(int i=0;i<nbOfTuple;i++)
7019 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::modulus<int>(),*ptrc++));
7022 throw INTERP_KERNEL::Exception(msg);
7025 throw INTERP_KERNEL::Exception(msg);
7027 else if(nbOfTuple2==1)
7029 int *ptr=getPointer();
7030 const int *ptrc=other->getConstPointer();
7031 for(int i=0;i<nbOfTuple;i++)
7032 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::modulus<int>());
7035 throw INTERP_KERNEL::Exception(msg);
7040 * Returns a new DataArrayInt that is the result of pow of two given arrays. There are 3
7043 * \param [in] a1 - an array to pow up.
7044 * \param [in] a2 - another array to sum up.
7045 * \return DataArrayInt * - the new instance of DataArrayInt.
7046 * The caller is to delete this result array using decrRef() as it is no more
7048 * \throw If either \a a1 or \a a2 is NULL.
7049 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
7050 * \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
7051 * \throw If there is a negative value in \a a2.
7053 DataArrayInt *DataArrayInt::Pow(const DataArrayInt *a1, const DataArrayInt *a2)
7056 throw INTERP_KERNEL::Exception("DataArrayInt::Pow : at least one of input instances is null !");
7057 int nbOfTuple=a1->getNumberOfTuples();
7058 int nbOfTuple2=a2->getNumberOfTuples();
7059 int nbOfComp=a1->getNumberOfComponents();
7060 int nbOfComp2=a2->getNumberOfComponents();
7061 if(nbOfTuple!=nbOfTuple2)
7062 throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of tuples mismatches !");
7063 if(nbOfComp!=1 || nbOfComp2!=1)
7064 throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of components of both arrays must be equal to 1 !");
7065 MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuple,1);
7066 const int *ptr1(a1->begin()),*ptr2(a2->begin());
7067 int *ptr=ret->getPointer();
7068 for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
7073 for(int j=0;j<*ptr2;j++)
7079 std::ostringstream oss; oss << "DataArrayInt::Pow : on tuple #" << i << " of a2 value is < 0 (" << *ptr2 << ") !";
7080 throw INTERP_KERNEL::Exception(oss.str().c_str());
7087 * Apply pow on values of another DataArrayInt to values of \a this one.
7089 * \param [in] other - an array to pow to \a this one.
7090 * \throw If \a other is NULL.
7091 * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
7092 * \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
7093 * \throw If there is a negative value in \a other.
7095 void DataArrayInt::powEqual(const DataArrayInt *other)
7098 throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : input instance is null !");
7099 int nbOfTuple=getNumberOfTuples();
7100 int nbOfTuple2=other->getNumberOfTuples();
7101 int nbOfComp=getNumberOfComponents();
7102 int nbOfComp2=other->getNumberOfComponents();
7103 if(nbOfTuple!=nbOfTuple2)
7104 throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of tuples mismatches !");
7105 if(nbOfComp!=1 || nbOfComp2!=1)
7106 throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of components of both arrays must be equal to 1 !");
7107 int *ptr=getPointer();
7108 const int *ptrc=other->begin();
7109 for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
7114 for(int j=0;j<*ptrc;j++)
7120 std::ostringstream oss; oss << "DataArrayInt::powEqual : on tuple #" << i << " of other value is < 0 (" << *ptrc << ") !";
7121 throw INTERP_KERNEL::Exception(oss.str().c_str());
7128 * Returns a C array which is a renumbering map in "Old to New" mode for the input array.
7129 * This map, if applied to \a start array, would make it sorted. For example, if
7130 * \a start array contents are [9,10,0,6,4,11,3,7] then the contents of the result array is
7131 * [5,6,0,3,2,7,1,4].
7132 * \param [in] start - pointer to the first element of the array for which the
7133 * permutation map is computed.
7134 * \param [in] end - pointer specifying the end of the array \a start, so that
7135 * the last value of \a start is \a end[ -1 ].
7136 * \return int * - the result permutation array that the caller is to delete as it is no
7138 * \throw If there are equal values in the input array.
7140 int *DataArrayInt::CheckAndPreparePermutation(const int *start, const int *end)
7142 std::size_t sz=std::distance(start,end);
7143 int *ret=(int *)malloc(sz*sizeof(int));
7144 int *work=new int[sz];
7145 std::copy(start,end,work);
7146 std::sort(work,work+sz);
7147 if(std::unique(work,work+sz)!=work+sz)
7151 throw INTERP_KERNEL::Exception("Some elements are equals in the specified array !");
7153 std::map<int,int> m;
7154 for(int *workPt=work;workPt!=work+sz;workPt++)
7155 m[*workPt]=(int)std::distance(work,workPt);
7157 for(const int *iter=start;iter!=end;iter++,iter2++)
7164 * Returns a new DataArrayInt containing an arithmetic progression
7165 * that is equal to the sequence returned by Python \c range(\a begin,\a end,\a step )
7167 * \param [in] begin - the start value of the result sequence.
7168 * \param [in] end - limiting value, so that every value of the result array is less than
7170 * \param [in] step - specifies the increment or decrement.
7171 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7172 * array using decrRef() as it is no more needed.
7173 * \throw If \a step == 0.
7174 * \throw If \a end < \a begin && \a step > 0.
7175 * \throw If \a end > \a begin && \a step < 0.
7177 DataArrayInt *DataArrayInt::Range(int begin, int end, int step)
7179 int nbOfTuples=GetNumberOfItemGivenBESRelative(begin,end,step,"DataArrayInt::Range");
7180 MCAuto<DataArrayInt> ret=DataArrayInt::New();
7181 ret->alloc(nbOfTuples,1);
7182 int *ptr=ret->getPointer();
7185 for(int i=begin;i<end;i+=step,ptr++)
7190 for(int i=begin;i>end;i+=step,ptr++)
7197 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
7200 void DataArrayInt::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
7205 tinyInfo[0]=getNumberOfTuples();
7206 tinyInfo[1]=getNumberOfComponents();
7216 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
7219 void DataArrayInt::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
7223 int nbOfCompo=getNumberOfComponents();
7224 tinyInfo.resize(nbOfCompo+1);
7225 tinyInfo[0]=getName();
7226 for(int i=0;i<nbOfCompo;i++)
7227 tinyInfo[i+1]=getInfoOnComponent(i);
7232 tinyInfo[0]=getName();
7237 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
7238 * This method returns if a feeding is needed.
7240 bool DataArrayInt::resizeForUnserialization(const std::vector<int>& tinyInfoI)
7242 int nbOfTuple=tinyInfoI[0];
7243 int nbOfComp=tinyInfoI[1];
7244 if(nbOfTuple!=-1 || nbOfComp!=-1)
7246 alloc(nbOfTuple,nbOfComp);
7253 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
7254 * This method returns if a feeding is needed.
7256 void DataArrayInt::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
7258 setName(tinyInfoS[0]);
7261 int nbOfCompo=tinyInfoI[1];
7262 for(int i=0;i<nbOfCompo;i++)
7263 setInfoOnComponent(i,tinyInfoS[i+1]);
7267 DataArrayIntIterator::DataArrayIntIterator(DataArrayInt *da):DataArrayIterator<int>(da)
7271 DataArrayInt32Tuple::DataArrayInt32Tuple(int *pt, int nbOfComp):DataArrayTuple<int>(pt,nbOfComp)
7275 std::string DataArrayIntTuple::repr() const
7277 std::ostringstream oss; oss << "(";
7278 for(int i=0;i<_nb_of_compo-1;i++)
7279 oss << _pt[i] << ", ";
7280 oss << _pt[_nb_of_compo-1] << ")";
7284 int DataArrayIntTuple::intValue() const
7286 return this->zeValue();
7290 * This method returns a newly allocated instance the caller should dealed with by a MEDCoupling::DataArrayInt::decrRef.
7291 * This method performs \b no copy of data. The content is only referenced using MEDCoupling::DataArrayInt::useArray with ownership set to \b false.
7292 * 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
7293 * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
7295 DataArrayInt *DataArrayIntTuple::buildDAInt(int nbOfTuples, int nbOfCompo) const
7297 return this->buildDA(nbOfTuples,nbOfCompo);