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 * Returns either a \a deep or \a shallow copy of this array. For more info see
812 * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
813 * \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
814 * \return DataArrayDouble * - either a new instance of DataArrayDouble (if \a dCpy
815 * == \a true) or \a this instance (if \a dCpy == \a false).
817 DataArrayDouble *DataArrayDouble::performCopyOrIncrRef(bool dCpy) const
819 return DataArrayTemplateClassic<double>::PerformCopyOrIncrRef(dCpy,*this);
823 * Assign zero to all values in \a this array. To know more on filling arrays see
824 * \ref MEDCouplingArrayFill.
825 * \throw If \a this is not allocated.
827 void DataArrayDouble::fillWithZero()
833 * Checks that \a this array is consistently **increasing** or **decreasing** in value,
834 * with at least absolute difference value of |\a eps| at each step.
835 * If not an exception is thrown.
836 * \param [in] increasing - if \a true, the array values should be increasing.
837 * \param [in] eps - minimal absolute difference between the neighbor values at which
838 * the values are considered different.
839 * \throw If sequence of values is not strictly monotonic in agreement with \a
841 * \throw If \a this->getNumberOfComponents() != 1.
842 * \throw If \a this is not allocated.
844 void DataArrayDouble::checkMonotonic(bool increasing, double eps) const
846 if(!isMonotonic(increasing,eps))
849 throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not INCREASING monotonic !");
851 throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not DECREASING monotonic !");
856 * Checks that \a this array is consistently **increasing** or **decreasing** in value,
857 * with at least absolute difference value of |\a eps| at each step.
858 * \param [in] increasing - if \a true, array values should be increasing.
859 * \param [in] eps - minimal absolute difference between the neighbor values at which
860 * the values are considered different.
861 * \return bool - \a true if values change in accordance with \a increasing arg.
862 * \throw If \a this->getNumberOfComponents() != 1.
863 * \throw If \a this is not allocated.
865 bool DataArrayDouble::isMonotonic(bool increasing, double eps) const
868 if(getNumberOfComponents()!=1)
869 throw INTERP_KERNEL::Exception("DataArrayDouble::isMonotonic : only supported with 'this' array with ONE component !");
870 int nbOfElements=getNumberOfTuples();
871 const double *ptr=getConstPointer();
875 double absEps=fabs(eps);
878 for(int i=1;i<nbOfElements;i++)
880 if(ptr[i]<(ref+absEps))
888 for(int i=1;i<nbOfElements;i++)
890 if(ptr[i]>(ref-absEps))
899 * Returns a textual and human readable representation of \a this instance of
900 * DataArrayDouble. This text is shown when a DataArrayDouble is printed in Python.
901 * \return std::string - text describing \a this DataArrayDouble.
903 * \sa reprNotTooLong, reprZip
905 std::string DataArrayDouble::repr() const
907 std::ostringstream ret;
912 std::string DataArrayDouble::reprZip() const
914 std::ostringstream ret;
920 * This method is close to repr method except that when \a this has more than 1000 tuples, all tuples are not
921 * printed out to avoid to consume too much space in interpretor.
924 std::string DataArrayDouble::reprNotTooLong() const
926 std::ostringstream ret;
927 reprNotTooLongStream(ret);
931 void DataArrayDouble::writeVTK(std::ostream& ofs, int indent, const std::string& nameInFile, DataArrayByte *byteArr) const
933 static const char SPACE[4]={' ',' ',' ',' '};
935 std::string idt(indent,' ');
937 ofs << idt << "<DataArray type=\"Float32\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
939 bool areAllEmpty(true);
940 for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
944 for(std::size_t i=0;i<_info_on_compo.size();i++)
945 ofs << " ComponentName" << i << "=\"" << _info_on_compo[i] << "\"";
949 ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
950 INTERP_KERNEL::AutoPtr<float> tmp(new float[getNbOfElems()]);
952 // to make Visual C++ happy : instead of std::copy(begin(),end(),(float *)tmp);
953 for(const double *src=begin();src!=end();src++,pt++)
955 const char *data(reinterpret_cast<const char *>((float *)tmp));
956 std::size_t sz(getNbOfElems()*sizeof(float));
957 byteArr->insertAtTheEnd(data,data+sz);
958 byteArr->insertAtTheEnd(SPACE,SPACE+4);
962 ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
963 std::copy(begin(),end(),std::ostream_iterator<double>(ofs," "));
965 ofs << std::endl << idt << "</DataArray>\n";
968 void DataArrayDouble::reprStream(std::ostream& stream) const
970 stream << "Name of double array : \"" << _name << "\"\n";
971 reprWithoutNameStream(stream);
974 void DataArrayDouble::reprZipStream(std::ostream& stream) const
976 stream << "Name of double array : \"" << _name << "\"\n";
977 reprZipWithoutNameStream(stream);
980 void DataArrayDouble::reprNotTooLongStream(std::ostream& stream) const
982 stream << "Name of double array : \"" << _name << "\"\n";
983 reprNotTooLongWithoutNameStream(stream);
986 void DataArrayDouble::reprWithoutNameStream(std::ostream& stream) const
988 DataArray::reprWithoutNameStream(stream);
989 stream.precision(17);
990 _mem.repr(getNumberOfComponents(),stream);
993 void DataArrayDouble::reprZipWithoutNameStream(std::ostream& stream) const
995 DataArray::reprWithoutNameStream(stream);
996 stream.precision(17);
997 _mem.reprZip(getNumberOfComponents(),stream);
1000 void DataArrayDouble::reprNotTooLongWithoutNameStream(std::ostream& stream) const
1002 DataArray::reprWithoutNameStream(stream);
1003 stream.precision(17);
1004 _mem.reprNotTooLong(getNumberOfComponents(),stream);
1007 void DataArrayDouble::reprCppStream(const std::string& varName, std::ostream& stream) const
1009 int nbTuples(getNumberOfTuples()),nbComp(getNumberOfComponents());
1010 const double *data(getConstPointer());
1011 stream.precision(17);
1012 stream << "DataArrayDouble *" << varName << "=DataArrayDouble::New();" << std::endl;
1013 if(nbTuples*nbComp>=1)
1015 stream << "const double " << varName << "Data[" << nbTuples*nbComp << "]={";
1016 std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<double>(stream,","));
1017 stream << data[nbTuples*nbComp-1] << "};" << std::endl;
1018 stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
1021 stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
1022 stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
1026 * Method that gives a quick overvien of \a this for python.
1028 void DataArrayDouble::reprQuickOverview(std::ostream& stream) const
1030 static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
1031 stream << "DataArrayDouble C++ instance at " << this << ". ";
1034 int nbOfCompo=(int)_info_on_compo.size();
1037 int nbOfTuples=getNumberOfTuples();
1038 stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
1039 reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
1042 stream << "Number of components : 0.";
1045 stream << "*** No data allocated ****";
1048 void DataArrayDouble::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
1050 const double *data=begin();
1051 int nbOfTuples=getNumberOfTuples();
1052 int nbOfCompo=(int)_info_on_compo.size();
1053 std::ostringstream oss2; oss2 << "[";
1055 std::string oss2Str(oss2.str());
1056 bool isFinished=true;
1057 for(int i=0;i<nbOfTuples && isFinished;i++)
1062 for(int j=0;j<nbOfCompo;j++,data++)
1065 if(j!=nbOfCompo-1) oss2 << ", ";
1071 if(i!=nbOfTuples-1) oss2 << ", ";
1072 std::string oss3Str(oss2.str());
1073 if(oss3Str.length()<maxNbOfByteInRepr)
1085 * Equivalent to DataArrayDouble::isEqual except that if false the reason of
1086 * mismatch is given.
1088 * \param [in] other the instance to be compared with \a this
1089 * \param [in] prec the precision to compare numeric data of the arrays.
1090 * \param [out] reason In case of inequality returns the reason.
1091 * \sa DataArrayDouble::isEqual
1093 bool DataArrayDouble::isEqualIfNotWhy(const DataArrayDouble& other, double prec, std::string& reason) const
1095 if(!areInfoEqualsIfNotWhy(other,reason))
1097 return _mem.isEqual(other._mem,prec,reason);
1101 * Checks if \a this and another DataArrayDouble are fully equal. For more info see
1102 * \ref MEDCouplingArrayBasicsCompare.
1103 * \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1104 * \param [in] prec - precision value to compare numeric data of the arrays.
1105 * \return bool - \a true if the two arrays are equal, \a false else.
1107 bool DataArrayDouble::isEqual(const DataArrayDouble& other, double prec) const
1110 return isEqualIfNotWhy(other,prec,tmp);
1114 * Checks if values of \a this and another DataArrayDouble are equal. For more info see
1115 * \ref MEDCouplingArrayBasicsCompare.
1116 * \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1117 * \param [in] prec - precision value to compare numeric data of the arrays.
1118 * \return bool - \a true if the values of two arrays are equal, \a false else.
1120 bool DataArrayDouble::isEqualWithoutConsideringStr(const DataArrayDouble& other, double prec) const
1123 return _mem.isEqual(other._mem,prec,tmp);
1127 * This method checks that all tuples in \a other are in \a this.
1128 * If true, the output param \a tupleIds contains the tuples ids of \a this that correspond to tupes in \a this.
1129 * 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.
1131 * \param [in] other - the array having the same number of components than \a this.
1132 * \param [out] tupleIds - the tuple ids containing the same number of tuples than \a other has.
1133 * \sa DataArrayDouble::findCommonTuples
1135 bool DataArrayDouble::areIncludedInMe(const DataArrayDouble *other, double prec, DataArrayInt *&tupleIds) const
1138 throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : input array is NULL !");
1139 checkAllocated(); other->checkAllocated();
1140 if(getNumberOfComponents()!=other->getNumberOfComponents())
1141 throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : the number of components does not match !");
1142 MCAuto<DataArrayDouble> a=DataArrayDouble::Aggregate(this,other);
1143 DataArrayInt *c=0,*ci=0;
1144 a->findCommonTuples(prec,getNumberOfTuples(),c,ci);
1145 MCAuto<DataArrayInt> cSafe(c),ciSafe(ci);
1146 int newNbOfTuples=-1;
1147 MCAuto<DataArrayInt> ids=DataArrayInt::ConvertIndexArrayToO2N(a->getNumberOfTuples(),c->begin(),ci->begin(),ci->end(),newNbOfTuples);
1148 MCAuto<DataArrayInt> ret1=ids->selectByTupleIdSafeSlice(getNumberOfTuples(),a->getNumberOfTuples(),1);
1149 tupleIds=ret1.retn();
1150 return newNbOfTuples==getNumberOfTuples();
1154 * Searches for tuples coincident within \a prec tolerance. Each tuple is considered
1155 * as coordinates of a point in getNumberOfComponents()-dimensional space. The
1156 * distance separating two points is computed with the infinite norm.
1158 * Indices of coincident tuples are stored in output arrays.
1159 * A pair of arrays (\a comm, \a commIndex) is called "Surjective Format 2".
1161 * This method is typically used by MEDCouplingPointSet::findCommonNodes() and
1162 * MEDCouplingUMesh::mergeNodes().
1163 * \param [in] prec - minimal absolute distance between two tuples (infinite norm) at which they are
1164 * considered not coincident.
1165 * \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
1166 * tuples have id strictly lower than \a limitTupleId then they are not returned.
1167 * \param [out] comm - the array holding ids (== indices) of coincident tuples.
1168 * \a comm->getNumberOfComponents() == 1.
1169 * \a comm->getNumberOfTuples() == \a commIndex->back().
1170 * \param [out] commIndex - the array dividing all indices stored in \a comm into
1171 * groups of (indices of) coincident tuples. Its every value is a tuple
1172 * index where a next group of tuples begins. For example the second
1173 * group of tuples in \a comm is described by following range of indices:
1174 * [ \a commIndex[1], \a commIndex[2] ). \a commIndex->getNumberOfTuples()-1
1175 * gives the number of groups of coincident tuples.
1176 * \throw If \a this is not allocated.
1177 * \throw If the number of components is not in [1,2,3,4].
1179 * \if ENABLE_EXAMPLES
1180 * \ref cpp_mcdataarraydouble_findcommontuples "Here is a C++ example".
1182 * \ref py_mcdataarraydouble_findcommontuples "Here is a Python example".
1184 * \sa DataArrayInt::ConvertIndexArrayToO2N(), DataArrayDouble::areIncludedInMe
1186 void DataArrayDouble::findCommonTuples(double prec, int limitTupleId, DataArrayInt *&comm, DataArrayInt *&commIndex) const
1189 int nbOfCompo=getNumberOfComponents();
1190 if ((nbOfCompo<1) || (nbOfCompo>4)) //test before work
1191 throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : Unexpected spacedim of coords. Must be 1, 2, 3 or 4.");
1193 int nbOfTuples=getNumberOfTuples();
1195 MCAuto<DataArrayInt> c(DataArrayInt::New()),cI(DataArrayInt::New()); c->alloc(0,1); cI->pushBackSilent(0);
1199 findCommonTuplesAlg<4>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1202 findCommonTuplesAlg<3>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1205 findCommonTuplesAlg<2>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1208 findCommonTuplesAlg<1>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1211 throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : nb of components managed are 1,2,3 and 4 ! not implemented for other number of components !");
1214 commIndex=cI.retn();
1218 * This methods returns the minimal distance between the two set of points \a this and \a other.
1219 * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
1220 * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
1222 * \param [out] thisTupleId the tuple id in \a this corresponding to the returned minimal distance
1223 * \param [out] otherTupleId the tuple id in \a other corresponding to the returned minimal distance
1224 * \return the minimal distance between the two set of points \a this and \a other.
1225 * \sa DataArrayDouble::findClosestTupleId
1227 double DataArrayDouble::minimalDistanceTo(const DataArrayDouble *other, int& thisTupleId, int& otherTupleId) const
1229 MCAuto<DataArrayInt> part1=findClosestTupleId(other);
1230 int nbOfCompo(getNumberOfComponents());
1231 int otherNbTuples(other->getNumberOfTuples());
1232 const double *thisPt(begin()),*otherPt(other->begin());
1233 const int *part1Pt(part1->begin());
1234 double ret=std::numeric_limits<double>::max();
1235 for(int i=0;i<otherNbTuples;i++,part1Pt++,otherPt+=nbOfCompo)
1238 for(int j=0;j<nbOfCompo;j++)
1239 tmp+=(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j])*(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j]);
1241 { ret=tmp; thisTupleId=*part1Pt; otherTupleId=i; }
1247 * This methods returns for each tuple in \a other which tuple in \a this is the closest.
1248 * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
1249 * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
1251 * \return a newly allocated (new object to be dealt by the caller) DataArrayInt having \c other->getNumberOfTuples() tuples and one components.
1252 * \sa DataArrayDouble::minimalDistanceTo
1254 DataArrayInt *DataArrayDouble::findClosestTupleId(const DataArrayDouble *other) const
1257 throw INTERP_KERNEL::Exception("DataArrayDouble::findClosestTupleId : other instance is NULL !");
1258 checkAllocated(); other->checkAllocated();
1259 int nbOfCompo=getNumberOfComponents();
1260 if(nbOfCompo!=other->getNumberOfComponents())
1262 std::ostringstream oss; oss << "DataArrayDouble::findClosestTupleId : number of components in this is " << nbOfCompo;
1263 oss << ", whereas number of components in other is " << other->getNumberOfComponents() << "! Should be equal !";
1264 throw INTERP_KERNEL::Exception(oss.str().c_str());
1266 int nbOfTuples=other->getNumberOfTuples();
1267 int thisNbOfTuples=getNumberOfTuples();
1268 MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuples,1);
1270 getMinMaxPerComponent(bounds);
1275 double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2])),zDelta(fabs(bounds[5]-bounds[4]));
1276 double delta=std::max(xDelta,yDelta); delta=std::max(delta,zDelta);
1277 double characSize=pow((delta*delta*delta)/((double)thisNbOfTuples),1./3.);
1278 BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1279 FindClosestTupleIdAlg<3>(myTree,3.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1284 double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2]));
1285 double delta=std::max(xDelta,yDelta);
1286 double characSize=sqrt(delta/(double)thisNbOfTuples);
1287 BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1288 FindClosestTupleIdAlg<2>(myTree,2.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1293 double characSize=fabs(bounds[1]-bounds[0])/thisNbOfTuples;
1294 BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1295 FindClosestTupleIdAlg<1>(myTree,1.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1299 throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for findClosestTupleId. Must be 1, 2 or 3.");
1305 * This method expects that \a this and \a otherBBoxFrmt arrays are bounding box arrays ( as the output of MEDCouplingPointSet::getBoundingBoxForBBTree method ).
1306 * 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
1307 * how many bounding boxes in \a otherBBoxFrmt.
1308 * So, this method expects that \a this and \a otherBBoxFrmt have the same number of components.
1310 * \param [in] otherBBoxFrmt - It is an array .
1311 * \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.
1312 * \sa MEDCouplingPointSet::getBoundingBoxForBBTree
1313 * \throw If \a this and \a otherBBoxFrmt have not the same number of components.
1314 * \throw If \a this and \a otherBBoxFrmt number of components is not even (BBox format).
1316 DataArrayInt *DataArrayDouble::computeNbOfInteractionsWith(const DataArrayDouble *otherBBoxFrmt, double eps) const
1319 throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : input array is NULL !");
1320 if(!isAllocated() || !otherBBoxFrmt->isAllocated())
1321 throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : this and input array must be allocated !");
1322 int nbOfComp(getNumberOfComponents()),nbOfTuples(getNumberOfTuples());
1323 if(nbOfComp!=otherBBoxFrmt->getNumberOfComponents())
1325 std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : this number of components (" << nbOfComp << ") must be equal to the number of components of input array (" << otherBBoxFrmt->getNumberOfComponents() << ") !";
1326 throw INTERP_KERNEL::Exception(oss.str().c_str());
1330 std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : Number of components (" << nbOfComp << ") is not even ! It should be to be compatible with bbox format !";
1331 throw INTERP_KERNEL::Exception(oss.str().c_str());
1333 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbOfTuples,1);
1334 const double *thisBBPtr(begin());
1335 int *retPtr(ret->getPointer());
1340 BBTree<3,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
1341 for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
1342 *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
1347 BBTree<2,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
1348 for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
1349 *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
1354 BBTree<1,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
1355 for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
1356 *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
1360 throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : space dimension supported are [1,2,3] !");
1367 * Returns a copy of \a this array by excluding coincident tuples. Each tuple is
1368 * considered as coordinates of a point in getNumberOfComponents()-dimensional
1369 * space. The distance between tuples is computed using norm2. If several tuples are
1370 * not far each from other than \a prec, only one of them remains in the result
1371 * array. The order of tuples in the result array is same as in \a this one except
1372 * that coincident tuples are excluded.
1373 * \param [in] prec - minimal absolute distance between two tuples at which they are
1374 * considered not coincident.
1375 * \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
1376 * tuples have id strictly lower than \a limitTupleId then they are not excluded.
1377 * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1378 * is to delete using decrRef() as it is no more needed.
1379 * \throw If \a this is not allocated.
1380 * \throw If the number of components is not in [1,2,3,4].
1382 * \if ENABLE_EXAMPLES
1383 * \ref py_mcdataarraydouble_getdifferentvalues "Here is a Python example".
1386 DataArrayDouble *DataArrayDouble::getDifferentValues(double prec, int limitTupleId) const
1389 DataArrayInt *c0=0,*cI0=0;
1390 findCommonTuples(prec,limitTupleId,c0,cI0);
1391 MCAuto<DataArrayInt> c(c0),cI(cI0);
1392 int newNbOfTuples=-1;
1393 MCAuto<DataArrayInt> o2n=DataArrayInt::ConvertIndexArrayToO2N(getNumberOfTuples(),c0->begin(),cI0->begin(),cI0->end(),newNbOfTuples);
1394 return renumberAndReduce(o2n->getConstPointer(),newNbOfTuples);
1398 * Copy all components in a specified order from another DataArrayDouble.
1399 * Both numerical and textual data is copied. The number of tuples in \a this and
1400 * the other array can be different.
1401 * \param [in] a - the array to copy data from.
1402 * \param [in] compoIds - sequence of zero based indices of components, data of which is
1404 * \throw If \a a is NULL.
1405 * \throw If \a compoIds.size() != \a a->getNumberOfComponents().
1406 * \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
1408 * \if ENABLE_EXAMPLES
1409 * \ref py_mcdataarraydouble_setselectedcomponents "Here is a Python example".
1412 void DataArrayDouble::setSelectedComponents(const DataArrayDouble *a, const std::vector<int>& compoIds)
1415 throw INTERP_KERNEL::Exception("DataArrayDouble::setSelectedComponents : input DataArrayDouble is NULL !");
1417 copyPartOfStringInfoFrom2(compoIds,*a);
1418 std::size_t partOfCompoSz=compoIds.size();
1419 int nbOfCompo=getNumberOfComponents();
1420 int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
1421 const double *ac=a->getConstPointer();
1422 double *nc=getPointer();
1423 for(int i=0;i<nbOfTuples;i++)
1424 for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
1425 nc[nbOfCompo*i+compoIds[j]]=*ac;
1429 * Checks if 0.0 value is present in \a this array. If it is the case, an exception
1431 * \throw If zero is found in \a this array.
1433 void DataArrayDouble::checkNoNullValues() const
1435 const double *tmp=getConstPointer();
1436 std::size_t nbOfElems=getNbOfElems();
1437 const double *where=std::find(tmp,tmp+nbOfElems,0.);
1438 if(where!=tmp+nbOfElems)
1439 throw INTERP_KERNEL::Exception("A value 0.0 have been detected !");
1443 * Computes minimal and maximal value in each component. An output array is filled
1444 * with \c 2 * \a this->getNumberOfComponents() values, so the caller is to allocate
1445 * enough memory before calling this method.
1446 * \param [out] bounds - array of size at least 2 *\a this->getNumberOfComponents().
1447 * It is filled as follows:<br>
1448 * \a bounds[0] = \c min_of_component_0 <br>
1449 * \a bounds[1] = \c max_of_component_0 <br>
1450 * \a bounds[2] = \c min_of_component_1 <br>
1451 * \a bounds[3] = \c max_of_component_1 <br>
1454 void DataArrayDouble::getMinMaxPerComponent(double *bounds) const
1457 int dim=getNumberOfComponents();
1458 for (int idim=0; idim<dim; idim++)
1460 bounds[idim*2]=std::numeric_limits<double>::max();
1461 bounds[idim*2+1]=-std::numeric_limits<double>::max();
1463 const double *ptr=getConstPointer();
1464 int nbOfTuples=getNumberOfTuples();
1465 for(int i=0;i<nbOfTuples;i++)
1467 for(int idim=0;idim<dim;idim++)
1469 if(bounds[idim*2]>ptr[i*dim+idim])
1471 bounds[idim*2]=ptr[i*dim+idim];
1473 if(bounds[idim*2+1]<ptr[i*dim+idim])
1475 bounds[idim*2+1]=ptr[i*dim+idim];
1482 * This method retrieves a newly allocated DataArrayDouble instance having same number of tuples than \a this and twice number of components than \a this
1483 * to store both the min and max per component of each tuples.
1484 * \param [in] epsilon the width of the bbox (identical in each direction) - 0.0 by default
1486 * \return a newly created DataArrayDouble instance having \c this->getNumberOfTuples() tuples and 2 * \c this->getNumberOfComponent() components
1488 * \throw If \a this is not allocated yet.
1490 DataArrayDouble *DataArrayDouble::computeBBoxPerTuple(double epsilon) const
1493 const double *dataPtr=getConstPointer();
1494 int nbOfCompo=getNumberOfComponents();
1495 int nbTuples=getNumberOfTuples();
1496 MCAuto<DataArrayDouble> bbox=DataArrayDouble::New();
1497 bbox->alloc(nbTuples,2*nbOfCompo);
1498 double *bboxPtr=bbox->getPointer();
1499 for(int i=0;i<nbTuples;i++)
1501 for(int j=0;j<nbOfCompo;j++)
1503 bboxPtr[2*nbOfCompo*i+2*j]=dataPtr[nbOfCompo*i+j]-epsilon;
1504 bboxPtr[2*nbOfCompo*i+2*j+1]=dataPtr[nbOfCompo*i+j]+epsilon;
1511 * For each tuples **t** in \a other, this method retrieves tuples in \a this that are equal to **t**.
1512 * Two tuples are considered equal if the euclidian distance between the two tuples is lower than \a eps.
1514 * \param [in] other a DataArrayDouble having same number of components than \a this.
1515 * \param [in] eps absolute precision representing distance (using infinite norm) between 2 tuples behind which 2 tuples are considered equal.
1516 * \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.
1517 * \a cI allows to extract information in \a c.
1518 * \param [out] cI is an indirection array that allows to extract the data contained in \a c.
1520 * \throw In case of:
1521 * - \a this is not allocated
1522 * - \a other is not allocated or null
1523 * - \a this and \a other do not have the same number of components
1524 * - if number of components of \a this is not in [1,2,3]
1526 * \sa MEDCouplingPointSet::getNodeIdsNearPoints, DataArrayDouble::getDifferentValues
1528 void DataArrayDouble::computeTupleIdsNearTuples(const DataArrayDouble *other, double eps, DataArrayInt *& c, DataArrayInt *& cI) const
1531 throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : input pointer other is null !");
1533 other->checkAllocated();
1534 int nbOfCompo=getNumberOfComponents();
1535 int otherNbOfCompo=other->getNumberOfComponents();
1536 if(nbOfCompo!=otherNbOfCompo)
1537 throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : number of components should be equal between this and other !");
1538 int nbOfTuplesOther=other->getNumberOfTuples();
1539 MCAuto<DataArrayInt> cArr(DataArrayInt::New()),cIArr(DataArrayInt::New()); cArr->alloc(0,1); cIArr->pushBackSilent(0);
1544 BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
1545 FindTupleIdsNearTuplesAlg<3>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
1550 BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
1551 FindTupleIdsNearTuplesAlg<2>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
1556 BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
1557 FindTupleIdsNearTuplesAlg<1>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
1561 throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for computeTupleIdsNearTuples. Must be 1, 2 or 3.");
1563 c=cArr.retn(); cI=cIArr.retn();
1567 * 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
1568 * around origin of 'radius' 1.
1570 * \param [in] eps absolute epsilon. under that value of delta between max and min no scale is performed.
1572 void DataArrayDouble::recenterForMaxPrecision(double eps)
1575 int dim=getNumberOfComponents();
1576 std::vector<double> bounds(2*dim);
1577 getMinMaxPerComponent(&bounds[0]);
1578 for(int i=0;i<dim;i++)
1580 double delta=bounds[2*i+1]-bounds[2*i];
1581 double offset=(bounds[2*i]+bounds[2*i+1])/2.;
1583 applyLin(1./delta,-offset/delta,i);
1585 applyLin(1.,-offset,i);
1590 * Returns the maximal value and all its locations within \a this one-dimensional array.
1591 * \param [out] tupleIds - a new instance of DataArrayInt containg indices of
1592 * tuples holding the maximal value. The caller is to delete it using
1593 * decrRef() as it is no more needed.
1594 * \return double - the maximal value among all values of \a this array.
1595 * \throw If \a this->getNumberOfComponents() != 1
1596 * \throw If \a this->getNumberOfTuples() < 1
1598 double DataArrayDouble::getMaxValue2(DataArrayInt*& tupleIds) const
1602 double ret=getMaxValue(tmp);
1603 tupleIds=findIdsInRange(ret,ret);
1608 * Returns the minimal value and all its locations within \a this one-dimensional array.
1609 * \param [out] tupleIds - a new instance of DataArrayInt containg indices of
1610 * tuples holding the minimal value. The caller is to delete it using
1611 * decrRef() as it is no more needed.
1612 * \return double - the minimal value among all values of \a this array.
1613 * \throw If \a this->getNumberOfComponents() != 1
1614 * \throw If \a this->getNumberOfTuples() < 1
1616 double DataArrayDouble::getMinValue2(DataArrayInt*& tupleIds) const
1620 double ret=getMinValue(tmp);
1621 tupleIds=findIdsInRange(ret,ret);
1626 * 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.
1627 * This method only works for single component array.
1629 * \return a value in [ 0, \c this->getNumberOfTuples() )
1631 * \throw If \a this is not allocated
1634 int DataArrayDouble::count(double value, double eps) const
1638 if(getNumberOfComponents()!=1)
1639 throw INTERP_KERNEL::Exception("DataArrayDouble::count : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
1640 const double *vals=begin();
1641 int nbOfTuples=getNumberOfTuples();
1642 for(int i=0;i<nbOfTuples;i++,vals++)
1643 if(fabs(*vals-value)<=eps)
1649 * Returns the average value of \a this one-dimensional array.
1650 * \return double - the average value over all values of \a this array.
1651 * \throw If \a this->getNumberOfComponents() != 1
1652 * \throw If \a this->getNumberOfTuples() < 1
1654 double DataArrayDouble::getAverageValue() const
1656 if(getNumberOfComponents()!=1)
1657 throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
1658 int nbOfTuples=getNumberOfTuples();
1660 throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : array exists but number of tuples must be > 0 !");
1661 const double *vals=getConstPointer();
1662 double ret=std::accumulate(vals,vals+nbOfTuples,0.);
1663 return ret/nbOfTuples;
1667 * Returns the Euclidean norm of the vector defined by \a this array.
1668 * \return double - the value of the Euclidean norm, i.e.
1669 * the square root of the inner product of vector.
1670 * \throw If \a this is not allocated.
1672 double DataArrayDouble::norm2() const
1676 std::size_t nbOfElems=getNbOfElems();
1677 const double *pt=getConstPointer();
1678 for(std::size_t i=0;i<nbOfElems;i++,pt++)
1684 * Returns the maximum norm of the vector defined by \a this array.
1685 * This method works even if the number of components is diferent from one.
1686 * If the number of elements in \a this is 0, -1. is returned.
1687 * \return double - the value of the maximum norm, i.e.
1688 * the maximal absolute value among values of \a this array (whatever its number of components).
1689 * \throw If \a this is not allocated.
1691 double DataArrayDouble::normMax() const
1695 std::size_t nbOfElems(getNbOfElems());
1696 const double *pt(getConstPointer());
1697 for(std::size_t i=0;i<nbOfElems;i++,pt++)
1699 double val(std::abs(*pt));
1707 * Returns the minimum norm (absolute value) of the vector defined by \a this array.
1708 * This method works even if the number of components is diferent from one.
1709 * If the number of elements in \a this is 0, std::numeric_limits<double>::max() is returned.
1710 * \return double - the value of the minimum norm, i.e.
1711 * the minimal absolute value among values of \a this array (whatever its number of components).
1712 * \throw If \a this is not allocated.
1714 double DataArrayDouble::normMin() const
1717 double ret(std::numeric_limits<double>::max());
1718 std::size_t nbOfElems(getNbOfElems());
1719 const double *pt(getConstPointer());
1720 for(std::size_t i=0;i<nbOfElems;i++,pt++)
1722 double val(std::abs(*pt));
1730 * Accumulates values of each component of \a this array.
1731 * \param [out] res - an array of length \a this->getNumberOfComponents(), allocated
1732 * by the caller, that is filled by this method with sum value for each
1734 * \throw If \a this is not allocated.
1736 void DataArrayDouble::accumulate(double *res) const
1739 const double *ptr=getConstPointer();
1740 int nbTuple=getNumberOfTuples();
1741 int nbComps=getNumberOfComponents();
1742 std::fill(res,res+nbComps,0.);
1743 for(int i=0;i<nbTuple;i++)
1744 std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<double>());
1748 * This method returns the min distance from an external tuple defined by [ \a tupleBg , \a tupleEnd ) to \a this and
1749 * the first tuple in \a this that matches the returned distance. If there is no tuples in \a this an exception will be thrown.
1752 * \a this is expected to be allocated and expected to have a number of components equal to the distance from \a tupleBg to
1753 * \a tupleEnd. If not an exception will be thrown.
1755 * \param [in] tupleBg start pointer (included) of input external tuple
1756 * \param [in] tupleEnd end pointer (not included) of input external tuple
1757 * \param [out] tupleId the tuple id in \a this that matches the min of distance between \a this and input external tuple
1758 * \return the min distance.
1759 * \sa MEDCouplingUMesh::distanceToPoint
1761 double DataArrayDouble::distanceToTuple(const double *tupleBg, const double *tupleEnd, int& tupleId) const
1764 int nbTuple=getNumberOfTuples();
1765 int nbComps=getNumberOfComponents();
1766 if(nbComps!=(int)std::distance(tupleBg,tupleEnd))
1767 { 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()); }
1769 throw INTERP_KERNEL::Exception("DataArrayDouble::distanceToTuple : no tuple in this ! No distance to compute !");
1770 double ret0=std::numeric_limits<double>::max();
1772 const double *work=getConstPointer();
1773 for(int i=0;i<nbTuple;i++)
1776 for(int j=0;j<nbComps;j++,work++)
1777 val+=(*work-tupleBg[j])*((*work-tupleBg[j]));
1781 { ret0=val; tupleId=i; }
1787 * Accumulate values of the given component of \a this array.
1788 * \param [in] compId - the index of the component of interest.
1789 * \return double - a sum value of \a compId-th component.
1790 * \throw If \a this is not allocated.
1791 * \throw If \a the condition ( 0 <= \a compId < \a this->getNumberOfComponents() ) is
1794 double DataArrayDouble::accumulate(int compId) const
1797 const double *ptr=getConstPointer();
1798 int nbTuple=getNumberOfTuples();
1799 int nbComps=getNumberOfComponents();
1800 if(compId<0 || compId>=nbComps)
1801 throw INTERP_KERNEL::Exception("DataArrayDouble::accumulate : Invalid compId specified : No such nb of components !");
1803 for(int i=0;i<nbTuple;i++)
1804 ret+=ptr[i*nbComps+compId];
1809 * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
1810 * The returned array will have same number of components than \a this and number of tuples equal to
1811 * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
1813 * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
1814 * 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.
1816 * \param [in] bgOfIndex - begin (included) of the input index array.
1817 * \param [in] endOfIndex - end (excluded) of the input index array.
1818 * \return DataArrayDouble * - the new instance having the same number of components than \a this.
1820 * \throw If bgOfIndex or end is NULL.
1821 * \throw If input index array is not ascendingly sorted.
1822 * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
1823 * \throw If std::distance(bgOfIndex,endOfIndex)==0.
1825 DataArrayDouble *DataArrayDouble::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
1827 if(!bgOfIndex || !endOfIndex)
1828 throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : input pointer NULL !");
1830 int nbCompo=getNumberOfComponents();
1831 int nbOfTuples=getNumberOfTuples();
1832 int sz=(int)std::distance(bgOfIndex,endOfIndex);
1834 throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : invalid size of input index array !");
1836 MCAuto<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(sz,nbCompo);
1837 const int *w=bgOfIndex;
1838 if(*w<0 || *w>=nbOfTuples)
1839 throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
1840 const double *srcPt=begin()+(*w)*nbCompo;
1841 double *tmp=ret->getPointer();
1842 for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
1844 std::fill(tmp,tmp+nbCompo,0.);
1847 for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
1849 if(j>=0 && j<nbOfTuples)
1850 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<double>());
1853 std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
1854 throw INTERP_KERNEL::Exception(oss.str().c_str());
1860 std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
1861 throw INTERP_KERNEL::Exception(oss.str().c_str());
1864 ret->copyStringInfoFrom(*this);
1869 * 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.
1870 * This method expects that \a this as only one component. The returned array will have \a this->getNumberOfTuples()+1 tuple with also one component.
1871 * The ith element of returned array is equal to the sum of elements in \a this with rank strictly lower than i.
1873 * \return DataArrayDouble - A newly built array containing cum sum of \a this.
1875 MCAuto<DataArrayDouble> DataArrayDouble::cumSum() const
1878 checkNbOfComps(1,"DataArrayDouble::cumSum : this is expected to be single component");
1879 int nbOfTuple(getNumberOfTuples());
1880 MCAuto<DataArrayDouble> ret(DataArrayDouble::New()); ret->alloc(nbOfTuple+1,1);
1881 double *ptr(ret->getPointer());
1883 const double *thisPtr(begin());
1884 for(int i=0;i<nbOfTuple;i++)
1885 ptr[i+1]=ptr[i]+thisPtr[i];
1890 * Converts each 2D point defined by the tuple of \a this array from the Polar to the
1891 * Cartesian coordinate system. The two components of the tuple of \a this array are
1892 * considered to contain (1) radius and (2) angle of the point in the Polar CS.
1893 * \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
1894 * contains X and Y coordinates of the point in the Cartesian CS. The caller
1895 * is to delete this array using decrRef() as it is no more needed. The array
1896 * does not contain any textual info on components.
1897 * \throw If \a this->getNumberOfComponents() != 2.
1898 * \sa fromCartToPolar
1900 DataArrayDouble *DataArrayDouble::fromPolarToCart() const
1903 int nbOfComp(getNumberOfComponents());
1905 throw INTERP_KERNEL::Exception("DataArrayDouble::fromPolarToCart : must be an array with exactly 2 components !");
1906 int nbOfTuple(getNumberOfTuples());
1907 DataArrayDouble *ret(DataArrayDouble::New());
1908 ret->alloc(nbOfTuple,2);
1909 double *w(ret->getPointer());
1910 const double *wIn(getConstPointer());
1911 for(int i=0;i<nbOfTuple;i++,w+=2,wIn+=2)
1913 w[0]=wIn[0]*cos(wIn[1]);
1914 w[1]=wIn[0]*sin(wIn[1]);
1920 * Converts each 3D point defined by the tuple of \a this array from the Cylindrical to
1921 * the Cartesian coordinate system. The three components of the tuple of \a this array
1922 * are considered to contain (1) radius, (2) azimuth and (3) altitude of the point in
1923 * the Cylindrical CS.
1924 * \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
1925 * contains X, Y and Z coordinates of the point in the Cartesian CS. The info
1926 * on the third component is copied from \a this array. The caller
1927 * is to delete this array using decrRef() as it is no more needed.
1928 * \throw If \a this->getNumberOfComponents() != 3.
1931 DataArrayDouble *DataArrayDouble::fromCylToCart() const
1934 int nbOfComp(getNumberOfComponents());
1936 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCylToCart : must be an array with exactly 3 components !");
1937 int nbOfTuple(getNumberOfTuples());
1938 DataArrayDouble *ret(DataArrayDouble::New());
1939 ret->alloc(getNumberOfTuples(),3);
1940 double *w(ret->getPointer());
1941 const double *wIn(getConstPointer());
1942 for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
1944 w[0]=wIn[0]*cos(wIn[1]);
1945 w[1]=wIn[0]*sin(wIn[1]);
1948 ret->setInfoOnComponent(2,getInfoOnComponent(2));
1953 * Converts each 3D point defined by the tuple of \a this array from the Spherical to
1954 * the Cartesian coordinate system. The three components of the tuple of \a this array
1955 * are considered to contain (1) radius, (2) polar angle and (3) azimuthal angle of the
1956 * point in the Cylindrical CS.
1957 * \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
1958 * contains X, Y and Z coordinates of the point in the Cartesian CS. The info
1959 * on the third component is copied from \a this array. The caller
1960 * is to delete this array using decrRef() as it is no more needed.
1961 * \throw If \a this->getNumberOfComponents() != 3.
1962 * \sa fromCartToSpher
1964 DataArrayDouble *DataArrayDouble::fromSpherToCart() const
1967 int nbOfComp(getNumberOfComponents());
1969 throw INTERP_KERNEL::Exception("DataArrayDouble::fromSpherToCart : must be an array with exactly 3 components !");
1970 int nbOfTuple(getNumberOfTuples());
1971 DataArrayDouble *ret(DataArrayDouble::New());
1972 ret->alloc(getNumberOfTuples(),3);
1973 double *w(ret->getPointer());
1974 const double *wIn(getConstPointer());
1975 for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
1977 w[0]=wIn[0]*cos(wIn[2])*sin(wIn[1]);
1978 w[1]=wIn[0]*sin(wIn[2])*sin(wIn[1]);
1979 w[2]=wIn[0]*cos(wIn[1]);
1985 * 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.
1986 * 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.
1987 * If \a at equals to AX_CYL the returned array will be the result of operation cylindric to cartesian of \a this...
1989 * \param [in] atOfThis - The axis type of \a this.
1990 * \return DataArrayDouble * - the new instance of DataArrayDouble (that must be dealed by caller) containing the result of the cartesianizification of \a this.
1992 DataArrayDouble *DataArrayDouble::cartesianize(MEDCouplingAxisType atOfThis) const
1995 int nbOfComp(getNumberOfComponents());
1996 MCAuto<DataArrayDouble> ret;
2004 ret=fromCylToCart();
2009 ret=fromPolarToCart();
2013 throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : For AX_CYL, number of components must be in [2,3] !");
2017 ret=fromSpherToCart();
2022 ret=fromPolarToCart();
2026 throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : For AX_CYL, number of components must be in [2,3] !");
2028 throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : not recognized axis type ! Only AX_CART, AX_CYL and AX_SPHER supported !");
2030 ret->copyStringInfoFrom(*this);
2035 * This method returns a newly created array to be deallocated that contains the result of conversion from cartesian to polar.
2036 * This method expects that \a this has exactly 2 components.
2037 * \sa fromPolarToCart
2039 DataArrayDouble *DataArrayDouble::fromCartToPolar() const
2041 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2043 int nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2045 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToPolar : must be an array with exactly 2 components !");
2046 ret->alloc(nbTuples,2);
2047 double *retPtr(ret->getPointer());
2048 const double *ptr(begin());
2049 for(int i=0;i<nbTuples;i++,ptr+=2,retPtr+=2)
2051 retPtr[0]=sqrt(ptr[0]*ptr[0]+ptr[1]*ptr[1]);
2052 retPtr[1]=atan2(ptr[1],ptr[0]);
2058 * This method returns a newly created array to be deallocated that contains the result of conversion from cartesian to cylindrical.
2059 * This method expects that \a this has exactly 3 components.
2062 DataArrayDouble *DataArrayDouble::fromCartToCyl() const
2064 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2066 int nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2068 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCyl : must be an array with exactly 3 components !");
2069 ret->alloc(nbTuples,3);
2070 double *retPtr(ret->getPointer());
2071 const double *ptr(begin());
2072 for(int i=0;i<nbTuples;i++,ptr+=3,retPtr+=3)
2074 retPtr[0]=sqrt(ptr[0]*ptr[0]+ptr[1]*ptr[1]);
2075 retPtr[1]=atan2(ptr[1],ptr[0]);
2082 * This method returns a newly created array to be deallocated that contains the result of conversion from cartesian to spherical coordinates.
2083 * \sa fromSpherToCart
2085 DataArrayDouble *DataArrayDouble::fromCartToSpher() const
2087 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2089 int nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2091 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToSpher : must be an array with exactly 3 components !");
2092 ret->alloc(nbTuples,3);
2093 double *retPtr(ret->getPointer());
2094 const double *ptr(begin());
2095 for(int i=0;i<nbTuples;i++,ptr+=3,retPtr+=3)
2097 retPtr[0]=sqrt(ptr[0]*ptr[0]+ptr[1]*ptr[1]+ptr[2]*ptr[2]);
2098 retPtr[1]=acos(ptr[2]/retPtr[0]);
2099 retPtr[2]=atan2(ptr[1],ptr[0]);
2105 * 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.
2106 * This method expects that \a this has exactly 3 components.
2107 * \sa MEDCouplingFieldDouble::computeVectorFieldCyl
2109 DataArrayDouble *DataArrayDouble::fromCartToCylGiven(const DataArrayDouble *coords, const double center[3], const double vect[3]) const
2112 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : input coords are NULL !");
2113 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2114 checkAllocated(); coords->checkAllocated();
2115 int nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2117 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : must be an array with exactly 3 components !");
2118 if(coords->getNumberOfComponents()!=3)
2119 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : coords array must have exactly 3 components !");
2120 if(coords->getNumberOfTuples()!=nbTuples)
2121 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : coords array must have the same number of tuples !");
2122 ret->alloc(nbTuples,nbOfComp);
2123 double magOfVect(sqrt(vect[0]*vect[0]+vect[1]*vect[1]+vect[2]*vect[2]));
2125 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : magnitude of vect is too low !");
2126 double Ur[3],Uteta[3],Uz[3],*retPtr(ret->getPointer());
2127 const double *coo(coords->begin()),*vectField(begin());
2128 std::transform(vect,vect+3,Uz,std::bind2nd(std::multiplies<double>(),1./magOfVect));
2129 for(int i=0;i<nbTuples;i++,vectField+=3,retPtr+=3,coo+=3)
2131 std::transform(coo,coo+3,center,Ur,std::minus<double>());
2132 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];
2133 double magOfTeta(sqrt(Uteta[0]*Uteta[0]+Uteta[1]*Uteta[1]+Uteta[2]*Uteta[2]));
2134 std::transform(Uteta,Uteta+3,Uteta,std::bind2nd(std::multiplies<double>(),1./magOfTeta));
2135 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];
2136 retPtr[0]=Ur[0]*vectField[0]+Ur[1]*vectField[1]+Ur[2]*vectField[2];
2137 retPtr[1]=Uteta[0]*vectField[0]+Uteta[1]*vectField[1]+Uteta[2]*vectField[2];
2138 retPtr[2]=Uz[0]*vectField[0]+Uz[1]*vectField[1]+Uz[2]*vectField[2];
2140 ret->copyStringInfoFrom(*this);
2145 * Computes the doubly contracted product of every tensor defined by the tuple of \a this
2146 * array contating 6 components.
2147 * \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
2148 * is calculated from the tuple <em>(t)</em> of \a this array as follows:
2149 * \f$ t[0]^2+t[1]^2+t[2]^2+2*t[3]^2+2*t[4]^2+2*t[5]^2\f$.
2150 * The caller is to delete this result array using decrRef() as it is no more needed.
2151 * \throw If \a this->getNumberOfComponents() != 6.
2153 DataArrayDouble *DataArrayDouble::doublyContractedProduct() const
2156 int nbOfComp(getNumberOfComponents());
2158 throw INTERP_KERNEL::Exception("DataArrayDouble::doublyContractedProduct : must be an array with exactly 6 components !");
2159 DataArrayDouble *ret=DataArrayDouble::New();
2160 int nbOfTuple=getNumberOfTuples();
2161 ret->alloc(nbOfTuple,1);
2162 const double *src=getConstPointer();
2163 double *dest=ret->getPointer();
2164 for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
2165 *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];
2170 * Computes the determinant of every square matrix defined by the tuple of \a this
2171 * array, which contains either 4, 6 or 9 components. The case of 6 components
2172 * corresponds to that of the upper triangular matrix.
2173 * \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
2174 * is the determinant of matrix of the corresponding tuple of \a this array.
2175 * The caller is to delete this result array using decrRef() as it is no more
2177 * \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2179 DataArrayDouble *DataArrayDouble::determinant() const
2182 DataArrayDouble *ret=DataArrayDouble::New();
2183 int nbOfTuple=getNumberOfTuples();
2184 ret->alloc(nbOfTuple,1);
2185 const double *src=getConstPointer();
2186 double *dest=ret->getPointer();
2187 switch(getNumberOfComponents())
2190 for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
2191 *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];
2194 for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
2195 *dest=src[0]*src[3]-src[1]*src[2];
2198 for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
2199 *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];
2203 throw INTERP_KERNEL::Exception("DataArrayDouble::determinant : Invalid number of components ! must be in 4,6,9 !");
2208 * Computes 3 eigenvalues of every upper triangular matrix defined by the tuple of
2209 * \a this array, which contains 6 components.
2210 * \return DataArrayDouble * - the new instance of DataArrayDouble containing 3
2211 * components, whose each tuple contains the eigenvalues of the matrix of
2212 * corresponding tuple of \a this array.
2213 * The caller is to delete this result array using decrRef() as it is no more
2215 * \throw If \a this->getNumberOfComponents() != 6.
2217 DataArrayDouble *DataArrayDouble::eigenValues() const
2220 int nbOfComp=getNumberOfComponents();
2222 throw INTERP_KERNEL::Exception("DataArrayDouble::eigenValues : must be an array with exactly 6 components !");
2223 DataArrayDouble *ret=DataArrayDouble::New();
2224 int nbOfTuple=getNumberOfTuples();
2225 ret->alloc(nbOfTuple,3);
2226 const double *src=getConstPointer();
2227 double *dest=ret->getPointer();
2228 for(int i=0;i<nbOfTuple;i++,dest+=3,src+=6)
2229 INTERP_KERNEL::computeEigenValues6(src,dest);
2234 * Computes 3 eigenvectors of every upper triangular matrix defined by the tuple of
2235 * \a this array, which contains 6 components.
2236 * \return DataArrayDouble * - the new instance of DataArrayDouble containing 9
2237 * components, whose each tuple contains 3 eigenvectors of the matrix of
2238 * corresponding tuple of \a this array.
2239 * The caller is to delete this result array using decrRef() as it is no more
2241 * \throw If \a this->getNumberOfComponents() != 6.
2243 DataArrayDouble *DataArrayDouble::eigenVectors() const
2246 int nbOfComp=getNumberOfComponents();
2248 throw INTERP_KERNEL::Exception("DataArrayDouble::eigenVectors : must be an array with exactly 6 components !");
2249 DataArrayDouble *ret=DataArrayDouble::New();
2250 int nbOfTuple=getNumberOfTuples();
2251 ret->alloc(nbOfTuple,9);
2252 const double *src=getConstPointer();
2253 double *dest=ret->getPointer();
2254 for(int i=0;i<nbOfTuple;i++,src+=6)
2257 INTERP_KERNEL::computeEigenValues6(src,tmp);
2258 for(int j=0;j<3;j++,dest+=3)
2259 INTERP_KERNEL::computeEigenVectorForEigenValue6(src,tmp[j],1e-12,dest);
2265 * Computes the inverse matrix of every matrix defined by the tuple of \a this
2266 * array, which contains either 4, 6 or 9 components. The case of 6 components
2267 * corresponds to that of the upper triangular matrix.
2268 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2269 * same number of components as \a this one, whose each tuple is the inverse
2270 * matrix of the matrix of corresponding tuple of \a this array.
2271 * The caller is to delete this result array using decrRef() as it is no more
2273 * \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2275 DataArrayDouble *DataArrayDouble::inverse() const
2278 int nbOfComp=getNumberOfComponents();
2279 if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
2280 throw INTERP_KERNEL::Exception("DataArrayDouble::inversion : must be an array with 4,6 or 9 components !");
2281 DataArrayDouble *ret=DataArrayDouble::New();
2282 int nbOfTuple=getNumberOfTuples();
2283 ret->alloc(nbOfTuple,nbOfComp);
2284 const double *src=getConstPointer();
2285 double *dest=ret->getPointer();
2287 for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
2289 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];
2290 dest[0]=(src[1]*src[2]-src[4]*src[4])/det;
2291 dest[1]=(src[0]*src[2]-src[5]*src[5])/det;
2292 dest[2]=(src[0]*src[1]-src[3]*src[3])/det;
2293 dest[3]=(src[5]*src[4]-src[3]*src[2])/det;
2294 dest[4]=(src[5]*src[3]-src[0]*src[4])/det;
2295 dest[5]=(src[3]*src[4]-src[1]*src[5])/det;
2297 else if(nbOfComp==4)
2298 for(int i=0;i<nbOfTuple;i++,dest+=4,src+=4)
2300 double det=src[0]*src[3]-src[1]*src[2];
2302 dest[1]=-src[1]/det;
2303 dest[2]=-src[2]/det;
2307 for(int i=0;i<nbOfTuple;i++,dest+=9,src+=9)
2309 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];
2310 dest[0]=(src[4]*src[8]-src[7]*src[5])/det;
2311 dest[1]=(src[7]*src[2]-src[1]*src[8])/det;
2312 dest[2]=(src[1]*src[5]-src[4]*src[2])/det;
2313 dest[3]=(src[6]*src[5]-src[3]*src[8])/det;
2314 dest[4]=(src[0]*src[8]-src[6]*src[2])/det;
2315 dest[5]=(src[2]*src[3]-src[0]*src[5])/det;
2316 dest[6]=(src[3]*src[7]-src[6]*src[4])/det;
2317 dest[7]=(src[6]*src[1]-src[0]*src[7])/det;
2318 dest[8]=(src[0]*src[4]-src[1]*src[3])/det;
2324 * Computes the trace of every matrix defined by the tuple of \a this
2325 * array, which contains either 4, 6 or 9 components. The case of 6 components
2326 * corresponds to that of the upper triangular matrix.
2327 * \return DataArrayDouble * - the new instance of DataArrayDouble containing
2328 * 1 component, whose each tuple is the trace of
2329 * the matrix of corresponding tuple of \a this array.
2330 * The caller is to delete this result array using decrRef() as it is no more
2332 * \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2334 DataArrayDouble *DataArrayDouble::trace() const
2337 int nbOfComp=getNumberOfComponents();
2338 if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
2339 throw INTERP_KERNEL::Exception("DataArrayDouble::trace : must be an array with 4,6 or 9 components !");
2340 DataArrayDouble *ret=DataArrayDouble::New();
2341 int nbOfTuple=getNumberOfTuples();
2342 ret->alloc(nbOfTuple,1);
2343 const double *src=getConstPointer();
2344 double *dest=ret->getPointer();
2346 for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
2347 *dest=src[0]+src[1]+src[2];
2348 else if(nbOfComp==4)
2349 for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
2350 *dest=src[0]+src[3];
2352 for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
2353 *dest=src[0]+src[4]+src[8];
2358 * Computes the stress deviator tensor of every stress tensor defined by the tuple of
2359 * \a this array, which contains 6 components.
2360 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2361 * same number of components and tuples as \a this array.
2362 * The caller is to delete this result array using decrRef() as it is no more
2364 * \throw If \a this->getNumberOfComponents() != 6.
2366 DataArrayDouble *DataArrayDouble::deviator() const
2369 int nbOfComp=getNumberOfComponents();
2371 throw INTERP_KERNEL::Exception("DataArrayDouble::deviator : must be an array with exactly 6 components !");
2372 DataArrayDouble *ret=DataArrayDouble::New();
2373 int nbOfTuple=getNumberOfTuples();
2374 ret->alloc(nbOfTuple,6);
2375 const double *src=getConstPointer();
2376 double *dest=ret->getPointer();
2377 for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
2379 double tr=(src[0]+src[1]+src[2])/3.;
2391 * Computes the magnitude of every vector defined by the tuple of
2393 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2394 * same number of tuples as \a this array and one component.
2395 * The caller is to delete this result array using decrRef() as it is no more
2397 * \throw If \a this is not allocated.
2399 DataArrayDouble *DataArrayDouble::magnitude() const
2402 int nbOfComp=getNumberOfComponents();
2403 DataArrayDouble *ret=DataArrayDouble::New();
2404 int nbOfTuple=getNumberOfTuples();
2405 ret->alloc(nbOfTuple,1);
2406 const double *src=getConstPointer();
2407 double *dest=ret->getPointer();
2408 for(int i=0;i<nbOfTuple;i++,dest++)
2411 for(int j=0;j<nbOfComp;j++,src++)
2419 * Computes for each tuple the sum of number of components values in the tuple and return it.
2421 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2422 * same number of tuples as \a this array and one component.
2423 * The caller is to delete this result array using decrRef() as it is no more
2425 * \throw If \a this is not allocated.
2427 DataArrayDouble *DataArrayDouble::sumPerTuple() const
2430 int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
2431 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2432 ret->alloc(nbOfTuple,1);
2433 const double *src(getConstPointer());
2434 double *dest(ret->getPointer());
2435 for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
2436 *dest=std::accumulate(src,src+nbOfComp,0.);
2441 * Computes the maximal value within every tuple of \a this array.
2442 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2443 * same number of tuples as \a this array and one component.
2444 * The caller is to delete this result array using decrRef() as it is no more
2446 * \throw If \a this is not allocated.
2447 * \sa DataArrayDouble::maxPerTupleWithCompoId
2449 DataArrayDouble *DataArrayDouble::maxPerTuple() const
2452 int nbOfComp=getNumberOfComponents();
2453 MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
2454 int nbOfTuple=getNumberOfTuples();
2455 ret->alloc(nbOfTuple,1);
2456 const double *src=getConstPointer();
2457 double *dest=ret->getPointer();
2458 for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
2459 *dest=*std::max_element(src,src+nbOfComp);
2464 * Computes the maximal value within every tuple of \a this array and it returns the first component
2465 * id for each tuple that corresponds to the maximal value within the tuple.
2467 * \param [out] compoIdOfMaxPerTuple - the new new instance of DataArrayInt containing the
2468 * same number of tuples and only one component.
2469 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2470 * same number of tuples as \a this array and one component.
2471 * The caller is to delete this result array using decrRef() as it is no more
2473 * \throw If \a this is not allocated.
2474 * \sa DataArrayDouble::maxPerTuple
2476 DataArrayDouble *DataArrayDouble::maxPerTupleWithCompoId(DataArrayInt* &compoIdOfMaxPerTuple) const
2479 int nbOfComp=getNumberOfComponents();
2480 MCAuto<DataArrayDouble> ret0=DataArrayDouble::New();
2481 MCAuto<DataArrayInt> ret1=DataArrayInt::New();
2482 int nbOfTuple=getNumberOfTuples();
2483 ret0->alloc(nbOfTuple,1); ret1->alloc(nbOfTuple,1);
2484 const double *src=getConstPointer();
2485 double *dest=ret0->getPointer(); int *dest1=ret1->getPointer();
2486 for(int i=0;i<nbOfTuple;i++,dest++,dest1++,src+=nbOfComp)
2488 const double *loc=std::max_element(src,src+nbOfComp);
2490 *dest1=(int)std::distance(src,loc);
2492 compoIdOfMaxPerTuple=ret1.retn();
2497 * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c this->getNumberOfTuples() tuples.
2498 * \n This returned array contains the euclidian distance for each tuple in \a this.
2499 * \n So the returned array can be seen as a dense symmetrical matrix whose diagonal elements are equal to 0.
2500 * \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)
2502 * \warning use this method with care because it can leads to big amount of consumed memory !
2504 * \return A newly allocated (huge) MEDCoupling::DataArrayDouble instance that the caller should deal with.
2506 * \throw If \a this is not allocated.
2508 * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrixWith
2510 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrix() const
2513 int nbOfComp=getNumberOfComponents();
2514 int nbOfTuples=getNumberOfTuples();
2515 const double *inData=getConstPointer();
2516 MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
2517 ret->alloc(nbOfTuples*nbOfTuples,1);
2518 double *outData=ret->getPointer();
2519 for(int i=0;i<nbOfTuples;i++)
2521 outData[i*nbOfTuples+i]=0.;
2522 for(int j=i+1;j<nbOfTuples;j++)
2525 for(int k=0;k<nbOfComp;k++)
2526 { double delta=inData[i*nbOfComp+k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
2528 outData[i*nbOfTuples+j]=dist;
2529 outData[j*nbOfTuples+i]=dist;
2536 * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c other->getNumberOfTuples() tuples.
2537 * \n This returned array contains the euclidian distance for each tuple in \a other with each tuple in \a this.
2538 * \n So the returned array can be seen as a dense rectangular matrix with \c other->getNumberOfTuples() rows and \c this->getNumberOfTuples() columns.
2539 * \n Output rectangular matrix is sorted along rows.
2540 * \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)
2542 * \warning use this method with care because it can leads to big amount of consumed memory !
2544 * \param [in] other DataArrayDouble instance having same number of components than \a this.
2545 * \return A newly allocated (huge) MEDCoupling::DataArrayDouble instance that the caller should deal with.
2547 * \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.
2549 * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrix
2551 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrixWith(const DataArrayDouble *other) const
2554 throw INTERP_KERNEL::Exception("DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : input parameter is null !");
2556 other->checkAllocated();
2557 int nbOfComp=getNumberOfComponents();
2558 int otherNbOfComp=other->getNumberOfComponents();
2559 if(nbOfComp!=otherNbOfComp)
2561 std::ostringstream oss; oss << "DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : this nb of compo=" << nbOfComp << " and other nb of compo=" << otherNbOfComp << ". It should match !";
2562 throw INTERP_KERNEL::Exception(oss.str().c_str());
2564 int nbOfTuples=getNumberOfTuples();
2565 int otherNbOfTuples=other->getNumberOfTuples();
2566 const double *inData=getConstPointer();
2567 const double *inDataOther=other->getConstPointer();
2568 MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
2569 ret->alloc(otherNbOfTuples*nbOfTuples,1);
2570 double *outData=ret->getPointer();
2571 for(int i=0;i<otherNbOfTuples;i++,inDataOther+=nbOfComp)
2573 for(int j=0;j<nbOfTuples;j++)
2576 for(int k=0;k<nbOfComp;k++)
2577 { double delta=inDataOther[k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
2579 outData[i*nbOfTuples+j]=dist;
2586 * Sorts value within every tuple of \a this array.
2587 * \param [in] asc - if \a true, the values are sorted in ascending order, else,
2588 * in descending order.
2589 * \throw If \a this is not allocated.
2591 void DataArrayDouble::sortPerTuple(bool asc)
2594 double *pt=getPointer();
2595 int nbOfTuple=getNumberOfTuples();
2596 int nbOfComp=getNumberOfComponents();
2598 for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
2599 std::sort(pt,pt+nbOfComp);
2601 for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
2602 std::sort(pt,pt+nbOfComp,std::greater<double>());
2607 * Modify all elements of \a this array, so that
2608 * an element _x_ becomes \f$ numerator / x \f$.
2609 * \warning If an exception is thrown because of presence of 0.0 element in \a this
2610 * array, all elements processed before detection of the zero element remain
2612 * \param [in] numerator - the numerator used to modify array elements.
2613 * \throw If \a this is not allocated.
2614 * \throw If there is an element equal to 0.0 in \a this array.
2616 void DataArrayDouble::applyInv(double numerator)
2619 double *ptr=getPointer();
2620 std::size_t nbOfElems=getNbOfElems();
2621 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2623 if(std::abs(*ptr)>std::numeric_limits<double>::min())
2625 *ptr=numerator/(*ptr);
2629 std::ostringstream oss; oss << "DataArrayDouble::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
2631 throw INTERP_KERNEL::Exception(oss.str().c_str());
2638 * Modify all elements of \a this array, so that
2639 * an element _x_ becomes <em> val ^ x </em>. Contrary to DataArrayInt::applyPow
2640 * all values in \a this have to be >= 0 if val is \b not integer.
2641 * \param [in] val - the value used to apply pow on all array elements.
2642 * \throw If \a this is not allocated.
2643 * \warning If an exception is thrown because of presence of 0 element in \a this
2644 * array and \a val is \b not integer, all elements processed before detection of the zero element remain
2647 void DataArrayDouble::applyPow(double val)
2650 double *ptr=getPointer();
2651 std::size_t nbOfElems=getNbOfElems();
2653 bool isInt=((double)val2)==val;
2656 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2662 std::ostringstream oss; oss << "DataArrayDouble::applyPow (double) : At elem # " << i << " value is " << *ptr << " ! must be >=0. !";
2663 throw INTERP_KERNEL::Exception(oss.str().c_str());
2669 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2670 *ptr=pow(*ptr,val2);
2676 * Modify all elements of \a this array, so that
2677 * an element _x_ becomes \f$ val ^ x \f$.
2678 * \param [in] val - the value used to apply pow on all array elements.
2679 * \throw If \a this is not allocated.
2680 * \throw If \a val < 0.
2681 * \warning If an exception is thrown because of presence of 0 element in \a this
2682 * array, all elements processed before detection of the zero element remain
2685 void DataArrayDouble::applyRPow(double val)
2689 throw INTERP_KERNEL::Exception("DataArrayDouble::applyRPow : the input value has to be >= 0 !");
2690 double *ptr=getPointer();
2691 std::size_t nbOfElems=getNbOfElems();
2692 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2698 * Returns a new DataArrayDouble created from \a this one by applying \a
2699 * FunctionToEvaluate to every tuple of \a this array. Textual data is not copied.
2700 * For more info see \ref MEDCouplingArrayApplyFunc
2701 * \param [in] nbOfComp - number of components in the result array.
2702 * \param [in] func - the \a FunctionToEvaluate declared as
2703 * \c bool (*\a func)(\c const \c double *\a pos, \c double *\a res),
2704 * where \a pos points to the first component of a tuple of \a this array
2705 * and \a res points to the first component of a tuple of the result array.
2706 * Note that length (number of components) of \a pos can differ from
2708 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2709 * same number of tuples as \a this array.
2710 * The caller is to delete this result array using decrRef() as it is no more
2712 * \throw If \a this is not allocated.
2713 * \throw If \a func returns \a false.
2715 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, FunctionToEvaluate func) const
2718 DataArrayDouble *newArr=DataArrayDouble::New();
2719 int nbOfTuples=getNumberOfTuples();
2720 int oldNbOfComp=getNumberOfComponents();
2721 newArr->alloc(nbOfTuples,nbOfComp);
2722 const double *ptr=getConstPointer();
2723 double *ptrToFill=newArr->getPointer();
2724 for(int i=0;i<nbOfTuples;i++)
2726 if(!func(ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp))
2728 std::ostringstream oss; oss << "For tuple # " << i << " with value (";
2729 std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
2730 oss << ") : Evaluation of function failed !";
2732 throw INTERP_KERNEL::Exception(oss.str().c_str());
2739 * Returns a new DataArrayDouble created from \a this one by applying a function to every
2740 * tuple of \a this array. Textual data is not copied.
2741 * For more info see \ref MEDCouplingArrayApplyFunc1.
2742 * \param [in] nbOfComp - number of components in the result array.
2743 * \param [in] func - the expression defining how to transform a tuple of \a this array.
2744 * Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
2745 * \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
2746 * If false the computation is carried on without any notification. When false the evaluation is a little faster.
2747 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2748 * same number of tuples as \a this array and \a nbOfComp components.
2749 * The caller is to delete this result array using decrRef() as it is no more
2751 * \throw If \a this is not allocated.
2752 * \throw If computing \a func fails.
2754 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, const std::string& func, bool isSafe) const
2756 INTERP_KERNEL::ExprParser expr(func);
2758 std::set<std::string> vars;
2759 expr.getTrueSetOfVars(vars);
2760 std::vector<std::string> varsV(vars.begin(),vars.end());
2761 return applyFuncNamedCompo(nbOfComp,varsV,func,isSafe);
2765 * Returns a new DataArrayDouble created from \a this one by applying a function to every
2766 * tuple of \a this array. Textual data is not copied. This method works by tuples (whatever its size).
2767 * If \a this is a one component array, call applyFuncOnThis instead that performs the same work faster.
2769 * For more info see \ref MEDCouplingArrayApplyFunc0.
2770 * \param [in] func - the expression defining how to transform a tuple of \a this array.
2771 * Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
2772 * \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
2773 * If false the computation is carried on without any notification. When false the evaluation is a little faster.
2774 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2775 * same number of tuples and components as \a this array.
2776 * The caller is to delete this result array using decrRef() as it is no more
2778 * \sa applyFuncOnThis
2779 * \throw If \a this is not allocated.
2780 * \throw If computing \a func fails.
2782 DataArrayDouble *DataArrayDouble::applyFunc(const std::string& func, bool isSafe) const
2784 int nbOfComp(getNumberOfComponents());
2786 throw INTERP_KERNEL::Exception("DataArrayDouble::applyFunc : output number of component must be > 0 !");
2788 int nbOfTuples(getNumberOfTuples());
2789 MCAuto<DataArrayDouble> newArr(DataArrayDouble::New());
2790 newArr->alloc(nbOfTuples,nbOfComp);
2791 INTERP_KERNEL::ExprParser expr(func);
2793 std::set<std::string> vars;
2794 expr.getTrueSetOfVars(vars);
2795 if((int)vars.size()>1)
2797 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 : ";
2798 std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
2799 throw INTERP_KERNEL::Exception(oss.str().c_str());
2803 expr.prepareFastEvaluator();
2804 newArr->rearrange(1);
2805 newArr->fillWithValue(expr.evaluateDouble());
2806 newArr->rearrange(nbOfComp);
2807 return newArr.retn();
2809 std::vector<std::string> vars2(vars.begin(),vars.end());
2810 double buff,*ptrToFill(newArr->getPointer());
2811 const double *ptr(begin());
2812 std::vector<double> stck;
2813 expr.prepareExprEvaluationDouble(vars2,1,1,0,&buff,&buff+1);
2814 expr.prepareFastEvaluator();
2817 for(int i=0;i<nbOfTuples;i++)
2819 for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
2822 expr.evaluateDoubleInternal(stck);
2823 *ptrToFill=stck.back();
2830 for(int i=0;i<nbOfTuples;i++)
2832 for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
2837 expr.evaluateDoubleInternalSafe(stck);
2839 catch(INTERP_KERNEL::Exception& e)
2841 std::ostringstream oss; oss << "For tuple # " << i << " component # " << iComp << " with value (";
2843 oss << ") : Evaluation of function failed !" << e.what();
2844 throw INTERP_KERNEL::Exception(oss.str().c_str());
2846 *ptrToFill=stck.back();
2851 return newArr.retn();
2855 * This method is a non const method that modify the array in \a this.
2856 * This method only works on one component array. It means that function \a func must
2857 * contain at most one variable.
2858 * This method is a specialization of applyFunc method with one parameter on one component array.
2860 * \param [in] func - the expression defining how to transform a tuple of \a this array.
2861 * Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
2862 * \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
2863 * If false the computation is carried on without any notification. When false the evaluation is a little faster.
2867 void DataArrayDouble::applyFuncOnThis(const std::string& func, bool isSafe)
2869 int nbOfComp(getNumberOfComponents());
2871 throw INTERP_KERNEL::Exception("DataArrayDouble::applyFuncOnThis : output number of component must be > 0 !");
2873 int nbOfTuples(getNumberOfTuples());
2874 INTERP_KERNEL::ExprParser expr(func);
2876 std::set<std::string> vars;
2877 expr.getTrueSetOfVars(vars);
2878 if((int)vars.size()>1)
2880 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 : ";
2881 std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
2882 throw INTERP_KERNEL::Exception(oss.str().c_str());
2886 expr.prepareFastEvaluator();
2887 std::vector<std::string> compInfo(getInfoOnComponents());
2889 fillWithValue(expr.evaluateDouble());
2890 rearrange(nbOfComp);
2891 setInfoOnComponents(compInfo);
2894 std::vector<std::string> vars2(vars.begin(),vars.end());
2895 double buff,*ptrToFill(getPointer());
2896 const double *ptr(begin());
2897 std::vector<double> stck;
2898 expr.prepareExprEvaluationDouble(vars2,1,1,0,&buff,&buff+1);
2899 expr.prepareFastEvaluator();
2902 for(int i=0;i<nbOfTuples;i++)
2904 for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
2907 expr.evaluateDoubleInternal(stck);
2908 *ptrToFill=stck.back();
2915 for(int i=0;i<nbOfTuples;i++)
2917 for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
2922 expr.evaluateDoubleInternalSafe(stck);
2924 catch(INTERP_KERNEL::Exception& e)
2926 std::ostringstream oss; oss << "For tuple # " << i << " component # " << iComp << " with value (";
2928 oss << ") : Evaluation of function failed !" << e.what();
2929 throw INTERP_KERNEL::Exception(oss.str().c_str());
2931 *ptrToFill=stck.back();
2939 * Returns a new DataArrayDouble created from \a this one by applying a function to every
2940 * tuple of \a this array. Textual data is not copied.
2941 * For more info see \ref MEDCouplingArrayApplyFunc2.
2942 * \param [in] nbOfComp - number of components in the result array.
2943 * \param [in] func - the expression defining how to transform a tuple of \a this array.
2944 * Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
2945 * \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
2946 * If false the computation is carried on without any notification. When false the evaluation is a little faster.
2947 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2948 * same number of tuples as \a this array.
2949 * The caller is to delete this result array using decrRef() as it is no more
2951 * \throw If \a this is not allocated.
2952 * \throw If \a func contains vars that are not in \a this->getInfoOnComponent().
2953 * \throw If computing \a func fails.
2955 DataArrayDouble *DataArrayDouble::applyFuncCompo(int nbOfComp, const std::string& func, bool isSafe) const
2957 return applyFuncNamedCompo(nbOfComp,getVarsOnComponent(),func,isSafe);
2961 * Returns a new DataArrayDouble created from \a this one by applying a function to every
2962 * tuple of \a this array. Textual data is not copied.
2963 * For more info see \ref MEDCouplingArrayApplyFunc3.
2964 * \param [in] nbOfComp - number of components in the result array.
2965 * \param [in] varsOrder - sequence of vars defining their order.
2966 * \param [in] func - the expression defining how to transform a tuple of \a this array.
2967 * Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
2968 * \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
2969 * If false the computation is carried on without any notification. When false the evaluation is a little faster.
2970 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2971 * same number of tuples as \a this array.
2972 * The caller is to delete this result array using decrRef() as it is no more
2974 * \throw If \a this is not allocated.
2975 * \throw If \a func contains vars not in \a varsOrder.
2976 * \throw If computing \a func fails.
2978 DataArrayDouble *DataArrayDouble::applyFuncNamedCompo(int nbOfComp, const std::vector<std::string>& varsOrder, const std::string& func, bool isSafe) const
2981 throw INTERP_KERNEL::Exception("DataArrayDouble::applyFuncNamedCompo : output number of component must be > 0 !");
2982 std::vector<std::string> varsOrder2(varsOrder);
2983 int oldNbOfComp(getNumberOfComponents());
2984 for(int i=(int)varsOrder.size();i<oldNbOfComp;i++)
2985 varsOrder2.push_back(std::string());
2987 int nbOfTuples(getNumberOfTuples());
2988 INTERP_KERNEL::ExprParser expr(func);
2990 std::set<std::string> vars;
2991 expr.getTrueSetOfVars(vars);
2992 if((int)vars.size()>oldNbOfComp)
2994 std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
2995 oss << vars.size() << " variables : ";
2996 std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
2997 throw INTERP_KERNEL::Exception(oss.str().c_str());
2999 MCAuto<DataArrayDouble> newArr(DataArrayDouble::New());
3000 newArr->alloc(nbOfTuples,nbOfComp);
3001 INTERP_KERNEL::AutoPtr<double> buff(new double[oldNbOfComp]);
3002 double *buffPtr(buff),*ptrToFill;
3003 std::vector<double> stck;
3004 for(int iComp=0;iComp<nbOfComp;iComp++)
3006 expr.prepareExprEvaluationDouble(varsOrder2,oldNbOfComp,nbOfComp,iComp,buffPtr,buffPtr+oldNbOfComp);
3007 expr.prepareFastEvaluator();
3008 const double *ptr(getConstPointer());
3009 ptrToFill=newArr->getPointer()+iComp;
3012 for(int i=0;i<nbOfTuples;i++,ptrToFill+=nbOfComp,ptr+=oldNbOfComp)
3014 std::copy(ptr,ptr+oldNbOfComp,buffPtr);
3015 expr.evaluateDoubleInternal(stck);
3016 *ptrToFill=stck.back();
3022 for(int i=0;i<nbOfTuples;i++,ptrToFill+=nbOfComp,ptr+=oldNbOfComp)
3024 std::copy(ptr,ptr+oldNbOfComp,buffPtr);
3027 expr.evaluateDoubleInternalSafe(stck);
3028 *ptrToFill=stck.back();
3031 catch(INTERP_KERNEL::Exception& e)
3033 std::ostringstream oss; oss << "For tuple # " << i << " with value (";
3034 std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
3035 oss << ") : Evaluation of function failed !" << e.what();
3036 throw INTERP_KERNEL::Exception(oss.str().c_str());
3041 return newArr.retn();
3044 void DataArrayDouble::applyFuncFast32(const std::string& func)
3047 INTERP_KERNEL::ExprParser expr(func);
3049 char *funcStr=expr.compileX86();
3051 *((void **)&funcPtr)=funcStr;//he he...
3053 double *ptr=getPointer();
3054 int nbOfComp=getNumberOfComponents();
3055 int nbOfTuples=getNumberOfTuples();
3056 int nbOfElems=nbOfTuples*nbOfComp;
3057 for(int i=0;i<nbOfElems;i++,ptr++)
3062 void DataArrayDouble::applyFuncFast64(const std::string& func)
3065 INTERP_KERNEL::ExprParser expr(func);
3067 char *funcStr=expr.compileX86_64();
3069 *((void **)&funcPtr)=funcStr;//he he...
3071 double *ptr=getPointer();
3072 int nbOfComp=getNumberOfComponents();
3073 int nbOfTuples=getNumberOfTuples();
3074 int nbOfElems=nbOfTuples*nbOfComp;
3075 for(int i=0;i<nbOfElems;i++,ptr++)
3081 * \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.
3083 MCAuto<DataArrayDouble> DataArrayDouble::symmetry3DPlane(const double point[3], const double normalVector[3]) const
3086 if(getNumberOfComponents()!=3)
3087 throw INTERP_KERNEL::Exception("DataArrayDouble::symmetry3DPlane : this is excepted to have 3 components !");
3088 int nbTuples(getNumberOfTuples());
3089 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
3090 ret->alloc(nbTuples,3);
3091 Symmetry3DPlane(point,normalVector,nbTuples,begin(),ret->getPointer());
3095 DataArrayDoubleIterator *DataArrayDouble::iterator()
3097 return new DataArrayDoubleIterator(this);
3101 * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional
3102 * array whose values are within a given range. Textual data is not copied.
3103 * \param [in] vmin - a lowest acceptable value (included).
3104 * \param [in] vmax - a greatest acceptable value (included).
3105 * \return DataArrayInt * - the new instance of DataArrayInt.
3106 * The caller is to delete this result array using decrRef() as it is no more
3108 * \throw If \a this->getNumberOfComponents() != 1.
3110 * \sa DataArrayDouble::findIdsNotInRange
3112 * \if ENABLE_EXAMPLES
3113 * \ref cpp_mcdataarraydouble_getidsinrange "Here is a C++ example".<br>
3114 * \ref py_mcdataarraydouble_getidsinrange "Here is a Python example".
3117 DataArrayInt *DataArrayDouble::findIdsInRange(double vmin, double vmax) const
3120 if(getNumberOfComponents()!=1)
3121 throw INTERP_KERNEL::Exception("DataArrayDouble::findIdsInRange : this must have exactly one component !");
3122 const double *cptr(begin());
3123 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
3124 int nbOfTuples(getNumberOfTuples());
3125 for(int i=0;i<nbOfTuples;i++,cptr++)
3126 if(*cptr>=vmin && *cptr<=vmax)
3127 ret->pushBackSilent(i);
3132 * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional
3133 * array whose values are not within a given range. Textual data is not copied.
3134 * \param [in] vmin - a lowest not acceptable value (excluded).
3135 * \param [in] vmax - a greatest not acceptable value (excluded).
3136 * \return DataArrayInt * - the new instance of DataArrayInt.
3137 * The caller is to delete this result array using decrRef() as it is no more
3139 * \throw If \a this->getNumberOfComponents() != 1.
3141 * \sa DataArrayDouble::findIdsInRange
3143 DataArrayInt *DataArrayDouble::findIdsNotInRange(double vmin, double vmax) const
3146 if(getNumberOfComponents()!=1)
3147 throw INTERP_KERNEL::Exception("DataArrayDouble::findIdsNotInRange : this must have exactly one component !");
3148 const double *cptr(begin());
3149 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
3150 int nbOfTuples(getNumberOfTuples());
3151 for(int i=0;i<nbOfTuples;i++,cptr++)
3152 if(*cptr<vmin || *cptr>vmax)
3153 ret->pushBackSilent(i);
3158 * Returns a new DataArrayDouble by concatenating two given arrays, so that (1) the number
3159 * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
3160 * the number of component in the result array is same as that of each of given arrays.
3161 * Info on components is copied from the first of the given arrays. Number of components
3162 * in the given arrays must be the same.
3163 * \param [in] a1 - an array to include in the result array.
3164 * \param [in] a2 - another array to include in the result array.
3165 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3166 * The caller is to delete this result array using decrRef() as it is no more
3168 * \throw If both \a a1 and \a a2 are NULL.
3169 * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
3171 DataArrayDouble *DataArrayDouble::Aggregate(const DataArrayDouble *a1, const DataArrayDouble *a2)
3173 std::vector<const DataArrayDouble *> tmp(2);
3174 tmp[0]=a1; tmp[1]=a2;
3175 return Aggregate(tmp);
3179 * Returns a new DataArrayDouble by concatenating all given arrays, so that (1) the number
3180 * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
3181 * the number of component in the result array is same as that of each of given arrays.
3182 * Info on components is copied from the first of the given arrays. Number of components
3183 * in the given arrays must be the same.
3184 * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it
3185 * not the object itself.
3186 * \param [in] arr - a sequence of arrays to include in the result array.
3187 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3188 * The caller is to delete this result array using decrRef() as it is no more
3190 * \throw If all arrays within \a arr are NULL.
3191 * \throw If getNumberOfComponents() of arrays within \a arr.
3193 DataArrayDouble *DataArrayDouble::Aggregate(const std::vector<const DataArrayDouble *>& arr)
3195 std::vector<const DataArrayDouble *> a;
3196 for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
3200 throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : input list must contain at least one NON EMPTY DataArrayDouble !");
3201 std::vector<const DataArrayDouble *>::const_iterator it=a.begin();
3202 int nbOfComp=(*it)->getNumberOfComponents();
3203 int nbt=(*it++)->getNumberOfTuples();
3204 for(int i=1;it!=a.end();it++,i++)
3206 if((*it)->getNumberOfComponents()!=nbOfComp)
3207 throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : Nb of components mismatch for array aggregation !");
3208 nbt+=(*it)->getNumberOfTuples();
3210 MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
3211 ret->alloc(nbt,nbOfComp);
3212 double *pt=ret->getPointer();
3213 for(it=a.begin();it!=a.end();it++)
3214 pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
3215 ret->copyStringInfoFrom(*(a[0]));
3220 * Returns a new DataArrayDouble containing a dot product of two given arrays, so that
3221 * the i-th tuple of the result array is a sum of products of j-th components of i-th
3222 * tuples of given arrays (\f$ a_i = \sum_{j=1}^n a1_j * a2_j \f$).
3223 * Info on components and name is copied from the first of the given arrays.
3224 * Number of tuples and components in the given arrays must be the same.
3225 * \param [in] a1 - a given array.
3226 * \param [in] a2 - another given array.
3227 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3228 * The caller is to delete this result array using decrRef() as it is no more
3230 * \throw If either \a a1 or \a a2 is NULL.
3231 * \throw If any given array is not allocated.
3232 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3233 * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
3235 DataArrayDouble *DataArrayDouble::Dot(const DataArrayDouble *a1, const DataArrayDouble *a2)
3238 throw INTERP_KERNEL::Exception("DataArrayDouble::Dot : input DataArrayDouble instance is NULL !");
3239 a1->checkAllocated();
3240 a2->checkAllocated();
3241 int nbOfComp=a1->getNumberOfComponents();
3242 if(nbOfComp!=a2->getNumberOfComponents())
3243 throw INTERP_KERNEL::Exception("Nb of components mismatch for array Dot !");
3244 int nbOfTuple=a1->getNumberOfTuples();
3245 if(nbOfTuple!=a2->getNumberOfTuples())
3246 throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Dot !");
3247 DataArrayDouble *ret=DataArrayDouble::New();
3248 ret->alloc(nbOfTuple,1);
3249 double *retPtr=ret->getPointer();
3250 const double *a1Ptr=a1->getConstPointer();
3251 const double *a2Ptr=a2->getConstPointer();
3252 for(int i=0;i<nbOfTuple;i++)
3255 for(int j=0;j<nbOfComp;j++)
3256 sum+=a1Ptr[i*nbOfComp+j]*a2Ptr[i*nbOfComp+j];
3259 ret->setInfoOnComponent(0,a1->getInfoOnComponent(0));
3260 ret->setName(a1->getName());
3265 * Returns a new DataArrayDouble containing a cross product of two given arrays, so that
3266 * the i-th tuple of the result array contains 3 components of a vector which is a cross
3267 * product of two vectors defined by the i-th tuples of given arrays.
3268 * Info on components is copied from the first of the given arrays.
3269 * Number of tuples in the given arrays must be the same.
3270 * Number of components in the given arrays must be 3.
3271 * \param [in] a1 - a given array.
3272 * \param [in] a2 - another given array.
3273 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3274 * The caller is to delete this result array using decrRef() as it is no more
3276 * \throw If either \a a1 or \a a2 is NULL.
3277 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3278 * \throw If \a a1->getNumberOfComponents() != 3
3279 * \throw If \a a2->getNumberOfComponents() != 3
3281 DataArrayDouble *DataArrayDouble::CrossProduct(const DataArrayDouble *a1, const DataArrayDouble *a2)
3284 throw INTERP_KERNEL::Exception("DataArrayDouble::CrossProduct : input DataArrayDouble instance is NULL !");
3285 int nbOfComp=a1->getNumberOfComponents();
3286 if(nbOfComp!=a2->getNumberOfComponents())
3287 throw INTERP_KERNEL::Exception("Nb of components mismatch for array crossProduct !");
3289 throw INTERP_KERNEL::Exception("Nb of components must be equal to 3 for array crossProduct !");
3290 int nbOfTuple=a1->getNumberOfTuples();
3291 if(nbOfTuple!=a2->getNumberOfTuples())
3292 throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array crossProduct !");
3293 DataArrayDouble *ret=DataArrayDouble::New();
3294 ret->alloc(nbOfTuple,3);
3295 double *retPtr=ret->getPointer();
3296 const double *a1Ptr=a1->getConstPointer();
3297 const double *a2Ptr=a2->getConstPointer();
3298 for(int i=0;i<nbOfTuple;i++)
3300 retPtr[3*i]=a1Ptr[3*i+1]*a2Ptr[3*i+2]-a1Ptr[3*i+2]*a2Ptr[3*i+1];
3301 retPtr[3*i+1]=a1Ptr[3*i+2]*a2Ptr[3*i]-a1Ptr[3*i]*a2Ptr[3*i+2];
3302 retPtr[3*i+2]=a1Ptr[3*i]*a2Ptr[3*i+1]-a1Ptr[3*i+1]*a2Ptr[3*i];
3304 ret->copyStringInfoFrom(*a1);
3309 * Returns a new DataArrayDouble containing maximal values of two given arrays.
3310 * Info on components is copied from the first of the given arrays.
3311 * Number of tuples and components in the given arrays must be the same.
3312 * \param [in] a1 - an array to compare values with another one.
3313 * \param [in] a2 - another array to compare values with the first one.
3314 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3315 * The caller is to delete this result array using decrRef() as it is no more
3317 * \throw If either \a a1 or \a a2 is NULL.
3318 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3319 * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
3321 DataArrayDouble *DataArrayDouble::Max(const DataArrayDouble *a1, const DataArrayDouble *a2)
3324 throw INTERP_KERNEL::Exception("DataArrayDouble::Max : input DataArrayDouble instance is NULL !");
3325 int nbOfComp=a1->getNumberOfComponents();
3326 if(nbOfComp!=a2->getNumberOfComponents())
3327 throw INTERP_KERNEL::Exception("Nb of components mismatch for array Max !");
3328 int nbOfTuple=a1->getNumberOfTuples();
3329 if(nbOfTuple!=a2->getNumberOfTuples())
3330 throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Max !");
3331 DataArrayDouble *ret=DataArrayDouble::New();
3332 ret->alloc(nbOfTuple,nbOfComp);
3333 double *retPtr=ret->getPointer();
3334 const double *a1Ptr=a1->getConstPointer();
3335 const double *a2Ptr=a2->getConstPointer();
3336 int nbElem=nbOfTuple*nbOfComp;
3337 for(int i=0;i<nbElem;i++)
3338 retPtr[i]=std::max(a1Ptr[i],a2Ptr[i]);
3339 ret->copyStringInfoFrom(*a1);
3344 * Returns a new DataArrayDouble containing minimal values of two given arrays.
3345 * Info on components is copied from the first of the given arrays.
3346 * Number of tuples and components in the given arrays must be the same.
3347 * \param [in] a1 - an array to compare values with another one.
3348 * \param [in] a2 - another array to compare values with the first one.
3349 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3350 * The caller is to delete this result array using decrRef() as it is no more
3352 * \throw If either \a a1 or \a a2 is NULL.
3353 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3354 * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
3356 DataArrayDouble *DataArrayDouble::Min(const DataArrayDouble *a1, const DataArrayDouble *a2)
3359 throw INTERP_KERNEL::Exception("DataArrayDouble::Min : input DataArrayDouble instance is NULL !");
3360 int nbOfComp=a1->getNumberOfComponents();
3361 if(nbOfComp!=a2->getNumberOfComponents())
3362 throw INTERP_KERNEL::Exception("Nb of components mismatch for array min !");
3363 int nbOfTuple=a1->getNumberOfTuples();
3364 if(nbOfTuple!=a2->getNumberOfTuples())
3365 throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array min !");
3366 DataArrayDouble *ret=DataArrayDouble::New();
3367 ret->alloc(nbOfTuple,nbOfComp);
3368 double *retPtr=ret->getPointer();
3369 const double *a1Ptr=a1->getConstPointer();
3370 const double *a2Ptr=a2->getConstPointer();
3371 int nbElem=nbOfTuple*nbOfComp;
3372 for(int i=0;i<nbElem;i++)
3373 retPtr[i]=std::min(a1Ptr[i],a2Ptr[i]);
3374 ret->copyStringInfoFrom(*a1);
3379 * Returns a new DataArrayDouble that is the result of pow of two given arrays. There are 3
3382 * \param [in] a1 - an array to pow up.
3383 * \param [in] a2 - another array to sum up.
3384 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3385 * The caller is to delete this result array using decrRef() as it is no more
3387 * \throw If either \a a1 or \a a2 is NULL.
3388 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3389 * \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
3390 * \throw If there is a negative value in \a a1.
3392 DataArrayDouble *DataArrayDouble::Pow(const DataArrayDouble *a1, const DataArrayDouble *a2)
3395 throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : at least one of input instances is null !");
3396 int nbOfTuple=a1->getNumberOfTuples();
3397 int nbOfTuple2=a2->getNumberOfTuples();
3398 int nbOfComp=a1->getNumberOfComponents();
3399 int nbOfComp2=a2->getNumberOfComponents();
3400 if(nbOfTuple!=nbOfTuple2)
3401 throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of tuples mismatches !");
3402 if(nbOfComp!=1 || nbOfComp2!=1)
3403 throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of components of both arrays must be equal to 1 !");
3404 MCAuto<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbOfTuple,1);
3405 const double *ptr1(a1->begin()),*ptr2(a2->begin());
3406 double *ptr=ret->getPointer();
3407 for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
3411 *ptr=pow(*ptr1,*ptr2);
3415 std::ostringstream oss; oss << "DataArrayDouble::Pow : on tuple #" << i << " of a1 value is < 0 (" << *ptr1 << ") !";
3416 throw INTERP_KERNEL::Exception(oss.str().c_str());
3423 * Apply pow on values of another DataArrayDouble to values of \a this one.
3425 * \param [in] other - an array to pow to \a this one.
3426 * \throw If \a other is NULL.
3427 * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
3428 * \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
3429 * \throw If there is a negative value in \a this.
3431 void DataArrayDouble::powEqual(const DataArrayDouble *other)
3434 throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : input instance is null !");
3435 int nbOfTuple=getNumberOfTuples();
3436 int nbOfTuple2=other->getNumberOfTuples();
3437 int nbOfComp=getNumberOfComponents();
3438 int nbOfComp2=other->getNumberOfComponents();
3439 if(nbOfTuple!=nbOfTuple2)
3440 throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of tuples mismatches !");
3441 if(nbOfComp!=1 || nbOfComp2!=1)
3442 throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of components of both arrays must be equal to 1 !");
3443 double *ptr=getPointer();
3444 const double *ptrc=other->begin();
3445 for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
3448 *ptr=pow(*ptr,*ptrc);
3451 std::ostringstream oss; oss << "DataArrayDouble::powEqual : on tuple #" << i << " of this value is < 0 (" << *ptr << ") !";
3452 throw INTERP_KERNEL::Exception(oss.str().c_str());
3459 * This method is \b NOT wrapped into python because it can be useful only for performance reasons in C++ context.
3460 * All values in \a this must be 0. or 1. within eps error. 0 means false, 1 means true.
3461 * If an another value than 0 or 1 appear (within eps precision) an INTERP_KERNEL::Exception will be thrown.
3463 * \throw if \a this is not allocated.
3464 * \throw if \a this has not exactly one component.
3466 std::vector<bool> DataArrayDouble::toVectorOfBool(double eps) const
3469 if(getNumberOfComponents()!=1)
3470 throw INTERP_KERNEL::Exception("DataArrayDouble::toVectorOfBool : must be applied on single component array !");
3471 int nbt(getNumberOfTuples());
3472 std::vector<bool> ret(nbt);
3473 const double *pt(begin());
3474 for(int i=0;i<nbt;i++)
3478 else if(fabs(pt[i]-1.)<eps)
3482 std::ostringstream oss; oss << "DataArrayDouble::toVectorOfBool : the tuple #" << i << " has value " << pt[i] << " is invalid ! must be 0. or 1. !";
3483 throw INTERP_KERNEL::Exception(oss.str().c_str());
3490 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
3493 void DataArrayDouble::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
3498 tinyInfo[0]=getNumberOfTuples();
3499 tinyInfo[1]=getNumberOfComponents();
3509 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
3512 void DataArrayDouble::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
3516 int nbOfCompo=getNumberOfComponents();
3517 tinyInfo.resize(nbOfCompo+1);
3518 tinyInfo[0]=getName();
3519 for(int i=0;i<nbOfCompo;i++)
3520 tinyInfo[i+1]=getInfoOnComponent(i);
3525 tinyInfo[0]=getName();
3530 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
3531 * This method returns if a feeding is needed.
3533 bool DataArrayDouble::resizeForUnserialization(const std::vector<int>& tinyInfoI)
3535 int nbOfTuple=tinyInfoI[0];
3536 int nbOfComp=tinyInfoI[1];
3537 if(nbOfTuple!=-1 || nbOfComp!=-1)
3539 alloc(nbOfTuple,nbOfComp);
3546 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
3548 void DataArrayDouble::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
3550 setName(tinyInfoS[0]);
3553 int nbOfCompo=getNumberOfComponents();
3554 for(int i=0;i<nbOfCompo;i++)
3555 setInfoOnComponent(i,tinyInfoS[i+1]);
3560 * Low static method that operates 3D rotation of 'nbNodes' 3D nodes whose coordinates are arranged in \a coordsIn
3561 * around an axe ( \a center, \a vect) and with angle \a angle.
3563 void DataArrayDouble::Rotate3DAlg(const double *center, const double *vect, double angle, int nbNodes, const double *coordsIn, double *coordsOut)
3565 if(!center || !vect)
3566 throw INTERP_KERNEL::Exception("DataArrayDouble::Rotate3DAlg : null vector in input !");
3567 double sina(sin(angle));
3568 double cosa(cos(angle));
3569 double vectorNorm[3];
3571 double matrixTmp[9];
3572 double norm(sqrt(vect[0]*vect[0]+vect[1]*vect[1]+vect[2]*vect[2]));
3573 if(norm<std::numeric_limits<double>::min())
3574 throw INTERP_KERNEL::Exception("DataArrayDouble::Rotate3DAlg : magnitude of input vector is too close of 0. !");
3575 std::transform(vect,vect+3,vectorNorm,std::bind2nd(std::multiplies<double>(),1/norm));
3576 //rotation matrix computation
3577 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;
3578 matrixTmp[0]=vectorNorm[0]*vectorNorm[0]; matrixTmp[1]=vectorNorm[0]*vectorNorm[1]; matrixTmp[2]=vectorNorm[0]*vectorNorm[2];
3579 matrixTmp[3]=vectorNorm[1]*vectorNorm[0]; matrixTmp[4]=vectorNorm[1]*vectorNorm[1]; matrixTmp[5]=vectorNorm[1]*vectorNorm[2];
3580 matrixTmp[6]=vectorNorm[2]*vectorNorm[0]; matrixTmp[7]=vectorNorm[2]*vectorNorm[1]; matrixTmp[8]=vectorNorm[2]*vectorNorm[2];
3581 std::transform(matrixTmp,matrixTmp+9,matrixTmp,std::bind2nd(std::multiplies<double>(),1-cosa));
3582 std::transform(matrix,matrix+9,matrixTmp,matrix,std::plus<double>());
3583 matrixTmp[0]=0.; matrixTmp[1]=-vectorNorm[2]; matrixTmp[2]=vectorNorm[1];
3584 matrixTmp[3]=vectorNorm[2]; matrixTmp[4]=0.; matrixTmp[5]=-vectorNorm[0];
3585 matrixTmp[6]=-vectorNorm[1]; matrixTmp[7]=vectorNorm[0]; matrixTmp[8]=0.;
3586 std::transform(matrixTmp,matrixTmp+9,matrixTmp,std::bind2nd(std::multiplies<double>(),sina));
3587 std::transform(matrix,matrix+9,matrixTmp,matrix,std::plus<double>());
3588 //rotation matrix computed.
3590 for(int i=0; i<nbNodes; i++)
3592 std::transform(coordsIn+i*3,coordsIn+(i+1)*3,center,tmp,std::minus<double>());
3593 coordsOut[i*3]=matrix[0]*tmp[0]+matrix[1]*tmp[1]+matrix[2]*tmp[2]+center[0];
3594 coordsOut[i*3+1]=matrix[3]*tmp[0]+matrix[4]*tmp[1]+matrix[5]*tmp[2]+center[1];
3595 coordsOut[i*3+2]=matrix[6]*tmp[0]+matrix[7]*tmp[1]+matrix[8]*tmp[2]+center[2];
3599 void DataArrayDouble::Symmetry3DPlane(const double point[3], const double normalVector[3], int nbNodes, const double *coordsIn, double *coordsOut)
3601 double matrix[9],matrix2[9],matrix3[9];
3602 double vect[3],crossVect[3];
3603 INTERP_KERNEL::orthogonalVect3(normalVector,vect);
3604 crossVect[0]=normalVector[1]*vect[2]-normalVector[2]*vect[1];
3605 crossVect[1]=normalVector[2]*vect[0]-normalVector[0]*vect[2];
3606 crossVect[2]=normalVector[0]*vect[1]-normalVector[1]*vect[0];
3607 double nv(INTERP_KERNEL::norm<3>(vect)),ni(INTERP_KERNEL::norm<3>(normalVector)),nc(INTERP_KERNEL::norm<3>(crossVect));
3608 matrix[0]=vect[0]/nv; matrix[1]=crossVect[0]/nc; matrix[2]=-normalVector[0]/ni;
3609 matrix[3]=vect[1]/nv; matrix[4]=crossVect[1]/nc; matrix[5]=-normalVector[1]/ni;
3610 matrix[6]=vect[2]/nv; matrix[7]=crossVect[2]/nc; matrix[8]=-normalVector[2]/ni;
3611 matrix2[0]=vect[0]/nv; matrix2[1]=vect[1]/nv; matrix2[2]=vect[2]/nv;
3612 matrix2[3]=crossVect[0]/nc; matrix2[4]=crossVect[1]/nc; matrix2[5]=crossVect[2]/nc;
3613 matrix2[6]=normalVector[0]/ni; matrix2[7]=normalVector[1]/ni; matrix2[8]=normalVector[2]/ni;
3614 for(int i=0;i<3;i++)
3615 for(int j=0;j<3;j++)
3618 for(int k=0;k<3;k++)
3619 val+=matrix[3*i+k]*matrix2[3*k+j];
3622 //rotation matrix computed.
3624 for(int i=0; i<nbNodes; i++)
3626 std::transform(coordsIn+i*3,coordsIn+(i+1)*3,point,tmp,std::minus<double>());
3627 coordsOut[i*3]=matrix3[0]*tmp[0]+matrix3[1]*tmp[1]+matrix3[2]*tmp[2]+point[0];
3628 coordsOut[i*3+1]=matrix3[3]*tmp[0]+matrix3[4]*tmp[1]+matrix3[5]*tmp[2]+point[1];
3629 coordsOut[i*3+2]=matrix3[6]*tmp[0]+matrix3[7]*tmp[1]+matrix3[8]*tmp[2]+point[2];
3633 void DataArrayDouble::GiveBaseForPlane(const double normalVector[3], double baseOfPlane[9])
3635 double vect[3],crossVect[3];
3636 INTERP_KERNEL::orthogonalVect3(normalVector,vect);
3637 crossVect[0]=normalVector[1]*vect[2]-normalVector[2]*vect[1];
3638 crossVect[1]=normalVector[2]*vect[0]-normalVector[0]*vect[2];
3639 crossVect[2]=normalVector[0]*vect[1]-normalVector[1]*vect[0];
3640 double nv(INTERP_KERNEL::norm<3>(vect)),ni(INTERP_KERNEL::norm<3>(normalVector)),nc(INTERP_KERNEL::norm<3>(crossVect));
3641 baseOfPlane[0]=vect[0]/nv; baseOfPlane[1]=vect[1]/nv; baseOfPlane[2]=vect[2]/nv;
3642 baseOfPlane[3]=crossVect[0]/nc; baseOfPlane[4]=crossVect[1]/nc; baseOfPlane[5]=crossVect[2]/nc;
3643 baseOfPlane[6]=normalVector[0]/ni; baseOfPlane[7]=normalVector[1]/ni; baseOfPlane[8]=normalVector[2]/ni;
3647 * Low static method that operates 3D rotation of \a nbNodes 3D nodes whose coordinates are arranged in \a coords
3648 * around the center point \a center and with angle \a angle.
3650 void DataArrayDouble::Rotate2DAlg(const double *center, double angle, int nbNodes, const double *coordsIn, double *coordsOut)
3652 double cosa=cos(angle);
3653 double sina=sin(angle);
3655 matrix[0]=cosa; matrix[1]=-sina; matrix[2]=sina; matrix[3]=cosa;
3657 for(int i=0; i<nbNodes; i++)
3659 std::transform(coordsIn+i*2,coordsIn+(i+1)*2,center,tmp,std::minus<double>());
3660 coordsOut[i*2]=matrix[0]*tmp[0]+matrix[1]*tmp[1]+center[0];
3661 coordsOut[i*2+1]=matrix[2]*tmp[0]+matrix[3]*tmp[1]+center[1];
3665 DataArrayDoubleIterator::DataArrayDoubleIterator(DataArrayDouble *da):DataArrayIterator<double>(da)
3669 DataArrayDoubleTuple::DataArrayDoubleTuple(double *pt, int nbOfComp):DataArrayTuple<double>(pt,nbOfComp)
3674 std::string DataArrayDoubleTuple::repr() const
3676 std::ostringstream oss; oss.precision(17); oss << "(";
3677 for(int i=0;i<_nb_of_compo-1;i++)
3678 oss << _pt[i] << ", ";
3679 oss << _pt[_nb_of_compo-1] << ")";
3683 double DataArrayDoubleTuple::doubleValue() const
3685 return this->zeValue();
3689 * This method returns a newly allocated instance the caller should dealed with by a MEDCoupling::DataArrayDouble::decrRef.
3690 * This method performs \b no copy of data. The content is only referenced using MEDCoupling::DataArrayDouble::useArray with ownership set to \b false.
3691 * 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
3692 * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
3694 DataArrayDouble *DataArrayDoubleTuple::buildDADouble(int nbOfTuples, int nbOfCompo) const
3696 return this->buildDA(nbOfTuples,nbOfCompo);
3700 * Returns a new instance of DataArrayInt. The caller is to delete this array
3701 * using decrRef() as it is no more needed.
3703 DataArrayInt *DataArrayInt::New()
3705 return new DataArrayInt;
3709 * Returns the only one value in \a this, if and only if number of elements
3710 * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
3711 * \return double - the sole value stored in \a this array.
3712 * \throw If at least one of conditions stated above is not fulfilled.
3714 int DataArrayInt::intValue() const
3718 if(getNbOfElems()==1)
3720 return *getConstPointer();
3723 throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is allocated but number of elements is not equal to 1 !");
3726 throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is not allocated !");
3730 * Returns an integer value characterizing \a this array, which is useful for a quick
3731 * comparison of many instances of DataArrayInt.
3732 * \return int - the hash value.
3733 * \throw If \a this is not allocated.
3735 int DataArrayInt::getHashCode() const
3738 std::size_t nbOfElems=getNbOfElems();
3739 int ret=nbOfElems*65536;
3744 const int *pt=begin();
3745 for(std::size_t i=0;i<nbOfElems;i+=delta)
3746 ret0+=pt[i] & 0x1FFF;
3751 * Returns a full copy of \a this. For more info on copying data arrays see
3752 * \ref MEDCouplingArrayBasicsCopyDeep.
3753 * \return DataArrayInt * - a new instance of DataArrayInt.
3755 DataArrayInt *DataArrayInt::deepCopy() const
3757 return new DataArrayInt(*this);
3761 * Returns either a \a deep or \a shallow copy of this array. For more info see
3762 * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
3763 * \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
3764 * \return DataArrayInt * - either a new instance of DataArrayInt (if \a dCpy
3765 * == \a true) or \a this instance (if \a dCpy == \a false).
3767 DataArrayInt *DataArrayInt::performCopyOrIncrRef(bool dCpy) const
3769 return DataArrayTemplateClassic<int>::PerformCopyOrIncrRef(dCpy,*this);
3773 * Assign zero to all values in \a this array. To know more on filling arrays see
3774 * \ref MEDCouplingArrayFill.
3775 * \throw If \a this is not allocated.
3777 void DataArrayInt::fillWithZero()
3783 * Set all values in \a this array so that the i-th element equals to \a init + i
3784 * (i starts from zero). To know more on filling arrays see \ref MEDCouplingArrayFill.
3785 * \param [in] init - value to assign to the first element of array.
3786 * \throw If \a this->getNumberOfComponents() != 1
3787 * \throw If \a this is not allocated.
3789 void DataArrayInt::iota(int init)
3792 if(getNumberOfComponents()!=1)
3793 throw INTERP_KERNEL::Exception("DataArrayInt::iota : works only for arrays with only one component, you can call 'rearrange' method before !");
3794 int *ptr=getPointer();
3795 int ntuples=getNumberOfTuples();
3796 for(int i=0;i<ntuples;i++)
3802 * Returns a textual and human readable representation of \a this instance of
3803 * DataArrayInt. This text is shown when a DataArrayInt is printed in Python.
3804 * \return std::string - text describing \a this DataArrayInt.
3806 * \sa reprNotTooLong, reprZip
3808 std::string DataArrayInt::repr() const
3810 std::ostringstream ret;
3815 std::string DataArrayInt::reprZip() const
3817 std::ostringstream ret;
3823 * This method is close to repr method except that when \a this has more than 1000 tuples, all tuples are not
3824 * printed out to avoid to consume too much space in interpretor.
3827 std::string DataArrayInt::reprNotTooLong() const
3829 std::ostringstream ret;
3830 reprNotTooLongStream(ret);
3834 void DataArrayInt::writeVTK(std::ostream& ofs, int indent, const std::string& type, const std::string& nameInFile, DataArrayByte *byteArr) const
3836 static const char SPACE[4]={' ',' ',' ',' '};
3838 std::string idt(indent,' ');
3839 ofs << idt << "<DataArray type=\"" << type << "\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
3842 ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
3843 if(std::string(type)=="Int32")
3845 const char *data(reinterpret_cast<const char *>(begin()));
3846 std::size_t sz(getNbOfElems()*sizeof(int));
3847 byteArr->insertAtTheEnd(data,data+sz);
3848 byteArr->insertAtTheEnd(SPACE,SPACE+4);
3850 else if(std::string(type)=="Int8")
3852 INTERP_KERNEL::AutoPtr<char> tmp(new char[getNbOfElems()]);
3853 std::copy(begin(),end(),(char *)tmp);
3854 byteArr->insertAtTheEnd((char *)tmp,(char *)tmp+getNbOfElems());
3855 byteArr->insertAtTheEnd(SPACE,SPACE+4);
3857 else if(std::string(type)=="UInt8")
3859 INTERP_KERNEL::AutoPtr<unsigned char> tmp(new unsigned char[getNbOfElems()]);
3860 std::copy(begin(),end(),(unsigned char *)tmp);
3861 byteArr->insertAtTheEnd((unsigned char *)tmp,(unsigned char *)tmp+getNbOfElems());
3862 byteArr->insertAtTheEnd(SPACE,SPACE+4);
3865 throw INTERP_KERNEL::Exception("DataArrayInt::writeVTK : Only Int32, Int8 and UInt8 supported !");
3869 ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
3870 std::copy(begin(),end(),std::ostream_iterator<int>(ofs," "));
3872 ofs << std::endl << idt << "</DataArray>\n";
3875 void DataArrayInt::reprStream(std::ostream& stream) const
3877 stream << "Name of int array : \"" << _name << "\"\n";
3878 reprWithoutNameStream(stream);
3881 void DataArrayInt::reprZipStream(std::ostream& stream) const
3883 stream << "Name of int array : \"" << _name << "\"\n";
3884 reprZipWithoutNameStream(stream);
3887 void DataArrayInt::reprNotTooLongStream(std::ostream& stream) const
3889 stream << "Name of int array : \"" << _name << "\"\n";
3890 reprNotTooLongWithoutNameStream(stream);
3893 void DataArrayInt::reprWithoutNameStream(std::ostream& stream) const
3895 DataArray::reprWithoutNameStream(stream);
3896 _mem.repr(getNumberOfComponents(),stream);
3899 void DataArrayInt::reprZipWithoutNameStream(std::ostream& stream) const
3901 DataArray::reprWithoutNameStream(stream);
3902 _mem.reprZip(getNumberOfComponents(),stream);
3905 void DataArrayInt::reprNotTooLongWithoutNameStream(std::ostream& stream) const
3907 DataArray::reprWithoutNameStream(stream);
3908 stream.precision(17);
3909 _mem.reprNotTooLong(getNumberOfComponents(),stream);
3912 void DataArrayInt::reprCppStream(const std::string& varName, std::ostream& stream) const
3914 int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
3915 const int *data=getConstPointer();
3916 stream << "DataArrayInt *" << varName << "=DataArrayInt::New();" << std::endl;
3917 if(nbTuples*nbComp>=1)
3919 stream << "const int " << varName << "Data[" << nbTuples*nbComp << "]={";
3920 std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<int>(stream,","));
3921 stream << data[nbTuples*nbComp-1] << "};" << std::endl;
3922 stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
3925 stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
3926 stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
3930 * Method that gives a quick overvien of \a this for python.
3932 void DataArrayInt::reprQuickOverview(std::ostream& stream) const
3934 static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
3935 stream << "DataArrayInt C++ instance at " << this << ". ";
3938 int nbOfCompo=(int)_info_on_compo.size();
3941 int nbOfTuples=getNumberOfTuples();
3942 stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
3943 reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
3946 stream << "Number of components : 0.";
3949 stream << "*** No data allocated ****";
3952 void DataArrayInt::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
3954 const int *data=begin();
3955 int nbOfTuples=getNumberOfTuples();
3956 int nbOfCompo=(int)_info_on_compo.size();
3957 std::ostringstream oss2; oss2 << "[";
3958 std::string oss2Str(oss2.str());
3959 bool isFinished=true;
3960 for(int i=0;i<nbOfTuples && isFinished;i++)
3965 for(int j=0;j<nbOfCompo;j++,data++)
3968 if(j!=nbOfCompo-1) oss2 << ", ";
3974 if(i!=nbOfTuples-1) oss2 << ", ";
3975 std::string oss3Str(oss2.str());
3976 if(oss3Str.length()<maxNbOfByteInRepr)
3988 * Computes distribution of values of \a this one-dimensional array between given value
3989 * ranges (casts). This method is typically useful for entity number spliting by types,
3991 * \warning The values contained in \a arrBg should be sorted ascendently. No
3992 * check of this is be done. If not, the result is not warranted.
3993 * \param [in] arrBg - the array of ascending values defining the value ranges. The i-th
3994 * value of \a arrBg (\a arrBg[ i ]) gives the lowest value of the i-th range,
3995 * and the greatest value of the i-th range equals to \a arrBg[ i+1 ] - 1. \a
3996 * arrBg containing \a n values defines \a n-1 ranges. The last value of \a arrBg
3997 * should be more than every value in \a this array.
3998 * \param [in] arrEnd - specifies the end of the array \a arrBg, so that
3999 * the last value of \a arrBg is \a arrEnd[ -1 ].
4000 * \param [out] castArr - a new instance of DataArrayInt, of same size as \a this array
4001 * (same number of tuples and components), the caller is to delete
4002 * using decrRef() as it is no more needed.
4003 * This array contains indices of ranges for every value of \a this array. I.e.
4004 * the i-th value of \a castArr gives the index of range the i-th value of \a this
4005 * belongs to. Or, in other words, this parameter contains for each tuple in \a
4006 * this in which cast it holds.
4007 * \param [out] rankInsideCast - a new instance of DataArrayInt, of same size as \a this
4008 * array, the caller is to delete using decrRef() as it is no more needed.
4009 * This array contains ranks of values of \a this array within ranges
4010 * they belongs to. I.e. the i-th value of \a rankInsideCast gives the rank of
4011 * the i-th value of \a this array within the \a castArr[ i ]-th range, to which
4012 * the i-th value of \a this belongs to. Or, in other words, this param contains
4013 * for each tuple its rank inside its cast. The rank is computed as difference
4014 * between the value and the lowest value of range.
4015 * \param [out] castsPresent - a new instance of DataArrayInt, containing indices of
4016 * ranges (casts) to which at least one value of \a this array belongs.
4017 * Or, in other words, this param contains the casts that \a this contains.
4018 * The caller is to delete this array using decrRef() as it is no more needed.
4020 * \b Example: If \a this contains [6,5,0,3,2,7,8,1,4] and \a arrBg contains [0,4,9] then
4021 * the output of this method will be :
4022 * - \a castArr : [1,1,0,0,0,1,1,0,1]
4023 * - \a rankInsideCast: [2,1,0,3,2,3,4,1,0]
4024 * - \a castsPresent : [0,1]
4026 * I.e. values of \a this array belong to 2 ranges: #0 and #1. Value 6 belongs to the
4027 * range #1 and its rank within this range is 2; etc.
4029 * \throw If \a this->getNumberOfComponents() != 1.
4030 * \throw If \a arrEnd - arrBg < 2.
4031 * \throw If any value of \a this is not less than \a arrEnd[-1].
4033 void DataArrayInt::splitByValueRange(const int *arrBg, const int *arrEnd,
4034 DataArrayInt *& castArr, DataArrayInt *& rankInsideCast, DataArrayInt *& castsPresent) const
4037 if(getNumberOfComponents()!=1)
4038 throw INTERP_KERNEL::Exception("Call splitByValueRange method on DataArrayInt with only one component, you can call 'rearrange' method before !");
4039 int nbOfTuples=getNumberOfTuples();
4040 std::size_t nbOfCast=std::distance(arrBg,arrEnd);
4042 throw INTERP_KERNEL::Exception("DataArrayInt::splitByValueRange : The input array giving the cast range values should be of size >=2 !");
4044 const int *work=getConstPointer();
4045 typedef std::reverse_iterator<const int *> rintstart;
4046 rintstart bg(arrEnd);//OK no problem because size of 'arr' is greater or equal 2
4047 rintstart end2(arrBg);
4048 MCAuto<DataArrayInt> ret1=DataArrayInt::New();
4049 MCAuto<DataArrayInt> ret2=DataArrayInt::New();
4050 MCAuto<DataArrayInt> ret3=DataArrayInt::New();
4051 ret1->alloc(nbOfTuples,1);
4052 ret2->alloc(nbOfTuples,1);
4053 int *ret1Ptr=ret1->getPointer();
4054 int *ret2Ptr=ret2->getPointer();
4055 std::set<std::size_t> castsDetected;
4056 for(int i=0;i<nbOfTuples;i++)
4058 rintstart res=std::find_if(bg,end2,std::bind2nd(std::less_equal<int>(), work[i]));
4059 std::size_t pos=std::distance(bg,res);
4060 std::size_t pos2=nbOfCast-pos;
4063 ret1Ptr[i]=(int)pos2;
4064 ret2Ptr[i]=work[i]-arrBg[pos2];
4065 castsDetected.insert(pos2);
4069 std::ostringstream oss; oss << "DataArrayInt::splitByValueRange : At rank #" << i << " the value is " << work[i] << " should be in [0," << *bg << ") !";
4070 throw INTERP_KERNEL::Exception(oss.str().c_str());
4073 ret3->alloc((int)castsDetected.size(),1);
4074 std::copy(castsDetected.begin(),castsDetected.end(),ret3->getPointer());
4075 castArr=ret1.retn();
4076 rankInsideCast=ret2.retn();
4077 castsPresent=ret3.retn();
4081 * 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 ).
4082 * 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 ).
4083 * This method works only if \a this is allocated and single component. If not an exception will be thrown.
4085 * \param [out] strt - the start of the range (included) if true is returned.
4086 * \param [out] sttoopp - the end of the range (not included) if true is returned.
4087 * \param [out] stteepp - the step of the range if true is returned.
4088 * \return the verdict of the check.
4090 * \sa DataArray::GetNumberOfItemGivenBES
4092 bool DataArrayInt::isRange(int& strt, int& sttoopp, int& stteepp) const
4095 if(getNumberOfComponents()!=1)
4096 throw INTERP_KERNEL::Exception("DataArrayInt::isRange : this must be single component array !");
4097 int nbTuples(getNumberOfTuples());
4099 { strt=0; sttoopp=0; stteepp=1; return true; }
4100 const int *pt(begin());
4103 { sttoopp=strt+1; stteepp=1; return true; }
4104 strt=*pt; sttoopp=pt[nbTuples-1];
4110 int a(sttoopp-1-strt),tmp(strt);
4111 if(a%(nbTuples-1)!=0)
4113 stteepp=a/(nbTuples-1);
4114 for(int i=0;i<nbTuples;i++,tmp+=stteepp)
4122 int a(strt-sttoopp-1),tmp(strt);
4123 if(a%(nbTuples-1)!=0)
4125 stteepp=-(a/(nbTuples-1));
4126 for(int i=0;i<nbTuples;i++,tmp+=stteepp)
4135 * Modifies in place \a this one-dimensional array so that each value \a v = \a indArrBg[ \a v ],
4136 * i.e. a current value is used as in index to get a new value from \a indArrBg.
4137 * \param [in] indArrBg - pointer to the first element of array of new values to assign
4139 * \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
4140 * the last value of \a indArrBg is \a indArrEnd[ -1 ].
4141 * \throw If \a this->getNumberOfComponents() != 1
4142 * \throw If any value of \a this can't be used as a valid index for
4143 * [\a indArrBg, \a indArrEnd).
4147 void DataArrayInt::transformWithIndArr(const int *indArrBg, const int *indArrEnd)
4149 this->checkAllocated();
4150 if(this->getNumberOfComponents()!=1)
4151 throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
4152 int nbElemsIn((int)std::distance(indArrBg,indArrEnd)),nbOfTuples(getNumberOfTuples()),*pt(getPointer());
4153 for(int i=0;i<nbOfTuples;i++,pt++)
4155 if(*pt>=0 && *pt<nbElemsIn)
4159 std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " of this value is " << *pt << ", should be in [0," << nbElemsIn << ") !";
4160 throw INTERP_KERNEL::Exception(oss.str().c_str());
4163 this->declareAsNew();
4166 void DataArrayInt::transformWithIndArr(const MapKeyVal<int>& m)
4168 this->checkAllocated();
4169 if(this->getNumberOfComponents()!=1)
4170 throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
4171 const std::map<int,int> dat(m.data());
4172 int nbOfTuples(getNumberOfTuples()),*pt(getPointer());
4173 for(int i=0;i<nbOfTuples;i++,pt++)
4175 std::map<int,int>::const_iterator it(dat.find(*pt));
4180 std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " of this value is " << *pt << " not in map !";
4181 throw INTERP_KERNEL::Exception(oss.str().c_str());
4184 this->declareAsNew();
4188 * Creates a one-dimensional DataArrayInt (\a res) whose contents are computed from
4189 * values of \a this (\a a) and the given (\a indArr) arrays as follows:
4190 * \a res[ \a indArr[ \a a[ i ]]] = i. I.e. for each value in place i \a v = \a a[ i ],
4191 * new value in place \a indArr[ \a v ] is i.
4192 * \param [in] indArrBg - the array holding indices within the result array to assign
4193 * indices of values of \a this array pointing to values of \a indArrBg.
4194 * \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
4195 * the last value of \a indArrBg is \a indArrEnd[ -1 ].
4196 * \return DataArrayInt * - the new instance of DataArrayInt.
4197 * The caller is to delete this result array using decrRef() as it is no more
4199 * \throw If \a this->getNumberOfComponents() != 1.
4200 * \throw If any value of \a this array is not a valid index for \a indArrBg array.
4201 * \throw If any value of \a indArrBg is not a valid index for \a this array.
4203 DataArrayInt *DataArrayInt::transformWithIndArrR(const int *indArrBg, const int *indArrEnd) const
4206 if(getNumberOfComponents()!=1)
4207 throw INTERP_KERNEL::Exception("Call transformWithIndArrR method on DataArrayInt with only one component, you can call 'rearrange' method before !");
4208 int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
4209 int nbOfTuples=getNumberOfTuples();
4210 const int *pt=getConstPointer();
4211 MCAuto<DataArrayInt> ret=DataArrayInt::New();
4212 ret->alloc(nbOfTuples,1);
4213 ret->fillWithValue(-1);
4214 int *tmp=ret->getPointer();
4215 for(int i=0;i<nbOfTuples;i++,pt++)
4217 if(*pt>=0 && *pt<nbElemsIn)
4219 int pos=indArrBg[*pt];
4220 if(pos>=0 && pos<nbOfTuples)
4224 std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value of new pos is " << pos << " ( indArrBg[" << *pt << "]) ! Should be in [0," << nbOfTuples << ") !";
4225 throw INTERP_KERNEL::Exception(oss.str().c_str());
4230 std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn << " !";
4231 throw INTERP_KERNEL::Exception(oss.str().c_str());
4238 * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
4239 * from values of \a this array, which is supposed to contain a renumbering map in
4240 * "Old to New" mode. The result array contains a renumbering map in "New to Old" mode.
4241 * To know how to use the renumbering maps see \ref numbering.
4242 * \param [in] newNbOfElem - the number of tuples in the result array.
4243 * \return DataArrayInt * - the new instance of DataArrayInt.
4244 * The caller is to delete this result array using decrRef() as it is no more
4247 * \if ENABLE_EXAMPLES
4248 * \ref cpp_mcdataarrayint_invertarrayo2n2n2o "Here is a C++ example".<br>
4249 * \ref py_mcdataarrayint_invertarrayo2n2n2o "Here is a Python example".
4252 DataArrayInt *DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const
4254 MCAuto<DataArrayInt> ret(DataArrayInt::New());
4255 ret->alloc(newNbOfElem,1);
4256 int nbOfOldNodes(this->getNumberOfTuples());
4257 const int *old2New(begin());
4258 int *pt(ret->getPointer());
4259 for(int i=0;i!=nbOfOldNodes;i++)
4261 int newp(old2New[i]);
4264 if(newp>=0 && newp<newNbOfElem)
4268 std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2O : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
4269 throw INTERP_KERNEL::Exception(oss.str().c_str());
4277 * This method is similar to DataArrayInt::invertArrayO2N2N2O except that
4278 * 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]
4280 DataArrayInt *DataArrayInt::invertArrayO2N2N2OBis(int newNbOfElem) const
4282 MCAuto<DataArrayInt> ret=DataArrayInt::New();
4283 ret->alloc(newNbOfElem,1);
4284 int nbOfOldNodes=getNumberOfTuples();
4285 const int *old2New=getConstPointer();
4286 int *pt=ret->getPointer();
4287 for(int i=nbOfOldNodes-1;i>=0;i--)
4289 int newp(old2New[i]);
4292 if(newp>=0 && newp<newNbOfElem)
4296 std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2OBis : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
4297 throw INTERP_KERNEL::Exception(oss.str().c_str());
4305 * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
4306 * from values of \a this array, which is supposed to contain a renumbering map in
4307 * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
4308 * To know how to use the renumbering maps see \ref numbering.
4309 * \param [in] newNbOfElem - the number of tuples in the result array.
4310 * \return DataArrayInt * - the new instance of DataArrayInt.
4311 * The caller is to delete this result array using decrRef() as it is no more
4314 * \if ENABLE_EXAMPLES
4315 * \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
4317 * \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
4318 * \sa invertArrayN2O2O2NOptimized
4321 DataArrayInt *DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const
4324 MCAuto<DataArrayInt> ret=DataArrayInt::New();
4325 ret->alloc(oldNbOfElem,1);
4326 const int *new2Old=getConstPointer();
4327 int *pt=ret->getPointer();
4328 std::fill(pt,pt+oldNbOfElem,-1);
4329 int nbOfNewElems=getNumberOfTuples();
4330 for(int i=0;i<nbOfNewElems;i++)
4333 if(v>=0 && v<oldNbOfElem)
4337 std::ostringstream oss; oss << "DataArrayInt::invertArrayN2O2O2N : in new id #" << i << " old value is " << v << " expected to be in [0," << oldNbOfElem << ") !";
4338 throw INTERP_KERNEL::Exception(oss.str().c_str());
4345 * Creates a map, whose contents are computed
4346 * from values of \a this array, which is supposed to contain a renumbering map in
4347 * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
4348 * To know how to use the renumbering maps see \ref numbering.
4349 * \param [in] newNbOfElem - the number of tuples in the result array.
4350 * \return MapII - the new instance of Map.
4352 * \if ENABLE_EXAMPLES
4353 * \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
4355 * \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
4356 * \sa invertArrayN2O2O2N
4359 MCAuto< MapKeyVal<int> > DataArrayInt::invertArrayN2O2O2NOptimized() const
4362 MCAuto< MapKeyVal<int> > ret(MapKeyVal<int>::New());
4363 std::map<int,int>& m(ret->data());
4364 const int *new2Old(begin());
4365 int nbOfNewElems(this->getNumberOfTuples());
4366 for(int i=0;i<nbOfNewElems;i++)
4375 * Equivalent to DataArrayInt::isEqual except that if false the reason of
4376 * mismatch is given.
4378 * \param [in] other the instance to be compared with \a this
4379 * \param [out] reason In case of inequality returns the reason.
4380 * \sa DataArrayInt::isEqual
4382 bool DataArrayInt::isEqualIfNotWhy(const DataArrayInt& other, std::string& reason) const
4384 if(!areInfoEqualsIfNotWhy(other,reason))
4386 return _mem.isEqual(other._mem,0,reason);
4390 * Checks if \a this and another DataArrayInt are fully equal. For more info see
4391 * \ref MEDCouplingArrayBasicsCompare.
4392 * \param [in] other - an instance of DataArrayInt to compare with \a this one.
4393 * \return bool - \a true if the two arrays are equal, \a false else.
4395 bool DataArrayInt::isEqual(const DataArrayInt& other) const
4398 return isEqualIfNotWhy(other,tmp);
4402 * Checks if values of \a this and another DataArrayInt are equal. For more info see
4403 * \ref MEDCouplingArrayBasicsCompare.
4404 * \param [in] other - an instance of DataArrayInt to compare with \a this one.
4405 * \return bool - \a true if the values of two arrays are equal, \a false else.
4407 bool DataArrayInt::isEqualWithoutConsideringStr(const DataArrayInt& other) const
4410 return _mem.isEqual(other._mem,0,tmp);
4414 * Checks if values of \a this and another DataArrayInt are equal. Comparison is
4415 * performed on sorted value sequences.
4416 * For more info see\ref MEDCouplingArrayBasicsCompare.
4417 * \param [in] other - an instance of DataArrayInt to compare with \a this one.
4418 * \return bool - \a true if the sorted values of two arrays are equal, \a false else.
4420 bool DataArrayInt::isEqualWithoutConsideringStrAndOrder(const DataArrayInt& other) const
4422 MCAuto<DataArrayInt> a=deepCopy();
4423 MCAuto<DataArrayInt> b=other.deepCopy();
4426 return a->isEqualWithoutConsideringStr(*b);
4430 * This method compares content of input vector \a v and \a this.
4431 * 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.
4432 * For performance reasons \a this is expected to be sorted ascendingly. If not an exception will be thrown.
4434 * \param [in] v - the vector of 'flags' to be compared with \a this.
4436 * \throw If \a this is not sorted ascendingly.
4437 * \throw If \a this has not exactly one component.
4438 * \throw If \a this is not allocated.
4440 bool DataArrayInt::isFittingWith(const std::vector<bool>& v) const
4443 if(getNumberOfComponents()!=1)
4444 throw INTERP_KERNEL::Exception("DataArrayInt::isFittingWith : number of components of this should be equal to one !");
4445 const int *w(begin()),*end2(end());
4446 int refVal=-std::numeric_limits<int>::max();
4448 std::vector<bool>::const_iterator it(v.begin());
4449 for(;it!=v.end();it++,i++)
4461 std::ostringstream oss; oss << "DataArrayInt::isFittingWith : At pos #" << std::distance(begin(),w-1) << " this is not sorted ascendingly !";
4462 throw INTERP_KERNEL::Exception(oss.str().c_str());
4476 * 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
4477 * put True to the corresponding entry in \a vec.
4478 * \a vec is expected to be with the same size than the number of tuples of \a this.
4480 * \sa DataArrayInt::switchOnTupleNotEqualTo.
4482 void DataArrayInt::switchOnTupleEqualTo(int val, std::vector<bool>& vec) const
4485 if(getNumberOfComponents()!=1)
4486 throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleEqualTo : number of components of this should be equal to one !");
4487 int nbOfTuples(getNumberOfTuples());
4488 if(nbOfTuples!=(int)vec.size())
4489 throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleEqualTo : number of tuples of this should be equal to size of input vector of bool !");
4490 const int *pt(begin());
4491 for(int i=0;i<nbOfTuples;i++)
4497 * 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
4498 * put True to the corresponding entry in \a vec.
4499 * \a vec is expected to be with the same size than the number of tuples of \a this.
4501 * \sa DataArrayInt::switchOnTupleEqualTo.
4503 void DataArrayInt::switchOnTupleNotEqualTo(int val, std::vector<bool>& vec) const
4506 if(getNumberOfComponents()!=1)
4507 throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleNotEqualTo : number of components of this should be equal to one !");
4508 int nbOfTuples(getNumberOfTuples());
4509 if(nbOfTuples!=(int)vec.size())
4510 throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleNotEqualTo : number of tuples of this should be equal to size of input vector of bool !");
4511 const int *pt(begin());
4512 for(int i=0;i<nbOfTuples;i++)
4518 * Computes for each tuple the sum of number of components values in the tuple and return it.
4520 * \return DataArrayInt * - the new instance of DataArrayInt containing the
4521 * same number of tuples as \a this array and one component.
4522 * The caller is to delete this result array using decrRef() as it is no more
4524 * \throw If \a this is not allocated.
4526 DataArrayInt *DataArrayInt::sumPerTuple() const
4529 int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
4530 MCAuto<DataArrayInt> ret(DataArrayInt::New());
4531 ret->alloc(nbOfTuple,1);
4532 const int *src(getConstPointer());
4533 int *dest(ret->getPointer());
4534 for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
4535 *dest=std::accumulate(src,src+nbOfComp,0);
4540 * Checks that \a this array is consistently **increasing** or **decreasing** in value.
4541 * If not an exception is thrown.
4542 * \param [in] increasing - if \a true, the array values should be increasing.
4543 * \throw If sequence of values is not strictly monotonic in agreement with \a
4545 * \throw If \a this->getNumberOfComponents() != 1.
4546 * \throw If \a this is not allocated.
4548 void DataArrayInt::checkMonotonic(bool increasing) const
4550 if(!isMonotonic(increasing))
4553 throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not INCREASING monotonic !");
4555 throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not DECREASING monotonic !");
4560 * Checks that \a this array is consistently **increasing** or **decreasing** in value.
4561 * \param [in] increasing - if \a true, array values should be increasing.
4562 * \return bool - \a true if values change in accordance with \a increasing arg.
4563 * \throw If \a this->getNumberOfComponents() != 1.
4564 * \throw If \a this is not allocated.
4566 bool DataArrayInt::isMonotonic(bool increasing) const
4569 if(getNumberOfComponents()!=1)
4570 throw INTERP_KERNEL::Exception("DataArrayInt::isMonotonic : only supported with 'this' array with ONE component !");
4571 int nbOfElements=getNumberOfTuples();
4572 const int *ptr=getConstPointer();
4578 for(int i=1;i<nbOfElements;i++)
4588 for(int i=1;i<nbOfElements;i++)
4600 * This method check that array consistently INCREASING or DECREASING in value.
4602 bool DataArrayInt::isStrictlyMonotonic(bool increasing) const
4605 if(getNumberOfComponents()!=1)
4606 throw INTERP_KERNEL::Exception("DataArrayInt::isStrictlyMonotonic : only supported with 'this' array with ONE component !");
4607 int nbOfElements=getNumberOfTuples();
4608 const int *ptr=getConstPointer();
4614 for(int i=1;i<nbOfElements;i++)
4624 for(int i=1;i<nbOfElements;i++)
4636 * This method check that array consistently INCREASING or DECREASING in value.
4638 void DataArrayInt::checkStrictlyMonotonic(bool increasing) const
4640 if(!isStrictlyMonotonic(increasing))
4643 throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly INCREASING monotonic !");
4645 throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly DECREASING monotonic !");
4650 * Creates a new one-dimensional DataArrayInt of the same size as \a this and a given
4651 * one-dimensional arrays that must be of the same length. The result array describes
4652 * correspondence between \a this and \a other arrays, so that
4653 * <em> other.getIJ(i,0) == this->getIJ(ret->getIJ(i),0)</em>. If such a permutation is
4654 * not possible because some element in \a other is not in \a this, an exception is thrown.
4655 * \param [in] other - an array to compute permutation to.
4656 * \return DataArrayInt * - a new instance of DataArrayInt, which is a permutation array
4657 * from \a this to \a other. The caller is to delete this array using decrRef() as it is
4659 * \throw If \a this->getNumberOfComponents() != 1.
4660 * \throw If \a other->getNumberOfComponents() != 1.
4661 * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples().
4662 * \throw If \a other includes a value which is not in \a this array.
4664 * \if ENABLE_EXAMPLES
4665 * \ref cpp_mcdataarrayint_buildpermutationarr "Here is a C++ example".
4667 * \ref py_mcdataarrayint_buildpermutationarr "Here is a Python example".
4670 DataArrayInt *DataArrayInt::buildPermutationArr(const DataArrayInt& other) const
4673 if(getNumberOfComponents()!=1 || other.getNumberOfComponents()!=1)
4674 throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' have to have exactly ONE component !");
4675 int nbTuple=getNumberOfTuples();
4676 other.checkAllocated();
4677 if(nbTuple!=other.getNumberOfTuples())
4678 throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' must have the same number of tuple !");
4679 MCAuto<DataArrayInt> ret=DataArrayInt::New();
4680 ret->alloc(nbTuple,1);
4681 ret->fillWithValue(-1);
4682 const int *pt=getConstPointer();
4683 std::map<int,int> mm;
4684 for(int i=0;i<nbTuple;i++)
4686 pt=other.getConstPointer();
4687 int *retToFill=ret->getPointer();
4688 for(int i=0;i<nbTuple;i++)
4690 std::map<int,int>::const_iterator it=mm.find(pt[i]);
4693 std::ostringstream oss; oss << "DataArrayInt::buildPermutationArr : Arrays mismatch : element (" << pt[i] << ") in 'other' not findable in 'this' !";
4694 throw INTERP_KERNEL::Exception(oss.str().c_str());
4696 retToFill[i]=(*it).second;
4702 * Elements of \a partOfThis are expected to be included in \a this.
4703 * The returned array \a ret is so that this[ret]==partOfThis
4705 * 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]
4706 * the return array will contain [3,2,5,7].
4708 * \a this is expected to be a 1 compo allocated array.
4709 * \param [in] partOfThis - A 1 compo allocated array
4710 * \return - A newly allocated array to be dealed by caller having the same number of tuples than \a partOfThis.
4711 * \throw if two same element is present twice in \a this
4712 * \throw if an element in \a partOfThis is \b NOT in \a this.
4714 DataArrayInt *DataArrayInt::indicesOfSubPart(const DataArrayInt& partOfThis) const
4716 if(getNumberOfComponents()!=1 || partOfThis.getNumberOfComponents()!=1)
4717 throw INTERP_KERNEL::Exception("DataArrayInt::indicesOfSubPart : this and input array must be one component array !");
4718 checkAllocated(); partOfThis.checkAllocated();
4719 int thisNbTuples(getNumberOfTuples()),nbTuples(partOfThis.getNumberOfTuples());
4720 const int *thisPt(begin()),*pt(partOfThis.begin());
4721 MCAuto<DataArrayInt> ret(DataArrayInt::New());
4722 ret->alloc(nbTuples,1);
4723 int *retPt(ret->getPointer());
4724 std::map<int,int> m;
4725 for(int i=0;i<thisNbTuples;i++,thisPt++)
4727 if(m.size()!=thisNbTuples)
4728 throw INTERP_KERNEL::Exception("DataArrayInt::indicesOfSubPart : some elements appears more than once !");
4729 for(int i=0;i<nbTuples;i++,retPt++,pt++)
4731 std::map<int,int>::const_iterator it(m.find(*pt));
4733 *retPt=(*it).second;
4736 std::ostringstream oss; oss << "DataArrayInt::indicesOfSubPart : At pos #" << i << " of input array value is " << *pt << " not in this !";
4737 throw INTERP_KERNEL::Exception(oss.str());
4744 * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode.
4745 * This map, if applied to \a this array, would make it sorted. For example, if
4746 * \a this array contents are [9,10,0,6,4,11,3,7] then the contents of the result array
4747 * are [5,6,0,3,2,7,1,4]; if this result array (\a res) is used as an argument in call
4748 * \a this->renumber(\a res) then the returned array contains [0,3,4,6,7,9,10,11].
4749 * This method is useful for renumbering (in MED file for example). For more info
4750 * on renumbering see \ref numbering.
4751 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4752 * array using decrRef() as it is no more needed.
4753 * \throw If \a this is not allocated.
4754 * \throw If \a this->getNumberOfComponents() != 1.
4755 * \throw If there are equal values in \a this array.
4757 DataArrayInt *DataArrayInt::checkAndPreparePermutation() const
4760 if(getNumberOfComponents()!=1)
4761 throw INTERP_KERNEL::Exception("DataArrayInt::checkAndPreparePermutation : number of components must == 1 !");
4762 int nbTuples=getNumberOfTuples();
4763 const int *pt=getConstPointer();
4764 int *pt2=CheckAndPreparePermutation(pt,pt+nbTuples);
4765 DataArrayInt *ret=DataArrayInt::New();
4766 ret->useArray(pt2,true,C_DEALLOC,nbTuples,1);
4771 * 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
4772 * input array \a ids2.
4773 * \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.
4774 * 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
4776 * In case of success (no throw) : \c ids1->renumber(ret)->isEqual(ids2) where \a ret is the return of this method.
4778 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4779 * array using decrRef() as it is no more needed.
4780 * \throw If either ids1 or ids2 is null not allocated or not with one components.
4783 DataArrayInt *DataArrayInt::FindPermutationFromFirstToSecond(const DataArrayInt *ids1, const DataArrayInt *ids2)
4786 throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be not null !");
4787 if(!ids1->isAllocated() || !ids2->isAllocated())
4788 throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be allocated !");
4789 if(ids1->getNumberOfComponents()!=1 || ids2->getNumberOfComponents()!=1)
4790 throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays have exactly one component !");
4791 if(ids1->getNumberOfTuples()!=ids2->getNumberOfTuples())
4793 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 !";
4794 throw INTERP_KERNEL::Exception(oss.str().c_str());
4796 MCAuto<DataArrayInt> p1(ids1->deepCopy());
4797 MCAuto<DataArrayInt> p2(ids2->deepCopy());
4798 p1->sort(true); p2->sort(true);
4799 if(!p1->isEqualWithoutConsideringStr(*p2))
4800 throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two arrays are not lying on same ids ! Impossible to find a permutation between the 2 arrays !");
4801 p1=ids1->checkAndPreparePermutation();
4802 p2=ids2->checkAndPreparePermutation();
4803 p2=p2->invertArrayO2N2N2O(p2->getNumberOfTuples());
4804 p2=p2->selectByTupleIdSafe(p1->begin(),p1->end());
4809 * Returns two arrays describing a surjective mapping from \a this set of values (\a A)
4810 * onto a set of values of size \a targetNb (\a B). The surjective function is
4811 * \a B[ \a A[ i ]] = i. That is to say that for each \a id in [0,\a targetNb), where \a
4812 * targetNb < \a this->getNumberOfTuples(), there exists at least one tupleId (\a tid) so
4813 * that <em> this->getIJ( tid, 0 ) == id</em>. <br>
4814 * The first of out arrays returns indices of elements of \a this array, grouped by their
4815 * place in the set \a B. The second out array is the index of the first one; it shows how
4816 * many elements of \a A are mapped into each element of \a B. <br>
4818 * mapping and its usage in renumbering see \ref numbering. <br>
4820 * - \a this: [0,3,2,3,2,2,1,2]
4822 * - \a arr: [0, 6, 2,4,5,7, 1,3]
4823 * - \a arrI: [0,1,2,6,8]
4825 * This result means: <br>
4826 * the element of \a B 0 encounters within \a A once (\a arrI[ 0+1 ] - \a arrI[ 0 ]) and
4827 * its index within \a A is 0 ( \a arr[ 0:1 ] == \a arr[ \a arrI[ 0 ] : \a arrI[ 0+1 ]]);<br>
4828 * the element of \a B 2 encounters within \a A 4 times (\a arrI[ 2+1 ] - \a arrI[ 2 ]) and
4829 * its indices within \a A are [2,4,5,7] ( \a arr[ 2:6 ] == \a arr[ \a arrI[ 2 ] :
4830 * \a arrI[ 2+1 ]]); <br> etc.
4831 * \param [in] targetNb - the size of the set \a B. \a targetNb must be equal or more
4832 * than the maximal value of \a A.
4833 * \param [out] arr - a new instance of DataArrayInt returning indices of
4834 * elements of \a this, grouped by their place in the set \a B. The caller is to delete
4835 * this array using decrRef() as it is no more needed.
4836 * \param [out] arrI - a new instance of DataArrayInt returning size of groups of equal
4837 * elements of \a this. The caller is to delete this array using decrRef() as it
4838 * is no more needed.
4839 * \throw If \a this is not allocated.
4840 * \throw If \a this->getNumberOfComponents() != 1.
4841 * \throw If any value in \a this is more or equal to \a targetNb.
4843 void DataArrayInt::changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, DataArrayInt *&arrI) const
4846 if(getNumberOfComponents()!=1)
4847 throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : number of components must == 1 !");
4848 int nbOfTuples=getNumberOfTuples();
4849 MCAuto<DataArrayInt> ret(DataArrayInt::New());
4850 MCAuto<DataArrayInt> retI(DataArrayInt::New());
4851 retI->alloc(targetNb+1,1);
4852 const int *input=getConstPointer();
4853 std::vector< std::vector<int> > tmp(targetNb);
4854 for(int i=0;i<nbOfTuples;i++)
4857 if(tmp2>=0 && tmp2<targetNb)
4858 tmp[tmp2].push_back(i);
4861 std::ostringstream oss; oss << "DataArrayInt::changeSurjectiveFormat : At pos " << i << " presence of element " << tmp2 << " ! should be in [0," << targetNb << ") !";
4862 throw INTERP_KERNEL::Exception(oss.str().c_str());
4865 int *retIPtr=retI->getPointer();
4867 for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++,retIPtr++)
4868 retIPtr[1]=retIPtr[0]+(int)((*it1).size());
4869 if(nbOfTuples!=retI->getIJ(targetNb,0))
4870 throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : big problem should never happen !");
4871 ret->alloc(nbOfTuples,1);
4872 int *retPtr=ret->getPointer();
4873 for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++)
4874 retPtr=std::copy((*it1).begin(),(*it1).end(),retPtr);
4881 * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode computed
4882 * from a zip representation of a surjective format (returned e.g. by
4883 * \ref MEDCoupling::DataArrayDouble::findCommonTuples() "DataArrayDouble::findCommonTuples()"
4884 * for example). The result array minimizes the permutation. <br>
4885 * For more info on renumbering see \ref numbering. <br>
4887 * - \a nbOfOldTuples: 10
4888 * - \a arr : [0,3, 5,7,9]
4889 * - \a arrIBg : [0,2,5]
4890 * - \a newNbOfTuples: 7
4891 * - result array : [0,1,2,0,3,4,5,4,6,4]
4893 * \param [in] nbOfOldTuples - number of tuples in the initial array \a arr.
4894 * \param [in] arr - the array of tuple indices grouped by \a arrIBg array.
4895 * \param [in] arrIBg - the array dividing all indices stored in \a arr into groups of
4896 * (indices of) equal values. Its every element (except the last one) points to
4897 * the first element of a group of equal values.
4898 * \param [in] arrIEnd - specifies the end of \a arrIBg, so that the last element of \a
4899 * arrIBg is \a arrIEnd[ -1 ].
4900 * \param [out] newNbOfTuples - number of tuples after surjection application.
4901 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4902 * array using decrRef() as it is no more needed.
4903 * \throw If any value of \a arr breaks condition ( 0 <= \a arr[ i ] < \a nbOfOldTuples ).
4905 DataArrayInt *DataArrayInt::ConvertIndexArrayToO2N(int nbOfOldTuples, const int *arr, const int *arrIBg, const int *arrIEnd, int &newNbOfTuples)
4907 MCAuto<DataArrayInt> ret=DataArrayInt::New();
4908 ret->alloc(nbOfOldTuples,1);
4909 int *pt=ret->getPointer();
4910 std::fill(pt,pt+nbOfOldTuples,-1);
4911 int nbOfGrps=((int)std::distance(arrIBg,arrIEnd))-1;
4912 const int *cIPtr=arrIBg;
4913 for(int i=0;i<nbOfGrps;i++)
4914 pt[arr[cIPtr[i]]]=-(i+2);
4916 for(int iNode=0;iNode<nbOfOldTuples;iNode++)
4924 int grpId=-(pt[iNode]+2);
4925 for(int j=cIPtr[grpId];j<cIPtr[grpId+1];j++)
4927 if(arr[j]>=0 && arr[j]<nbOfOldTuples)
4931 std::ostringstream oss; oss << "DataArrayInt::ConvertIndexArrayToO2N : With element #" << j << " value is " << arr[j] << " should be in [0," << nbOfOldTuples << ") !";
4932 throw INTERP_KERNEL::Exception(oss.str().c_str());
4939 newNbOfTuples=newNb;
4944 * Returns a new DataArrayInt containing a renumbering map in "New to Old" mode,
4945 * which if applied to \a this array would make it sorted ascendingly.
4946 * For more info on renumbering see \ref numbering. <br>
4948 * - \a this: [2,0,1,1,0,1,2,0,1,1,0,0]
4949 * - result: [10,0,5,6,1,7,11,2,8,9,3,4]
4950 * - after applying result to \a this: [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2]
4952 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4953 * array using decrRef() as it is no more needed.
4954 * \throw If \a this is not allocated.
4955 * \throw If \a this->getNumberOfComponents() != 1.
4957 DataArrayInt *DataArrayInt::buildPermArrPerLevel() const
4960 if(getNumberOfComponents()!=1)
4961 throw INTERP_KERNEL::Exception("DataArrayInt::buildPermArrPerLevel : number of components must == 1 !");
4962 int nbOfTuples=getNumberOfTuples();
4963 const int *pt=getConstPointer();
4964 std::map<int,int> m;
4965 MCAuto<DataArrayInt> ret=DataArrayInt::New();
4966 ret->alloc(nbOfTuples,1);
4967 int *opt=ret->getPointer();
4968 for(int i=0;i<nbOfTuples;i++,pt++,opt++)
4971 std::map<int,int>::iterator it=m.find(val);
4980 m.insert(std::pair<int,int>(val,1));
4984 for(std::map<int,int>::iterator it=m.begin();it!=m.end();it++)
4986 int vt=(*it).second;
4990 pt=getConstPointer();
4991 opt=ret->getPointer();
4992 for(int i=0;i<nbOfTuples;i++,pt++,opt++)
4999 * Checks if \a this array has the given size, and if its contents is equal to an array filled with
5000 * iota(). This method is particularly useful for DataArrayInt instances that represent
5001 * a renumbering array, to check if there is a real need in renumbering.
5002 * This method checks than \a this can be considered as an identity mapping
5003 * of a set having \a sizeExpected elements into itself.
5005 * \param [in] sizeExpected - The number of elements expected.
5006 * \return bool - \a true if \a this array contents == \a range( \a this->getNumberOfTuples())
5007 * \throw If \a this is not allocated.
5008 * \throw If \a this->getNumberOfComponents() != 1.
5010 bool DataArrayInt::isIota(int sizeExpected) const
5013 if(getNumberOfComponents()!=1)
5015 int nbOfTuples(getNumberOfTuples());
5016 if(nbOfTuples!=sizeExpected)
5018 const int *pt=getConstPointer();
5019 for(int i=0;i<nbOfTuples;i++,pt++)
5026 * Checks if all values in \a this array are equal to \a val.
5027 * \param [in] val - value to check equality of array values to.
5028 * \return bool - \a true if all values are \a val.
5029 * \throw If \a this is not allocated.
5030 * \throw If \a this->getNumberOfComponents() != 1
5031 * \sa DataArrayInt::checkUniformAndGuess
5033 bool DataArrayInt::isUniform(int val) const
5036 if(getNumberOfComponents()!=1)
5037 throw INTERP_KERNEL::Exception("DataArrayInt::isUniform : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
5038 const int *w(begin()),*end2(end());
5046 * This method checks that \a this is uniform. If not and exception will be thrown.
5047 * In case of uniformity the corresponding value is returned.
5049 * \return int - the unique value contained in this
5050 * \throw If \a this is not allocated.
5051 * \throw If \a this->getNumberOfComponents() != 1
5052 * \throw If \a this is not uniform.
5053 * \sa DataArrayInt::isUniform
5055 int DataArrayInt::checkUniformAndGuess() const
5058 if(getNumberOfComponents()!=1)
5059 throw INTERP_KERNEL::Exception("DataArrayInt::checkUniformAndGuess : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
5061 throw INTERP_KERNEL::Exception("DataArrayInt::checkUniformAndGuess : this is empty !");
5062 const int *w(begin()),*end2(end());
5066 throw INTERP_KERNEL::Exception("DataArrayInt::checkUniformAndGuess : this is not uniform !");
5071 * Checks if all values in \a this array are unique.
5072 * \return bool - \a true if condition above is true
5073 * \throw If \a this is not allocated.
5074 * \throw If \a this->getNumberOfComponents() != 1
5076 bool DataArrayInt::hasUniqueValues() const
5079 if(getNumberOfComponents()!=1)
5080 throw INTERP_KERNEL::Exception("DataArrayInt::hasOnlyUniqueValues: must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
5081 int nbOfTuples(getNumberOfTuples());
5082 std::set<int> s(begin(),end()); // in C++11, should use unordered_set (O(1) complexity)
5083 if (s.size() != nbOfTuples)
5089 * Copy all components in a specified order from another DataArrayInt.
5090 * The specified components become the first ones in \a this array.
5091 * Both numerical and textual data is copied. The number of tuples in \a this and
5092 * the other array can be different.
5093 * \param [in] a - the array to copy data from.
5094 * \param [in] compoIds - sequence of zero based indices of components, data of which is
5096 * \throw If \a a is NULL.
5097 * \throw If \a compoIds.size() != \a a->getNumberOfComponents().
5098 * \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
5100 * \if ENABLE_EXAMPLES
5101 * \ref py_mcdataarrayint_setselectedcomponents "Here is a Python example".
5104 void DataArrayInt::setSelectedComponents(const DataArrayInt *a, const std::vector<int>& compoIds)
5107 throw INTERP_KERNEL::Exception("DataArrayInt::setSelectedComponents : input DataArrayInt is NULL !");
5109 a->checkAllocated();
5110 copyPartOfStringInfoFrom2(compoIds,*a);
5111 std::size_t partOfCompoSz=compoIds.size();
5112 int nbOfCompo=getNumberOfComponents();
5113 int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
5114 const int *ac=a->getConstPointer();
5115 int *nc=getPointer();
5116 for(int i=0;i<nbOfTuples;i++)
5117 for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
5118 nc[nbOfCompo*i+compoIds[j]]=*ac;
5121 DataArrayIntIterator *DataArrayInt::iterator()
5123 return new DataArrayIntIterator(this);
5127 * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to a
5128 * given one. The ids are sorted in the ascending order.
5129 * \param [in] val - the value to find 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.
5134 * \sa DataArrayInt::findIdsEqualTuple
5136 DataArrayInt *DataArrayInt::findIdsEqual(int val) const
5139 if(getNumberOfComponents()!=1)
5140 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqual : the array must have only one component, you can call 'rearrange' method before !");
5141 const int *cptr(getConstPointer());
5142 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
5143 int nbOfTuples=getNumberOfTuples();
5144 for(int i=0;i<nbOfTuples;i++,cptr++)
5146 ret->pushBackSilent(i);
5151 * Creates a new DataArrayInt containing IDs (indices) of tuples holding value \b not
5152 * equal to a given one.
5153 * \param [in] val - the value to ignore within \a this.
5154 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5155 * array using decrRef() as it is no more needed.
5156 * \throw If \a this is not allocated.
5157 * \throw If \a this->getNumberOfComponents() != 1.
5159 DataArrayInt *DataArrayInt::findIdsNotEqual(int val) const
5162 if(getNumberOfComponents()!=1)
5163 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotEqual : the array must have only one component, you can call 'rearrange' method before !");
5164 const int *cptr(getConstPointer());
5165 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
5166 int nbOfTuples=getNumberOfTuples();
5167 for(int i=0;i<nbOfTuples;i++,cptr++)
5169 ret->pushBackSilent(i);
5174 * Creates a new DataArrayInt containing IDs (indices) of tuples holding tuple equal to those defined by [ \a tupleBg , \a tupleEnd )
5175 * This method is an extension of DataArrayInt::findIdsEqual method.
5177 * \param [in] tupleBg - the begin (included) of the input tuple to find within \a this.
5178 * \param [in] tupleEnd - the end (excluded) of the input tuple to find within \a this.
5179 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5180 * array using decrRef() as it is no more needed.
5181 * \throw If \a this is not allocated.
5182 * \throw If \a this->getNumberOfComponents() != std::distance(tupleBg,tupleEnd).
5183 * \throw If \a this->getNumberOfComponents() is equal to 0.
5184 * \sa DataArrayInt::findIdsEqual
5186 DataArrayInt *DataArrayInt::findIdsEqualTuple(const int *tupleBg, const int *tupleEnd) const
5188 std::size_t nbOfCompoExp(std::distance(tupleBg,tupleEnd));
5190 if(getNumberOfComponents()!=(int)nbOfCompoExp)
5192 std::ostringstream oss; oss << "DataArrayInt::findIdsEqualTuple : mismatch of number of components. Input tuple has " << nbOfCompoExp << " whereas this array has " << getNumberOfComponents() << " components !";
5193 throw INTERP_KERNEL::Exception(oss.str().c_str());
5196 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqualTuple : number of components should be > 0 !");
5197 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
5198 const int *bg(begin()),*end2(end()),*work(begin());
5201 work=std::search(work,end2,tupleBg,tupleEnd);
5204 std::size_t pos(std::distance(bg,work));
5205 if(pos%nbOfCompoExp==0)
5206 ret->pushBackSilent(pos/nbOfCompoExp);
5214 * Assigns \a newValue to all elements holding \a oldValue within \a this
5215 * one-dimensional array.
5216 * \param [in] oldValue - the value to replace.
5217 * \param [in] newValue - the value to assign.
5218 * \return int - number of replacements performed.
5219 * \throw If \a this is not allocated.
5220 * \throw If \a this->getNumberOfComponents() != 1.
5222 int DataArrayInt::changeValue(int oldValue, int newValue)
5225 if(getNumberOfComponents()!=1)
5226 throw INTERP_KERNEL::Exception("DataArrayInt::changeValue : the array must have only one component, you can call 'rearrange' method before !");
5227 if(oldValue==newValue)
5229 int *start(getPointer()),*end2(start+getNbOfElems());
5231 for(int *val=start;val!=end2;val++)
5245 * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to
5246 * one of given values.
5247 * \param [in] valsBg - an array of values to find within \a this array.
5248 * \param [in] valsEnd - specifies the end of the array \a valsBg, so that
5249 * the last value of \a valsBg is \a valsEnd[ -1 ].
5250 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5251 * array using decrRef() as it is no more needed.
5252 * \throw If \a this->getNumberOfComponents() != 1.
5254 DataArrayInt *DataArrayInt::findIdsEqualList(const int *valsBg, const int *valsEnd) const
5256 if(getNumberOfComponents()!=1)
5257 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqualList : the array must have only one component, you can call 'rearrange' method before !");
5258 std::set<int> vals2(valsBg,valsEnd);
5259 const int *cptr(getConstPointer());
5260 std::vector<int> res;
5261 int nbOfTuples(getNumberOfTuples());
5262 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
5263 for(int i=0;i<nbOfTuples;i++,cptr++)
5264 if(vals2.find(*cptr)!=vals2.end())
5265 ret->pushBackSilent(i);
5270 * Creates a new DataArrayInt containing IDs (indices) of tuples holding values \b not
5271 * equal to any of given values.
5272 * \param [in] valsBg - an array of values to ignore within \a this array.
5273 * \param [in] valsEnd - specifies the end of the array \a valsBg, so that
5274 * the last value of \a valsBg is \a valsEnd[ -1 ].
5275 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5276 * array using decrRef() as it is no more needed.
5277 * \throw If \a this->getNumberOfComponents() != 1.
5279 DataArrayInt *DataArrayInt::findIdsNotEqualList(const int *valsBg, const int *valsEnd) const
5281 if(getNumberOfComponents()!=1)
5282 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotEqualList : the array must have only one component, you can call 'rearrange' method before !");
5283 std::set<int> vals2(valsBg,valsEnd);
5284 const int *cptr=getConstPointer();
5285 std::vector<int> res;
5286 int nbOfTuples=getNumberOfTuples();
5287 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
5288 for(int i=0;i<nbOfTuples;i++,cptr++)
5289 if(vals2.find(*cptr)==vals2.end())
5290 ret->pushBackSilent(i);
5295 * This method is an extension of DataArrayInt::findIdFirstEqual method because this method works for DataArrayInt with
5296 * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
5297 * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
5298 * If any the tuple id is returned. If not -1 is returned.
5300 * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
5301 * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
5303 * \return tuple id where \b tupl is. -1 if no such tuple exists in \b this.
5304 * \sa DataArrayInt::findIdSequence, DataArrayInt::presenceOfTuple.
5306 int DataArrayInt::findIdFirstEqualTuple(const std::vector<int>& tupl) const
5309 int nbOfCompo=getNumberOfComponents();
5311 throw INTERP_KERNEL::Exception("DataArrayInt::findIdFirstEqualTuple : 0 components in 'this' !");
5312 if(nbOfCompo!=(int)tupl.size())
5314 std::ostringstream oss; oss << "DataArrayInt::findIdFirstEqualTuple : 'this' contains " << nbOfCompo << " components and searching for a tuple of length " << tupl.size() << " !";
5315 throw INTERP_KERNEL::Exception(oss.str().c_str());
5317 const int *cptr=getConstPointer();
5318 std::size_t nbOfVals=getNbOfElems();
5319 for(const int *work=cptr;work!=cptr+nbOfVals;)
5321 work=std::search(work,cptr+nbOfVals,tupl.begin(),tupl.end());
5322 if(work!=cptr+nbOfVals)
5324 if(std::distance(cptr,work)%nbOfCompo!=0)
5327 return std::distance(cptr,work)/nbOfCompo;
5334 * This method searches the sequence specified in input parameter \b vals in \b this.
5335 * This works only for DataArrayInt having number of components equal to one (if not an INTERP_KERNEL::Exception will be thrown).
5336 * This method differs from DataArrayInt::findIdFirstEqualTuple in that the position is internal raw data is not considered here contrary to DataArrayInt::findIdFirstEqualTuple.
5337 * \sa DataArrayInt::findIdFirstEqualTuple
5339 int DataArrayInt::findIdSequence(const std::vector<int>& vals) const
5342 int nbOfCompo=getNumberOfComponents();
5344 throw INTERP_KERNEL::Exception("DataArrayInt::findIdSequence : works only for DataArrayInt instance with one component !");
5345 const int *cptr=getConstPointer();
5346 std::size_t nbOfVals=getNbOfElems();
5347 const int *loc=std::search(cptr,cptr+nbOfVals,vals.begin(),vals.end());
5348 if(loc!=cptr+nbOfVals)
5349 return std::distance(cptr,loc);
5354 * This method expects to be called when number of components of this is equal to one.
5355 * This method returns the tuple id, if it exists, of the first tuple equal to \b value.
5356 * If not any tuple contains \b value -1 is returned.
5357 * \sa DataArrayInt::presenceOfValue
5359 int DataArrayInt::findIdFirstEqual(int value) const
5362 if(getNumberOfComponents()!=1)
5363 throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
5364 const int *cptr=getConstPointer();
5365 int nbOfTuples=getNumberOfTuples();
5366 const int *ret=std::find(cptr,cptr+nbOfTuples,value);
5367 if(ret!=cptr+nbOfTuples)
5368 return std::distance(cptr,ret);
5373 * This method expects to be called when number of components of this is equal to one.
5374 * This method returns the tuple id, if it exists, of the first tuple so that the value is contained in \b vals.
5375 * If not any tuple contains one of the values contained in 'vals' -1 is returned.
5376 * \sa DataArrayInt::presenceOfValue
5378 int DataArrayInt::findIdFirstEqual(const std::vector<int>& vals) const
5381 if(getNumberOfComponents()!=1)
5382 throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
5383 std::set<int> vals2(vals.begin(),vals.end());
5384 const int *cptr=getConstPointer();
5385 int nbOfTuples=getNumberOfTuples();
5386 for(const int *w=cptr;w!=cptr+nbOfTuples;w++)
5387 if(vals2.find(*w)!=vals2.end())
5388 return std::distance(cptr,w);
5393 * This method returns the number of values in \a this that are equals to input parameter \a value.
5394 * This method only works for single component array.
5396 * \return a value in [ 0, \c this->getNumberOfTuples() )
5398 * \throw If \a this is not allocated
5401 int DataArrayInt::count(int value) const
5405 if(getNumberOfComponents()!=1)
5406 throw INTERP_KERNEL::Exception("DataArrayInt::count : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
5407 const int *vals=begin();
5408 int nbOfTuples=getNumberOfTuples();
5409 for(int i=0;i<nbOfTuples;i++,vals++)
5416 * This method is an extension of DataArrayInt::presenceOfValue method because this method works for DataArrayInt with
5417 * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
5418 * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
5419 * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
5420 * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
5421 * \sa DataArrayInt::findIdFirstEqualTuple
5423 bool DataArrayInt::presenceOfTuple(const std::vector<int>& tupl) const
5425 return findIdFirstEqualTuple(tupl)!=-1;
5430 * Returns \a true if a given value is present within \a this one-dimensional array.
5431 * \param [in] value - the value to find within \a this array.
5432 * \return bool - \a true in case if \a value is present within \a this array.
5433 * \throw If \a this is not allocated.
5434 * \throw If \a this->getNumberOfComponents() != 1.
5435 * \sa findIdFirstEqual()
5437 bool DataArrayInt::presenceOfValue(int value) const
5439 return findIdFirstEqual(value)!=-1;
5443 * This method expects to be called when number of components of this is equal to one.
5444 * This method returns true if it exists a tuple so that the value is contained in \b vals.
5445 * If not any tuple contains one of the values contained in 'vals' false is returned.
5446 * \sa DataArrayInt::findIdFirstEqual
5448 bool DataArrayInt::presenceOfValue(const std::vector<int>& vals) const
5450 return findIdFirstEqual(vals)!=-1;
5454 * Accumulates values of each component of \a this array.
5455 * \param [out] res - an array of length \a this->getNumberOfComponents(), allocated
5456 * by the caller, that is filled by this method with sum value for each
5458 * \throw If \a this is not allocated.
5460 void DataArrayInt::accumulate(int *res) const
5463 const int *ptr=getConstPointer();
5464 int nbTuple=getNumberOfTuples();
5465 int nbComps=getNumberOfComponents();
5466 std::fill(res,res+nbComps,0);
5467 for(int i=0;i<nbTuple;i++)
5468 std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<int>());
5471 int DataArrayInt::accumulate(int compId) const
5474 const int *ptr=getConstPointer();
5475 int nbTuple=getNumberOfTuples();
5476 int nbComps=getNumberOfComponents();
5477 if(compId<0 || compId>=nbComps)
5478 throw INTERP_KERNEL::Exception("DataArrayInt::accumulate : Invalid compId specified : No such nb of components !");
5480 for(int i=0;i<nbTuple;i++)
5481 ret+=ptr[i*nbComps+compId];
5486 * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
5487 * The returned array will have same number of components than \a this and number of tuples equal to
5488 * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
5490 * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
5492 * \param [in] bgOfIndex - begin (included) of the input index array.
5493 * \param [in] endOfIndex - end (excluded) of the input index array.
5494 * \return DataArrayInt * - the new instance having the same number of components than \a this.
5496 * \throw If bgOfIndex or end is NULL.
5497 * \throw If input index array is not ascendingly sorted.
5498 * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
5499 * \throw If std::distance(bgOfIndex,endOfIndex)==0.
5501 DataArrayInt *DataArrayInt::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
5503 if(!bgOfIndex || !endOfIndex)
5504 throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : input pointer NULL !");
5506 int nbCompo=getNumberOfComponents();
5507 int nbOfTuples=getNumberOfTuples();
5508 int sz=(int)std::distance(bgOfIndex,endOfIndex);
5510 throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : invalid size of input index array !");
5512 MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(sz,nbCompo);
5513 const int *w=bgOfIndex;
5514 if(*w<0 || *w>=nbOfTuples)
5515 throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
5516 const int *srcPt=begin()+(*w)*nbCompo;
5517 int *tmp=ret->getPointer();
5518 for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
5520 std::fill(tmp,tmp+nbCompo,0);
5523 for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
5525 if(j>=0 && j<nbOfTuples)
5526 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<int>());
5529 std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
5530 throw INTERP_KERNEL::Exception(oss.str().c_str());
5536 std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
5537 throw INTERP_KERNEL::Exception(oss.str().c_str());
5540 ret->copyStringInfoFrom(*this);
5545 * Returns a new DataArrayInt by concatenating two given arrays, so that (1) the number
5546 * of tuples in the result array is <em> a1->getNumberOfTuples() + a2->getNumberOfTuples() -
5547 * offsetA2</em> and (2)
5548 * the number of component in the result array is same as that of each of given arrays.
5549 * First \a offsetA2 tuples of \a a2 are skipped and thus are missing from the result array.
5550 * Info on components is copied from the first of the given arrays. Number of components
5551 * in the given arrays must be the same.
5552 * \param [in] a1 - an array to include in the result array.
5553 * \param [in] a2 - another array to include in the result array.
5554 * \param [in] offsetA2 - number of tuples of \a a2 to skip.
5555 * \return DataArrayInt * - the new instance of DataArrayInt.
5556 * The caller is to delete this result array using decrRef() as it is no more
5558 * \throw If either \a a1 or \a a2 is NULL.
5559 * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
5561 DataArrayInt *DataArrayInt::Aggregate(const DataArrayInt *a1, const DataArrayInt *a2, int offsetA2)
5564 throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input DataArrayInt instance is NULL !");
5565 int nbOfComp=a1->getNumberOfComponents();
5566 if(nbOfComp!=a2->getNumberOfComponents())
5567 throw INTERP_KERNEL::Exception("Nb of components mismatch for array Aggregation !");
5568 int nbOfTuple1=a1->getNumberOfTuples();
5569 int nbOfTuple2=a2->getNumberOfTuples();
5570 DataArrayInt *ret=DataArrayInt::New();
5571 ret->alloc(nbOfTuple1+nbOfTuple2-offsetA2,nbOfComp);
5572 int *pt=std::copy(a1->getConstPointer(),a1->getConstPointer()+nbOfTuple1*nbOfComp,ret->getPointer());
5573 std::copy(a2->getConstPointer()+offsetA2*nbOfComp,a2->getConstPointer()+nbOfTuple2*nbOfComp,pt);
5574 ret->copyStringInfoFrom(*a1);
5579 * Returns a new DataArrayInt by concatenating all given arrays, so that (1) the number
5580 * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
5581 * the number of component in the result array is same as that of each of given arrays.
5582 * Info on components is copied from the first of the given arrays. Number of components
5583 * in the given arrays must be the same.
5584 * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it
5585 * not the object itself.
5586 * \param [in] arr - a sequence of arrays to include in the result array.
5587 * \return DataArrayInt * - the new instance of DataArrayInt.
5588 * The caller is to delete this result array using decrRef() as it is no more
5590 * \throw If all arrays within \a arr are NULL.
5591 * \throw If getNumberOfComponents() of arrays within \a arr.
5593 DataArrayInt *DataArrayInt::Aggregate(const std::vector<const DataArrayInt *>& arr)
5595 std::vector<const DataArrayInt *> a;
5596 for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
5600 throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input list must be NON EMPTY !");
5601 std::vector<const DataArrayInt *>::const_iterator it=a.begin();
5602 int nbOfComp=(*it)->getNumberOfComponents();
5603 int nbt=(*it++)->getNumberOfTuples();
5604 for(int i=1;it!=a.end();it++,i++)
5606 if((*it)->getNumberOfComponents()!=nbOfComp)
5607 throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : Nb of components mismatch for array aggregation !");
5608 nbt+=(*it)->getNumberOfTuples();
5610 MCAuto<DataArrayInt> ret=DataArrayInt::New();
5611 ret->alloc(nbt,nbOfComp);
5612 int *pt=ret->getPointer();
5613 for(it=a.begin();it!=a.end();it++)
5614 pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
5615 ret->copyStringInfoFrom(*(a[0]));
5620 * This method takes as input a list of DataArrayInt instances \a arrs that represent each a packed index arrays.
5621 * A packed index array is an allocated array with one component, and at least one tuple. The first element
5622 * of each array in \a arrs must be 0. Each array in \a arrs is expected to be increasingly monotonic.
5623 * 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.
5625 * \return DataArrayInt * - a new object to be managed by the caller.
5627 DataArrayInt *DataArrayInt::AggregateIndexes(const std::vector<const DataArrayInt *>& arrs)
5630 for(std::vector<const DataArrayInt *>::const_iterator it4=arrs.begin();it4!=arrs.end();it4++)
5634 (*it4)->checkAllocated();
5635 if((*it4)->getNumberOfComponents()!=1)
5637 std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of compo != 1 at pos " << std::distance(arrs.begin(),it4) << " !";
5638 throw INTERP_KERNEL::Exception(oss.str().c_str());
5640 int nbTupl=(*it4)->getNumberOfTuples();
5643 std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of tuples < 1 at pos " << std::distance(arrs.begin(),it4) << " !";
5644 throw INTERP_KERNEL::Exception(oss.str().c_str());
5646 if((*it4)->front()!=0)
5648 std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with front value != 0 at pos " << std::distance(arrs.begin(),it4) << " !";
5649 throw INTERP_KERNEL::Exception(oss.str().c_str());
5655 std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a null instance at pos " << std::distance(arrs.begin(),it4) << " !";
5656 throw INTERP_KERNEL::Exception(oss.str().c_str());
5660 throw INTERP_KERNEL::Exception("DataArrayInt::AggregateIndexes : input list must be NON EMPTY !");
5661 MCAuto<DataArrayInt> ret=DataArrayInt::New();
5662 ret->alloc(retSz,1);
5663 int *pt=ret->getPointer(); *pt++=0;
5664 for(std::vector<const DataArrayInt *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
5665 pt=std::transform((*it)->begin()+1,(*it)->end(),pt,std::bind2nd(std::plus<int>(),pt[-1]));
5666 ret->copyStringInfoFrom(*(arrs[0]));
5671 * Returns in a single walk in \a this the min value and the max value in \a this.
5672 * \a this is expected to be single component array.
5674 * \param [out] minValue - the min value in \a this.
5675 * \param [out] maxValue - the max value in \a this.
5677 * \sa getMinValueInArray, getMinValue, getMaxValueInArray, getMaxValue
5679 void DataArrayInt::getMinMaxValues(int& minValue, int& maxValue) const
5682 if(getNumberOfComponents()!=1)
5683 throw INTERP_KERNEL::Exception("DataArrayInt::getMinMaxValues : must be applied on DataArrayInt with only one component !");
5684 int nbTuples(getNumberOfTuples());
5685 const int *pt(begin());
5686 minValue=std::numeric_limits<int>::max(); maxValue=-std::numeric_limits<int>::max();
5687 for(int i=0;i<nbTuples;i++,pt++)
5697 * Modify all elements of \a this array, so that
5698 * an element _x_ becomes \f$ numerator / x \f$.
5699 * \warning If an exception is thrown because of presence of 0 element in \a this
5700 * array, all elements processed before detection of the zero element remain
5702 * \param [in] numerator - the numerator used to modify array elements.
5703 * \throw If \a this is not allocated.
5704 * \throw If there is an element equal to 0 in \a this array.
5706 void DataArrayInt::applyInv(int numerator)
5709 int *ptr=getPointer();
5710 std::size_t nbOfElems=getNbOfElems();
5711 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
5715 *ptr=numerator/(*ptr);
5719 std::ostringstream oss; oss << "DataArrayInt::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
5721 throw INTERP_KERNEL::Exception(oss.str().c_str());
5728 * Modify all elements of \a this array, so that
5729 * an element _x_ becomes \f$ x / val \f$.
5730 * \param [in] val - the denominator used to modify array elements.
5731 * \throw If \a this is not allocated.
5732 * \throw If \a val == 0.
5734 void DataArrayInt::applyDivideBy(int val)
5737 throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to divide by 0 !");
5739 int *ptr=getPointer();
5740 std::size_t nbOfElems=getNbOfElems();
5741 std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::divides<int>(),val));
5746 * Modify all elements of \a this array, so that
5747 * an element _x_ becomes <em> x % val </em>.
5748 * \param [in] val - the divisor used to modify array elements.
5749 * \throw If \a this is not allocated.
5750 * \throw If \a val <= 0.
5752 void DataArrayInt::applyModulus(int val)
5755 throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to operate modulus on value <= 0 !");
5757 int *ptr=getPointer();
5758 std::size_t nbOfElems=getNbOfElems();
5759 std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::modulus<int>(),val));
5764 * This method works only on data array with one component.
5765 * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
5766 * this[*id] in [\b vmin,\b vmax)
5768 * \param [in] vmin begin of range. This value is included in range (included).
5769 * \param [in] vmax end of range. This value is \b not included in range (excluded).
5770 * \return a newly allocated data array that the caller should deal with.
5772 * \sa DataArrayInt::findIdsNotInRange , DataArrayInt::findIdsStricltyNegative
5774 DataArrayInt *DataArrayInt::findIdsInRange(int vmin, int vmax) const
5776 InRange<int> ir(vmin,vmax);
5777 MCAuto<DataArrayInt> ret(findIdsAdv(ir));
5782 * This method works only on data array with one component.
5783 * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
5784 * this[*id] \b not in [\b vmin,\b vmax)
5786 * \param [in] vmin begin of range. This value is \b not included in range (excluded).
5787 * \param [in] vmax end of range. This value is included in range (included).
5788 * \return a newly allocated data array that the caller should deal with.
5790 * \sa DataArrayInt::findIdsInRange , DataArrayInt::findIdsStricltyNegative
5792 DataArrayInt *DataArrayInt::findIdsNotInRange(int vmin, int vmax) const
5794 NotInRange<int> nir(vmin,vmax);
5795 MCAuto<DataArrayInt> ret(findIdsAdv(nir));
5800 * This method works only on data array with one component.
5801 * 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.
5803 * \param [in] vmin begin of range. This value is included in range (included).
5804 * \param [in] vmax end of range. This value is \b not included in range (excluded).
5805 * \return if all ids in \a this are so that (*this)[i]==i for all i in [ 0, \c this->getNumberOfTuples() ). */
5806 bool DataArrayInt::checkAllIdsInRange(int vmin, int vmax) const
5809 if(getNumberOfComponents()!=1)
5810 throw INTERP_KERNEL::Exception("DataArrayInt::checkAllIdsInRange : this must have exactly one component !");
5811 int nbOfTuples=getNumberOfTuples();
5813 const int *cptr=getConstPointer();
5814 for(int i=0;i<nbOfTuples;i++,cptr++)
5816 if(*cptr>=vmin && *cptr<vmax)
5817 { ret=ret && *cptr==i; }
5820 std::ostringstream oss; oss << "DataArrayInt::checkAllIdsInRange : tuple #" << i << " has value " << *cptr << " should be in [" << vmin << "," << vmax << ") !";
5821 throw INTERP_KERNEL::Exception(oss.str().c_str());
5828 * Modify all elements of \a this array, so that
5829 * an element _x_ becomes <em> val % x </em>.
5830 * \warning If an exception is thrown because of presence of an element <= 0 in \a this
5831 * array, all elements processed before detection of the zero element remain
5833 * \param [in] val - the divident used to modify array elements.
5834 * \throw If \a this is not allocated.
5835 * \throw If there is an element equal to or less than 0 in \a this array.
5837 void DataArrayInt::applyRModulus(int val)
5840 int *ptr=getPointer();
5841 std::size_t nbOfElems=getNbOfElems();
5842 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
5850 std::ostringstream oss; oss << "DataArrayInt::applyRModulus : presence of value <=0 in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
5852 throw INTERP_KERNEL::Exception(oss.str().c_str());
5859 * Modify all elements of \a this array, so that
5860 * an element _x_ becomes <em> val ^ x </em>.
5861 * \param [in] val - the value used to apply pow on all array elements.
5862 * \throw If \a this is not allocated.
5863 * \throw If \a val < 0.
5865 void DataArrayInt::applyPow(int val)
5869 throw INTERP_KERNEL::Exception("DataArrayInt::applyPow : input pow in < 0 !");
5870 int *ptr=getPointer();
5871 std::size_t nbOfElems=getNbOfElems();
5874 std::fill(ptr,ptr+nbOfElems,1);
5877 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
5880 for(int j=0;j<val;j++)
5888 * Modify all elements of \a this array, so that
5889 * an element _x_ becomes \f$ val ^ x \f$.
5890 * \param [in] val - the value used to apply pow on all array elements.
5891 * \throw If \a this is not allocated.
5892 * \throw If there is an element < 0 in \a this array.
5893 * \warning If an exception is thrown because of presence of 0 element in \a this
5894 * array, all elements processed before detection of the zero element remain
5897 void DataArrayInt::applyRPow(int val)
5900 int *ptr=getPointer();
5901 std::size_t nbOfElems=getNbOfElems();
5902 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
5907 for(int j=0;j<*ptr;j++)
5913 std::ostringstream oss; oss << "DataArrayInt::applyRPow : presence of negative value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
5915 throw INTERP_KERNEL::Exception(oss.str().c_str());
5922 * Returns a new DataArrayInt which is a minimal partition of elements of \a groups.
5923 * The i-th item of the result array is an ID of a set of elements belonging to a
5924 * unique set of groups, which the i-th element is a part of. This set of elements
5925 * belonging to a unique set of groups is called \a family, so the result array contains
5926 * IDs of families each element belongs to.
5928 * \b Example: if we have two groups of elements: \a group1 [0,4] and \a group2 [ 0,1,2 ],
5929 * then there are 3 families:
5930 * - \a family1 (with ID 1) contains element [0] belonging to ( \a group1 + \a group2 ),
5931 * - \a family2 (with ID 2) contains elements [4] belonging to ( \a group1 ),
5932 * - \a family3 (with ID 3) contains element [1,2] belonging to ( \a group2 ), <br>
5933 * and the result array contains IDs of families [ 1,3,3,0,2 ]. <br> Note a family ID 0 which
5934 * stands for the element #3 which is in none of groups.
5936 * \param [in] groups - sequence of groups of element IDs.
5937 * \param [in] newNb - total number of elements; it must be more than max ID of element
5939 * \param [out] fidsOfGroups - IDs of families the elements of each group belong to.
5940 * \return DataArrayInt * - a new instance of DataArrayInt containing IDs of families
5941 * each element with ID from range [0, \a newNb ) belongs to. The caller is to
5942 * delete this array using decrRef() as it is no more needed.
5943 * \throw If any element ID in \a groups violates condition ( 0 <= ID < \a newNb ).
5945 DataArrayInt *DataArrayInt::MakePartition(const std::vector<const DataArrayInt *>& groups, int newNb, std::vector< std::vector<int> >& fidsOfGroups)
5947 std::vector<const DataArrayInt *> groups2;
5948 for(std::vector<const DataArrayInt *>::const_iterator it4=groups.begin();it4!=groups.end();it4++)
5950 groups2.push_back(*it4);
5951 MCAuto<DataArrayInt> ret=DataArrayInt::New();
5952 ret->alloc(newNb,1);
5953 int *retPtr=ret->getPointer();
5954 std::fill(retPtr,retPtr+newNb,0);
5956 for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++)
5958 const int *ptr=(*iter)->getConstPointer();
5959 std::size_t nbOfElem=(*iter)->getNbOfElems();
5961 for(int j=0;j<sfid;j++)
5964 for(std::size_t i=0;i<nbOfElem;i++)
5966 if(ptr[i]>=0 && ptr[i]<newNb)
5968 if(retPtr[ptr[i]]==j)
5976 std::ostringstream oss; oss << "DataArrayInt::MakePartition : In group \"" << (*iter)->getName() << "\" in tuple #" << i << " value = " << ptr[i] << " ! Should be in [0," << newNb;
5978 throw INTERP_KERNEL::Exception(oss.str().c_str());
5985 fidsOfGroups.clear();
5986 fidsOfGroups.resize(groups2.size());
5988 for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++,grId++)
5991 const int *ptr=(*iter)->getConstPointer();
5992 std::size_t nbOfElem=(*iter)->getNbOfElems();
5993 for(const int *p=ptr;p!=ptr+nbOfElem;p++)
5994 tmp.insert(retPtr[*p]);
5995 fidsOfGroups[grId].insert(fidsOfGroups[grId].end(),tmp.begin(),tmp.end());
6001 * Returns a new DataArrayInt which contains all elements of given one-dimensional
6002 * arrays. The result array does not contain any duplicates and its values
6003 * are sorted in ascending order.
6004 * \param [in] arr - sequence of DataArrayInt's to unite.
6005 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6006 * array using decrRef() as it is no more needed.
6007 * \throw If any \a arr[i] is not allocated.
6008 * \throw If \a arr[i]->getNumberOfComponents() != 1.
6010 DataArrayInt *DataArrayInt::BuildUnion(const std::vector<const DataArrayInt *>& arr)
6012 std::vector<const DataArrayInt *> a;
6013 for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
6016 for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
6018 (*it)->checkAllocated();
6019 if((*it)->getNumberOfComponents()!=1)
6020 throw INTERP_KERNEL::Exception("DataArrayInt::BuildUnion : only single component allowed !");
6024 for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
6026 const int *pt=(*it)->getConstPointer();
6027 int nbOfTuples=(*it)->getNumberOfTuples();
6028 r.insert(pt,pt+nbOfTuples);
6030 DataArrayInt *ret=DataArrayInt::New();
6031 ret->alloc((int)r.size(),1);
6032 std::copy(r.begin(),r.end(),ret->getPointer());
6037 * Returns a new DataArrayInt which contains elements present in each of given one-dimensional
6038 * arrays. The result array does not contain any duplicates and its values
6039 * are sorted in ascending order.
6040 * \param [in] arr - sequence of DataArrayInt's to intersect.
6041 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6042 * array using decrRef() as it is no more needed.
6043 * \throw If any \a arr[i] is not allocated.
6044 * \throw If \a arr[i]->getNumberOfComponents() != 1.
6046 DataArrayInt *DataArrayInt::BuildIntersection(const std::vector<const DataArrayInt *>& arr)
6048 std::vector<const DataArrayInt *> a;
6049 for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
6052 for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
6054 (*it)->checkAllocated();
6055 if((*it)->getNumberOfComponents()!=1)
6056 throw INTERP_KERNEL::Exception("DataArrayInt::BuildIntersection : only single component allowed !");
6060 for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
6062 const int *pt=(*it)->getConstPointer();
6063 int nbOfTuples=(*it)->getNumberOfTuples();
6064 std::set<int> s1(pt,pt+nbOfTuples);
6068 std::set_intersection(r.begin(),r.end(),s1.begin(),s1.end(),inserter(r2,r2.end()));
6074 DataArrayInt *ret(DataArrayInt::New());
6075 ret->alloc((int)r.size(),1);
6076 std::copy(r.begin(),r.end(),ret->getPointer());
6081 namespace MEDCouplingImpl
6086 OpSwitchedOn(int *pt):_pt(pt),_cnt(0) { }
6087 void operator()(const bool& b) { if(b) *_pt++=_cnt; _cnt++; }
6096 OpSwitchedOff(int *pt):_pt(pt),_cnt(0) { }
6097 void operator()(const bool& b) { if(!b) *_pt++=_cnt; _cnt++; }
6106 * This method returns the list of ids in ascending mode so that v[id]==true.
6108 DataArrayInt *DataArrayInt::BuildListOfSwitchedOn(const std::vector<bool>& v)
6110 int sz((int)std::count(v.begin(),v.end(),true));
6111 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
6112 std::for_each(v.begin(),v.end(),MEDCouplingImpl::OpSwitchedOn(ret->getPointer()));
6117 * This method returns the list of ids in ascending mode so that v[id]==false.
6119 DataArrayInt *DataArrayInt::BuildListOfSwitchedOff(const std::vector<bool>& v)
6121 int sz((int)std::count(v.begin(),v.end(),false));
6122 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
6123 std::for_each(v.begin(),v.end(),MEDCouplingImpl::OpSwitchedOff(ret->getPointer()));
6128 * This method allows to put a vector of vector of integer into a more compact data stucture (skyline).
6129 * This method is not available into python because no available optimized data structure available to map std::vector< std::vector<int> >.
6131 * \param [in] v the input data structure to be translate into skyline format.
6132 * \param [out] data the first element of the skyline format. The user is expected to deal with newly allocated array.
6133 * \param [out] dataIndex the second element of the skyline format.
6135 void DataArrayInt::PutIntoToSkylineFrmt(const std::vector< std::vector<int> >& v, DataArrayInt *& data, DataArrayInt *& dataIndex)
6137 int sz((int)v.size());
6138 MCAuto<DataArrayInt> ret0(DataArrayInt::New()),ret1(DataArrayInt::New());
6139 ret1->alloc(sz+1,1);
6140 int *pt(ret1->getPointer()); *pt=0;
6141 for(int i=0;i<sz;i++,pt++)
6142 pt[1]=pt[0]+(int)v[i].size();
6143 ret0->alloc(ret1->back(),1);
6144 pt=ret0->getPointer();
6145 for(int i=0;i<sz;i++)
6146 pt=std::copy(v[i].begin(),v[i].end(),pt);
6147 data=ret0.retn(); dataIndex=ret1.retn();
6151 * Returns a new DataArrayInt which contains a complement of elements of \a this
6152 * one-dimensional array. I.e. the result array contains all elements from the range [0,
6153 * \a nbOfElement) not present in \a this array.
6154 * \param [in] nbOfElement - maximal size of the result array.
6155 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6156 * array using decrRef() as it is no more needed.
6157 * \throw If \a this is not allocated.
6158 * \throw If \a this->getNumberOfComponents() != 1.
6159 * \throw If any element \a x of \a this array violates condition ( 0 <= \a x < \a
6162 DataArrayInt *DataArrayInt::buildComplement(int nbOfElement) const
6165 if(getNumberOfComponents()!=1)
6166 throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : only single component allowed !");
6167 std::vector<bool> tmp(nbOfElement);
6168 const int *pt=getConstPointer();
6169 int nbOfTuples=getNumberOfTuples();
6170 for(const int *w=pt;w!=pt+nbOfTuples;w++)
6171 if(*w>=0 && *w<nbOfElement)
6174 throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : an element is not in valid range : [0,nbOfElement) !");
6175 int nbOfRetVal=(int)std::count(tmp.begin(),tmp.end(),false);
6176 DataArrayInt *ret=DataArrayInt::New();
6177 ret->alloc(nbOfRetVal,1);
6179 int *retPtr=ret->getPointer();
6180 for(int i=0;i<nbOfElement;i++)
6187 * Returns a new DataArrayInt containing elements of \a this one-dimensional missing
6188 * from an \a other one-dimensional array.
6189 * \param [in] other - a DataArrayInt containing elements not to include in the result array.
6190 * \return DataArrayInt * - a new instance of DataArrayInt with one component. The
6191 * caller is to delete this array using decrRef() as it is no more needed.
6192 * \throw If \a other is NULL.
6193 * \throw If \a other is not allocated.
6194 * \throw If \a other->getNumberOfComponents() != 1.
6195 * \throw If \a this is not allocated.
6196 * \throw If \a this->getNumberOfComponents() != 1.
6197 * \sa DataArrayInt::buildSubstractionOptimized()
6199 DataArrayInt *DataArrayInt::buildSubstraction(const DataArrayInt *other) const
6202 throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : DataArrayInt pointer in input is NULL !");
6204 other->checkAllocated();
6205 if(getNumberOfComponents()!=1)
6206 throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed !");
6207 if(other->getNumberOfComponents()!=1)
6208 throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed for other type !");
6209 const int *pt=getConstPointer();
6210 int nbOfTuples=getNumberOfTuples();
6211 std::set<int> s1(pt,pt+nbOfTuples);
6212 pt=other->getConstPointer();
6213 nbOfTuples=other->getNumberOfTuples();
6214 std::set<int> s2(pt,pt+nbOfTuples);
6216 std::set_difference(s1.begin(),s1.end(),s2.begin(),s2.end(),std::back_insert_iterator< std::vector<int> >(r));
6217 DataArrayInt *ret=DataArrayInt::New();
6218 ret->alloc((int)r.size(),1);
6219 std::copy(r.begin(),r.end(),ret->getPointer());
6224 * \a this is expected to have one component and to be sorted ascendingly (as for \a other).
6225 * \a other is expected to be a part of \a this. If not DataArrayInt::buildSubstraction should be called instead.
6227 * \param [in] other an array with one component and expected to be sorted ascendingly.
6228 * \ret list of ids in \a this but not in \a other.
6229 * \sa DataArrayInt::buildSubstraction
6231 DataArrayInt *DataArrayInt::buildSubstractionOptimized(const DataArrayInt *other) const
6233 static const char *MSG="DataArrayInt::buildSubstractionOptimized : only single component allowed !";
6234 if(!other) throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstractionOptimized : NULL input array !");
6235 checkAllocated(); other->checkAllocated();
6236 if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
6237 if(other->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
6238 const int *pt1Bg(begin()),*pt1End(end()),*pt2Bg(other->begin()),*pt2End(other->end());
6239 const int *work1(pt1Bg),*work2(pt2Bg);
6240 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6241 for(;work1!=pt1End;work1++)
6243 if(work2!=pt2End && *work1==*work2)
6246 ret->pushBackSilent(*work1);
6253 * Returns a new DataArrayInt which contains all elements of \a this and a given
6254 * one-dimensional arrays. The result array does not contain any duplicates
6255 * and its values are sorted in ascending order.
6256 * \param [in] other - an array to unite with \a this one.
6257 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6258 * array using decrRef() as it is no more needed.
6259 * \throw If \a this or \a other is not allocated.
6260 * \throw If \a this->getNumberOfComponents() != 1.
6261 * \throw If \a other->getNumberOfComponents() != 1.
6263 DataArrayInt *DataArrayInt::buildUnion(const DataArrayInt *other) const
6265 std::vector<const DataArrayInt *>arrs(2);
6266 arrs[0]=this; arrs[1]=other;
6267 return BuildUnion(arrs);
6272 * Returns a new DataArrayInt which contains elements present in both \a this and a given
6273 * one-dimensional arrays. The result array does not contain any duplicates
6274 * and its values are sorted in ascending order.
6275 * \param [in] other - an array to intersect with \a this one.
6276 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6277 * array using decrRef() as it is no more needed.
6278 * \throw If \a this or \a other is not allocated.
6279 * \throw If \a this->getNumberOfComponents() != 1.
6280 * \throw If \a other->getNumberOfComponents() != 1.
6282 DataArrayInt *DataArrayInt::buildIntersection(const DataArrayInt *other) const
6284 std::vector<const DataArrayInt *>arrs(2);
6285 arrs[0]=this; arrs[1]=other;
6286 return BuildIntersection(arrs);
6290 * This method can be applied on allocated with one component DataArrayInt instance.
6291 * This method is typically relevant for sorted arrays. All consecutive duplicated items in \a this will appear only once in returned DataArrayInt instance.
6292 * 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]
6294 * \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.
6296 * \sa DataArrayInt::buildUniqueNotSorted
6298 DataArrayInt *DataArrayInt::buildUnique() const
6301 if(getNumberOfComponents()!=1)
6302 throw INTERP_KERNEL::Exception("DataArrayInt::buildUnique : only single component allowed !");
6303 int nbOfTuples=getNumberOfTuples();
6304 MCAuto<DataArrayInt> tmp=deepCopy();
6305 int *data=tmp->getPointer();
6306 int *last=std::unique(data,data+nbOfTuples);
6307 MCAuto<DataArrayInt> ret=DataArrayInt::New();
6308 ret->alloc(std::distance(data,last),1);
6309 std::copy(data,last,ret->getPointer());
6314 * This method can be applied on allocated with one component DataArrayInt instance.
6315 * This method keep elements only once by keeping the same order in \a this that is not expected to be sorted.
6317 * \return a newly allocated array that contain the result of the unique operation applied on \a this.
6319 * \throw if \a this is not allocated or if \a this has not exactly one component.
6321 * \sa DataArrayInt::buildUnique
6323 DataArrayInt *DataArrayInt::buildUniqueNotSorted() const
6326 if(getNumberOfComponents()!=1)
6327 throw INTERP_KERNEL::Exception("DataArrayInt::buildUniqueNotSorted : only single component allowed !");
6329 getMinMaxValues(minVal,maxVal);
6330 std::vector<bool> b(maxVal-minVal+1,false);
6331 const int *ptBg(begin()),*endBg(end());
6332 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6333 for(const int *pt=ptBg;pt!=endBg;pt++)
6337 ret->pushBackSilent(*pt);
6341 ret->copyStringInfoFrom(*this);
6346 * Returns a new DataArrayInt which contains size of every of groups described by \a this
6347 * "index" array. Such "index" array is returned for example by
6348 * \ref MEDCoupling::MEDCouplingUMesh::buildDescendingConnectivity
6349 * "MEDCouplingUMesh::buildDescendingConnectivity" and
6350 * \ref MEDCoupling::MEDCouplingUMesh::getNodalConnectivityIndex
6351 * "MEDCouplingUMesh::getNodalConnectivityIndex" etc.
6352 * This method preforms the reverse operation of DataArrayInt::computeOffsetsFull.
6353 * \return DataArrayInt * - a new instance of DataArrayInt, whose number of tuples
6354 * equals to \a this->getNumberOfComponents() - 1, and number of components is 1.
6355 * The caller is to delete this array using decrRef() as it is no more needed.
6356 * \throw If \a this is not allocated.
6357 * \throw If \a this->getNumberOfComponents() != 1.
6358 * \throw If \a this->getNumberOfTuples() < 2.
6361 * - this contains [1,3,6,7,7,9,15]
6362 * - result array contains [2,3,1,0,2,6],
6363 * where 2 = 3 - 1, 3 = 6 - 3, 1 = 7 - 6 etc.
6365 * \sa DataArrayInt::computeOffsetsFull
6367 DataArrayInt *DataArrayInt::deltaShiftIndex() const
6370 if(getNumberOfComponents()!=1)
6371 throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : only single component allowed !");
6372 int nbOfTuples=getNumberOfTuples();
6374 throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : 1 tuple at least must be present in 'this' !");
6375 const int *ptr=getConstPointer();
6376 DataArrayInt *ret=DataArrayInt::New();
6377 ret->alloc(nbOfTuples-1,1);
6378 int *out=ret->getPointer();
6379 std::transform(ptr+1,ptr+nbOfTuples,ptr,out,std::minus<int>());
6384 * Modifies \a this one-dimensional array so that value of each element \a x
6385 * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
6386 * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number of tuples
6387 * and components remains the same.<br>
6388 * This method is useful for allToAllV in MPI with contiguous policy. This method
6389 * differs from computeOffsetsFull() in that the number of tuples is \b not changed by
6391 * \throw If \a this is not allocated.
6392 * \throw If \a this->getNumberOfComponents() != 1.
6395 * - Before \a this contains [3,5,1,2,0,8]
6396 * - After \a this contains [0,3,8,9,11,11]<br>
6397 * Note that the last element 19 = 11 + 8 is missing because size of \a this
6398 * array is retained and thus there is no space to store the last element.
6400 void DataArrayInt::computeOffsets()
6403 if(getNumberOfComponents()!=1)
6404 throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets : only single component allowed !");
6405 int nbOfTuples=getNumberOfTuples();
6408 int *work=getPointer();
6411 for(int i=1;i<nbOfTuples;i++)
6414 work[i]=work[i-1]+tmp;
6422 * Modifies \a this one-dimensional array so that value of each element \a x
6423 * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
6424 * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number
6425 * components remains the same and number of tuples is inceamented by one.<br>
6426 * This method is useful for allToAllV in MPI with contiguous policy. This method
6427 * differs from computeOffsets() in that the number of tuples is changed by this one.
6428 * This method preforms the reverse operation of DataArrayInt::deltaShiftIndex.
6429 * \throw If \a this is not allocated.
6430 * \throw If \a this->getNumberOfComponents() != 1.
6433 * - Before \a this contains [3,5,1,2,0,8]
6434 * - After \a this contains [0,3,8,9,11,11,19]<br>
6435 * \sa DataArrayInt::deltaShiftIndex
6437 void DataArrayInt::computeOffsetsFull()
6440 if(getNumberOfComponents()!=1)
6441 throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsetsFull : only single component allowed !");
6442 int nbOfTuples=getNumberOfTuples();
6443 int *ret=(int *)malloc((nbOfTuples+1)*sizeof(int));
6444 const int *work=getConstPointer();
6446 for(int i=0;i<nbOfTuples;i++)
6447 ret[i+1]=work[i]+ret[i];
6448 useArray(ret,true,C_DEALLOC,nbOfTuples+1,1);
6453 * Returns two new DataArrayInt instances whose contents is computed from that of \a this and \a listOfIds arrays as follows.
6454 * \a this is expected to be an offset format ( as returned by DataArrayInt::computeOffsetsFull ) that is to say with one component
6455 * and ** sorted strictly increasingly **. \a listOfIds is expected to be sorted ascendingly (not strictly needed for \a listOfIds).
6456 * This methods searches in \a this, considered as a set of contiguous \c this->getNumberOfComponents() ranges, all ids in \a listOfIds
6457 * filling completely one of the ranges in \a this.
6459 * \param [in] listOfIds a list of ids that has to be sorted ascendingly.
6460 * \param [out] rangeIdsFetched the range ids fetched
6461 * \param [out] idsInInputListThatFetch contains the list of ids in \a listOfIds that are \b fully included in a range in \a this. So
6462 * \a idsInInputListThatFetch is a part of input \a listOfIds.
6464 * \sa DataArrayInt::computeOffsetsFull
6467 * - \a this : [0,3,7,9,15,18]
6468 * - \a listOfIds contains [0,1,2,3,7,8,15,16,17]
6469 * - \a rangeIdsFetched result array: [0,2,4]
6470 * - \a idsInInputListThatFetch result array: [0,1,2,7,8,15,16,17]
6471 * In this example id 3 in input \a listOfIds is alone so it do not appear in output \a idsInInputListThatFetch.
6474 void DataArrayInt::findIdsRangesInListOfIds(const DataArrayInt *listOfIds, DataArrayInt *& rangeIdsFetched, DataArrayInt *& idsInInputListThatFetch) const
6477 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : input list of ids is null !");
6478 listOfIds->checkAllocated(); checkAllocated();
6479 if(listOfIds->getNumberOfComponents()!=1)
6480 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : input list of ids must have exactly one component !");
6481 if(getNumberOfComponents()!=1)
6482 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : this must have exactly one component !");
6483 MCAuto<DataArrayInt> ret0=DataArrayInt::New(); ret0->alloc(0,1);
6484 MCAuto<DataArrayInt> ret1=DataArrayInt::New(); ret1->alloc(0,1);
6485 const int *tupEnd(listOfIds->end()),*offBg(begin()),*offEnd(end()-1);
6486 const int *tupPtr(listOfIds->begin()),*offPtr(offBg);
6487 while(tupPtr!=tupEnd && offPtr!=offEnd)
6489 if(*tupPtr==*offPtr)
6492 while(i<offPtr[1] && *tupPtr==i && tupPtr!=tupEnd) { i++; tupPtr++; }
6495 ret0->pushBackSilent((int)std::distance(offBg,offPtr));
6496 ret1->pushBackValsSilent(tupPtr-(offPtr[1]-offPtr[0]),tupPtr);
6501 { if(*tupPtr<*offPtr) tupPtr++; else offPtr++; }
6503 rangeIdsFetched=ret0.retn();
6504 idsInInputListThatFetch=ret1.retn();
6508 * Returns a new DataArrayInt whose contents is computed from that of \a this and \a
6509 * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
6510 * "index" array of a "iota" array, thus, whose each element gives an index of a group
6511 * beginning within the "iota" array. And \a this is a one-dimensional array
6512 * considered as a selector of groups described by \a offsets to include into the result array.
6513 * \throw If \a offsets is NULL.
6514 * \throw If \a offsets is not allocated.
6515 * \throw If \a offsets->getNumberOfComponents() != 1.
6516 * \throw If \a offsets is not monotonically increasing.
6517 * \throw If \a this is not allocated.
6518 * \throw If \a this->getNumberOfComponents() != 1.
6519 * \throw If any element of \a this is not a valid index for \a offsets array.
6522 * - \a this: [0,2,3]
6523 * - \a offsets: [0,3,6,10,14,20]
6524 * - result array: [0,1,2,6,7,8,9,10,11,12,13] == <br>
6525 * \c range(0,3) + \c range(6,10) + \c range(10,14) ==<br>
6526 * \c range( \a offsets[ \a this[0] ], offsets[ \a this[0]+1 ]) +
6527 * \c range( \a offsets[ \a this[1] ], offsets[ \a this[1]+1 ]) +
6528 * \c range( \a offsets[ \a this[2] ], offsets[ \a this[2]+1 ])
6530 DataArrayInt *DataArrayInt::buildExplicitArrByRanges(const DataArrayInt *offsets) const
6533 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : DataArrayInt pointer in input is NULL !");
6535 if(getNumberOfComponents()!=1)
6536 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : only single component allowed !");
6537 offsets->checkAllocated();
6538 if(offsets->getNumberOfComponents()!=1)
6539 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : input array should have only single component !");
6540 int othNbTuples=offsets->getNumberOfTuples()-1;
6541 int nbOfTuples=getNumberOfTuples();
6542 int retNbOftuples=0;
6543 const int *work=getConstPointer();
6544 const int *offPtr=offsets->getConstPointer();
6545 for(int i=0;i<nbOfTuples;i++)
6548 if(val>=0 && val<othNbTuples)
6550 int delta=offPtr[val+1]-offPtr[val];
6552 retNbOftuples+=delta;
6555 std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << val << " of offset array has a delta < 0 !";
6556 throw INTERP_KERNEL::Exception(oss.str().c_str());
6561 std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << i << " in this contains " << val;
6562 oss << " whereas offsets array is of size " << othNbTuples+1 << " !";
6563 throw INTERP_KERNEL::Exception(oss.str().c_str());
6566 MCAuto<DataArrayInt> ret=DataArrayInt::New();
6567 ret->alloc(retNbOftuples,1);
6568 int *retPtr=ret->getPointer();
6569 for(int i=0;i<nbOfTuples;i++)
6572 int start=offPtr[val];
6573 int off=offPtr[val+1]-start;
6574 for(int j=0;j<off;j++,retPtr++)
6581 * Returns a new DataArrayInt whose contents is computed using \a this that must be a
6582 * scaled array (monotonically increasing).
6583 from that of \a this and \a
6584 * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
6585 * "index" array of a "iota" array, thus, whose each element gives an index of a group
6586 * beginning within the "iota" array. And \a this is a one-dimensional array
6587 * considered as a selector of groups described by \a offsets to include into the result array.
6588 * \throw If \a is NULL.
6589 * \throw If \a this is not allocated.
6590 * \throw If \a this->getNumberOfComponents() != 1.
6591 * \throw If \a this->getNumberOfTuples() == 0.
6592 * \throw If \a this is not monotonically increasing.
6593 * \throw If any element of ids in ( \a bg \a stop \a step ) points outside the scale in \a this.
6596 * - \a bg , \a stop and \a step : (0,5,2)
6597 * - \a this: [0,3,6,10,14,20]
6598 * - result array: [0,0,0, 2,2,2,2, 4,4,4,4,4,4] == <br>
6600 DataArrayInt *DataArrayInt::buildExplicitArrOfSliceOnScaledArr(int bg, int stop, int step) const
6603 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : not allocated array !");
6604 if(getNumberOfComponents()!=1)
6605 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of components is expected to be equal to one !");
6606 int nbOfTuples(getNumberOfTuples());
6608 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of tuples must be != 0 !");
6609 const int *ids(begin());
6610 int nbOfEltsInSlc(GetNumberOfItemGivenBESRelative(bg,stop,step,"DataArrayInt::buildExplicitArrOfSliceOnScaledArr")),sz(0),pos(bg);
6611 for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
6613 if(pos>=0 && pos<nbOfTuples-1)
6615 int delta(ids[pos+1]-ids[pos]);
6619 std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " and at this pos this is not monotonically increasing !";
6620 throw INTERP_KERNEL::Exception(oss.str().c_str());
6625 std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " should be in [0," << nbOfTuples-1 << ") !";
6626 throw INTERP_KERNEL::Exception(oss.str().c_str());
6629 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
6630 int *retPtr(ret->getPointer());
6632 for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
6634 int delta(ids[pos+1]-ids[pos]);
6635 for(int j=0;j<delta;j++,retPtr++)
6642 * 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.
6643 * 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
6644 * in tuple **i** of returned DataArrayInt.
6645 * If ranges overlapped (in theory it should not) this method do not detect it and always returns the first range.
6647 * 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)]
6648 * The return DataArrayInt will contain : **[0,4,1,2,2,3]**
6650 * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
6651 * for lower value included and 2nd component is the upper value of corresponding range **excluded**.
6652 * \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
6653 * is thrown if no ranges in \a ranges contains value in \a this.
6655 * \sa DataArrayInt::findIdInRangeForEachTuple
6657 DataArrayInt *DataArrayInt::findRangeIdForEachTuple(const DataArrayInt *ranges) const
6660 throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : null input pointer !");
6661 if(ranges->getNumberOfComponents()!=2)
6662 throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : input DataArrayInt instance should have 2 components !");
6664 if(getNumberOfComponents()!=1)
6665 throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : this should have only one component !");
6666 int nbTuples=getNumberOfTuples();
6667 MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
6668 int nbOfRanges=ranges->getNumberOfTuples();
6669 const int *rangesPtr=ranges->getConstPointer();
6670 int *retPtr=ret->getPointer();
6671 const int *inPtr=getConstPointer();
6672 for(int i=0;i<nbTuples;i++,retPtr++)
6676 for(int j=0;j<nbOfRanges && !found;j++)
6677 if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
6678 { *retPtr=j; found=true; }
6683 std::ostringstream oss; oss << "DataArrayInt::findRangeIdForEachTuple : tuple #" << i << " not found by any ranges !";
6684 throw INTERP_KERNEL::Exception(oss.str().c_str());
6691 * 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.
6692 * 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
6693 * in tuple **i** of returned DataArrayInt.
6694 * If ranges overlapped (in theory it should not) this method do not detect it and always returns the sub position of the first range.
6696 * 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)]
6697 * The return DataArrayInt will contain : **[1,2,4,0,2,2]**
6698 * This method is often called in pair with DataArrayInt::findRangeIdForEachTuple method.
6700 * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
6701 * for lower value included and 2nd component is the upper value of corresponding range **excluded**.
6702 * \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
6703 * is thrown if no ranges in \a ranges contains value in \a this.
6704 * \sa DataArrayInt::findRangeIdForEachTuple
6706 DataArrayInt *DataArrayInt::findIdInRangeForEachTuple(const DataArrayInt *ranges) const
6709 throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : null input pointer !");
6710 if(ranges->getNumberOfComponents()!=2)
6711 throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : input DataArrayInt instance should have 2 components !");
6713 if(getNumberOfComponents()!=1)
6714 throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : this should have only one component !");
6715 int nbTuples=getNumberOfTuples();
6716 MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
6717 int nbOfRanges=ranges->getNumberOfTuples();
6718 const int *rangesPtr=ranges->getConstPointer();
6719 int *retPtr=ret->getPointer();
6720 const int *inPtr=getConstPointer();
6721 for(int i=0;i<nbTuples;i++,retPtr++)
6725 for(int j=0;j<nbOfRanges && !found;j++)
6726 if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
6727 { *retPtr=val-rangesPtr[2*j]; found=true; }
6732 std::ostringstream oss; oss << "DataArrayInt::findIdInRangeForEachTuple : tuple #" << i << " not found by any ranges !";
6733 throw INTERP_KERNEL::Exception(oss.str().c_str());
6740 * \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).
6741 * 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).
6742 * 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 !
6743 * If this method has correctly worked, \a this will be able to be considered as a linked list.
6744 * This method does nothing if number of tuples is lower of equal to 1.
6746 * This method is useful for users having an unstructured mesh having only SEG2 to rearrange internaly the connectibity without any coordinates consideration.
6748 * \sa MEDCouplingUMesh::orderConsecutiveCells1D, DataArrayInt::fromLinkedListOfPairToList
6750 void DataArrayInt::sortEachPairToMakeALinkedList()
6753 if(getNumberOfComponents()!=2)
6754 throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : Only works on DataArrayInt instance with nb of components equal to 2 !");
6755 int nbOfTuples(getNumberOfTuples());
6758 int *conn(getPointer());
6759 for(int i=1;i<nbOfTuples;i++,conn+=2)
6763 if(conn[2]==conn[3])
6765 std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " presence of a pair filled with same ids !";
6766 throw INTERP_KERNEL::Exception(oss.str().c_str());
6768 if(conn[2]!=conn[1] && conn[3]==conn[1] && conn[2]!=conn[0])
6769 std::swap(conn[2],conn[3]);
6770 //not(conn[2]==conn[1] && conn[3]!=conn[1] && conn[3]!=conn[0])
6771 if(conn[2]!=conn[1] || conn[3]==conn[1] || conn[3]==conn[0])
6773 std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " something is invalid !";
6774 throw INTERP_KERNEL::Exception(oss.str().c_str());
6779 if(conn[0]==conn[1] || conn[2]==conn[3])
6780 throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : In the 2 first tuples presence of a pair filled with same ids !");
6783 s.insert(conn,conn+4);
6785 throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : This can't be considered as a linked list regarding 2 first tuples !");
6786 if(std::count(conn,conn+4,conn[0])==2)
6791 if(conn[2]==conn[0])
6795 std::copy(tmp,tmp+4,conn);
6798 {//here we are sure to have (std::count(conn,conn+4,conn[1])==2)
6799 if(conn[1]==conn[3])
6800 std::swap(conn[2],conn[3]);
6807 * \a this is expected to be a correctly linked list of pairs.
6809 * \sa DataArrayInt::sortEachPairToMakeALinkedList
6811 MCAuto<DataArrayInt> DataArrayInt::fromLinkedListOfPairToList() const
6814 checkNbOfComps(2,"DataArrayInt::fromLinkedListOfPairToList : this is expected to have 2 components");
6815 int nbTuples(getNumberOfTuples());
6817 throw INTERP_KERNEL::Exception("DataArrayInt::fromLinkedListOfPairToList : no tuples in this ! Not a linked list !");
6818 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbTuples+1,1);
6819 const int *thisPtr(begin());
6820 int *retPtr(ret->getPointer());
6821 retPtr[0]=thisPtr[0];
6822 for(int i=0;i<nbTuples;i++)
6824 retPtr[i+1]=thisPtr[2*i+1];
6826 if(thisPtr[2*i+1]!=thisPtr[2*(i+1)+0])
6828 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 ?";
6829 throw INTERP_KERNEL::Exception(oss.str());
6836 * This method returns all different values found in \a this. This method throws if \a this has not been allocated.
6837 * But the number of components can be different from one.
6838 * \return a newly allocated array (that should be dealt by the caller) containing different values in \a this.
6840 DataArrayInt *DataArrayInt::getDifferentValues() const
6844 ret.insert(begin(),end());
6845 MCAuto<DataArrayInt> ret2=DataArrayInt::New(); ret2->alloc((int)ret.size(),1);
6846 std::copy(ret.begin(),ret.end(),ret2->getPointer());
6851 * This method is a refinement of DataArrayInt::getDifferentValues because it returns not only different values in \a this but also, for each of
6852 * them it tells which tuple id have this id.
6853 * This method works only on arrays with one component (if it is not the case call DataArrayInt::rearrange(1) ).
6854 * This method returns two arrays having same size.
6855 * 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.
6856 * 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]]
6858 std::vector<DataArrayInt *> DataArrayInt::partitionByDifferentValues(std::vector<int>& differentIds) const
6861 if(getNumberOfComponents()!=1)
6862 throw INTERP_KERNEL::Exception("DataArrayInt::partitionByDifferentValues : this should have only one component !");
6864 std::map<int,int> m,m2,m3;
6865 for(const int *w=begin();w!=end();w++)
6867 differentIds.resize(m.size());
6868 std::vector<DataArrayInt *> ret(m.size());
6869 std::vector<int *> retPtr(m.size());
6870 for(std::map<int,int>::const_iterator it=m.begin();it!=m.end();it++,id++)
6873 ret[id]=DataArrayInt::New();
6874 ret[id]->alloc((*it).second,1);
6875 retPtr[id]=ret[id]->getPointer();
6876 differentIds[id]=(*it).first;
6879 for(const int *w=begin();w!=end();w++,id++)
6881 retPtr[m2[*w]][m3[*w]++]=id;
6887 * This method split ids in [0, \c this->getNumberOfTuples() ) using \a this array as a field of weight (>=0 each).
6888 * The aim of this method is to return a set of \a nbOfSlices chunk of contiguous ids as balanced as possible.
6890 * \param [in] nbOfSlices - number of slices expected.
6891 * \return - a vector having a size equal to \a nbOfSlices giving the start (included) and the stop (excluded) of each chunks.
6893 * \sa DataArray::GetSlice
6894 * \throw If \a this is not allocated or not with exactly one component.
6895 * \throw If an element in \a this if < 0.
6897 std::vector< std::pair<int,int> > DataArrayInt::splitInBalancedSlices(int nbOfSlices) const
6899 if(!isAllocated() || getNumberOfComponents()!=1)
6900 throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : this array should have number of components equal to one and must be allocated !");
6902 throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : number of slices must be >= 1 !");
6903 int sum(accumulate(0)),nbOfTuples(getNumberOfTuples());
6904 int sumPerSlc(sum/nbOfSlices),pos(0);
6905 const int *w(begin());
6906 std::vector< std::pair<int,int> > ret(nbOfSlices);
6907 for(int i=0;i<nbOfSlices;i++)
6909 std::pair<int,int> p(pos,-1);
6911 while(locSum<sumPerSlc && pos<nbOfTuples) { pos++; locSum+=*w++; }
6915 p.second=nbOfTuples;
6922 * Returns a new DataArrayInt that is a modulus of two given arrays. There are 3
6924 * 1. The arrays have same number of tuples and components. Then each value of
6925 * the result array (_a_) is a division of the corresponding values of \a a1 and
6926 * \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, j ].
6927 * 2. The arrays have same number of tuples and one array, say _a2_, has one
6929 * _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, 0 ].
6930 * 3. The arrays have same number of components and one array, say _a2_, has one
6932 * _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ 0, j ].
6934 * Info on components is copied either from the first array (in the first case) or from
6935 * the array with maximal number of elements (getNbOfElems()).
6936 * \warning No check of division by zero is performed!
6937 * \param [in] a1 - a dividend array.
6938 * \param [in] a2 - a divisor array.
6939 * \return DataArrayInt * - the new instance of DataArrayInt.
6940 * The caller is to delete this result array using decrRef() as it is no more
6942 * \throw If either \a a1 or \a a2 is NULL.
6943 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
6944 * \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
6945 * none of them has number of tuples or components equal to 1.
6947 DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt *a2)
6950 throw INTERP_KERNEL::Exception("DataArrayInt::Modulus : input DataArrayInt instance is NULL !");
6951 int nbOfTuple1=a1->getNumberOfTuples();
6952 int nbOfTuple2=a2->getNumberOfTuples();
6953 int nbOfComp1=a1->getNumberOfComponents();
6954 int nbOfComp2=a2->getNumberOfComponents();
6955 if(nbOfTuple2==nbOfTuple1)
6957 if(nbOfComp1==nbOfComp2)
6959 MCAuto<DataArrayInt> ret=DataArrayInt::New();
6960 ret->alloc(nbOfTuple2,nbOfComp1);
6961 std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::modulus<int>());
6962 ret->copyStringInfoFrom(*a1);
6965 else if(nbOfComp2==1)
6967 MCAuto<DataArrayInt> ret=DataArrayInt::New();
6968 ret->alloc(nbOfTuple1,nbOfComp1);
6969 const int *a2Ptr=a2->getConstPointer();
6970 const int *a1Ptr=a1->getConstPointer();
6971 int *res=ret->getPointer();
6972 for(int i=0;i<nbOfTuple1;i++)
6973 res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::modulus<int>(),a2Ptr[i]));
6974 ret->copyStringInfoFrom(*a1);
6979 a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
6983 else if(nbOfTuple2==1)
6985 a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
6986 MCAuto<DataArrayInt> ret=DataArrayInt::New();
6987 ret->alloc(nbOfTuple1,nbOfComp1);
6988 const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
6989 int *pt=ret->getPointer();
6990 for(int i=0;i<nbOfTuple1;i++)
6991 pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::modulus<int>());
6992 ret->copyStringInfoFrom(*a1);
6997 a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Modulus !");//will always throw an exception
7003 * Modify \a this array so that each value becomes a modulus of division of this value by
7004 * a value of another DataArrayInt. There are 3 valid cases.
7005 * 1. The arrays have same number of tuples and components. Then each value of
7006 * \a this array is divided by the corresponding value of \a other one, i.e.:
7007 * _a_ [ i, j ] %= _other_ [ i, j ].
7008 * 2. The arrays have same number of tuples and \a other array has one component. Then
7009 * _a_ [ i, j ] %= _other_ [ i, 0 ].
7010 * 3. The arrays have same number of components and \a other array has one tuple. Then
7011 * _a_ [ i, j ] %= _a2_ [ 0, j ].
7013 * \warning No check of division by zero is performed!
7014 * \param [in] other - a divisor array.
7015 * \throw If \a other is NULL.
7016 * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
7017 * \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
7018 * \a other has number of both tuples and components not equal to 1.
7020 void DataArrayInt::modulusEqual(const DataArrayInt *other)
7023 throw INTERP_KERNEL::Exception("DataArrayInt::modulusEqual : input DataArrayInt instance is NULL !");
7024 const char *msg="Nb of tuples mismatch for DataArrayInt::modulusEqual !";
7025 checkAllocated(); other->checkAllocated();
7026 int nbOfTuple=getNumberOfTuples();
7027 int nbOfTuple2=other->getNumberOfTuples();
7028 int nbOfComp=getNumberOfComponents();
7029 int nbOfComp2=other->getNumberOfComponents();
7030 if(nbOfTuple==nbOfTuple2)
7032 if(nbOfComp==nbOfComp2)
7034 std::transform(begin(),end(),other->begin(),getPointer(),std::modulus<int>());
7036 else if(nbOfComp2==1)
7038 if(nbOfComp2==nbOfComp)
7040 int *ptr=getPointer();
7041 const int *ptrc=other->getConstPointer();
7042 for(int i=0;i<nbOfTuple;i++)
7043 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::modulus<int>(),*ptrc++));
7046 throw INTERP_KERNEL::Exception(msg);
7049 throw INTERP_KERNEL::Exception(msg);
7051 else if(nbOfTuple2==1)
7053 int *ptr=getPointer();
7054 const int *ptrc=other->getConstPointer();
7055 for(int i=0;i<nbOfTuple;i++)
7056 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::modulus<int>());
7059 throw INTERP_KERNEL::Exception(msg);
7064 * Returns a new DataArrayInt that is the result of pow of two given arrays. There are 3
7067 * \param [in] a1 - an array to pow up.
7068 * \param [in] a2 - another array to sum up.
7069 * \return DataArrayInt * - the new instance of DataArrayInt.
7070 * The caller is to delete this result array using decrRef() as it is no more
7072 * \throw If either \a a1 or \a a2 is NULL.
7073 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
7074 * \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
7075 * \throw If there is a negative value in \a a2.
7077 DataArrayInt *DataArrayInt::Pow(const DataArrayInt *a1, const DataArrayInt *a2)
7080 throw INTERP_KERNEL::Exception("DataArrayInt::Pow : at least one of input instances is null !");
7081 int nbOfTuple=a1->getNumberOfTuples();
7082 int nbOfTuple2=a2->getNumberOfTuples();
7083 int nbOfComp=a1->getNumberOfComponents();
7084 int nbOfComp2=a2->getNumberOfComponents();
7085 if(nbOfTuple!=nbOfTuple2)
7086 throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of tuples mismatches !");
7087 if(nbOfComp!=1 || nbOfComp2!=1)
7088 throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of components of both arrays must be equal to 1 !");
7089 MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuple,1);
7090 const int *ptr1(a1->begin()),*ptr2(a2->begin());
7091 int *ptr=ret->getPointer();
7092 for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
7097 for(int j=0;j<*ptr2;j++)
7103 std::ostringstream oss; oss << "DataArrayInt::Pow : on tuple #" << i << " of a2 value is < 0 (" << *ptr2 << ") !";
7104 throw INTERP_KERNEL::Exception(oss.str().c_str());
7111 * Apply pow on values of another DataArrayInt to values of \a this one.
7113 * \param [in] other - an array to pow to \a this one.
7114 * \throw If \a other is NULL.
7115 * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
7116 * \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
7117 * \throw If there is a negative value in \a other.
7119 void DataArrayInt::powEqual(const DataArrayInt *other)
7122 throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : input instance is null !");
7123 int nbOfTuple=getNumberOfTuples();
7124 int nbOfTuple2=other->getNumberOfTuples();
7125 int nbOfComp=getNumberOfComponents();
7126 int nbOfComp2=other->getNumberOfComponents();
7127 if(nbOfTuple!=nbOfTuple2)
7128 throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of tuples mismatches !");
7129 if(nbOfComp!=1 || nbOfComp2!=1)
7130 throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of components of both arrays must be equal to 1 !");
7131 int *ptr=getPointer();
7132 const int *ptrc=other->begin();
7133 for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
7138 for(int j=0;j<*ptrc;j++)
7144 std::ostringstream oss; oss << "DataArrayInt::powEqual : on tuple #" << i << " of other value is < 0 (" << *ptrc << ") !";
7145 throw INTERP_KERNEL::Exception(oss.str().c_str());
7152 * Returns a C array which is a renumbering map in "Old to New" mode for the input array.
7153 * This map, if applied to \a start array, would make it sorted. For example, if
7154 * \a start array contents are [9,10,0,6,4,11,3,7] then the contents of the result array is
7155 * [5,6,0,3,2,7,1,4].
7156 * \param [in] start - pointer to the first element of the array for which the
7157 * permutation map is computed.
7158 * \param [in] end - pointer specifying the end of the array \a start, so that
7159 * the last value of \a start is \a end[ -1 ].
7160 * \return int * - the result permutation array that the caller is to delete as it is no
7162 * \throw If there are equal values in the input array.
7164 int *DataArrayInt::CheckAndPreparePermutation(const int *start, const int *end)
7166 std::size_t sz=std::distance(start,end);
7167 int *ret=(int *)malloc(sz*sizeof(int));
7168 int *work=new int[sz];
7169 std::copy(start,end,work);
7170 std::sort(work,work+sz);
7171 if(std::unique(work,work+sz)!=work+sz)
7175 throw INTERP_KERNEL::Exception("Some elements are equals in the specified array !");
7177 std::map<int,int> m;
7178 for(int *workPt=work;workPt!=work+sz;workPt++)
7179 m[*workPt]=(int)std::distance(work,workPt);
7181 for(const int *iter=start;iter!=end;iter++,iter2++)
7188 * Returns a new DataArrayInt containing an arithmetic progression
7189 * that is equal to the sequence returned by Python \c range(\a begin,\a end,\a step )
7191 * \param [in] begin - the start value of the result sequence.
7192 * \param [in] end - limiting value, so that every value of the result array is less than
7194 * \param [in] step - specifies the increment or decrement.
7195 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7196 * array using decrRef() as it is no more needed.
7197 * \throw If \a step == 0.
7198 * \throw If \a end < \a begin && \a step > 0.
7199 * \throw If \a end > \a begin && \a step < 0.
7201 DataArrayInt *DataArrayInt::Range(int begin, int end, int step)
7203 int nbOfTuples=GetNumberOfItemGivenBESRelative(begin,end,step,"DataArrayInt::Range");
7204 MCAuto<DataArrayInt> ret=DataArrayInt::New();
7205 ret->alloc(nbOfTuples,1);
7206 int *ptr=ret->getPointer();
7209 for(int i=begin;i<end;i+=step,ptr++)
7214 for(int i=begin;i>end;i+=step,ptr++)
7221 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
7224 void DataArrayInt::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
7229 tinyInfo[0]=getNumberOfTuples();
7230 tinyInfo[1]=getNumberOfComponents();
7240 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
7243 void DataArrayInt::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
7247 int nbOfCompo=getNumberOfComponents();
7248 tinyInfo.resize(nbOfCompo+1);
7249 tinyInfo[0]=getName();
7250 for(int i=0;i<nbOfCompo;i++)
7251 tinyInfo[i+1]=getInfoOnComponent(i);
7256 tinyInfo[0]=getName();
7261 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
7262 * This method returns if a feeding is needed.
7264 bool DataArrayInt::resizeForUnserialization(const std::vector<int>& tinyInfoI)
7266 int nbOfTuple=tinyInfoI[0];
7267 int nbOfComp=tinyInfoI[1];
7268 if(nbOfTuple!=-1 || nbOfComp!=-1)
7270 alloc(nbOfTuple,nbOfComp);
7277 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
7278 * This method returns if a feeding is needed.
7280 void DataArrayInt::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
7282 setName(tinyInfoS[0]);
7285 int nbOfCompo=tinyInfoI[1];
7286 for(int i=0;i<nbOfCompo;i++)
7287 setInfoOnComponent(i,tinyInfoS[i+1]);
7291 DataArrayIntIterator::DataArrayIntIterator(DataArrayInt *da):DataArrayIterator<int>(da)
7295 DataArrayIntTuple::DataArrayIntTuple(int *pt, int nbOfComp):DataArrayTuple<int>(pt,nbOfComp)
7299 std::string DataArrayIntTuple::repr() const
7301 std::ostringstream oss; oss << "(";
7302 for(int i=0;i<_nb_of_compo-1;i++)
7303 oss << _pt[i] << ", ";
7304 oss << _pt[_nb_of_compo-1] << ")";
7308 int DataArrayIntTuple::intValue() const
7310 return this->zeValue();
7314 * This method returns a newly allocated instance the caller should dealed with by a MEDCoupling::DataArrayInt::decrRef.
7315 * This method performs \b no copy of data. The content is only referenced using MEDCoupling::DataArrayInt::useArray with ownership set to \b false.
7316 * 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
7317 * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
7319 DataArrayInt *DataArrayIntTuple::buildDAInt(int nbOfTuples, int nbOfCompo) const
7321 return this->buildDA(nbOfTuples,nbOfCompo);