1 // Copyright (C) 2007-2016 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 // Author : Anthony Geay (EDF R&D)
21 #include "MEDCouplingMemArray.txx"
24 #include "GenMathFormulae.hxx"
25 #include "InterpKernelAutoPtr.hxx"
26 #include "InterpKernelExprParser.hxx"
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>;
48 template class MEDCoupling::DataArrayDiscrete<Int32>;
49 template class MEDCoupling::DataArrayDiscreteSigned<Int32>;
51 template<int SPACEDIM>
52 void DataArrayDouble::findCommonTuplesAlg(const double *bbox, int nbNodes, int limitNodeId, double prec, DataArrayInt *c, DataArrayInt *cI) const
54 const double *coordsPtr=getConstPointer();
55 BBTreePts<SPACEDIM,int> myTree(bbox,0,0,nbNodes,prec);
56 std::vector<bool> isDone(nbNodes);
57 for(int i=0;i<nbNodes;i++)
61 std::vector<int> intersectingElems;
62 myTree.getElementsAroundPoint(coordsPtr+i*SPACEDIM,intersectingElems);
63 if(intersectingElems.size()>1)
65 std::vector<int> commonNodes;
66 for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
70 commonNodes.push_back(*it);
73 if(!commonNodes.empty())
75 cI->pushBackSilent(cI->back()+(int)commonNodes.size()+1);
77 c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
84 template<int SPACEDIM>
85 void DataArrayDouble::FindTupleIdsNearTuplesAlg(const BBTreePts<SPACEDIM,int>& myTree, const double *pos, int nbOfTuples, double eps,
86 DataArrayInt *c, DataArrayInt *cI)
88 for(int i=0;i<nbOfTuples;i++)
90 std::vector<int> intersectingElems;
91 myTree.getElementsAroundPoint(pos+i*SPACEDIM,intersectingElems);
92 std::vector<int> commonNodes;
93 for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
94 commonNodes.push_back(*it);
95 cI->pushBackSilent(cI->back()+(int)commonNodes.size());
96 c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
100 template<int SPACEDIM>
101 void DataArrayDouble::FindClosestTupleIdAlg(const BBTreePts<SPACEDIM,int>& myTree, double dist, const double *pos, int nbOfTuples, const double *thisPt, int thisNbOfTuples, int *res)
103 double distOpt(dist);
104 const double *p(pos);
106 for(int i=0;i<nbOfTuples;i++,p+=SPACEDIM,r++)
111 double ret=myTree.getElementsAroundPoint2(p,distOpt,elem);
112 if(ret!=std::numeric_limits<double>::max())
114 distOpt=std::max(ret,1e-4);
119 { distOpt=2*distOpt; continue; }
124 int DataArray::EffectiveCircPerm(int nbOfShift, int nbOfTuples)
127 throw INTERP_KERNEL::Exception("DataArray::EffectiveCircPerm : number of tuples is expected to be > 0 !");
130 return nbOfShift%nbOfTuples;
136 return nbOfTuples-tmp;
140 std::size_t DataArray::getHeapMemorySizeWithoutChildren() const
142 std::size_t sz1=_name.capacity();
143 std::size_t sz2=_info_on_compo.capacity();
145 for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
146 sz3+=(*it).capacity();
150 std::vector<const BigMemoryObject *> DataArray::getDirectChildrenWithNull() const
152 return std::vector<const BigMemoryObject *>();
156 * Sets the attribute \a _name of \a this array.
157 * See \ref MEDCouplingArrayBasicsName "DataArrays infos" for more information.
158 * \param [in] name - new array name
160 void DataArray::setName(const std::string& name)
166 * Copies textual data from an \a other DataArray. The copied data are
167 * - the name attribute,
168 * - the information of components.
170 * For more information on these data see \ref MEDCouplingArrayBasicsName "DataArrays infos".
172 * \param [in] other - another instance of DataArray to copy the textual data from.
173 * \throw If number of components of \a this array differs from that of the \a other.
175 void DataArray::copyStringInfoFrom(const DataArray& other)
177 if(_info_on_compo.size()!=other._info_on_compo.size())
178 throw INTERP_KERNEL::Exception("Size of arrays mismatches on copyStringInfoFrom !");
180 _info_on_compo=other._info_on_compo;
183 void DataArray::copyPartOfStringInfoFrom(const DataArray& other, const std::vector<int>& compoIds)
185 int nbOfCompoOth=other.getNumberOfComponents();
186 std::size_t newNbOfCompo=compoIds.size();
187 for(std::size_t i=0;i<newNbOfCompo;i++)
188 if(compoIds[i]>=nbOfCompoOth || compoIds[i]<0)
190 std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompoOth << ")";
191 throw INTERP_KERNEL::Exception(oss.str().c_str());
193 for(std::size_t i=0;i<newNbOfCompo;i++)
194 setInfoOnComponent((int)i,other.getInfoOnComponent(compoIds[i]));
197 void DataArray::copyPartOfStringInfoFrom2(const std::vector<int>& compoIds, const DataArray& other)
199 std::size_t nbOfCompo(getNumberOfComponents());
200 std::size_t partOfCompoToSet=compoIds.size();
201 if(partOfCompoToSet!=other.getNumberOfComponents())
202 throw INTERP_KERNEL::Exception("Given compoIds has not the same size as number of components of given array !");
203 for(std::size_t i=0;i<partOfCompoToSet;i++)
204 if(compoIds[i]>=(int)nbOfCompo || compoIds[i]<0)
206 std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompo << ")";
207 throw INTERP_KERNEL::Exception(oss.str().c_str());
209 for(std::size_t i=0;i<partOfCompoToSet;i++)
210 setInfoOnComponent(compoIds[i],other.getInfoOnComponent((int)i));
213 bool DataArray::areInfoEqualsIfNotWhy(const DataArray& other, std::string& reason) const
215 std::ostringstream oss;
216 if(_name!=other._name)
218 oss << "Names DataArray mismatch : this name=\"" << _name << " other name=\"" << other._name << "\" !";
222 if(_info_on_compo!=other._info_on_compo)
224 oss << "Components DataArray mismatch : \nThis components=";
225 for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
226 oss << "\"" << *it << "\",";
227 oss << "\nOther components=";
228 for(std::vector<std::string>::const_iterator it=other._info_on_compo.begin();it!=other._info_on_compo.end();it++)
229 oss << "\"" << *it << "\",";
237 * Compares textual information of \a this DataArray with that of an \a other one.
238 * The compared data are
239 * - the name attribute,
240 * - the information of components.
242 * For more information on these data see \ref MEDCouplingArrayBasicsName "DataArrays infos".
243 * \param [in] other - another instance of DataArray to compare the textual data of.
244 * \return bool - \a true if the textual information is same, \a false else.
246 bool DataArray::areInfoEquals(const DataArray& other) const
249 return areInfoEqualsIfNotWhy(other,tmp);
252 void DataArray::reprWithoutNameStream(std::ostream& stream) const
254 stream << "Number of components : "<< getNumberOfComponents() << "\n";
255 stream << "Info of these components : ";
256 for(std::vector<std::string>::const_iterator iter=_info_on_compo.begin();iter!=_info_on_compo.end();iter++)
257 stream << "\"" << *iter << "\" ";
261 std::string DataArray::cppRepr(const std::string& varName) const
263 std::ostringstream ret;
264 reprCppStream(varName,ret);
269 * Sets information on all components. To know more on format of this information
270 * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
271 * \param [in] info - a vector of strings.
272 * \throw If size of \a info differs from the number of components of \a this.
274 void DataArray::setInfoOnComponents(const std::vector<std::string>& info)
276 if(getNumberOfComponents()!=info.size())
278 std::ostringstream oss; oss << "DataArray::setInfoOnComponents : input is of size " << info.size() << " whereas number of components is equal to " << getNumberOfComponents() << " !";
279 throw INTERP_KERNEL::Exception(oss.str().c_str());
285 * This method is only a dispatcher towards DataArrayDouble::setPartOfValues3, DataArrayInt::setPartOfValues3, DataArrayChar::setPartOfValues3 depending on the true
286 * type of \a this and \a aBase.
288 * \throw If \a aBase and \a this do not have the same type.
290 * \sa DataArrayDouble::setPartOfValues3, DataArrayInt::setPartOfValues3, DataArrayChar::setPartOfValues3.
292 void DataArray::setPartOfValuesBase3(const DataArray *aBase, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
295 throw INTERP_KERNEL::Exception("DataArray::setPartOfValuesBase3 : input aBase object is NULL !");
296 DataArrayDouble *this1(dynamic_cast<DataArrayDouble *>(this));
297 DataArrayInt *this2(dynamic_cast<DataArrayInt *>(this));
298 DataArrayChar *this3(dynamic_cast<DataArrayChar *>(this));
299 const DataArrayDouble *a1(dynamic_cast<const DataArrayDouble *>(aBase));
300 const DataArrayInt *a2(dynamic_cast<const DataArrayInt *>(aBase));
301 const DataArrayChar *a3(dynamic_cast<const DataArrayChar *>(aBase));
304 this1->setPartOfValues3(a1,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
309 this2->setPartOfValues3(a2,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
314 this3->setPartOfValues3(a3,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
317 throw INTERP_KERNEL::Exception("DataArray::setPartOfValuesBase3 : input aBase object and this do not have the same type !");
320 std::vector<std::string> DataArray::getVarsOnComponent() const
322 int nbOfCompo=(int)_info_on_compo.size();
323 std::vector<std::string> ret(nbOfCompo);
324 for(int i=0;i<nbOfCompo;i++)
325 ret[i]=getVarOnComponent(i);
329 std::vector<std::string> DataArray::getUnitsOnComponent() const
331 int nbOfCompo=(int)_info_on_compo.size();
332 std::vector<std::string> ret(nbOfCompo);
333 for(int i=0;i<nbOfCompo;i++)
334 ret[i]=getUnitOnComponent(i);
339 * Returns information on a component specified by an index.
340 * To know more on format of this information
341 * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
342 * \param [in] i - the index (zero based) of the component of interest.
343 * \return std::string - a string containing the information on \a i-th component.
344 * \throw If \a i is not a valid component index.
346 std::string DataArray::getInfoOnComponent(int i) const
348 if(i<(int)_info_on_compo.size() && i>=0)
349 return _info_on_compo[i];
352 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();
353 throw INTERP_KERNEL::Exception(oss.str().c_str());
358 * Returns the var part of the full information of the \a i-th component.
359 * For example, if \c getInfoOnComponent(0) returns "SIGXY [N/m^2]", then
360 * \c getVarOnComponent(0) returns "SIGXY".
361 * If a unit part of information is not detected by presence of
362 * two square brackets, then the full information is returned.
363 * To read more about the component information format, see
364 * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
365 * \param [in] i - the index (zero based) of the component of interest.
366 * \return std::string - a string containing the var information, or the full info.
367 * \throw If \a i is not a valid component index.
369 std::string DataArray::getVarOnComponent(int i) const
371 if(i<(int)_info_on_compo.size() && i>=0)
373 return GetVarNameFromInfo(_info_on_compo[i]);
377 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();
378 throw INTERP_KERNEL::Exception(oss.str().c_str());
383 * Returns the unit part of the full information of the \a i-th component.
384 * For example, if \c getInfoOnComponent(0) returns "SIGXY [ N/m^2]", then
385 * \c getUnitOnComponent(0) returns " N/m^2".
386 * If a unit part of information is not detected by presence of
387 * two square brackets, then an empty string is returned.
388 * To read more about the component information format, see
389 * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
390 * \param [in] i - the index (zero based) of the component of interest.
391 * \return std::string - a string containing the unit information, if any, or "".
392 * \throw If \a i is not a valid component index.
394 std::string DataArray::getUnitOnComponent(int i) const
396 if(i<(int)_info_on_compo.size() && i>=0)
398 return GetUnitFromInfo(_info_on_compo[i]);
402 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();
403 throw INTERP_KERNEL::Exception(oss.str().c_str());
408 * Returns the var part of the full component information.
409 * For example, if \a info == "SIGXY [N/m^2]", then this method returns "SIGXY".
410 * If a unit part of information is not detected by presence of
411 * two square brackets, then the whole \a info is returned.
412 * To read more about the component information format, see
413 * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
414 * \param [in] info - the full component information.
415 * \return std::string - a string containing only var information, or the \a info.
417 std::string DataArray::GetVarNameFromInfo(const std::string& info)
419 std::size_t p1=info.find_last_of('[');
420 std::size_t p2=info.find_last_of(']');
421 if(p1==std::string::npos || p2==std::string::npos)
426 return std::string();
427 std::size_t p3=info.find_last_not_of(' ',p1-1);
428 return info.substr(0,p3+1);
432 * Returns the unit part of the full component information.
433 * For example, if \a info == "SIGXY [ N/m^2]", then this method returns " N/m^2".
434 * If a unit part of information is not detected by presence of
435 * two square brackets, then an empty string is returned.
436 * To read more about the component information format, see
437 * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
438 * \param [in] info - the full component information.
439 * \return std::string - a string containing only unit information, if any, or "".
441 std::string DataArray::GetUnitFromInfo(const std::string& info)
443 std::size_t p1=info.find_last_of('[');
444 std::size_t p2=info.find_last_of(']');
445 if(p1==std::string::npos || p2==std::string::npos)
446 return std::string();
448 return std::string();
449 return info.substr(p1+1,p2-p1-1);
453 * This method put in info format the result of the merge of \a var and \a unit.
454 * The standard format for that is "var [unit]".
455 * Inversely you can retrieve the var part or the unit part of info string using resp. GetVarNameFromInfo and GetUnitFromInfo.
457 std::string DataArray::BuildInfoFromVarAndUnit(const std::string& var, const std::string& unit)
459 std::ostringstream oss;
460 oss << var << " [" << unit << "]";
464 std::string DataArray::GetAxisTypeRepr(MEDCouplingAxisType at)
469 return std::string("AX_CART");
471 return std::string("AX_CYL");
473 return std::string("AX_SPHER");
475 throw INTERP_KERNEL::Exception("DataArray::GetAxisTypeRepr : unrecognized axis type enum !");
480 * Returns a new DataArray by concatenating all given arrays, so that (1) the number
481 * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
482 * the number of component in the result array is same as that of each of given arrays.
483 * Info on components is copied from the first of the given arrays. Number of components
484 * in the given arrays must be the same.
485 * \param [in] arrs - a sequence of arrays to include in the result array. All arrays must have the same type.
486 * \return DataArray * - the new instance of DataArray (that can be either DataArrayInt, DataArrayDouble, DataArrayChar).
487 * The caller is to delete this result array using decrRef() as it is no more
489 * \throw If all arrays within \a arrs are NULL.
490 * \throw If all not null arrays in \a arrs have not the same type.
491 * \throw If getNumberOfComponents() of arrays within \a arrs.
493 DataArray *DataArray::Aggregate(const std::vector<const DataArray *>& arrs)
495 std::vector<const DataArray *> arr2;
496 for(std::vector<const DataArray *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
500 throw INTERP_KERNEL::Exception("DataArray::Aggregate : only null instance in input vector !");
501 std::vector<const DataArrayDouble *> arrd;
502 std::vector<const DataArrayInt *> arri;
503 std::vector<const DataArrayChar *> arrc;
504 for(std::vector<const DataArray *>::const_iterator it=arr2.begin();it!=arr2.end();it++)
506 const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(*it);
508 { arrd.push_back(a); continue; }
509 const DataArrayInt *b=dynamic_cast<const DataArrayInt *>(*it);
511 { arri.push_back(b); continue; }
512 const DataArrayChar *c=dynamic_cast<const DataArrayChar *>(*it);
514 { arrc.push_back(c); continue; }
515 throw INTERP_KERNEL::Exception("DataArray::Aggregate : presence of not null instance in inuput that is not in [DataArrayDouble, DataArrayInt, DataArrayChar] !");
517 if(arr2.size()==arrd.size())
518 return DataArrayDouble::Aggregate(arrd);
519 if(arr2.size()==arri.size())
520 return DataArrayInt::Aggregate(arri);
521 if(arr2.size()==arrc.size())
522 return DataArrayChar::Aggregate(arrc);
523 throw INTERP_KERNEL::Exception("DataArray::Aggregate : all input arrays must have the same type !");
527 * Sets information on a component specified by an index.
528 * To know more on format of this information
529 * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
530 * \warning Don't pass NULL as \a info!
531 * \param [in] i - the index (zero based) of the component of interest.
532 * \param [in] info - the string containing the information.
533 * \throw If \a i is not a valid component index.
535 void DataArray::setInfoOnComponent(int i, const std::string& info)
537 if(i<(int)_info_on_compo.size() && i>=0)
538 _info_on_compo[i]=info;
541 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();
542 throw INTERP_KERNEL::Exception(oss.str().c_str());
547 * Sets information on all components. This method can change number of components
548 * at certain conditions; if the conditions are not respected, an exception is thrown.
549 * The number of components can be changed in \a this only if \a this is not allocated.
550 * The condition of number of components must not be changed.
552 * To know more on format of the component information see
553 * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
554 * \param [in] info - a vector of component infos.
555 * \throw If \a this->getNumberOfComponents() != \a info.size() && \a this->isAllocated()
557 void DataArray::setInfoAndChangeNbOfCompo(const std::vector<std::string>& info)
559 if(getNumberOfComponents()!=info.size())
565 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 !";
566 throw INTERP_KERNEL::Exception(oss.str().c_str());
573 void DataArray::checkNbOfTuples(int nbOfTuples, const std::string& msg) const
575 if((int)getNumberOfTuples()!=nbOfTuples)
577 std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " << nbOfTuples << " having " << getNumberOfTuples() << " !";
578 throw INTERP_KERNEL::Exception(oss.str().c_str());
582 void DataArray::checkNbOfComps(int nbOfCompo, const std::string& msg) const
584 if((int)getNumberOfComponents()!=nbOfCompo)
586 std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << nbOfCompo << " having " << getNumberOfComponents() << " !";
587 throw INTERP_KERNEL::Exception(oss.str().c_str());
591 void DataArray::checkNbOfElems(std::size_t nbOfElems, const std::string& msg) const
593 if(getNbOfElems()!=nbOfElems)
595 std::ostringstream oss; oss << msg << " : mismatch number of elems : Expected " << nbOfElems << " having " << getNbOfElems() << " !";
596 throw INTERP_KERNEL::Exception(oss.str().c_str());
600 void DataArray::checkNbOfTuplesAndComp(const DataArray& other, const std::string& msg) const
602 if(getNumberOfTuples()!=other.getNumberOfTuples())
604 std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " << other.getNumberOfTuples() << " having " << getNumberOfTuples() << " !";
605 throw INTERP_KERNEL::Exception(oss.str().c_str());
607 if(getNumberOfComponents()!=other.getNumberOfComponents())
609 std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << other.getNumberOfComponents() << " having " << getNumberOfComponents() << " !";
610 throw INTERP_KERNEL::Exception(oss.str().c_str());
614 void DataArray::checkNbOfTuplesAndComp(int nbOfTuples, int nbOfCompo, const std::string& msg) const
616 checkNbOfTuples(nbOfTuples,msg);
617 checkNbOfComps(nbOfCompo,msg);
621 * Simply this method checks that \b value is in [0,\b ref).
623 void DataArray::CheckValueInRange(int ref, int value, const std::string& msg)
625 if(value<0 || value>=ref)
627 std::ostringstream oss; oss << "DataArray::CheckValueInRange : " << msg << " ! Expected in range [0," << ref << "[ having " << value << " !";
628 throw INTERP_KERNEL::Exception(oss.str().c_str());
633 * This method checks that [\b start, \b end) is compliant with ref length \b value.
634 * typicaly start in [0,\b value) and end in [0,\b value). If value==start and start==end, it is supported.
636 void DataArray::CheckValueInRangeEx(int value, int start, int end, const std::string& msg)
638 if(start<0 || start>=value)
640 if(value!=start || end!=start)
642 std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg << " ! Expected start " << start << " of input range, in [0," << value << "[ !";
643 throw INTERP_KERNEL::Exception(oss.str().c_str());
646 if(end<0 || end>value)
648 std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg << " ! Expected end " << end << " of input range, in [0," << value << "] !";
649 throw INTERP_KERNEL::Exception(oss.str().c_str());
653 void DataArray::CheckClosingParInRange(int ref, int value, const std::string& msg)
655 if(value<0 || value>ref)
657 std::ostringstream oss; oss << "DataArray::CheckClosingParInRange : " << msg << " ! Expected input range in [0," << ref << "] having closing open parenthesis " << value << " !";
658 throw INTERP_KERNEL::Exception(oss.str().c_str());
663 * 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,
664 * typically it is a whole slice of tuples of DataArray or cells, nodes of a mesh...
666 * The input \a sliceId should be an id in [0, \a nbOfSlices) that specifies the slice of work.
668 * \param [in] start - the start of the input slice of the whole work to perform splitted into slices.
669 * \param [in] stop - the stop of the input slice of the whole work to perform splitted into slices.
670 * \param [in] step - the step (that can be <0) of the input slice of the whole work to perform splitted into slices.
671 * \param [in] sliceId - the slice id considered
672 * \param [in] nbOfSlices - the number of slices (typically the number of cores on which the work is expected to be sliced)
673 * \param [out] startSlice - the start of the slice considered
674 * \param [out] stopSlice - the stop of the slice consided
676 * \throw If \a step == 0
677 * \throw If \a nbOfSlices not > 0
678 * \throw If \a sliceId not in [0,nbOfSlices)
680 void DataArray::GetSlice(int start, int stop, int step, int sliceId, int nbOfSlices, int& startSlice, int& stopSlice)
684 std::ostringstream oss; oss << "DataArray::GetSlice : nbOfSlices (" << nbOfSlices << ") must be > 0 !";
685 throw INTERP_KERNEL::Exception(oss.str().c_str());
687 if(sliceId<0 || sliceId>=nbOfSlices)
689 std::ostringstream oss; oss << "DataArray::GetSlice : sliceId (" << nbOfSlices << ") must be in [0 , nbOfSlices (" << nbOfSlices << ") ) !";
690 throw INTERP_KERNEL::Exception(oss.str().c_str());
692 int nbElems=GetNumberOfItemGivenBESRelative(start,stop,step,"DataArray::GetSlice");
693 int minNbOfElemsPerSlice=nbElems/nbOfSlices;
694 startSlice=start+minNbOfElemsPerSlice*step*sliceId;
695 if(sliceId<nbOfSlices-1)
696 stopSlice=start+minNbOfElemsPerSlice*step*(sliceId+1);
701 int DataArray::GetNumberOfItemGivenBES(int begin, int end, int step, const std::string& msg)
705 std::ostringstream oss; oss << msg << " : end before begin !";
706 throw INTERP_KERNEL::Exception(oss.str().c_str());
712 std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
713 throw INTERP_KERNEL::Exception(oss.str().c_str());
715 return (end-1-begin)/step+1;
718 int DataArray::GetNumberOfItemGivenBESRelative(int begin, int end, int step, const std::string& msg)
721 throw INTERP_KERNEL::Exception("DataArray::GetNumberOfItemGivenBES : step=0 is not allowed !");
722 if(end<begin && step>0)
724 std::ostringstream oss; oss << msg << " : end before begin whereas step is positive !";
725 throw INTERP_KERNEL::Exception(oss.str().c_str());
727 if(begin<end && step<0)
729 std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
730 throw INTERP_KERNEL::Exception(oss.str().c_str());
733 return (std::max(begin,end)-1-std::min(begin,end))/std::abs(step)+1;
738 int DataArray::GetPosOfItemGivenBESRelativeNoThrow(int value, int begin, int end, int step)
744 if(begin<=value && value<end)
746 if((value-begin)%step==0)
747 return (value-begin)/step;
756 if(begin>=value && value>end)
758 if((begin-value)%(-step)==0)
759 return (begin-value)/(-step);
772 * Returns a new instance of DataArrayDouble. The caller is to delete this array
773 * using decrRef() as it is no more needed.
775 DataArrayDouble *DataArrayDouble::New()
777 return new DataArrayDouble;
781 * Returns the only one value in \a this, if and only if number of elements
782 * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
783 * \return double - the sole value stored in \a this array.
784 * \throw If at least one of conditions stated above is not fulfilled.
786 double DataArrayDouble::doubleValue() const
790 if(getNbOfElems()==1)
792 return *getConstPointer();
795 throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is allocated but number of elements is not equal to 1 !");
798 throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is not allocated !");
802 * Returns a full copy of \a this. For more info on copying data arrays see
803 * \ref MEDCouplingArrayBasicsCopyDeep.
804 * \return DataArrayDouble * - a new instance of DataArrayDouble. The caller is to
805 * delete this array using decrRef() as it is no more needed.
807 DataArrayDouble *DataArrayDouble::deepCopy() const
809 return new DataArrayDouble(*this);
813 * Checks that \a this array is consistently **increasing** or **decreasing** in value,
814 * with at least absolute difference value of |\a eps| at each step.
815 * If not an exception is thrown.
816 * \param [in] increasing - if \a true, the array values should be increasing.
817 * \param [in] eps - minimal absolute difference between the neighbor values at which
818 * the values are considered different.
819 * \throw If sequence of values is not strictly monotonic in agreement with \a
821 * \throw If \a this->getNumberOfComponents() != 1.
822 * \throw If \a this is not allocated.
824 void DataArrayDouble::checkMonotonic(bool increasing, double eps) const
826 if(!isMonotonic(increasing,eps))
829 throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not INCREASING monotonic !");
831 throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not DECREASING monotonic !");
836 * Checks that \a this array is consistently **increasing** or **decreasing** in value,
837 * with at least absolute difference value of |\a eps| at each step.
838 * \param [in] increasing - if \a true, array values should be increasing.
839 * \param [in] eps - minimal absolute difference between the neighbor values at which
840 * the values are considered different.
841 * \return bool - \a true if values change in accordance with \a increasing arg.
842 * \throw If \a this->getNumberOfComponents() != 1.
843 * \throw If \a this is not allocated.
845 bool DataArrayDouble::isMonotonic(bool increasing, double eps) const
848 if(getNumberOfComponents()!=1)
849 throw INTERP_KERNEL::Exception("DataArrayDouble::isMonotonic : only supported with 'this' array with ONE component !");
850 int nbOfElements=getNumberOfTuples();
851 const double *ptr=getConstPointer();
855 double absEps=fabs(eps);
858 for(int i=1;i<nbOfElements;i++)
860 if(ptr[i]<(ref+absEps))
868 for(int i=1;i<nbOfElements;i++)
870 if(ptr[i]>(ref-absEps))
879 * Returns a textual and human readable representation of \a this instance of
880 * DataArrayDouble. This text is shown when a DataArrayDouble is printed in Python.
881 * \return std::string - text describing \a this DataArrayDouble.
883 * \sa reprNotTooLong, reprZip
885 std::string DataArrayDouble::repr() const
887 std::ostringstream ret;
892 std::string DataArrayDouble::reprZip() const
894 std::ostringstream ret;
899 void DataArrayDouble::writeVTK(std::ostream& ofs, int indent, const std::string& nameInFile, DataArrayByte *byteArr) const
901 static const char SPACE[4]={' ',' ',' ',' '};
903 std::string idt(indent,' ');
905 ofs << idt << "<DataArray type=\"Float32\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
907 bool areAllEmpty(true);
908 for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
912 for(std::size_t i=0;i<_info_on_compo.size();i++)
913 ofs << " ComponentName" << i << "=\"" << _info_on_compo[i] << "\"";
917 ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
918 INTERP_KERNEL::AutoPtr<float> tmp(new float[getNbOfElems()]);
920 // to make Visual C++ happy : instead of std::copy(begin(),end(),(float *)tmp);
921 for(const double *src=begin();src!=end();src++,pt++)
923 const char *data(reinterpret_cast<const char *>((float *)tmp));
924 std::size_t sz(getNbOfElems()*sizeof(float));
925 byteArr->insertAtTheEnd(data,data+sz);
926 byteArr->insertAtTheEnd(SPACE,SPACE+4);
930 ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
931 std::copy(begin(),end(),std::ostream_iterator<double>(ofs," "));
933 ofs << std::endl << idt << "</DataArray>\n";
936 void DataArrayDouble::reprCppStream(const std::string& varName, std::ostream& stream) const
938 int nbTuples(getNumberOfTuples()),nbComp(getNumberOfComponents());
939 const double *data(getConstPointer());
940 stream.precision(17);
941 stream << "DataArrayDouble *" << varName << "=DataArrayDouble::New();" << std::endl;
942 if(nbTuples*nbComp>=1)
944 stream << "const double " << varName << "Data[" << nbTuples*nbComp << "]={";
945 std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<double>(stream,","));
946 stream << data[nbTuples*nbComp-1] << "};" << std::endl;
947 stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
950 stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
951 stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
955 * Method that gives a quick overvien of \a this for python.
957 void DataArrayDouble::reprQuickOverview(std::ostream& stream) const
959 static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
960 stream << "DataArrayDouble C++ instance at " << this << ". ";
963 int nbOfCompo=(int)_info_on_compo.size();
966 int nbOfTuples=getNumberOfTuples();
967 stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
968 reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
971 stream << "Number of components : 0.";
974 stream << "*** No data allocated ****";
977 void DataArrayDouble::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
979 const double *data=begin();
980 int nbOfTuples=getNumberOfTuples();
981 int nbOfCompo=(int)_info_on_compo.size();
982 std::ostringstream oss2; oss2 << "[";
984 std::string oss2Str(oss2.str());
985 bool isFinished=true;
986 for(int i=0;i<nbOfTuples && isFinished;i++)
991 for(int j=0;j<nbOfCompo;j++,data++)
994 if(j!=nbOfCompo-1) oss2 << ", ";
1000 if(i!=nbOfTuples-1) oss2 << ", ";
1001 std::string oss3Str(oss2.str());
1002 if(oss3Str.length()<maxNbOfByteInRepr)
1014 * Equivalent to DataArrayDouble::isEqual except that if false the reason of
1015 * mismatch is given.
1017 * \param [in] other the instance to be compared with \a this
1018 * \param [in] prec the precision to compare numeric data of the arrays.
1019 * \param [out] reason In case of inequality returns the reason.
1020 * \sa DataArrayDouble::isEqual
1022 bool DataArrayDouble::isEqualIfNotWhy(const DataArrayDouble& other, double prec, std::string& reason) const
1024 if(!areInfoEqualsIfNotWhy(other,reason))
1026 return _mem.isEqual(other._mem,prec,reason);
1030 * Checks if \a this and another DataArrayDouble are fully equal. For more info see
1031 * \ref MEDCouplingArrayBasicsCompare.
1032 * \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1033 * \param [in] prec - precision value to compare numeric data of the arrays.
1034 * \return bool - \a true if the two arrays are equal, \a false else.
1036 bool DataArrayDouble::isEqual(const DataArrayDouble& other, double prec) const
1039 return isEqualIfNotWhy(other,prec,tmp);
1043 * Checks if values of \a this and another DataArrayDouble are equal. For more info see
1044 * \ref MEDCouplingArrayBasicsCompare.
1045 * \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1046 * \param [in] prec - precision value to compare numeric data of the arrays.
1047 * \return bool - \a true if the values of two arrays are equal, \a false else.
1049 bool DataArrayDouble::isEqualWithoutConsideringStr(const DataArrayDouble& other, double prec) const
1052 return _mem.isEqual(other._mem,prec,tmp);
1056 * This method checks that all tuples in \a other are in \a this.
1057 * If true, the output param \a tupleIds contains the tuples ids of \a this that correspond to tupes in \a this.
1058 * 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.
1060 * \param [in] other - the array having the same number of components than \a this.
1061 * \param [out] tupleIds - the tuple ids containing the same number of tuples than \a other has.
1062 * \sa DataArrayDouble::findCommonTuples
1064 bool DataArrayDouble::areIncludedInMe(const DataArrayDouble *other, double prec, DataArrayInt *&tupleIds) const
1067 throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : input array is NULL !");
1068 checkAllocated(); other->checkAllocated();
1069 if(getNumberOfComponents()!=other->getNumberOfComponents())
1070 throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : the number of components does not match !");
1071 MCAuto<DataArrayDouble> a=DataArrayDouble::Aggregate(this,other);
1072 DataArrayInt *c=0,*ci=0;
1073 a->findCommonTuples(prec,getNumberOfTuples(),c,ci);
1074 MCAuto<DataArrayInt> cSafe(c),ciSafe(ci);
1075 int newNbOfTuples=-1;
1076 MCAuto<DataArrayInt> ids=DataArrayInt::ConvertIndexArrayToO2N(a->getNumberOfTuples(),c->begin(),ci->begin(),ci->end(),newNbOfTuples);
1077 MCAuto<DataArrayInt> ret1=ids->selectByTupleIdSafeSlice(getNumberOfTuples(),a->getNumberOfTuples(),1);
1078 tupleIds=ret1.retn();
1079 return newNbOfTuples==getNumberOfTuples();
1083 * Searches for tuples coincident within \a prec tolerance. Each tuple is considered
1084 * as coordinates of a point in getNumberOfComponents()-dimensional space. The
1085 * distance separating two points is computed with the infinite norm.
1087 * Indices of coincident tuples are stored in output arrays.
1088 * A pair of arrays (\a comm, \a commIndex) is called "Surjective Format 2".
1090 * This method is typically used by MEDCouplingPointSet::findCommonNodes() and
1091 * MEDCouplingUMesh::mergeNodes().
1092 * \param [in] prec - minimal absolute distance between two tuples (infinite norm) at which they are
1093 * considered not coincident.
1094 * \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
1095 * tuples have id strictly lower than \a limitTupleId then they are not returned.
1096 * \param [out] comm - the array holding ids (== indices) of coincident tuples.
1097 * \a comm->getNumberOfComponents() == 1.
1098 * \a comm->getNumberOfTuples() == \a commIndex->back().
1099 * \param [out] commIndex - the array dividing all indices stored in \a comm into
1100 * groups of (indices of) coincident tuples. Its every value is a tuple
1101 * index where a next group of tuples begins. For example the second
1102 * group of tuples in \a comm is described by following range of indices:
1103 * [ \a commIndex[1], \a commIndex[2] ). \a commIndex->getNumberOfTuples()-1
1104 * gives the number of groups of coincident tuples.
1105 * \throw If \a this is not allocated.
1106 * \throw If the number of components is not in [1,2,3,4].
1108 * \if ENABLE_EXAMPLES
1109 * \ref cpp_mcdataarraydouble_findcommontuples "Here is a C++ example".
1111 * \ref py_mcdataarraydouble_findcommontuples "Here is a Python example".
1113 * \sa DataArrayInt::ConvertIndexArrayToO2N(), DataArrayDouble::areIncludedInMe
1115 void DataArrayDouble::findCommonTuples(double prec, int limitTupleId, DataArrayInt *&comm, DataArrayInt *&commIndex) const
1118 int nbOfCompo=getNumberOfComponents();
1119 if ((nbOfCompo<1) || (nbOfCompo>4)) //test before work
1120 throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : Unexpected spacedim of coords. Must be 1, 2, 3 or 4.");
1122 int nbOfTuples=getNumberOfTuples();
1124 MCAuto<DataArrayInt> c(DataArrayInt::New()),cI(DataArrayInt::New()); c->alloc(0,1); cI->pushBackSilent(0);
1128 findCommonTuplesAlg<4>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1131 findCommonTuplesAlg<3>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1134 findCommonTuplesAlg<2>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1137 findCommonTuplesAlg<1>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1140 throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : nb of components managed are 1,2,3 and 4 ! not implemented for other number of components !");
1143 commIndex=cI.retn();
1147 * This methods returns the minimal distance between the two set of points \a this and \a other.
1148 * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
1149 * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
1151 * \param [out] thisTupleId the tuple id in \a this corresponding to the returned minimal distance
1152 * \param [out] otherTupleId the tuple id in \a other corresponding to the returned minimal distance
1153 * \return the minimal distance between the two set of points \a this and \a other.
1154 * \sa DataArrayDouble::findClosestTupleId
1156 double DataArrayDouble::minimalDistanceTo(const DataArrayDouble *other, int& thisTupleId, int& otherTupleId) const
1158 MCAuto<DataArrayInt> part1=findClosestTupleId(other);
1159 int nbOfCompo(getNumberOfComponents());
1160 int otherNbTuples(other->getNumberOfTuples());
1161 const double *thisPt(begin()),*otherPt(other->begin());
1162 const int *part1Pt(part1->begin());
1163 double ret=std::numeric_limits<double>::max();
1164 for(int i=0;i<otherNbTuples;i++,part1Pt++,otherPt+=nbOfCompo)
1167 for(int j=0;j<nbOfCompo;j++)
1168 tmp+=(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j])*(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j]);
1170 { ret=tmp; thisTupleId=*part1Pt; otherTupleId=i; }
1176 * This methods returns for each tuple in \a other which tuple in \a this is the closest.
1177 * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
1178 * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
1180 * \return a newly allocated (new object to be dealt by the caller) DataArrayInt having \c other->getNumberOfTuples() tuples and one components.
1181 * \sa DataArrayDouble::minimalDistanceTo
1183 DataArrayInt *DataArrayDouble::findClosestTupleId(const DataArrayDouble *other) const
1186 throw INTERP_KERNEL::Exception("DataArrayDouble::findClosestTupleId : other instance is NULL !");
1187 checkAllocated(); other->checkAllocated();
1188 std::size_t nbOfCompo(getNumberOfComponents());
1189 if(nbOfCompo!=other->getNumberOfComponents())
1191 std::ostringstream oss; oss << "DataArrayDouble::findClosestTupleId : number of components in this is " << nbOfCompo;
1192 oss << ", whereas number of components in other is " << other->getNumberOfComponents() << "! Should be equal !";
1193 throw INTERP_KERNEL::Exception(oss.str().c_str());
1195 int nbOfTuples=other->getNumberOfTuples();
1196 int thisNbOfTuples=getNumberOfTuples();
1197 MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuples,1);
1199 getMinMaxPerComponent(bounds);
1204 double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2])),zDelta(fabs(bounds[5]-bounds[4]));
1205 double delta=std::max(xDelta,yDelta); delta=std::max(delta,zDelta);
1206 double characSize=pow((delta*delta*delta)/((double)thisNbOfTuples),1./3.);
1207 BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1208 FindClosestTupleIdAlg<3>(myTree,3.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1213 double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2]));
1214 double delta=std::max(xDelta,yDelta);
1215 double characSize=sqrt(delta/(double)thisNbOfTuples);
1216 BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1217 FindClosestTupleIdAlg<2>(myTree,2.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1222 double characSize=fabs(bounds[1]-bounds[0])/thisNbOfTuples;
1223 BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1224 FindClosestTupleIdAlg<1>(myTree,1.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1228 throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for findClosestTupleId. Must be 1, 2 or 3.");
1234 * This method expects that \a this and \a otherBBoxFrmt arrays are bounding box arrays ( as the output of MEDCouplingPointSet::getBoundingBoxForBBTree method ).
1235 * 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
1236 * how many bounding boxes in \a otherBBoxFrmt.
1237 * So, this method expects that \a this and \a otherBBoxFrmt have the same number of components.
1239 * \param [in] otherBBoxFrmt - It is an array .
1240 * \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.
1241 * \sa MEDCouplingPointSet::getBoundingBoxForBBTree
1242 * \throw If \a this and \a otherBBoxFrmt have not the same number of components.
1243 * \throw If \a this and \a otherBBoxFrmt number of components is not even (BBox format).
1245 DataArrayInt *DataArrayDouble::computeNbOfInteractionsWith(const DataArrayDouble *otherBBoxFrmt, double eps) const
1248 throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : input array is NULL !");
1249 if(!isAllocated() || !otherBBoxFrmt->isAllocated())
1250 throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : this and input array must be allocated !");
1251 std::size_t nbOfComp(getNumberOfComponents()),nbOfTuples(getNumberOfTuples());
1252 if(nbOfComp!=otherBBoxFrmt->getNumberOfComponents())
1254 std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : this number of components (" << nbOfComp << ") must be equal to the number of components of input array (" << otherBBoxFrmt->getNumberOfComponents() << ") !";
1255 throw INTERP_KERNEL::Exception(oss.str().c_str());
1259 std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : Number of components (" << nbOfComp << ") is not even ! It should be to be compatible with bbox format !";
1260 throw INTERP_KERNEL::Exception(oss.str().c_str());
1262 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbOfTuples,1);
1263 const double *thisBBPtr(begin());
1264 int *retPtr(ret->getPointer());
1269 BBTree<3,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
1270 for(std::size_t i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
1271 *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
1276 BBTree<2,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
1277 for(std::size_t i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
1278 *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
1283 BBTree<1,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
1284 for(std::size_t i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
1285 *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
1289 throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : space dimension supported are [1,2,3] !");
1296 * Returns a copy of \a this array by excluding coincident tuples. Each tuple is
1297 * considered as coordinates of a point in getNumberOfComponents()-dimensional
1298 * space. The distance between tuples is computed using norm2. If several tuples are
1299 * not far each from other than \a prec, only one of them remains in the result
1300 * array. The order of tuples in the result array is same as in \a this one except
1301 * that coincident tuples are excluded.
1302 * \param [in] prec - minimal absolute distance between two tuples at which they are
1303 * considered not coincident.
1304 * \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
1305 * tuples have id strictly lower than \a limitTupleId then they are not excluded.
1306 * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1307 * is to delete using decrRef() as it is no more needed.
1308 * \throw If \a this is not allocated.
1309 * \throw If the number of components is not in [1,2,3,4].
1311 * \if ENABLE_EXAMPLES
1312 * \ref py_mcdataarraydouble_getdifferentvalues "Here is a Python example".
1315 DataArrayDouble *DataArrayDouble::getDifferentValues(double prec, int limitTupleId) const
1318 DataArrayInt *c0=0,*cI0=0;
1319 findCommonTuples(prec,limitTupleId,c0,cI0);
1320 MCAuto<DataArrayInt> c(c0),cI(cI0);
1321 int newNbOfTuples=-1;
1322 MCAuto<DataArrayInt> o2n=DataArrayInt::ConvertIndexArrayToO2N(getNumberOfTuples(),c0->begin(),cI0->begin(),cI0->end(),newNbOfTuples);
1323 return renumberAndReduce(o2n->getConstPointer(),newNbOfTuples);
1327 * Copy all components in a specified order from another DataArrayDouble.
1328 * Both numerical and textual data is copied. The number of tuples in \a this and
1329 * the other array can be different.
1330 * \param [in] a - the array to copy data from.
1331 * \param [in] compoIds - sequence of zero based indices of components, data of which is
1333 * \throw If \a a is NULL.
1334 * \throw If \a compoIds.size() != \a a->getNumberOfComponents().
1335 * \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
1337 * \if ENABLE_EXAMPLES
1338 * \ref py_mcdataarraydouble_setselectedcomponents "Here is a Python example".
1341 void DataArrayDouble::setSelectedComponents(const DataArrayDouble *a, const std::vector<int>& compoIds)
1344 throw INTERP_KERNEL::Exception("DataArrayDouble::setSelectedComponents : input DataArrayDouble is NULL !");
1346 copyPartOfStringInfoFrom2(compoIds,*a);
1347 std::size_t partOfCompoSz=compoIds.size();
1348 int nbOfCompo=getNumberOfComponents();
1349 int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
1350 const double *ac=a->getConstPointer();
1351 double *nc=getPointer();
1352 for(int i=0;i<nbOfTuples;i++)
1353 for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
1354 nc[nbOfCompo*i+compoIds[j]]=*ac;
1358 * Checks if 0.0 value is present in \a this array. If it is the case, an exception
1360 * \throw If zero is found in \a this array.
1362 void DataArrayDouble::checkNoNullValues() const
1364 const double *tmp=getConstPointer();
1365 std::size_t nbOfElems=getNbOfElems();
1366 const double *where=std::find(tmp,tmp+nbOfElems,0.);
1367 if(where!=tmp+nbOfElems)
1368 throw INTERP_KERNEL::Exception("A value 0.0 have been detected !");
1372 * Computes minimal and maximal value in each component. An output array is filled
1373 * with \c 2 * \a this->getNumberOfComponents() values, so the caller is to allocate
1374 * enough memory before calling this method.
1375 * \param [out] bounds - array of size at least 2 *\a this->getNumberOfComponents().
1376 * It is filled as follows:<br>
1377 * \a bounds[0] = \c min_of_component_0 <br>
1378 * \a bounds[1] = \c max_of_component_0 <br>
1379 * \a bounds[2] = \c min_of_component_1 <br>
1380 * \a bounds[3] = \c max_of_component_1 <br>
1383 void DataArrayDouble::getMinMaxPerComponent(double *bounds) const
1386 int dim=getNumberOfComponents();
1387 for (int idim=0; idim<dim; idim++)
1389 bounds[idim*2]=std::numeric_limits<double>::max();
1390 bounds[idim*2+1]=-std::numeric_limits<double>::max();
1392 const double *ptr=getConstPointer();
1393 int nbOfTuples=getNumberOfTuples();
1394 for(int i=0;i<nbOfTuples;i++)
1396 for(int idim=0;idim<dim;idim++)
1398 if(bounds[idim*2]>ptr[i*dim+idim])
1400 bounds[idim*2]=ptr[i*dim+idim];
1402 if(bounds[idim*2+1]<ptr[i*dim+idim])
1404 bounds[idim*2+1]=ptr[i*dim+idim];
1411 * This method retrieves a newly allocated DataArrayDouble instance having same number of tuples than \a this and twice number of components than \a this
1412 * to store both the min and max per component of each tuples.
1413 * \param [in] epsilon the width of the bbox (identical in each direction) - 0.0 by default
1415 * \return a newly created DataArrayDouble instance having \c this->getNumberOfTuples() tuples and 2 * \c this->getNumberOfComponent() components
1417 * \throw If \a this is not allocated yet.
1419 DataArrayDouble *DataArrayDouble::computeBBoxPerTuple(double epsilon) const
1422 const double *dataPtr=getConstPointer();
1423 int nbOfCompo=getNumberOfComponents();
1424 int nbTuples=getNumberOfTuples();
1425 MCAuto<DataArrayDouble> bbox=DataArrayDouble::New();
1426 bbox->alloc(nbTuples,2*nbOfCompo);
1427 double *bboxPtr=bbox->getPointer();
1428 for(int i=0;i<nbTuples;i++)
1430 for(int j=0;j<nbOfCompo;j++)
1432 bboxPtr[2*nbOfCompo*i+2*j]=dataPtr[nbOfCompo*i+j]-epsilon;
1433 bboxPtr[2*nbOfCompo*i+2*j+1]=dataPtr[nbOfCompo*i+j]+epsilon;
1440 * For each tuples **t** in \a other, this method retrieves tuples in \a this that are equal to **t**.
1441 * Two tuples are considered equal if the euclidian distance between the two tuples is lower than \a eps.
1443 * \param [in] other a DataArrayDouble having same number of components than \a this.
1444 * \param [in] eps absolute precision representing distance (using infinite norm) between 2 tuples behind which 2 tuples are considered equal.
1445 * \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.
1446 * \a cI allows to extract information in \a c.
1447 * \param [out] cI is an indirection array that allows to extract the data contained in \a c.
1449 * \throw In case of:
1450 * - \a this is not allocated
1451 * - \a other is not allocated or null
1452 * - \a this and \a other do not have the same number of components
1453 * - if number of components of \a this is not in [1,2,3]
1455 * \sa MEDCouplingPointSet::getNodeIdsNearPoints, DataArrayDouble::getDifferentValues
1457 void DataArrayDouble::computeTupleIdsNearTuples(const DataArrayDouble *other, double eps, DataArrayInt *& c, DataArrayInt *& cI) const
1460 throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : input pointer other is null !");
1462 other->checkAllocated();
1463 int nbOfCompo=getNumberOfComponents();
1464 int otherNbOfCompo=other->getNumberOfComponents();
1465 if(nbOfCompo!=otherNbOfCompo)
1466 throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : number of components should be equal between this and other !");
1467 int nbOfTuplesOther=other->getNumberOfTuples();
1468 MCAuto<DataArrayInt> cArr(DataArrayInt::New()),cIArr(DataArrayInt::New()); cArr->alloc(0,1); cIArr->pushBackSilent(0);
1473 BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
1474 FindTupleIdsNearTuplesAlg<3>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
1479 BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
1480 FindTupleIdsNearTuplesAlg<2>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
1485 BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
1486 FindTupleIdsNearTuplesAlg<1>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
1490 throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for computeTupleIdsNearTuples. Must be 1, 2 or 3.");
1492 c=cArr.retn(); cI=cIArr.retn();
1496 * 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
1497 * around origin of 'radius' 1.
1499 * \param [in] eps absolute epsilon. under that value of delta between max and min no scale is performed.
1501 void DataArrayDouble::recenterForMaxPrecision(double eps)
1504 int dim=getNumberOfComponents();
1505 std::vector<double> bounds(2*dim);
1506 getMinMaxPerComponent(&bounds[0]);
1507 for(int i=0;i<dim;i++)
1509 double delta=bounds[2*i+1]-bounds[2*i];
1510 double offset=(bounds[2*i]+bounds[2*i+1])/2.;
1512 applyLin(1./delta,-offset/delta,i);
1514 applyLin(1.,-offset,i);
1519 * Returns the maximal value and all its locations within \a this one-dimensional array.
1520 * \param [out] tupleIds - a new instance of DataArrayInt containg indices of
1521 * tuples holding the maximal value. The caller is to delete it using
1522 * decrRef() as it is no more needed.
1523 * \return double - the maximal value among all values of \a this array.
1524 * \throw If \a this->getNumberOfComponents() != 1
1525 * \throw If \a this->getNumberOfTuples() < 1
1527 double DataArrayDouble::getMaxValue2(DataArrayInt*& tupleIds) const
1531 double ret=getMaxValue(tmp);
1532 tupleIds=findIdsInRange(ret,ret);
1537 * Returns the minimal value and all its locations within \a this one-dimensional array.
1538 * \param [out] tupleIds - a new instance of DataArrayInt containg indices of
1539 * tuples holding the minimal value. The caller is to delete it using
1540 * decrRef() as it is no more needed.
1541 * \return double - the minimal value among all values of \a this array.
1542 * \throw If \a this->getNumberOfComponents() != 1
1543 * \throw If \a this->getNumberOfTuples() < 1
1545 double DataArrayDouble::getMinValue2(DataArrayInt*& tupleIds) const
1549 double ret=getMinValue(tmp);
1550 tupleIds=findIdsInRange(ret,ret);
1555 * 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.
1556 * This method only works for single component array.
1558 * \return a value in [ 0, \c this->getNumberOfTuples() )
1560 * \throw If \a this is not allocated
1563 int DataArrayDouble::count(double value, double eps) const
1567 if(getNumberOfComponents()!=1)
1568 throw INTERP_KERNEL::Exception("DataArrayDouble::count : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
1569 const double *vals=begin();
1570 int nbOfTuples=getNumberOfTuples();
1571 for(int i=0;i<nbOfTuples;i++,vals++)
1572 if(fabs(*vals-value)<=eps)
1578 * Returns the average value of \a this one-dimensional array.
1579 * \return double - the average value over all values of \a this array.
1580 * \throw If \a this->getNumberOfComponents() != 1
1581 * \throw If \a this->getNumberOfTuples() < 1
1583 double DataArrayDouble::getAverageValue() const
1585 if(getNumberOfComponents()!=1)
1586 throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
1587 int nbOfTuples=getNumberOfTuples();
1589 throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : array exists but number of tuples must be > 0 !");
1590 const double *vals=getConstPointer();
1591 double ret=std::accumulate(vals,vals+nbOfTuples,0.);
1592 return ret/nbOfTuples;
1596 * Returns the Euclidean norm of the vector defined by \a this array.
1597 * \return double - the value of the Euclidean norm, i.e.
1598 * the square root of the inner product of vector.
1599 * \throw If \a this is not allocated.
1601 double DataArrayDouble::norm2() const
1605 std::size_t nbOfElems=getNbOfElems();
1606 const double *pt=getConstPointer();
1607 for(std::size_t i=0;i<nbOfElems;i++,pt++)
1613 * Returns the maximum norm of the vector defined by \a this array.
1614 * This method works even if the number of components is diferent from one.
1615 * If the number of elements in \a this is 0, -1. is returned.
1616 * \return double - the value of the maximum norm, i.e.
1617 * the maximal absolute value among values of \a this array (whatever its number of components).
1618 * \throw If \a this is not allocated.
1620 double DataArrayDouble::normMax() const
1624 std::size_t nbOfElems(getNbOfElems());
1625 const double *pt(getConstPointer());
1626 for(std::size_t i=0;i<nbOfElems;i++,pt++)
1628 double val(std::abs(*pt));
1636 * Returns the minimum norm (absolute value) of the vector defined by \a this array.
1637 * This method works even if the number of components is diferent from one.
1638 * If the number of elements in \a this is 0, std::numeric_limits<double>::max() is returned.
1639 * \return double - the value of the minimum norm, i.e.
1640 * the minimal absolute value among values of \a this array (whatever its number of components).
1641 * \throw If \a this is not allocated.
1643 double DataArrayDouble::normMin() const
1646 double ret(std::numeric_limits<double>::max());
1647 std::size_t nbOfElems(getNbOfElems());
1648 const double *pt(getConstPointer());
1649 for(std::size_t i=0;i<nbOfElems;i++,pt++)
1651 double val(std::abs(*pt));
1659 * Accumulates values of each component of \a this array.
1660 * \param [out] res - an array of length \a this->getNumberOfComponents(), allocated
1661 * by the caller, that is filled by this method with sum value for each
1663 * \throw If \a this is not allocated.
1665 void DataArrayDouble::accumulate(double *res) const
1668 const double *ptr=getConstPointer();
1669 int nbTuple=getNumberOfTuples();
1670 int nbComps=getNumberOfComponents();
1671 std::fill(res,res+nbComps,0.);
1672 for(int i=0;i<nbTuple;i++)
1673 std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<double>());
1677 * This method returns the min distance from an external tuple defined by [ \a tupleBg , \a tupleEnd ) to \a this and
1678 * the first tuple in \a this that matches the returned distance. If there is no tuples in \a this an exception will be thrown.
1681 * \a this is expected to be allocated and expected to have a number of components equal to the distance from \a tupleBg to
1682 * \a tupleEnd. If not an exception will be thrown.
1684 * \param [in] tupleBg start pointer (included) of input external tuple
1685 * \param [in] tupleEnd end pointer (not included) of input external tuple
1686 * \param [out] tupleId the tuple id in \a this that matches the min of distance between \a this and input external tuple
1687 * \return the min distance.
1688 * \sa MEDCouplingUMesh::distanceToPoint
1690 double DataArrayDouble::distanceToTuple(const double *tupleBg, const double *tupleEnd, int& tupleId) const
1693 int nbTuple=getNumberOfTuples();
1694 int nbComps=getNumberOfComponents();
1695 if(nbComps!=(int)std::distance(tupleBg,tupleEnd))
1696 { 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()); }
1698 throw INTERP_KERNEL::Exception("DataArrayDouble::distanceToTuple : no tuple in this ! No distance to compute !");
1699 double ret0=std::numeric_limits<double>::max();
1701 const double *work=getConstPointer();
1702 for(int i=0;i<nbTuple;i++)
1705 for(int j=0;j<nbComps;j++,work++)
1706 val+=(*work-tupleBg[j])*((*work-tupleBg[j]));
1710 { ret0=val; tupleId=i; }
1716 * Accumulate values of the given component of \a this array.
1717 * \param [in] compId - the index of the component of interest.
1718 * \return double - a sum value of \a compId-th component.
1719 * \throw If \a this is not allocated.
1720 * \throw If \a the condition ( 0 <= \a compId < \a this->getNumberOfComponents() ) is
1723 double DataArrayDouble::accumulate(int compId) const
1726 const double *ptr=getConstPointer();
1727 int nbTuple=getNumberOfTuples();
1728 int nbComps=getNumberOfComponents();
1729 if(compId<0 || compId>=nbComps)
1730 throw INTERP_KERNEL::Exception("DataArrayDouble::accumulate : Invalid compId specified : No such nb of components !");
1732 for(int i=0;i<nbTuple;i++)
1733 ret+=ptr[i*nbComps+compId];
1738 * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
1739 * The returned array will have same number of components than \a this and number of tuples equal to
1740 * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
1742 * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
1743 * 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.
1745 * \param [in] bgOfIndex - begin (included) of the input index array.
1746 * \param [in] endOfIndex - end (excluded) of the input index array.
1747 * \return DataArrayDouble * - the new instance having the same number of components than \a this.
1749 * \throw If bgOfIndex or end is NULL.
1750 * \throw If input index array is not ascendingly sorted.
1751 * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
1752 * \throw If std::distance(bgOfIndex,endOfIndex)==0.
1754 DataArrayDouble *DataArrayDouble::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
1756 if(!bgOfIndex || !endOfIndex)
1757 throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : input pointer NULL !");
1759 int nbCompo=getNumberOfComponents();
1760 int nbOfTuples=getNumberOfTuples();
1761 int sz=(int)std::distance(bgOfIndex,endOfIndex);
1763 throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : invalid size of input index array !");
1765 MCAuto<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(sz,nbCompo);
1766 const int *w=bgOfIndex;
1767 if(*w<0 || *w>=nbOfTuples)
1768 throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
1769 const double *srcPt=begin()+(*w)*nbCompo;
1770 double *tmp=ret->getPointer();
1771 for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
1773 std::fill(tmp,tmp+nbCompo,0.);
1776 for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
1778 if(j>=0 && j<nbOfTuples)
1779 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<double>());
1782 std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
1783 throw INTERP_KERNEL::Exception(oss.str().c_str());
1789 std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
1790 throw INTERP_KERNEL::Exception(oss.str().c_str());
1793 ret->copyStringInfoFrom(*this);
1798 * 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.
1799 * This method expects that \a this as only one component. The returned array will have \a this->getNumberOfTuples()+1 tuple with also one component.
1800 * The ith element of returned array is equal to the sum of elements in \a this with rank strictly lower than i.
1802 * \return DataArrayDouble - A newly built array containing cum sum of \a this.
1804 MCAuto<DataArrayDouble> DataArrayDouble::cumSum() const
1807 checkNbOfComps(1,"DataArrayDouble::cumSum : this is expected to be single component");
1808 int nbOfTuple(getNumberOfTuples());
1809 MCAuto<DataArrayDouble> ret(DataArrayDouble::New()); ret->alloc(nbOfTuple+1,1);
1810 double *ptr(ret->getPointer());
1812 const double *thisPtr(begin());
1813 for(int i=0;i<nbOfTuple;i++)
1814 ptr[i+1]=ptr[i]+thisPtr[i];
1819 * Converts each 2D point defined by the tuple of \a this array from the Polar to the
1820 * Cartesian coordinate system. The two components of the tuple of \a this array are
1821 * considered to contain (1) radius and (2) angle of the point in the Polar CS.
1822 * \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
1823 * contains X and Y coordinates of the point in the Cartesian CS. The caller
1824 * is to delete this array using decrRef() as it is no more needed. The array
1825 * does not contain any textual info on components.
1826 * \throw If \a this->getNumberOfComponents() != 2.
1827 * \sa fromCartToPolar
1829 DataArrayDouble *DataArrayDouble::fromPolarToCart() const
1832 int nbOfComp(getNumberOfComponents());
1834 throw INTERP_KERNEL::Exception("DataArrayDouble::fromPolarToCart : must be an array with exactly 2 components !");
1835 int nbOfTuple(getNumberOfTuples());
1836 DataArrayDouble *ret(DataArrayDouble::New());
1837 ret->alloc(nbOfTuple,2);
1838 double *w(ret->getPointer());
1839 const double *wIn(getConstPointer());
1840 for(int i=0;i<nbOfTuple;i++,w+=2,wIn+=2)
1842 w[0]=wIn[0]*cos(wIn[1]);
1843 w[1]=wIn[0]*sin(wIn[1]);
1849 * Converts each 3D point defined by the tuple of \a this array from the Cylindrical to
1850 * the Cartesian coordinate system. The three components of the tuple of \a this array
1851 * are considered to contain (1) radius, (2) azimuth and (3) altitude of the point in
1852 * the Cylindrical CS.
1853 * \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
1854 * contains X, Y and Z coordinates of the point in the Cartesian CS. The info
1855 * on the third component is copied from \a this array. The caller
1856 * is to delete this array using decrRef() as it is no more needed.
1857 * \throw If \a this->getNumberOfComponents() != 3.
1860 DataArrayDouble *DataArrayDouble::fromCylToCart() const
1863 int nbOfComp(getNumberOfComponents());
1865 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCylToCart : must be an array with exactly 3 components !");
1866 int nbOfTuple(getNumberOfTuples());
1867 DataArrayDouble *ret(DataArrayDouble::New());
1868 ret->alloc(getNumberOfTuples(),3);
1869 double *w(ret->getPointer());
1870 const double *wIn(getConstPointer());
1871 for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
1873 w[0]=wIn[0]*cos(wIn[1]);
1874 w[1]=wIn[0]*sin(wIn[1]);
1877 ret->setInfoOnComponent(2,getInfoOnComponent(2));
1882 * Converts each 3D point defined by the tuple of \a this array from the Spherical to
1883 * the Cartesian coordinate system. The three components of the tuple of \a this array
1884 * are considered to contain (1) radius, (2) polar angle and (3) azimuthal angle of the
1885 * point in the Cylindrical CS.
1886 * \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
1887 * contains X, Y and Z coordinates of the point in the Cartesian CS. The info
1888 * on the third component is copied from \a this array. The caller
1889 * is to delete this array using decrRef() as it is no more needed.
1890 * \throw If \a this->getNumberOfComponents() != 3.
1891 * \sa fromCartToSpher
1893 DataArrayDouble *DataArrayDouble::fromSpherToCart() const
1896 int nbOfComp(getNumberOfComponents());
1898 throw INTERP_KERNEL::Exception("DataArrayDouble::fromSpherToCart : must be an array with exactly 3 components !");
1899 int nbOfTuple(getNumberOfTuples());
1900 DataArrayDouble *ret(DataArrayDouble::New());
1901 ret->alloc(getNumberOfTuples(),3);
1902 double *w(ret->getPointer());
1903 const double *wIn(getConstPointer());
1904 for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
1906 w[0]=wIn[0]*cos(wIn[2])*sin(wIn[1]);
1907 w[1]=wIn[0]*sin(wIn[2])*sin(wIn[1]);
1908 w[2]=wIn[0]*cos(wIn[1]);
1914 * 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.
1915 * 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.
1916 * If \a at equals to AX_CYL the returned array will be the result of operation cylindric to cartesian of \a this...
1918 * \param [in] atOfThis - The axis type of \a this.
1919 * \return DataArrayDouble * - the new instance of DataArrayDouble (that must be dealed by caller) containing the result of the cartesianizification of \a this.
1921 DataArrayDouble *DataArrayDouble::cartesianize(MEDCouplingAxisType atOfThis) const
1924 int nbOfComp(getNumberOfComponents());
1925 MCAuto<DataArrayDouble> ret;
1933 ret=fromCylToCart();
1938 ret=fromPolarToCart();
1942 throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : For AX_CYL, number of components must be in [2,3] !");
1946 ret=fromSpherToCart();
1951 ret=fromPolarToCart();
1955 throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : For AX_CYL, number of components must be in [2,3] !");
1957 throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : not recognized axis type ! Only AX_CART, AX_CYL and AX_SPHER supported !");
1959 ret->copyStringInfoFrom(*this);
1964 * This method returns a newly created array to be deallocated that contains the result of conversion from cartesian to polar.
1965 * This method expects that \a this has exactly 2 components.
1966 * \sa fromPolarToCart
1968 DataArrayDouble *DataArrayDouble::fromCartToPolar() const
1970 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
1972 int nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
1974 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToPolar : must be an array with exactly 2 components !");
1975 ret->alloc(nbTuples,2);
1976 double *retPtr(ret->getPointer());
1977 const double *ptr(begin());
1978 for(int i=0;i<nbTuples;i++,ptr+=2,retPtr+=2)
1980 retPtr[0]=sqrt(ptr[0]*ptr[0]+ptr[1]*ptr[1]);
1981 retPtr[1]=atan2(ptr[1],ptr[0]);
1987 * This method returns a newly created array to be deallocated that contains the result of conversion from cartesian to cylindrical.
1988 * This method expects that \a this has exactly 3 components.
1991 DataArrayDouble *DataArrayDouble::fromCartToCyl() const
1993 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
1995 int nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
1997 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCyl : must be an array with exactly 3 components !");
1998 ret->alloc(nbTuples,3);
1999 double *retPtr(ret->getPointer());
2000 const double *ptr(begin());
2001 for(int i=0;i<nbTuples;i++,ptr+=3,retPtr+=3)
2003 retPtr[0]=sqrt(ptr[0]*ptr[0]+ptr[1]*ptr[1]);
2004 retPtr[1]=atan2(ptr[1],ptr[0]);
2011 * This method returns a newly created array to be deallocated that contains the result of conversion from cartesian to spherical coordinates.
2012 * \sa fromSpherToCart
2014 DataArrayDouble *DataArrayDouble::fromCartToSpher() const
2016 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2018 int nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2020 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToSpher : must be an array with exactly 3 components !");
2021 ret->alloc(nbTuples,3);
2022 double *retPtr(ret->getPointer());
2023 const double *ptr(begin());
2024 for(int i=0;i<nbTuples;i++,ptr+=3,retPtr+=3)
2026 retPtr[0]=sqrt(ptr[0]*ptr[0]+ptr[1]*ptr[1]+ptr[2]*ptr[2]);
2027 retPtr[1]=acos(ptr[2]/retPtr[0]);
2028 retPtr[2]=atan2(ptr[1],ptr[0]);
2034 * 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.
2035 * This method expects that \a this has exactly 3 components.
2036 * \sa MEDCouplingFieldDouble::computeVectorFieldCyl
2038 DataArrayDouble *DataArrayDouble::fromCartToCylGiven(const DataArrayDouble *coords, const double center[3], const double vect[3]) const
2041 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : input coords are NULL !");
2042 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2043 checkAllocated(); coords->checkAllocated();
2044 std::size_t nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2046 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : must be an array with exactly 3 components !");
2047 if(coords->getNumberOfComponents()!=3)
2048 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : coords array must have exactly 3 components !");
2049 if(coords->getNumberOfTuples()!=nbTuples)
2050 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : coords array must have the same number of tuples !");
2051 ret->alloc(nbTuples,nbOfComp);
2052 double magOfVect(sqrt(vect[0]*vect[0]+vect[1]*vect[1]+vect[2]*vect[2]));
2054 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : magnitude of vect is too low !");
2055 double Ur[3],Uteta[3],Uz[3],*retPtr(ret->getPointer());
2056 const double *coo(coords->begin()),*vectField(begin());
2057 std::transform(vect,vect+3,Uz,std::bind2nd(std::multiplies<double>(),1./magOfVect));
2058 for(int i=0;i<nbTuples;i++,vectField+=3,retPtr+=3,coo+=3)
2060 std::transform(coo,coo+3,center,Ur,std::minus<double>());
2061 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];
2062 double magOfTeta(sqrt(Uteta[0]*Uteta[0]+Uteta[1]*Uteta[1]+Uteta[2]*Uteta[2]));
2063 std::transform(Uteta,Uteta+3,Uteta,std::bind2nd(std::multiplies<double>(),1./magOfTeta));
2064 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];
2065 retPtr[0]=Ur[0]*vectField[0]+Ur[1]*vectField[1]+Ur[2]*vectField[2];
2066 retPtr[1]=Uteta[0]*vectField[0]+Uteta[1]*vectField[1]+Uteta[2]*vectField[2];
2067 retPtr[2]=Uz[0]*vectField[0]+Uz[1]*vectField[1]+Uz[2]*vectField[2];
2069 ret->copyStringInfoFrom(*this);
2074 * Computes the doubly contracted product of every tensor defined by the tuple of \a this
2075 * array contating 6 components.
2076 * \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
2077 * is calculated from the tuple <em>(t)</em> of \a this array as follows:
2078 * \f$ t[0]^2+t[1]^2+t[2]^2+2*t[3]^2+2*t[4]^2+2*t[5]^2\f$.
2079 * The caller is to delete this result array using decrRef() as it is no more needed.
2080 * \throw If \a this->getNumberOfComponents() != 6.
2082 DataArrayDouble *DataArrayDouble::doublyContractedProduct() const
2085 int nbOfComp(getNumberOfComponents());
2087 throw INTERP_KERNEL::Exception("DataArrayDouble::doublyContractedProduct : must be an array with exactly 6 components !");
2088 DataArrayDouble *ret=DataArrayDouble::New();
2089 int nbOfTuple=getNumberOfTuples();
2090 ret->alloc(nbOfTuple,1);
2091 const double *src=getConstPointer();
2092 double *dest=ret->getPointer();
2093 for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
2094 *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];
2099 * Computes the determinant of every square matrix defined by the tuple of \a this
2100 * array, which contains either 4, 6 or 9 components. The case of 6 components
2101 * corresponds to that of the upper triangular matrix.
2102 * \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
2103 * is the determinant of matrix of the corresponding tuple of \a this array.
2104 * The caller is to delete this result array using decrRef() as it is no more
2106 * \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2108 DataArrayDouble *DataArrayDouble::determinant() const
2111 DataArrayDouble *ret=DataArrayDouble::New();
2112 int nbOfTuple=getNumberOfTuples();
2113 ret->alloc(nbOfTuple,1);
2114 const double *src=getConstPointer();
2115 double *dest=ret->getPointer();
2116 switch(getNumberOfComponents())
2119 for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
2120 *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];
2123 for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
2124 *dest=src[0]*src[3]-src[1]*src[2];
2127 for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
2128 *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];
2132 throw INTERP_KERNEL::Exception("DataArrayDouble::determinant : Invalid number of components ! must be in 4,6,9 !");
2137 * Computes 3 eigenvalues of every upper triangular matrix defined by the tuple of
2138 * \a this array, which contains 6 components.
2139 * \return DataArrayDouble * - the new instance of DataArrayDouble containing 3
2140 * components, whose each tuple contains the eigenvalues of the matrix of
2141 * corresponding tuple of \a this array.
2142 * The caller is to delete this result array using decrRef() as it is no more
2144 * \throw If \a this->getNumberOfComponents() != 6.
2146 DataArrayDouble *DataArrayDouble::eigenValues() const
2149 int nbOfComp=getNumberOfComponents();
2151 throw INTERP_KERNEL::Exception("DataArrayDouble::eigenValues : must be an array with exactly 6 components !");
2152 DataArrayDouble *ret=DataArrayDouble::New();
2153 int nbOfTuple=getNumberOfTuples();
2154 ret->alloc(nbOfTuple,3);
2155 const double *src=getConstPointer();
2156 double *dest=ret->getPointer();
2157 for(int i=0;i<nbOfTuple;i++,dest+=3,src+=6)
2158 INTERP_KERNEL::computeEigenValues6(src,dest);
2163 * Computes 3 eigenvectors of every upper triangular matrix defined by the tuple of
2164 * \a this array, which contains 6 components.
2165 * \return DataArrayDouble * - the new instance of DataArrayDouble containing 9
2166 * components, whose each tuple contains 3 eigenvectors of the matrix of
2167 * corresponding tuple of \a this array.
2168 * The caller is to delete this result array using decrRef() as it is no more
2170 * \throw If \a this->getNumberOfComponents() != 6.
2172 DataArrayDouble *DataArrayDouble::eigenVectors() const
2175 int nbOfComp=getNumberOfComponents();
2177 throw INTERP_KERNEL::Exception("DataArrayDouble::eigenVectors : must be an array with exactly 6 components !");
2178 DataArrayDouble *ret=DataArrayDouble::New();
2179 int nbOfTuple=getNumberOfTuples();
2180 ret->alloc(nbOfTuple,9);
2181 const double *src=getConstPointer();
2182 double *dest=ret->getPointer();
2183 for(int i=0;i<nbOfTuple;i++,src+=6)
2186 INTERP_KERNEL::computeEigenValues6(src,tmp);
2187 for(int j=0;j<3;j++,dest+=3)
2188 INTERP_KERNEL::computeEigenVectorForEigenValue6(src,tmp[j],1e-12,dest);
2194 * Computes the inverse matrix of every matrix defined by the tuple of \a this
2195 * array, which contains either 4, 6 or 9 components. The case of 6 components
2196 * corresponds to that of the upper triangular matrix.
2197 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2198 * same number of components as \a this one, whose each tuple is the inverse
2199 * matrix of the matrix of corresponding tuple of \a this array.
2200 * The caller is to delete this result array using decrRef() as it is no more
2202 * \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2204 DataArrayDouble *DataArrayDouble::inverse() const
2207 int nbOfComp=getNumberOfComponents();
2208 if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
2209 throw INTERP_KERNEL::Exception("DataArrayDouble::inversion : must be an array with 4,6 or 9 components !");
2210 DataArrayDouble *ret=DataArrayDouble::New();
2211 int nbOfTuple=getNumberOfTuples();
2212 ret->alloc(nbOfTuple,nbOfComp);
2213 const double *src=getConstPointer();
2214 double *dest=ret->getPointer();
2216 for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
2218 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];
2219 dest[0]=(src[1]*src[2]-src[4]*src[4])/det;
2220 dest[1]=(src[0]*src[2]-src[5]*src[5])/det;
2221 dest[2]=(src[0]*src[1]-src[3]*src[3])/det;
2222 dest[3]=(src[5]*src[4]-src[3]*src[2])/det;
2223 dest[4]=(src[5]*src[3]-src[0]*src[4])/det;
2224 dest[5]=(src[3]*src[4]-src[1]*src[5])/det;
2226 else if(nbOfComp==4)
2227 for(int i=0;i<nbOfTuple;i++,dest+=4,src+=4)
2229 double det=src[0]*src[3]-src[1]*src[2];
2231 dest[1]=-src[1]/det;
2232 dest[2]=-src[2]/det;
2236 for(int i=0;i<nbOfTuple;i++,dest+=9,src+=9)
2238 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];
2239 dest[0]=(src[4]*src[8]-src[7]*src[5])/det;
2240 dest[1]=(src[7]*src[2]-src[1]*src[8])/det;
2241 dest[2]=(src[1]*src[5]-src[4]*src[2])/det;
2242 dest[3]=(src[6]*src[5]-src[3]*src[8])/det;
2243 dest[4]=(src[0]*src[8]-src[6]*src[2])/det;
2244 dest[5]=(src[2]*src[3]-src[0]*src[5])/det;
2245 dest[6]=(src[3]*src[7]-src[6]*src[4])/det;
2246 dest[7]=(src[6]*src[1]-src[0]*src[7])/det;
2247 dest[8]=(src[0]*src[4]-src[1]*src[3])/det;
2253 * Computes the trace of every matrix defined by the tuple of \a this
2254 * array, which contains either 4, 6 or 9 components. The case of 6 components
2255 * corresponds to that of the upper triangular matrix.
2256 * \return DataArrayDouble * - the new instance of DataArrayDouble containing
2257 * 1 component, whose each tuple is the trace of
2258 * the matrix of corresponding tuple of \a this array.
2259 * The caller is to delete this result array using decrRef() as it is no more
2261 * \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2263 DataArrayDouble *DataArrayDouble::trace() const
2266 int nbOfComp=getNumberOfComponents();
2267 if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
2268 throw INTERP_KERNEL::Exception("DataArrayDouble::trace : must be an array with 4,6 or 9 components !");
2269 DataArrayDouble *ret=DataArrayDouble::New();
2270 int nbOfTuple=getNumberOfTuples();
2271 ret->alloc(nbOfTuple,1);
2272 const double *src=getConstPointer();
2273 double *dest=ret->getPointer();
2275 for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
2276 *dest=src[0]+src[1]+src[2];
2277 else if(nbOfComp==4)
2278 for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
2279 *dest=src[0]+src[3];
2281 for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
2282 *dest=src[0]+src[4]+src[8];
2287 * Computes the stress deviator tensor of every stress tensor defined by the tuple of
2288 * \a this array, which contains 6 components.
2289 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2290 * same number of components and tuples as \a this array.
2291 * The caller is to delete this result array using decrRef() as it is no more
2293 * \throw If \a this->getNumberOfComponents() != 6.
2295 DataArrayDouble *DataArrayDouble::deviator() const
2298 int nbOfComp=getNumberOfComponents();
2300 throw INTERP_KERNEL::Exception("DataArrayDouble::deviator : must be an array with exactly 6 components !");
2301 DataArrayDouble *ret=DataArrayDouble::New();
2302 int nbOfTuple=getNumberOfTuples();
2303 ret->alloc(nbOfTuple,6);
2304 const double *src=getConstPointer();
2305 double *dest=ret->getPointer();
2306 for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
2308 double tr=(src[0]+src[1]+src[2])/3.;
2320 * Computes the magnitude of every vector defined by the tuple of
2322 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2323 * same number of tuples as \a this array and one component.
2324 * The caller is to delete this result array using decrRef() as it is no more
2326 * \throw If \a this is not allocated.
2328 DataArrayDouble *DataArrayDouble::magnitude() const
2331 int nbOfComp=getNumberOfComponents();
2332 DataArrayDouble *ret=DataArrayDouble::New();
2333 int nbOfTuple=getNumberOfTuples();
2334 ret->alloc(nbOfTuple,1);
2335 const double *src=getConstPointer();
2336 double *dest=ret->getPointer();
2337 for(int i=0;i<nbOfTuple;i++,dest++)
2340 for(int j=0;j<nbOfComp;j++,src++)
2348 * Computes the maximal value within every tuple of \a this array.
2349 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2350 * same number of tuples as \a this array and one component.
2351 * The caller is to delete this result array using decrRef() as it is no more
2353 * \throw If \a this is not allocated.
2354 * \sa DataArrayDouble::maxPerTupleWithCompoId
2356 DataArrayDouble *DataArrayDouble::maxPerTuple() const
2359 int nbOfComp=getNumberOfComponents();
2360 MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
2361 int nbOfTuple=getNumberOfTuples();
2362 ret->alloc(nbOfTuple,1);
2363 const double *src=getConstPointer();
2364 double *dest=ret->getPointer();
2365 for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
2366 *dest=*std::max_element(src,src+nbOfComp);
2371 * Computes the maximal value within every tuple of \a this array and it returns the first component
2372 * id for each tuple that corresponds to the maximal value within the tuple.
2374 * \param [out] compoIdOfMaxPerTuple - the new new instance of DataArrayInt containing the
2375 * same number of tuples and only one component.
2376 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2377 * same number of tuples as \a this array and one component.
2378 * The caller is to delete this result array using decrRef() as it is no more
2380 * \throw If \a this is not allocated.
2381 * \sa DataArrayDouble::maxPerTuple
2383 DataArrayDouble *DataArrayDouble::maxPerTupleWithCompoId(DataArrayInt* &compoIdOfMaxPerTuple) const
2386 int nbOfComp=getNumberOfComponents();
2387 MCAuto<DataArrayDouble> ret0=DataArrayDouble::New();
2388 MCAuto<DataArrayInt> ret1=DataArrayInt::New();
2389 int nbOfTuple=getNumberOfTuples();
2390 ret0->alloc(nbOfTuple,1); ret1->alloc(nbOfTuple,1);
2391 const double *src=getConstPointer();
2392 double *dest=ret0->getPointer(); int *dest1=ret1->getPointer();
2393 for(int i=0;i<nbOfTuple;i++,dest++,dest1++,src+=nbOfComp)
2395 const double *loc=std::max_element(src,src+nbOfComp);
2397 *dest1=(int)std::distance(src,loc);
2399 compoIdOfMaxPerTuple=ret1.retn();
2404 * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c this->getNumberOfTuples() tuples.
2405 * \n This returned array contains the euclidian distance for each tuple in \a this.
2406 * \n So the returned array can be seen as a dense symmetrical matrix whose diagonal elements are equal to 0.
2407 * \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)
2409 * \warning use this method with care because it can leads to big amount of consumed memory !
2411 * \return A newly allocated (huge) MEDCoupling::DataArrayDouble instance that the caller should deal with.
2413 * \throw If \a this is not allocated.
2415 * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrixWith
2417 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrix() const
2420 int nbOfComp=getNumberOfComponents();
2421 int nbOfTuples=getNumberOfTuples();
2422 const double *inData=getConstPointer();
2423 MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
2424 ret->alloc(nbOfTuples*nbOfTuples,1);
2425 double *outData=ret->getPointer();
2426 for(int i=0;i<nbOfTuples;i++)
2428 outData[i*nbOfTuples+i]=0.;
2429 for(int j=i+1;j<nbOfTuples;j++)
2432 for(int k=0;k<nbOfComp;k++)
2433 { double delta=inData[i*nbOfComp+k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
2435 outData[i*nbOfTuples+j]=dist;
2436 outData[j*nbOfTuples+i]=dist;
2443 * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c other->getNumberOfTuples() tuples.
2444 * \n This returned array contains the euclidian distance for each tuple in \a other with each tuple in \a this.
2445 * \n So the returned array can be seen as a dense rectangular matrix with \c other->getNumberOfTuples() rows and \c this->getNumberOfTuples() columns.
2446 * \n Output rectangular matrix is sorted along rows.
2447 * \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)
2449 * \warning use this method with care because it can leads to big amount of consumed memory !
2451 * \param [in] other DataArrayDouble instance having same number of components than \a this.
2452 * \return A newly allocated (huge) MEDCoupling::DataArrayDouble instance that the caller should deal with.
2454 * \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.
2456 * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrix
2458 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrixWith(const DataArrayDouble *other) const
2461 throw INTERP_KERNEL::Exception("DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : input parameter is null !");
2463 other->checkAllocated();
2464 int nbOfComp=getNumberOfComponents();
2465 int otherNbOfComp=other->getNumberOfComponents();
2466 if(nbOfComp!=otherNbOfComp)
2468 std::ostringstream oss; oss << "DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : this nb of compo=" << nbOfComp << " and other nb of compo=" << otherNbOfComp << ". It should match !";
2469 throw INTERP_KERNEL::Exception(oss.str().c_str());
2471 int nbOfTuples=getNumberOfTuples();
2472 int otherNbOfTuples=other->getNumberOfTuples();
2473 const double *inData=getConstPointer();
2474 const double *inDataOther=other->getConstPointer();
2475 MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
2476 ret->alloc(otherNbOfTuples*nbOfTuples,1);
2477 double *outData=ret->getPointer();
2478 for(int i=0;i<otherNbOfTuples;i++,inDataOther+=nbOfComp)
2480 for(int j=0;j<nbOfTuples;j++)
2483 for(int k=0;k<nbOfComp;k++)
2484 { double delta=inDataOther[k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
2486 outData[i*nbOfTuples+j]=dist;
2493 * Sorts value within every tuple of \a this array.
2494 * \param [in] asc - if \a true, the values are sorted in ascending order, else,
2495 * in descending order.
2496 * \throw If \a this is not allocated.
2498 void DataArrayDouble::sortPerTuple(bool asc)
2501 double *pt=getPointer();
2502 int nbOfTuple=getNumberOfTuples();
2503 int nbOfComp=getNumberOfComponents();
2505 for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
2506 std::sort(pt,pt+nbOfComp);
2508 for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
2509 std::sort(pt,pt+nbOfComp,std::greater<double>());
2514 * Modify all elements of \a this array, so that
2515 * an element _x_ becomes \f$ numerator / x \f$.
2516 * \warning If an exception is thrown because of presence of 0.0 element in \a this
2517 * array, all elements processed before detection of the zero element remain
2519 * \param [in] numerator - the numerator used to modify array elements.
2520 * \throw If \a this is not allocated.
2521 * \throw If there is an element equal to 0.0 in \a this array.
2523 void DataArrayDouble::applyInv(double numerator)
2526 double *ptr=getPointer();
2527 std::size_t nbOfElems=getNbOfElems();
2528 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2530 if(std::abs(*ptr)>std::numeric_limits<double>::min())
2532 *ptr=numerator/(*ptr);
2536 std::ostringstream oss; oss << "DataArrayDouble::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
2538 throw INTERP_KERNEL::Exception(oss.str().c_str());
2545 * Modify all elements of \a this array, so that
2546 * an element _x_ becomes <em> val ^ x </em>. Contrary to DataArrayInt::applyPow
2547 * all values in \a this have to be >= 0 if val is \b not integer.
2548 * \param [in] val - the value used to apply pow on all array elements.
2549 * \throw If \a this is not allocated.
2550 * \warning If an exception is thrown because of presence of 0 element in \a this
2551 * array and \a val is \b not integer, all elements processed before detection of the zero element remain
2554 void DataArrayDouble::applyPow(double val)
2557 double *ptr=getPointer();
2558 std::size_t nbOfElems=getNbOfElems();
2560 bool isInt=((double)val2)==val;
2563 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2569 std::ostringstream oss; oss << "DataArrayDouble::applyPow (double) : At elem # " << i << " value is " << *ptr << " ! must be >=0. !";
2570 throw INTERP_KERNEL::Exception(oss.str().c_str());
2576 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2577 *ptr=pow(*ptr,val2);
2583 * Modify all elements of \a this array, so that
2584 * an element _x_ becomes \f$ val ^ x \f$.
2585 * \param [in] val - the value used to apply pow on all array elements.
2586 * \throw If \a this is not allocated.
2587 * \throw If \a val < 0.
2588 * \warning If an exception is thrown because of presence of 0 element in \a this
2589 * array, all elements processed before detection of the zero element remain
2592 void DataArrayDouble::applyRPow(double val)
2596 throw INTERP_KERNEL::Exception("DataArrayDouble::applyRPow : the input value has to be >= 0 !");
2597 double *ptr=getPointer();
2598 std::size_t nbOfElems=getNbOfElems();
2599 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2605 * Returns a new DataArrayDouble created from \a this one by applying \a
2606 * FunctionToEvaluate to every tuple of \a this array. Textual data is not copied.
2607 * For more info see \ref MEDCouplingArrayApplyFunc
2608 * \param [in] nbOfComp - number of components in the result array.
2609 * \param [in] func - the \a FunctionToEvaluate declared as
2610 * \c bool (*\a func)(\c const \c double *\a pos, \c double *\a res),
2611 * where \a pos points to the first component of a tuple of \a this array
2612 * and \a res points to the first component of a tuple of the result array.
2613 * Note that length (number of components) of \a pos can differ from
2615 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2616 * same number of tuples as \a this array.
2617 * The caller is to delete this result array using decrRef() as it is no more
2619 * \throw If \a this is not allocated.
2620 * \throw If \a func returns \a false.
2622 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, FunctionToEvaluate func) const
2625 DataArrayDouble *newArr=DataArrayDouble::New();
2626 int nbOfTuples=getNumberOfTuples();
2627 int oldNbOfComp=getNumberOfComponents();
2628 newArr->alloc(nbOfTuples,nbOfComp);
2629 const double *ptr=getConstPointer();
2630 double *ptrToFill=newArr->getPointer();
2631 for(int i=0;i<nbOfTuples;i++)
2633 if(!func(ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp))
2635 std::ostringstream oss; oss << "For tuple # " << i << " with value (";
2636 std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
2637 oss << ") : Evaluation of function failed !";
2639 throw INTERP_KERNEL::Exception(oss.str().c_str());
2646 * Returns a new DataArrayDouble created from \a this one by applying a function to every
2647 * tuple of \a this array. Textual data is not copied.
2648 * For more info see \ref MEDCouplingArrayApplyFunc1.
2649 * \param [in] nbOfComp - number of components in the result array.
2650 * \param [in] func - the expression defining how to transform a tuple of \a this array.
2651 * Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
2652 * \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
2653 * If false the computation is carried on without any notification. When false the evaluation is a little faster.
2654 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2655 * same number of tuples as \a this array and \a nbOfComp components.
2656 * The caller is to delete this result array using decrRef() as it is no more
2658 * \throw If \a this is not allocated.
2659 * \throw If computing \a func fails.
2661 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, const std::string& func, bool isSafe) const
2663 INTERP_KERNEL::ExprParser expr(func);
2665 std::set<std::string> vars;
2666 expr.getTrueSetOfVars(vars);
2667 std::vector<std::string> varsV(vars.begin(),vars.end());
2668 return applyFuncNamedCompo(nbOfComp,varsV,func,isSafe);
2672 * Returns a new DataArrayDouble created from \a this one by applying a function to every
2673 * tuple of \a this array. Textual data is not copied. This method works by tuples (whatever its size).
2674 * If \a this is a one component array, call applyFuncOnThis instead that performs the same work faster.
2676 * For more info see \ref MEDCouplingArrayApplyFunc0.
2677 * \param [in] func - the expression defining how to transform a tuple of \a this array.
2678 * Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
2679 * \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
2680 * If false the computation is carried on without any notification. When false the evaluation is a little faster.
2681 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2682 * same number of tuples and components as \a this array.
2683 * The caller is to delete this result array using decrRef() as it is no more
2685 * \sa applyFuncOnThis
2686 * \throw If \a this is not allocated.
2687 * \throw If computing \a func fails.
2689 DataArrayDouble *DataArrayDouble::applyFunc(const std::string& func, bool isSafe) const
2691 int nbOfComp(getNumberOfComponents());
2693 throw INTERP_KERNEL::Exception("DataArrayDouble::applyFunc : output number of component must be > 0 !");
2695 int nbOfTuples(getNumberOfTuples());
2696 MCAuto<DataArrayDouble> newArr(DataArrayDouble::New());
2697 newArr->alloc(nbOfTuples,nbOfComp);
2698 INTERP_KERNEL::ExprParser expr(func);
2700 std::set<std::string> vars;
2701 expr.getTrueSetOfVars(vars);
2702 if((int)vars.size()>1)
2704 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 : ";
2705 std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
2706 throw INTERP_KERNEL::Exception(oss.str().c_str());
2710 expr.prepareFastEvaluator();
2711 newArr->rearrange(1);
2712 newArr->fillWithValue(expr.evaluateDouble());
2713 newArr->rearrange(nbOfComp);
2714 return newArr.retn();
2716 std::vector<std::string> vars2(vars.begin(),vars.end());
2717 double buff,*ptrToFill(newArr->getPointer());
2718 const double *ptr(begin());
2719 std::vector<double> stck;
2720 expr.prepareExprEvaluationDouble(vars2,1,1,0,&buff,&buff+1);
2721 expr.prepareFastEvaluator();
2724 for(int i=0;i<nbOfTuples;i++)
2726 for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
2729 expr.evaluateDoubleInternal(stck);
2730 *ptrToFill=stck.back();
2737 for(int i=0;i<nbOfTuples;i++)
2739 for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
2744 expr.evaluateDoubleInternalSafe(stck);
2746 catch(INTERP_KERNEL::Exception& e)
2748 std::ostringstream oss; oss << "For tuple # " << i << " component # " << iComp << " with value (";
2750 oss << ") : Evaluation of function failed !" << e.what();
2751 throw INTERP_KERNEL::Exception(oss.str().c_str());
2753 *ptrToFill=stck.back();
2758 return newArr.retn();
2762 * This method is a non const method that modify the array in \a this.
2763 * This method only works on one component array. It means that function \a func must
2764 * contain at most one variable.
2765 * This method is a specialization of applyFunc method with one parameter on one component array.
2767 * \param [in] func - the expression defining how to transform a tuple of \a this array.
2768 * Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
2769 * \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
2770 * If false the computation is carried on without any notification. When false the evaluation is a little faster.
2774 void DataArrayDouble::applyFuncOnThis(const std::string& func, bool isSafe)
2776 int nbOfComp(getNumberOfComponents());
2778 throw INTERP_KERNEL::Exception("DataArrayDouble::applyFuncOnThis : output number of component must be > 0 !");
2780 int nbOfTuples(getNumberOfTuples());
2781 INTERP_KERNEL::ExprParser expr(func);
2783 std::set<std::string> vars;
2784 expr.getTrueSetOfVars(vars);
2785 if((int)vars.size()>1)
2787 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 : ";
2788 std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
2789 throw INTERP_KERNEL::Exception(oss.str().c_str());
2793 expr.prepareFastEvaluator();
2794 std::vector<std::string> compInfo(getInfoOnComponents());
2796 fillWithValue(expr.evaluateDouble());
2797 rearrange(nbOfComp);
2798 setInfoOnComponents(compInfo);
2801 std::vector<std::string> vars2(vars.begin(),vars.end());
2802 double buff,*ptrToFill(getPointer());
2803 const double *ptr(begin());
2804 std::vector<double> stck;
2805 expr.prepareExprEvaluationDouble(vars2,1,1,0,&buff,&buff+1);
2806 expr.prepareFastEvaluator();
2809 for(int i=0;i<nbOfTuples;i++)
2811 for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
2814 expr.evaluateDoubleInternal(stck);
2815 *ptrToFill=stck.back();
2822 for(int i=0;i<nbOfTuples;i++)
2824 for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
2829 expr.evaluateDoubleInternalSafe(stck);
2831 catch(INTERP_KERNEL::Exception& e)
2833 std::ostringstream oss; oss << "For tuple # " << i << " component # " << iComp << " with value (";
2835 oss << ") : Evaluation of function failed !" << e.what();
2836 throw INTERP_KERNEL::Exception(oss.str().c_str());
2838 *ptrToFill=stck.back();
2846 * Returns a new DataArrayDouble created from \a this one by applying a function to every
2847 * tuple of \a this array. Textual data is not copied.
2848 * For more info see \ref MEDCouplingArrayApplyFunc2.
2849 * \param [in] nbOfComp - number of components in the result array.
2850 * \param [in] func - the expression defining how to transform a tuple of \a this array.
2851 * Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
2852 * \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
2853 * If false the computation is carried on without any notification. When false the evaluation is a little faster.
2854 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2855 * same number of tuples as \a this array.
2856 * The caller is to delete this result array using decrRef() as it is no more
2858 * \throw If \a this is not allocated.
2859 * \throw If \a func contains vars that are not in \a this->getInfoOnComponent().
2860 * \throw If computing \a func fails.
2862 DataArrayDouble *DataArrayDouble::applyFuncCompo(int nbOfComp, const std::string& func, bool isSafe) const
2864 return applyFuncNamedCompo(nbOfComp,getVarsOnComponent(),func,isSafe);
2868 * Returns a new DataArrayDouble created from \a this one by applying a function to every
2869 * tuple of \a this array. Textual data is not copied.
2870 * For more info see \ref MEDCouplingArrayApplyFunc3.
2871 * \param [in] nbOfComp - number of components in the result array.
2872 * \param [in] varsOrder - sequence of vars defining their order.
2873 * \param [in] func - the expression defining how to transform a tuple of \a this array.
2874 * Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
2875 * \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
2876 * If false the computation is carried on without any notification. When false the evaluation is a little faster.
2877 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2878 * same number of tuples as \a this array.
2879 * The caller is to delete this result array using decrRef() as it is no more
2881 * \throw If \a this is not allocated.
2882 * \throw If \a func contains vars not in \a varsOrder.
2883 * \throw If computing \a func fails.
2885 DataArrayDouble *DataArrayDouble::applyFuncNamedCompo(int nbOfComp, const std::vector<std::string>& varsOrder, const std::string& func, bool isSafe) const
2888 throw INTERP_KERNEL::Exception("DataArrayDouble::applyFuncNamedCompo : output number of component must be > 0 !");
2889 std::vector<std::string> varsOrder2(varsOrder);
2890 int oldNbOfComp(getNumberOfComponents());
2891 for(int i=(int)varsOrder.size();i<oldNbOfComp;i++)
2892 varsOrder2.push_back(std::string());
2894 int nbOfTuples(getNumberOfTuples());
2895 INTERP_KERNEL::ExprParser expr(func);
2897 std::set<std::string> vars;
2898 expr.getTrueSetOfVars(vars);
2899 if((int)vars.size()>oldNbOfComp)
2901 std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
2902 oss << vars.size() << " variables : ";
2903 std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
2904 throw INTERP_KERNEL::Exception(oss.str().c_str());
2906 MCAuto<DataArrayDouble> newArr(DataArrayDouble::New());
2907 newArr->alloc(nbOfTuples,nbOfComp);
2908 INTERP_KERNEL::AutoPtr<double> buff(new double[oldNbOfComp]);
2909 double *buffPtr(buff),*ptrToFill;
2910 std::vector<double> stck;
2911 for(int iComp=0;iComp<nbOfComp;iComp++)
2913 expr.prepareExprEvaluationDouble(varsOrder2,oldNbOfComp,nbOfComp,iComp,buffPtr,buffPtr+oldNbOfComp);
2914 expr.prepareFastEvaluator();
2915 const double *ptr(getConstPointer());
2916 ptrToFill=newArr->getPointer()+iComp;
2919 for(int i=0;i<nbOfTuples;i++,ptrToFill+=nbOfComp,ptr+=oldNbOfComp)
2921 std::copy(ptr,ptr+oldNbOfComp,buffPtr);
2922 expr.evaluateDoubleInternal(stck);
2923 *ptrToFill=stck.back();
2929 for(int i=0;i<nbOfTuples;i++,ptrToFill+=nbOfComp,ptr+=oldNbOfComp)
2931 std::copy(ptr,ptr+oldNbOfComp,buffPtr);
2934 expr.evaluateDoubleInternalSafe(stck);
2935 *ptrToFill=stck.back();
2938 catch(INTERP_KERNEL::Exception& e)
2940 std::ostringstream oss; oss << "For tuple # " << i << " with value (";
2941 std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
2942 oss << ") : Evaluation of function failed !" << e.what();
2943 throw INTERP_KERNEL::Exception(oss.str().c_str());
2948 return newArr.retn();
2951 void DataArrayDouble::applyFuncFast32(const std::string& func)
2954 INTERP_KERNEL::ExprParser expr(func);
2956 char *funcStr=expr.compileX86();
2958 *((void **)&funcPtr)=funcStr;//he he...
2960 double *ptr=getPointer();
2961 int nbOfComp=getNumberOfComponents();
2962 int nbOfTuples=getNumberOfTuples();
2963 int nbOfElems=nbOfTuples*nbOfComp;
2964 for(int i=0;i<nbOfElems;i++,ptr++)
2969 void DataArrayDouble::applyFuncFast64(const std::string& func)
2972 INTERP_KERNEL::ExprParser expr(func);
2974 char *funcStr=expr.compileX86_64();
2976 *((void **)&funcPtr)=funcStr;//he he...
2978 double *ptr=getPointer();
2979 int nbOfComp=getNumberOfComponents();
2980 int nbOfTuples=getNumberOfTuples();
2981 int nbOfElems=nbOfTuples*nbOfComp;
2982 for(int i=0;i<nbOfElems;i++,ptr++)
2988 * \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.
2990 MCAuto<DataArrayDouble> DataArrayDouble::symmetry3DPlane(const double point[3], const double normalVector[3]) const
2993 if(getNumberOfComponents()!=3)
2994 throw INTERP_KERNEL::Exception("DataArrayDouble::symmetry3DPlane : this is excepted to have 3 components !");
2995 int nbTuples(getNumberOfTuples());
2996 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2997 ret->alloc(nbTuples,3);
2998 Symmetry3DPlane(point,normalVector,nbTuples,begin(),ret->getPointer());
3002 DataArrayDoubleIterator *DataArrayDouble::iterator()
3004 return new DataArrayDoubleIterator(this);
3008 * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional
3009 * array whose values are within a given range. Textual data is not copied.
3010 * \param [in] vmin - a lowest acceptable value (included).
3011 * \param [in] vmax - a greatest acceptable value (included).
3012 * \return DataArrayInt * - the new instance of DataArrayInt.
3013 * The caller is to delete this result array using decrRef() as it is no more
3015 * \throw If \a this->getNumberOfComponents() != 1.
3017 * \sa DataArrayDouble::findIdsNotInRange
3019 * \if ENABLE_EXAMPLES
3020 * \ref cpp_mcdataarraydouble_getidsinrange "Here is a C++ example".<br>
3021 * \ref py_mcdataarraydouble_getidsinrange "Here is a Python example".
3024 DataArrayInt *DataArrayDouble::findIdsInRange(double vmin, double vmax) const
3027 if(getNumberOfComponents()!=1)
3028 throw INTERP_KERNEL::Exception("DataArrayDouble::findIdsInRange : this must have exactly one component !");
3029 const double *cptr(begin());
3030 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
3031 int nbOfTuples(getNumberOfTuples());
3032 for(int i=0;i<nbOfTuples;i++,cptr++)
3033 if(*cptr>=vmin && *cptr<=vmax)
3034 ret->pushBackSilent(i);
3039 * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional
3040 * array whose values are not within a given range. Textual data is not copied.
3041 * \param [in] vmin - a lowest not acceptable value (excluded).
3042 * \param [in] vmax - a greatest not acceptable value (excluded).
3043 * \return DataArrayInt * - the new instance of DataArrayInt.
3044 * The caller is to delete this result array using decrRef() as it is no more
3046 * \throw If \a this->getNumberOfComponents() != 1.
3048 * \sa DataArrayDouble::findIdsInRange
3050 DataArrayInt *DataArrayDouble::findIdsNotInRange(double vmin, double vmax) const
3053 if(getNumberOfComponents()!=1)
3054 throw INTERP_KERNEL::Exception("DataArrayDouble::findIdsNotInRange : this must have exactly one component !");
3055 const double *cptr(begin());
3056 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
3057 int nbOfTuples(getNumberOfTuples());
3058 for(int i=0;i<nbOfTuples;i++,cptr++)
3059 if(*cptr<vmin || *cptr>vmax)
3060 ret->pushBackSilent(i);
3065 * Returns a new DataArrayDouble by concatenating two given arrays, so that (1) the number
3066 * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
3067 * the number of component in the result array is same as that of each of given arrays.
3068 * Info on components is copied from the first of the given arrays. Number of components
3069 * in the given arrays must be the same.
3070 * \param [in] a1 - an array to include in the result array.
3071 * \param [in] a2 - another array to include in the result array.
3072 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3073 * The caller is to delete this result array using decrRef() as it is no more
3075 * \throw If both \a a1 and \a a2 are NULL.
3076 * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
3078 DataArrayDouble *DataArrayDouble::Aggregate(const DataArrayDouble *a1, const DataArrayDouble *a2)
3080 std::vector<const DataArrayDouble *> tmp(2);
3081 tmp[0]=a1; tmp[1]=a2;
3082 return Aggregate(tmp);
3086 * Returns a new DataArrayDouble by concatenating all given arrays, so that (1) the number
3087 * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
3088 * the number of component in the result array is same as that of each of given arrays.
3089 * Info on components is copied from the first of the given arrays. Number of components
3090 * in the given arrays must be the same.
3091 * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it
3092 * not the object itself.
3093 * \param [in] arr - a sequence of arrays to include in the result array.
3094 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3095 * The caller is to delete this result array using decrRef() as it is no more
3097 * \throw If all arrays within \a arr are NULL.
3098 * \throw If getNumberOfComponents() of arrays within \a arr.
3100 DataArrayDouble *DataArrayDouble::Aggregate(const std::vector<const DataArrayDouble *>& arr)
3102 std::vector<const DataArrayDouble *> a;
3103 for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
3107 throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : input list must contain at least one NON EMPTY DataArrayDouble !");
3108 std::vector<const DataArrayDouble *>::const_iterator it=a.begin();
3109 std::size_t nbOfComp((*it)->getNumberOfComponents());
3110 int nbt=(*it++)->getNumberOfTuples();
3111 for(int i=1;it!=a.end();it++,i++)
3113 if((*it)->getNumberOfComponents()!=nbOfComp)
3114 throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : Nb of components mismatch for array aggregation !");
3115 nbt+=(*it)->getNumberOfTuples();
3117 MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
3118 ret->alloc(nbt,nbOfComp);
3119 double *pt=ret->getPointer();
3120 for(it=a.begin();it!=a.end();it++)
3121 pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
3122 ret->copyStringInfoFrom(*(a[0]));
3127 * Returns a new DataArrayDouble containing a dot product of two given arrays, so that
3128 * the i-th tuple of the result array is a sum of products of j-th components of i-th
3129 * tuples of given arrays (\f$ a_i = \sum_{j=1}^n a1_j * a2_j \f$).
3130 * Info on components and name is copied from the first of the given arrays.
3131 * Number of tuples and components in the given arrays must be the same.
3132 * \param [in] a1 - a given array.
3133 * \param [in] a2 - another given array.
3134 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3135 * The caller is to delete this result array using decrRef() as it is no more
3137 * \throw If either \a a1 or \a a2 is NULL.
3138 * \throw If any given array is not allocated.
3139 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3140 * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
3142 DataArrayDouble *DataArrayDouble::Dot(const DataArrayDouble *a1, const DataArrayDouble *a2)
3145 throw INTERP_KERNEL::Exception("DataArrayDouble::Dot : input DataArrayDouble instance is NULL !");
3146 a1->checkAllocated();
3147 a2->checkAllocated();
3148 std::size_t nbOfComp(a1->getNumberOfComponents());
3149 if(nbOfComp!=a2->getNumberOfComponents())
3150 throw INTERP_KERNEL::Exception("Nb of components mismatch for array Dot !");
3151 std::size_t nbOfTuple(a1->getNumberOfTuples());
3152 if(nbOfTuple!=a2->getNumberOfTuples())
3153 throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Dot !");
3154 DataArrayDouble *ret=DataArrayDouble::New();
3155 ret->alloc(nbOfTuple,1);
3156 double *retPtr=ret->getPointer();
3157 const double *a1Ptr=a1->begin(),*a2Ptr(a2->begin());
3158 for(std::size_t i=0;i<nbOfTuple;i++)
3161 for(std::size_t j=0;j<nbOfComp;j++)
3162 sum+=a1Ptr[i*nbOfComp+j]*a2Ptr[i*nbOfComp+j];
3165 ret->setInfoOnComponent(0,a1->getInfoOnComponent(0));
3166 ret->setName(a1->getName());
3171 * Returns a new DataArrayDouble containing a cross product of two given arrays, so that
3172 * the i-th tuple of the result array contains 3 components of a vector which is a cross
3173 * product of two vectors defined by the i-th tuples of given arrays.
3174 * Info on components is copied from the first of the given arrays.
3175 * Number of tuples in the given arrays must be the same.
3176 * Number of components in the given arrays must be 3.
3177 * \param [in] a1 - a given array.
3178 * \param [in] a2 - another given array.
3179 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3180 * The caller is to delete this result array using decrRef() as it is no more
3182 * \throw If either \a a1 or \a a2 is NULL.
3183 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3184 * \throw If \a a1->getNumberOfComponents() != 3
3185 * \throw If \a a2->getNumberOfComponents() != 3
3187 DataArrayDouble *DataArrayDouble::CrossProduct(const DataArrayDouble *a1, const DataArrayDouble *a2)
3190 throw INTERP_KERNEL::Exception("DataArrayDouble::CrossProduct : input DataArrayDouble instance is NULL !");
3191 std::size_t nbOfComp(a1->getNumberOfComponents());
3192 if(nbOfComp!=a2->getNumberOfComponents())
3193 throw INTERP_KERNEL::Exception("Nb of components mismatch for array crossProduct !");
3195 throw INTERP_KERNEL::Exception("Nb of components must be equal to 3 for array crossProduct !");
3196 std::size_t nbOfTuple(a1->getNumberOfTuples());
3197 if(nbOfTuple!=a2->getNumberOfTuples())
3198 throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array crossProduct !");
3199 DataArrayDouble *ret=DataArrayDouble::New();
3200 ret->alloc(nbOfTuple,3);
3201 double *retPtr=ret->getPointer();
3202 const double *a1Ptr(a1->begin()),*a2Ptr(a2->begin());
3203 for(std::size_t i=0;i<nbOfTuple;i++)
3205 retPtr[3*i]=a1Ptr[3*i+1]*a2Ptr[3*i+2]-a1Ptr[3*i+2]*a2Ptr[3*i+1];
3206 retPtr[3*i+1]=a1Ptr[3*i+2]*a2Ptr[3*i]-a1Ptr[3*i]*a2Ptr[3*i+2];
3207 retPtr[3*i+2]=a1Ptr[3*i]*a2Ptr[3*i+1]-a1Ptr[3*i+1]*a2Ptr[3*i];
3209 ret->copyStringInfoFrom(*a1);
3214 * Returns a new DataArrayDouble containing maximal values of two given arrays.
3215 * Info on components is copied from the first of the given arrays.
3216 * Number of tuples and components in the given arrays must be the same.
3217 * \param [in] a1 - an array to compare values with another one.
3218 * \param [in] a2 - another array to compare values with the first one.
3219 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3220 * The caller is to delete this result array using decrRef() as it is no more
3222 * \throw If either \a a1 or \a a2 is NULL.
3223 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3224 * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
3226 DataArrayDouble *DataArrayDouble::Max(const DataArrayDouble *a1, const DataArrayDouble *a2)
3229 throw INTERP_KERNEL::Exception("DataArrayDouble::Max : input DataArrayDouble instance is NULL !");
3230 std::size_t nbOfComp(a1->getNumberOfComponents());
3231 if(nbOfComp!=a2->getNumberOfComponents())
3232 throw INTERP_KERNEL::Exception("Nb of components mismatch for array Max !");
3233 std::size_t nbOfTuple(a1->getNumberOfTuples());
3234 if(nbOfTuple!=a2->getNumberOfTuples())
3235 throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Max !");
3236 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
3237 ret->alloc(nbOfTuple,nbOfComp);
3238 double *retPtr(ret->getPointer());
3239 const double *a1Ptr(a1->begin()),*a2Ptr(a2->begin());
3240 std::size_t nbElem(nbOfTuple*nbOfComp);
3241 for(std::size_t i=0;i<nbElem;i++)
3242 retPtr[i]=std::max(a1Ptr[i],a2Ptr[i]);
3243 ret->copyStringInfoFrom(*a1);
3248 * Returns a new DataArrayDouble containing minimal values of two given arrays.
3249 * Info on components is copied from the first of the given arrays.
3250 * Number of tuples and components in the given arrays must be the same.
3251 * \param [in] a1 - an array to compare values with another one.
3252 * \param [in] a2 - another array to compare values with the first one.
3253 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3254 * The caller is to delete this result array using decrRef() as it is no more
3256 * \throw If either \a a1 or \a a2 is NULL.
3257 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3258 * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
3260 DataArrayDouble *DataArrayDouble::Min(const DataArrayDouble *a1, const DataArrayDouble *a2)
3263 throw INTERP_KERNEL::Exception("DataArrayDouble::Min : input DataArrayDouble instance is NULL !");
3264 std::size_t nbOfComp(a1->getNumberOfComponents());
3265 if(nbOfComp!=a2->getNumberOfComponents())
3266 throw INTERP_KERNEL::Exception("Nb of components mismatch for array min !");
3267 std::size_t nbOfTuple(a1->getNumberOfTuples());
3268 if(nbOfTuple!=a2->getNumberOfTuples())
3269 throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array min !");
3270 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
3271 ret->alloc(nbOfTuple,nbOfComp);
3272 double *retPtr(ret->getPointer());
3273 const double *a1Ptr(a1->begin()),*a2Ptr(a2->begin());
3274 std::size_t nbElem(nbOfTuple*nbOfComp);
3275 for(std::size_t i=0;i<nbElem;i++)
3276 retPtr[i]=std::min(a1Ptr[i],a2Ptr[i]);
3277 ret->copyStringInfoFrom(*a1);
3282 * Returns a new DataArrayDouble that is the result of pow of two given arrays. There are 3
3285 * \param [in] a1 - an array to pow up.
3286 * \param [in] a2 - another array to sum up.
3287 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3288 * The caller is to delete this result array using decrRef() as it is no more
3290 * \throw If either \a a1 or \a a2 is NULL.
3291 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3292 * \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
3293 * \throw If there is a negative value in \a a1.
3295 DataArrayDouble *DataArrayDouble::Pow(const DataArrayDouble *a1, const DataArrayDouble *a2)
3298 throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : at least one of input instances is null !");
3299 int nbOfTuple=a1->getNumberOfTuples();
3300 int nbOfTuple2=a2->getNumberOfTuples();
3301 int nbOfComp=a1->getNumberOfComponents();
3302 int nbOfComp2=a2->getNumberOfComponents();
3303 if(nbOfTuple!=nbOfTuple2)
3304 throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of tuples mismatches !");
3305 if(nbOfComp!=1 || nbOfComp2!=1)
3306 throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of components of both arrays must be equal to 1 !");
3307 MCAuto<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbOfTuple,1);
3308 const double *ptr1(a1->begin()),*ptr2(a2->begin());
3309 double *ptr=ret->getPointer();
3310 for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
3314 *ptr=pow(*ptr1,*ptr2);
3318 std::ostringstream oss; oss << "DataArrayDouble::Pow : on tuple #" << i << " of a1 value is < 0 (" << *ptr1 << ") !";
3319 throw INTERP_KERNEL::Exception(oss.str().c_str());
3326 * Apply pow on values of another DataArrayDouble to values of \a this one.
3328 * \param [in] other - an array to pow to \a this one.
3329 * \throw If \a other is NULL.
3330 * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
3331 * \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
3332 * \throw If there is a negative value in \a this.
3334 void DataArrayDouble::powEqual(const DataArrayDouble *other)
3337 throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : input instance is null !");
3338 int nbOfTuple=getNumberOfTuples();
3339 int nbOfTuple2=other->getNumberOfTuples();
3340 int nbOfComp=getNumberOfComponents();
3341 int nbOfComp2=other->getNumberOfComponents();
3342 if(nbOfTuple!=nbOfTuple2)
3343 throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of tuples mismatches !");
3344 if(nbOfComp!=1 || nbOfComp2!=1)
3345 throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of components of both arrays must be equal to 1 !");
3346 double *ptr=getPointer();
3347 const double *ptrc=other->begin();
3348 for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
3351 *ptr=pow(*ptr,*ptrc);
3354 std::ostringstream oss; oss << "DataArrayDouble::powEqual : on tuple #" << i << " of this value is < 0 (" << *ptr << ") !";
3355 throw INTERP_KERNEL::Exception(oss.str().c_str());
3362 * This method is \b NOT wrapped into python because it can be useful only for performance reasons in C++ context.
3363 * All values in \a this must be 0. or 1. within eps error. 0 means false, 1 means true.
3364 * If an another value than 0 or 1 appear (within eps precision) an INTERP_KERNEL::Exception will be thrown.
3366 * \throw if \a this is not allocated.
3367 * \throw if \a this has not exactly one component.
3369 std::vector<bool> DataArrayDouble::toVectorOfBool(double eps) const
3372 if(getNumberOfComponents()!=1)
3373 throw INTERP_KERNEL::Exception("DataArrayDouble::toVectorOfBool : must be applied on single component array !");
3374 int nbt(getNumberOfTuples());
3375 std::vector<bool> ret(nbt);
3376 const double *pt(begin());
3377 for(int i=0;i<nbt;i++)
3381 else if(fabs(pt[i]-1.)<eps)
3385 std::ostringstream oss; oss << "DataArrayDouble::toVectorOfBool : the tuple #" << i << " has value " << pt[i] << " is invalid ! must be 0. or 1. !";
3386 throw INTERP_KERNEL::Exception(oss.str().c_str());
3393 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
3396 void DataArrayDouble::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
3401 tinyInfo[0]=getNumberOfTuples();
3402 tinyInfo[1]=getNumberOfComponents();
3412 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
3415 void DataArrayDouble::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
3419 int nbOfCompo=getNumberOfComponents();
3420 tinyInfo.resize(nbOfCompo+1);
3421 tinyInfo[0]=getName();
3422 for(int i=0;i<nbOfCompo;i++)
3423 tinyInfo[i+1]=getInfoOnComponent(i);
3428 tinyInfo[0]=getName();
3433 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
3434 * This method returns if a feeding is needed.
3436 bool DataArrayDouble::resizeForUnserialization(const std::vector<int>& tinyInfoI)
3438 int nbOfTuple=tinyInfoI[0];
3439 int nbOfComp=tinyInfoI[1];
3440 if(nbOfTuple!=-1 || nbOfComp!=-1)
3442 alloc(nbOfTuple,nbOfComp);
3449 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
3451 void DataArrayDouble::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
3453 setName(tinyInfoS[0]);
3456 int nbOfCompo=getNumberOfComponents();
3457 for(int i=0;i<nbOfCompo;i++)
3458 setInfoOnComponent(i,tinyInfoS[i+1]);
3463 * Low static method that operates 3D rotation of 'nbNodes' 3D nodes whose coordinates are arranged in \a coordsIn
3464 * around an axe ( \a center, \a vect) and with angle \a angle.
3466 void DataArrayDouble::Rotate3DAlg(const double *center, const double *vect, double angle, int nbNodes, const double *coordsIn, double *coordsOut)
3468 if(!center || !vect)
3469 throw INTERP_KERNEL::Exception("DataArrayDouble::Rotate3DAlg : null vector in input !");
3470 double sina(sin(angle));
3471 double cosa(cos(angle));
3472 double vectorNorm[3];
3474 double matrixTmp[9];
3475 double norm(sqrt(vect[0]*vect[0]+vect[1]*vect[1]+vect[2]*vect[2]));
3476 if(norm<std::numeric_limits<double>::min())
3477 throw INTERP_KERNEL::Exception("DataArrayDouble::Rotate3DAlg : magnitude of input vector is too close of 0. !");
3478 std::transform(vect,vect+3,vectorNorm,std::bind2nd(std::multiplies<double>(),1/norm));
3479 //rotation matrix computation
3480 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;
3481 matrixTmp[0]=vectorNorm[0]*vectorNorm[0]; matrixTmp[1]=vectorNorm[0]*vectorNorm[1]; matrixTmp[2]=vectorNorm[0]*vectorNorm[2];
3482 matrixTmp[3]=vectorNorm[1]*vectorNorm[0]; matrixTmp[4]=vectorNorm[1]*vectorNorm[1]; matrixTmp[5]=vectorNorm[1]*vectorNorm[2];
3483 matrixTmp[6]=vectorNorm[2]*vectorNorm[0]; matrixTmp[7]=vectorNorm[2]*vectorNorm[1]; matrixTmp[8]=vectorNorm[2]*vectorNorm[2];
3484 std::transform(matrixTmp,matrixTmp+9,matrixTmp,std::bind2nd(std::multiplies<double>(),1-cosa));
3485 std::transform(matrix,matrix+9,matrixTmp,matrix,std::plus<double>());
3486 matrixTmp[0]=0.; matrixTmp[1]=-vectorNorm[2]; matrixTmp[2]=vectorNorm[1];
3487 matrixTmp[3]=vectorNorm[2]; matrixTmp[4]=0.; matrixTmp[5]=-vectorNorm[0];
3488 matrixTmp[6]=-vectorNorm[1]; matrixTmp[7]=vectorNorm[0]; matrixTmp[8]=0.;
3489 std::transform(matrixTmp,matrixTmp+9,matrixTmp,std::bind2nd(std::multiplies<double>(),sina));
3490 std::transform(matrix,matrix+9,matrixTmp,matrix,std::plus<double>());
3491 //rotation matrix computed.
3493 for(int i=0; i<nbNodes; i++)
3495 std::transform(coordsIn+i*3,coordsIn+(i+1)*3,center,tmp,std::minus<double>());
3496 coordsOut[i*3]=matrix[0]*tmp[0]+matrix[1]*tmp[1]+matrix[2]*tmp[2]+center[0];
3497 coordsOut[i*3+1]=matrix[3]*tmp[0]+matrix[4]*tmp[1]+matrix[5]*tmp[2]+center[1];
3498 coordsOut[i*3+2]=matrix[6]*tmp[0]+matrix[7]*tmp[1]+matrix[8]*tmp[2]+center[2];
3502 void DataArrayDouble::Symmetry3DPlane(const double point[3], const double normalVector[3], int nbNodes, const double *coordsIn, double *coordsOut)
3504 double matrix[9],matrix2[9],matrix3[9];
3505 double vect[3],crossVect[3];
3506 INTERP_KERNEL::orthogonalVect3(normalVector,vect);
3507 crossVect[0]=normalVector[1]*vect[2]-normalVector[2]*vect[1];
3508 crossVect[1]=normalVector[2]*vect[0]-normalVector[0]*vect[2];
3509 crossVect[2]=normalVector[0]*vect[1]-normalVector[1]*vect[0];
3510 double nv(INTERP_KERNEL::norm<3>(vect)),ni(INTERP_KERNEL::norm<3>(normalVector)),nc(INTERP_KERNEL::norm<3>(crossVect));
3511 matrix[0]=vect[0]/nv; matrix[1]=crossVect[0]/nc; matrix[2]=-normalVector[0]/ni;
3512 matrix[3]=vect[1]/nv; matrix[4]=crossVect[1]/nc; matrix[5]=-normalVector[1]/ni;
3513 matrix[6]=vect[2]/nv; matrix[7]=crossVect[2]/nc; matrix[8]=-normalVector[2]/ni;
3514 matrix2[0]=vect[0]/nv; matrix2[1]=vect[1]/nv; matrix2[2]=vect[2]/nv;
3515 matrix2[3]=crossVect[0]/nc; matrix2[4]=crossVect[1]/nc; matrix2[5]=crossVect[2]/nc;
3516 matrix2[6]=normalVector[0]/ni; matrix2[7]=normalVector[1]/ni; matrix2[8]=normalVector[2]/ni;
3517 for(int i=0;i<3;i++)
3518 for(int j=0;j<3;j++)
3521 for(int k=0;k<3;k++)
3522 val+=matrix[3*i+k]*matrix2[3*k+j];
3525 //rotation matrix computed.
3527 for(int i=0; i<nbNodes; i++)
3529 std::transform(coordsIn+i*3,coordsIn+(i+1)*3,point,tmp,std::minus<double>());
3530 coordsOut[i*3]=matrix3[0]*tmp[0]+matrix3[1]*tmp[1]+matrix3[2]*tmp[2]+point[0];
3531 coordsOut[i*3+1]=matrix3[3]*tmp[0]+matrix3[4]*tmp[1]+matrix3[5]*tmp[2]+point[1];
3532 coordsOut[i*3+2]=matrix3[6]*tmp[0]+matrix3[7]*tmp[1]+matrix3[8]*tmp[2]+point[2];
3536 void DataArrayDouble::GiveBaseForPlane(const double normalVector[3], double baseOfPlane[9])
3538 double vect[3],crossVect[3];
3539 INTERP_KERNEL::orthogonalVect3(normalVector,vect);
3540 crossVect[0]=normalVector[1]*vect[2]-normalVector[2]*vect[1];
3541 crossVect[1]=normalVector[2]*vect[0]-normalVector[0]*vect[2];
3542 crossVect[2]=normalVector[0]*vect[1]-normalVector[1]*vect[0];
3543 double nv(INTERP_KERNEL::norm<3>(vect)),ni(INTERP_KERNEL::norm<3>(normalVector)),nc(INTERP_KERNEL::norm<3>(crossVect));
3544 baseOfPlane[0]=vect[0]/nv; baseOfPlane[1]=vect[1]/nv; baseOfPlane[2]=vect[2]/nv;
3545 baseOfPlane[3]=crossVect[0]/nc; baseOfPlane[4]=crossVect[1]/nc; baseOfPlane[5]=crossVect[2]/nc;
3546 baseOfPlane[6]=normalVector[0]/ni; baseOfPlane[7]=normalVector[1]/ni; baseOfPlane[8]=normalVector[2]/ni;
3550 * Low static method that operates 3D rotation of \a nbNodes 3D nodes whose coordinates are arranged in \a coords
3551 * around the center point \a center and with angle \a angle.
3553 void DataArrayDouble::Rotate2DAlg(const double *center, double angle, int nbNodes, const double *coordsIn, double *coordsOut)
3555 double cosa=cos(angle);
3556 double sina=sin(angle);
3558 matrix[0]=cosa; matrix[1]=-sina; matrix[2]=sina; matrix[3]=cosa;
3560 for(int i=0; i<nbNodes; i++)
3562 std::transform(coordsIn+i*2,coordsIn+(i+1)*2,center,tmp,std::minus<double>());
3563 coordsOut[i*2]=matrix[0]*tmp[0]+matrix[1]*tmp[1]+center[0];
3564 coordsOut[i*2+1]=matrix[2]*tmp[0]+matrix[3]*tmp[1]+center[1];
3568 DataArrayDoubleIterator::DataArrayDoubleIterator(DataArrayDouble *da):DataArrayIterator<double>(da)
3572 DataArrayDoubleTuple::DataArrayDoubleTuple(double *pt, int nbOfComp):DataArrayTuple<double>(pt,nbOfComp)
3577 std::string DataArrayDoubleTuple::repr() const
3579 std::ostringstream oss; oss.precision(17); oss << "(";
3580 for(int i=0;i<_nb_of_compo-1;i++)
3581 oss << _pt[i] << ", ";
3582 oss << _pt[_nb_of_compo-1] << ")";
3586 double DataArrayDoubleTuple::doubleValue() const
3588 return this->zeValue();
3592 * This method returns a newly allocated instance the caller should dealed with by a MEDCoupling::DataArrayDouble::decrRef.
3593 * This method performs \b no copy of data. The content is only referenced using MEDCoupling::DataArrayDouble::useArray with ownership set to \b false.
3594 * 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
3595 * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
3597 DataArrayDouble *DataArrayDoubleTuple::buildDADouble(int nbOfTuples, int nbOfCompo) const
3599 return this->buildDA(nbOfTuples,nbOfCompo);
3603 * Returns a new instance of DataArrayInt. The caller is to delete this array
3604 * using decrRef() as it is no more needed.
3606 DataArrayInt *DataArrayInt::New()
3608 return new DataArrayInt;
3612 * Returns the only one value in \a this, if and only if number of elements
3613 * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
3614 * \return double - the sole value stored in \a this array.
3615 * \throw If at least one of conditions stated above is not fulfilled.
3617 int DataArrayInt::intValue() const
3621 if(getNbOfElems()==1)
3623 return *getConstPointer();
3626 throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is allocated but number of elements is not equal to 1 !");
3629 throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is not allocated !");
3633 * Returns an integer value characterizing \a this array, which is useful for a quick
3634 * comparison of many instances of DataArrayInt.
3635 * \return int - the hash value.
3636 * \throw If \a this is not allocated.
3638 int DataArrayInt::getHashCode() const
3641 std::size_t nbOfElems=getNbOfElems();
3642 int ret=nbOfElems*65536;
3647 const int *pt=begin();
3648 for(std::size_t i=0;i<nbOfElems;i+=delta)
3649 ret0+=pt[i] & 0x1FFF;
3654 * Returns a full copy of \a this. For more info on copying data arrays see
3655 * \ref MEDCouplingArrayBasicsCopyDeep.
3656 * \return DataArrayInt * - a new instance of DataArrayInt.
3658 DataArrayInt32 *DataArrayInt32::deepCopy() const
3660 return new DataArrayInt32(*this);
3664 * Returns a textual and human readable representation of \a this instance of
3665 * DataArrayInt. This text is shown when a DataArrayInt is printed in Python.
3666 * \return std::string - text describing \a this DataArrayInt.
3668 * \sa reprNotTooLong, reprZip
3670 std::string DataArrayInt::repr() const
3672 std::ostringstream ret;
3677 std::string DataArrayInt::reprZip() const
3679 std::ostringstream ret;
3684 void DataArrayInt::writeVTK(std::ostream& ofs, int indent, const std::string& type, const std::string& nameInFile, DataArrayByte *byteArr) const
3686 static const char SPACE[4]={' ',' ',' ',' '};
3688 std::string idt(indent,' ');
3689 ofs << idt << "<DataArray type=\"" << type << "\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
3692 ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
3693 if(std::string(type)=="Int32")
3695 const char *data(reinterpret_cast<const char *>(begin()));
3696 std::size_t sz(getNbOfElems()*sizeof(int));
3697 byteArr->insertAtTheEnd(data,data+sz);
3698 byteArr->insertAtTheEnd(SPACE,SPACE+4);
3700 else if(std::string(type)=="Int8")
3702 INTERP_KERNEL::AutoPtr<char> tmp(new char[getNbOfElems()]);
3703 std::copy(begin(),end(),(char *)tmp);
3704 byteArr->insertAtTheEnd((char *)tmp,(char *)tmp+getNbOfElems());
3705 byteArr->insertAtTheEnd(SPACE,SPACE+4);
3707 else if(std::string(type)=="UInt8")
3709 INTERP_KERNEL::AutoPtr<unsigned char> tmp(new unsigned char[getNbOfElems()]);
3710 std::copy(begin(),end(),(unsigned char *)tmp);
3711 byteArr->insertAtTheEnd((unsigned char *)tmp,(unsigned char *)tmp+getNbOfElems());
3712 byteArr->insertAtTheEnd(SPACE,SPACE+4);
3715 throw INTERP_KERNEL::Exception("DataArrayInt::writeVTK : Only Int32, Int8 and UInt8 supported !");
3719 ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
3720 std::copy(begin(),end(),std::ostream_iterator<int>(ofs," "));
3722 ofs << std::endl << idt << "</DataArray>\n";
3725 void DataArrayInt::reprCppStream(const std::string& varName, std::ostream& stream) const
3727 int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
3728 const int *data=getConstPointer();
3729 stream << "DataArrayInt *" << varName << "=DataArrayInt::New();" << std::endl;
3730 if(nbTuples*nbComp>=1)
3732 stream << "const int " << varName << "Data[" << nbTuples*nbComp << "]={";
3733 std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<int>(stream,","));
3734 stream << data[nbTuples*nbComp-1] << "};" << std::endl;
3735 stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
3738 stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
3739 stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
3743 * Method that gives a quick overvien of \a this for python.
3745 void DataArrayInt::reprQuickOverview(std::ostream& stream) const
3747 static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
3748 stream << "DataArrayInt C++ instance at " << this << ". ";
3751 int nbOfCompo=(int)_info_on_compo.size();
3754 int nbOfTuples=getNumberOfTuples();
3755 stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
3756 reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
3759 stream << "Number of components : 0.";
3762 stream << "*** No data allocated ****";
3765 void DataArrayInt::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
3767 const int *data=begin();
3768 int nbOfTuples=getNumberOfTuples();
3769 int nbOfCompo=(int)_info_on_compo.size();
3770 std::ostringstream oss2; oss2 << "[";
3771 std::string oss2Str(oss2.str());
3772 bool isFinished=true;
3773 for(int i=0;i<nbOfTuples && isFinished;i++)
3778 for(int j=0;j<nbOfCompo;j++,data++)
3781 if(j!=nbOfCompo-1) oss2 << ", ";
3787 if(i!=nbOfTuples-1) oss2 << ", ";
3788 std::string oss3Str(oss2.str());
3789 if(oss3Str.length()<maxNbOfByteInRepr)
3801 * Computes distribution of values of \a this one-dimensional array between given value
3802 * ranges (casts). This method is typically useful for entity number spliting by types,
3804 * \warning The values contained in \a arrBg should be sorted ascendently. No
3805 * check of this is be done. If not, the result is not warranted.
3806 * \param [in] arrBg - the array of ascending values defining the value ranges. The i-th
3807 * value of \a arrBg (\a arrBg[ i ]) gives the lowest value of the i-th range,
3808 * and the greatest value of the i-th range equals to \a arrBg[ i+1 ] - 1. \a
3809 * arrBg containing \a n values defines \a n-1 ranges. The last value of \a arrBg
3810 * should be more than every value in \a this array.
3811 * \param [in] arrEnd - specifies the end of the array \a arrBg, so that
3812 * the last value of \a arrBg is \a arrEnd[ -1 ].
3813 * \param [out] castArr - a new instance of DataArrayInt, of same size as \a this array
3814 * (same number of tuples and components), the caller is to delete
3815 * using decrRef() as it is no more needed.
3816 * This array contains indices of ranges for every value of \a this array. I.e.
3817 * the i-th value of \a castArr gives the index of range the i-th value of \a this
3818 * belongs to. Or, in other words, this parameter contains for each tuple in \a
3819 * this in which cast it holds.
3820 * \param [out] rankInsideCast - a new instance of DataArrayInt, of same size as \a this
3821 * array, the caller is to delete using decrRef() as it is no more needed.
3822 * This array contains ranks of values of \a this array within ranges
3823 * they belongs to. I.e. the i-th value of \a rankInsideCast gives the rank of
3824 * the i-th value of \a this array within the \a castArr[ i ]-th range, to which
3825 * the i-th value of \a this belongs to. Or, in other words, this param contains
3826 * for each tuple its rank inside its cast. The rank is computed as difference
3827 * between the value and the lowest value of range.
3828 * \param [out] castsPresent - a new instance of DataArrayInt, containing indices of
3829 * ranges (casts) to which at least one value of \a this array belongs.
3830 * Or, in other words, this param contains the casts that \a this contains.
3831 * The caller is to delete this array using decrRef() as it is no more needed.
3833 * \b Example: If \a this contains [6,5,0,3,2,7,8,1,4] and \a arrBg contains [0,4,9] then
3834 * the output of this method will be :
3835 * - \a castArr : [1,1,0,0,0,1,1,0,1]
3836 * - \a rankInsideCast: [2,1,0,3,2,3,4,1,0]
3837 * - \a castsPresent : [0,1]
3839 * I.e. values of \a this array belong to 2 ranges: #0 and #1. Value 6 belongs to the
3840 * range #1 and its rank within this range is 2; etc.
3842 * \throw If \a this->getNumberOfComponents() != 1.
3843 * \throw If \a arrEnd - arrBg < 2.
3844 * \throw If any value of \a this is not less than \a arrEnd[-1].
3846 void DataArrayInt::splitByValueRange(const int *arrBg, const int *arrEnd,
3847 DataArrayInt *& castArr, DataArrayInt *& rankInsideCast, DataArrayInt *& castsPresent) const
3850 if(getNumberOfComponents()!=1)
3851 throw INTERP_KERNEL::Exception("Call splitByValueRange method on DataArrayInt with only one component, you can call 'rearrange' method before !");
3852 int nbOfTuples=getNumberOfTuples();
3853 std::size_t nbOfCast=std::distance(arrBg,arrEnd);
3855 throw INTERP_KERNEL::Exception("DataArrayInt::splitByValueRange : The input array giving the cast range values should be of size >=2 !");
3857 const int *work=getConstPointer();
3858 typedef std::reverse_iterator<const int *> rintstart;
3859 rintstart bg(arrEnd);//OK no problem because size of 'arr' is greater or equal 2
3860 rintstart end2(arrBg);
3861 MCAuto<DataArrayInt> ret1=DataArrayInt::New();
3862 MCAuto<DataArrayInt> ret2=DataArrayInt::New();
3863 MCAuto<DataArrayInt> ret3=DataArrayInt::New();
3864 ret1->alloc(nbOfTuples,1);
3865 ret2->alloc(nbOfTuples,1);
3866 int *ret1Ptr=ret1->getPointer();
3867 int *ret2Ptr=ret2->getPointer();
3868 std::set<std::size_t> castsDetected;
3869 for(int i=0;i<nbOfTuples;i++)
3871 rintstart res=std::find_if(bg,end2,std::bind2nd(std::less_equal<int>(), work[i]));
3872 std::size_t pos=std::distance(bg,res);
3873 std::size_t pos2=nbOfCast-pos;
3876 ret1Ptr[i]=(int)pos2;
3877 ret2Ptr[i]=work[i]-arrBg[pos2];
3878 castsDetected.insert(pos2);
3882 std::ostringstream oss; oss << "DataArrayInt::splitByValueRange : At rank #" << i << " the value is " << work[i] << " should be in [0," << *bg << ") !";
3883 throw INTERP_KERNEL::Exception(oss.str().c_str());
3886 ret3->alloc((int)castsDetected.size(),1);
3887 std::copy(castsDetected.begin(),castsDetected.end(),ret3->getPointer());
3888 castArr=ret1.retn();
3889 rankInsideCast=ret2.retn();
3890 castsPresent=ret3.retn();
3894 * 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 ).
3895 * 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 ).
3896 * This method works only if \a this is allocated and single component. If not an exception will be thrown.
3898 * \param [out] strt - the start of the range (included) if true is returned.
3899 * \param [out] sttoopp - the end of the range (not included) if true is returned.
3900 * \param [out] stteepp - the step of the range if true is returned.
3901 * \return the verdict of the check.
3903 * \sa DataArray::GetNumberOfItemGivenBES
3905 bool DataArrayInt::isRange(int& strt, int& sttoopp, int& stteepp) const
3908 if(getNumberOfComponents()!=1)
3909 throw INTERP_KERNEL::Exception("DataArrayInt::isRange : this must be single component array !");
3910 int nbTuples(getNumberOfTuples());
3912 { strt=0; sttoopp=0; stteepp=1; return true; }
3913 const int *pt(begin());
3916 { sttoopp=strt+1; stteepp=1; return true; }
3917 strt=*pt; sttoopp=pt[nbTuples-1];
3923 int a(sttoopp-1-strt),tmp(strt);
3924 if(a%(nbTuples-1)!=0)
3926 stteepp=a/(nbTuples-1);
3927 for(int i=0;i<nbTuples;i++,tmp+=stteepp)
3935 int a(strt-sttoopp-1),tmp(strt);
3936 if(a%(nbTuples-1)!=0)
3938 stteepp=-(a/(nbTuples-1));
3939 for(int i=0;i<nbTuples;i++,tmp+=stteepp)
3948 * Modifies in place \a this one-dimensional array so that each value \a v = \a indArrBg[ \a v ],
3949 * i.e. a current value is used as in index to get a new value from \a indArrBg.
3950 * \param [in] indArrBg - pointer to the first element of array of new values to assign
3952 * \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
3953 * the last value of \a indArrBg is \a indArrEnd[ -1 ].
3954 * \throw If \a this->getNumberOfComponents() != 1
3955 * \throw If any value of \a this can't be used as a valid index for
3956 * [\a indArrBg, \a indArrEnd).
3960 void DataArrayInt::transformWithIndArr(const int *indArrBg, const int *indArrEnd)
3962 this->checkAllocated();
3963 if(this->getNumberOfComponents()!=1)
3964 throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
3965 int nbElemsIn((int)std::distance(indArrBg,indArrEnd)),nbOfTuples(getNumberOfTuples()),*pt(getPointer());
3966 for(int i=0;i<nbOfTuples;i++,pt++)
3968 if(*pt>=0 && *pt<nbElemsIn)
3972 std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " of this value is " << *pt << ", should be in [0," << nbElemsIn << ") !";
3973 throw INTERP_KERNEL::Exception(oss.str().c_str());
3976 this->declareAsNew();
3979 void DataArrayInt::transformWithIndArr(const MapKeyVal<int>& m)
3981 this->checkAllocated();
3982 if(this->getNumberOfComponents()!=1)
3983 throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
3984 const std::map<int,int> dat(m.data());
3985 int nbOfTuples(getNumberOfTuples()),*pt(getPointer());
3986 for(int i=0;i<nbOfTuples;i++,pt++)
3988 std::map<int,int>::const_iterator it(dat.find(*pt));
3993 std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " of this value is " << *pt << " not in map !";
3994 throw INTERP_KERNEL::Exception(oss.str().c_str());
3997 this->declareAsNew();
4001 * Creates a one-dimensional DataArrayInt (\a res) whose contents are computed from
4002 * values of \a this (\a a) and the given (\a indArr) arrays as follows:
4003 * \a res[ \a indArr[ \a a[ i ]]] = i. I.e. for each value in place i \a v = \a a[ i ],
4004 * new value in place \a indArr[ \a v ] is i.
4005 * \param [in] indArrBg - the array holding indices within the result array to assign
4006 * indices of values of \a this array pointing to values of \a indArrBg.
4007 * \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
4008 * the last value of \a indArrBg is \a indArrEnd[ -1 ].
4009 * \return DataArrayInt * - the new instance of DataArrayInt.
4010 * The caller is to delete this result array using decrRef() as it is no more
4012 * \throw If \a this->getNumberOfComponents() != 1.
4013 * \throw If any value of \a this array is not a valid index for \a indArrBg array.
4014 * \throw If any value of \a indArrBg is not a valid index for \a this array.
4016 DataArrayInt *DataArrayInt::transformWithIndArrR(const int *indArrBg, const int *indArrEnd) const
4019 if(getNumberOfComponents()!=1)
4020 throw INTERP_KERNEL::Exception("Call transformWithIndArrR method on DataArrayInt with only one component, you can call 'rearrange' method before !");
4021 int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
4022 int nbOfTuples=getNumberOfTuples();
4023 const int *pt=getConstPointer();
4024 MCAuto<DataArrayInt> ret=DataArrayInt::New();
4025 ret->alloc(nbOfTuples,1);
4026 ret->fillWithValue(-1);
4027 int *tmp=ret->getPointer();
4028 for(int i=0;i<nbOfTuples;i++,pt++)
4030 if(*pt>=0 && *pt<nbElemsIn)
4032 int pos=indArrBg[*pt];
4033 if(pos>=0 && pos<nbOfTuples)
4037 std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value of new pos is " << pos << " ( indArrBg[" << *pt << "]) ! Should be in [0," << nbOfTuples << ") !";
4038 throw INTERP_KERNEL::Exception(oss.str().c_str());
4043 std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn << " !";
4044 throw INTERP_KERNEL::Exception(oss.str().c_str());
4051 * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
4052 * from values of \a this array, which is supposed to contain a renumbering map in
4053 * "Old to New" mode. The result array contains a renumbering map in "New to Old" mode.
4054 * To know how to use the renumbering maps see \ref numbering.
4055 * \param [in] newNbOfElem - the number of tuples in the result array.
4056 * \return DataArrayInt * - the new instance of DataArrayInt.
4057 * The caller is to delete this result array using decrRef() as it is no more
4060 * \if ENABLE_EXAMPLES
4061 * \ref cpp_mcdataarrayint_invertarrayo2n2n2o "Here is a C++ example".<br>
4062 * \ref py_mcdataarrayint_invertarrayo2n2n2o "Here is a Python example".
4065 DataArrayInt *DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const
4067 MCAuto<DataArrayInt> ret(DataArrayInt::New());
4068 ret->alloc(newNbOfElem,1);
4069 int nbOfOldNodes(this->getNumberOfTuples());
4070 const int *old2New(begin());
4071 int *pt(ret->getPointer());
4072 for(int i=0;i!=nbOfOldNodes;i++)
4074 int newp(old2New[i]);
4077 if(newp>=0 && newp<newNbOfElem)
4081 std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2O : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
4082 throw INTERP_KERNEL::Exception(oss.str().c_str());
4090 * This method is similar to DataArrayInt::invertArrayO2N2N2O except that
4091 * 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]
4093 DataArrayInt *DataArrayInt::invertArrayO2N2N2OBis(int newNbOfElem) const
4095 MCAuto<DataArrayInt> ret=DataArrayInt::New();
4096 ret->alloc(newNbOfElem,1);
4097 int nbOfOldNodes=getNumberOfTuples();
4098 const int *old2New=getConstPointer();
4099 int *pt=ret->getPointer();
4100 for(int i=nbOfOldNodes-1;i>=0;i--)
4102 int newp(old2New[i]);
4105 if(newp>=0 && newp<newNbOfElem)
4109 std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2OBis : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
4110 throw INTERP_KERNEL::Exception(oss.str().c_str());
4118 * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
4119 * from values of \a this array, which is supposed to contain a renumbering map in
4120 * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
4121 * To know how to use the renumbering maps see \ref numbering.
4122 * \param [in] newNbOfElem - the number of tuples in the result array.
4123 * \return DataArrayInt * - the new instance of DataArrayInt.
4124 * The caller is to delete this result array using decrRef() as it is no more
4127 * \if ENABLE_EXAMPLES
4128 * \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
4130 * \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
4131 * \sa invertArrayN2O2O2NOptimized
4134 DataArrayInt *DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const
4137 MCAuto<DataArrayInt> ret=DataArrayInt::New();
4138 ret->alloc(oldNbOfElem,1);
4139 const int *new2Old=getConstPointer();
4140 int *pt=ret->getPointer();
4141 std::fill(pt,pt+oldNbOfElem,-1);
4142 int nbOfNewElems=getNumberOfTuples();
4143 for(int i=0;i<nbOfNewElems;i++)
4146 if(v>=0 && v<oldNbOfElem)
4150 std::ostringstream oss; oss << "DataArrayInt::invertArrayN2O2O2N : in new id #" << i << " old value is " << v << " expected to be in [0," << oldNbOfElem << ") !";
4151 throw INTERP_KERNEL::Exception(oss.str().c_str());
4158 * Creates a map, whose contents are computed
4159 * from values of \a this array, which is supposed to contain a renumbering map in
4160 * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
4161 * To know how to use the renumbering maps see \ref numbering.
4162 * \param [in] newNbOfElem - the number of tuples in the result array.
4163 * \return MapII - the new instance of Map.
4165 * \if ENABLE_EXAMPLES
4166 * \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
4168 * \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
4169 * \sa invertArrayN2O2O2N
4172 MCAuto< MapKeyVal<int> > DataArrayInt::invertArrayN2O2O2NOptimized() const
4175 MCAuto< MapKeyVal<int> > ret(MapKeyVal<int>::New());
4176 std::map<int,int>& m(ret->data());
4177 const int *new2Old(begin());
4178 int nbOfNewElems(this->getNumberOfTuples());
4179 for(int i=0;i<nbOfNewElems;i++)
4188 * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode.
4189 * This map, if applied to \a this array, would make it sorted. For example, if
4190 * \a this array contents are [9,10,0,6,4,11,3,7] then the contents of the result array
4191 * are [5,6,0,3,2,7,1,4]; if this result array (\a res) is used as an argument in call
4192 * \a this->renumber(\a res) then the returned array contains [0,3,4,6,7,9,10,11].
4193 * This method is useful for renumbering (in MED file for example). For more info
4194 * on renumbering see \ref numbering.
4195 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4196 * array using decrRef() as it is no more needed.
4197 * \throw If \a this is not allocated.
4198 * \throw If \a this->getNumberOfComponents() != 1.
4199 * \throw If there are equal values in \a this array.
4201 DataArrayInt *DataArrayInt::checkAndPreparePermutation() const
4204 if(getNumberOfComponents()!=1)
4205 throw INTERP_KERNEL::Exception("DataArrayInt::checkAndPreparePermutation : number of components must == 1 !");
4206 int nbTuples=getNumberOfTuples();
4207 const int *pt=getConstPointer();
4208 int *pt2=CheckAndPreparePermutation(pt,pt+nbTuples);
4209 DataArrayInt *ret=DataArrayInt::New();
4210 ret->useArray(pt2,true,C_DEALLOC,nbTuples,1);
4215 * 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
4216 * input array \a ids2.
4217 * \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.
4218 * 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
4220 * In case of success (no throw) : \c ids1->renumber(ret)->isEqual(ids2) where \a ret is the return of this method.
4222 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4223 * array using decrRef() as it is no more needed.
4224 * \throw If either ids1 or ids2 is null not allocated or not with one components.
4227 DataArrayInt *DataArrayInt::FindPermutationFromFirstToSecond(const DataArrayInt *ids1, const DataArrayInt *ids2)
4230 throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be not null !");
4231 if(!ids1->isAllocated() || !ids2->isAllocated())
4232 throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be allocated !");
4233 if(ids1->getNumberOfComponents()!=1 || ids2->getNumberOfComponents()!=1)
4234 throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays have exactly one component !");
4235 if(ids1->getNumberOfTuples()!=ids2->getNumberOfTuples())
4237 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 !";
4238 throw INTERP_KERNEL::Exception(oss.str().c_str());
4240 MCAuto<DataArrayInt> p1(ids1->deepCopy());
4241 MCAuto<DataArrayInt> p2(ids2->deepCopy());
4242 p1->sort(true); p2->sort(true);
4243 if(!p1->isEqualWithoutConsideringStr(*p2))
4244 throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two arrays are not lying on same ids ! Impossible to find a permutation between the 2 arrays !");
4245 p1=ids1->checkAndPreparePermutation();
4246 p2=ids2->checkAndPreparePermutation();
4247 p2=p2->invertArrayO2N2N2O(p2->getNumberOfTuples());
4248 p2=p2->selectByTupleIdSafe(p1->begin(),p1->end());
4253 * Returns two arrays describing a surjective mapping from \a this set of values (\a A)
4254 * onto a set of values of size \a targetNb (\a B). The surjective function is
4255 * \a B[ \a A[ i ]] = i. That is to say that for each \a id in [0,\a targetNb), where \a
4256 * targetNb < \a this->getNumberOfTuples(), there exists at least one tupleId (\a tid) so
4257 * that <em> this->getIJ( tid, 0 ) == id</em>. <br>
4258 * The first of out arrays returns indices of elements of \a this array, grouped by their
4259 * place in the set \a B. The second out array is the index of the first one; it shows how
4260 * many elements of \a A are mapped into each element of \a B. <br>
4262 * mapping and its usage in renumbering see \ref numbering. <br>
4264 * - \a this: [0,3,2,3,2,2,1,2]
4266 * - \a arr: [0, 6, 2,4,5,7, 1,3]
4267 * - \a arrI: [0,1,2,6,8]
4269 * This result means: <br>
4270 * the element of \a B 0 encounters within \a A once (\a arrI[ 0+1 ] - \a arrI[ 0 ]) and
4271 * its index within \a A is 0 ( \a arr[ 0:1 ] == \a arr[ \a arrI[ 0 ] : \a arrI[ 0+1 ]]);<br>
4272 * the element of \a B 2 encounters within \a A 4 times (\a arrI[ 2+1 ] - \a arrI[ 2 ]) and
4273 * its indices within \a A are [2,4,5,7] ( \a arr[ 2:6 ] == \a arr[ \a arrI[ 2 ] :
4274 * \a arrI[ 2+1 ]]); <br> etc.
4275 * \param [in] targetNb - the size of the set \a B. \a targetNb must be equal or more
4276 * than the maximal value of \a A.
4277 * \param [out] arr - a new instance of DataArrayInt returning indices of
4278 * elements of \a this, grouped by their place in the set \a B. The caller is to delete
4279 * this array using decrRef() as it is no more needed.
4280 * \param [out] arrI - a new instance of DataArrayInt returning size of groups of equal
4281 * elements of \a this. The caller is to delete this array using decrRef() as it
4282 * is no more needed.
4283 * \throw If \a this is not allocated.
4284 * \throw If \a this->getNumberOfComponents() != 1.
4285 * \throw If any value in \a this is more or equal to \a targetNb.
4287 void DataArrayInt::changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, DataArrayInt *&arrI) const
4290 if(getNumberOfComponents()!=1)
4291 throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : number of components must == 1 !");
4292 int nbOfTuples=getNumberOfTuples();
4293 MCAuto<DataArrayInt> ret(DataArrayInt::New());
4294 MCAuto<DataArrayInt> retI(DataArrayInt::New());
4295 retI->alloc(targetNb+1,1);
4296 const int *input=getConstPointer();
4297 std::vector< std::vector<int> > tmp(targetNb);
4298 for(int i=0;i<nbOfTuples;i++)
4301 if(tmp2>=0 && tmp2<targetNb)
4302 tmp[tmp2].push_back(i);
4305 std::ostringstream oss; oss << "DataArrayInt::changeSurjectiveFormat : At pos " << i << " presence of element " << tmp2 << " ! should be in [0," << targetNb << ") !";
4306 throw INTERP_KERNEL::Exception(oss.str().c_str());
4309 int *retIPtr=retI->getPointer();
4311 for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++,retIPtr++)
4312 retIPtr[1]=retIPtr[0]+(int)((*it1).size());
4313 if(nbOfTuples!=retI->getIJ(targetNb,0))
4314 throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : big problem should never happen !");
4315 ret->alloc(nbOfTuples,1);
4316 int *retPtr=ret->getPointer();
4317 for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++)
4318 retPtr=std::copy((*it1).begin(),(*it1).end(),retPtr);
4325 * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode computed
4326 * from a zip representation of a surjective format (returned e.g. by
4327 * \ref MEDCoupling::DataArrayDouble::findCommonTuples() "DataArrayDouble::findCommonTuples()"
4328 * for example). The result array minimizes the permutation. <br>
4329 * For more info on renumbering see \ref numbering. <br>
4331 * - \a nbOfOldTuples: 10
4332 * - \a arr : [0,3, 5,7,9]
4333 * - \a arrIBg : [0,2,5]
4334 * - \a newNbOfTuples: 7
4335 * - result array : [0,1,2,0,3,4,5,4,6,4]
4337 * \param [in] nbOfOldTuples - number of tuples in the initial array \a arr.
4338 * \param [in] arr - the array of tuple indices grouped by \a arrIBg array.
4339 * \param [in] arrIBg - the array dividing all indices stored in \a arr into groups of
4340 * (indices of) equal values. Its every element (except the last one) points to
4341 * the first element of a group of equal values.
4342 * \param [in] arrIEnd - specifies the end of \a arrIBg, so that the last element of \a
4343 * arrIBg is \a arrIEnd[ -1 ].
4344 * \param [out] newNbOfTuples - number of tuples after surjection application.
4345 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4346 * array using decrRef() as it is no more needed.
4347 * \throw If any value of \a arr breaks condition ( 0 <= \a arr[ i ] < \a nbOfOldTuples ).
4349 DataArrayInt *DataArrayInt::ConvertIndexArrayToO2N(int nbOfOldTuples, const int *arr, const int *arrIBg, const int *arrIEnd, int &newNbOfTuples)
4351 MCAuto<DataArrayInt> ret=DataArrayInt::New();
4352 ret->alloc(nbOfOldTuples,1);
4353 int *pt=ret->getPointer();
4354 std::fill(pt,pt+nbOfOldTuples,-1);
4355 int nbOfGrps=((int)std::distance(arrIBg,arrIEnd))-1;
4356 const int *cIPtr=arrIBg;
4357 for(int i=0;i<nbOfGrps;i++)
4358 pt[arr[cIPtr[i]]]=-(i+2);
4360 for(int iNode=0;iNode<nbOfOldTuples;iNode++)
4368 int grpId=-(pt[iNode]+2);
4369 for(int j=cIPtr[grpId];j<cIPtr[grpId+1];j++)
4371 if(arr[j]>=0 && arr[j]<nbOfOldTuples)
4375 std::ostringstream oss; oss << "DataArrayInt::ConvertIndexArrayToO2N : With element #" << j << " value is " << arr[j] << " should be in [0," << nbOfOldTuples << ") !";
4376 throw INTERP_KERNEL::Exception(oss.str().c_str());
4383 newNbOfTuples=newNb;
4388 * Returns a new DataArrayInt containing a renumbering map in "New to Old" mode,
4389 * which if applied to \a this array would make it sorted ascendingly.
4390 * For more info on renumbering see \ref numbering. <br>
4392 * - \a this: [2,0,1,1,0,1,2,0,1,1,0,0]
4393 * - result: [10,0,5,6,1,7,11,2,8,9,3,4]
4394 * - after applying result to \a this: [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2]
4396 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4397 * array using decrRef() as it is no more needed.
4398 * \throw If \a this is not allocated.
4399 * \throw If \a this->getNumberOfComponents() != 1.
4401 DataArrayInt *DataArrayInt::buildPermArrPerLevel() const
4404 if(getNumberOfComponents()!=1)
4405 throw INTERP_KERNEL::Exception("DataArrayInt::buildPermArrPerLevel : number of components must == 1 !");
4406 int nbOfTuples=getNumberOfTuples();
4407 const int *pt=getConstPointer();
4408 std::map<int,int> m;
4409 MCAuto<DataArrayInt> ret=DataArrayInt::New();
4410 ret->alloc(nbOfTuples,1);
4411 int *opt=ret->getPointer();
4412 for(int i=0;i<nbOfTuples;i++,pt++,opt++)
4415 std::map<int,int>::iterator it=m.find(val);
4424 m.insert(std::pair<int,int>(val,1));
4428 for(std::map<int,int>::iterator it=m.begin();it!=m.end();it++)
4430 int vt=(*it).second;
4434 pt=getConstPointer();
4435 opt=ret->getPointer();
4436 for(int i=0;i<nbOfTuples;i++,pt++,opt++)
4443 * Checks if \a this array has the given size, and if its contents is equal to an array filled with
4444 * iota(). This method is particularly useful for DataArrayInt instances that represent
4445 * a renumbering array, to check if there is a real need in renumbering.
4446 * This method checks than \a this can be considered as an identity mapping
4447 * of a set having \a sizeExpected elements into itself.
4449 * \param [in] sizeExpected - The number of elements expected.
4450 * \return bool - \a true if \a this array contents == \a range( \a this->getNumberOfTuples())
4451 * \throw If \a this is not allocated.
4452 * \throw If \a this->getNumberOfComponents() != 1.
4454 bool DataArrayInt::isIota(int sizeExpected) const
4457 if(getNumberOfComponents()!=1)
4459 int nbOfTuples(getNumberOfTuples());
4460 if(nbOfTuples!=sizeExpected)
4462 const int *pt=getConstPointer();
4463 for(int i=0;i<nbOfTuples;i++,pt++)
4470 * Checks if all values in \a this array are equal to \a val.
4471 * \param [in] val - value to check equality of array values to.
4472 * \return bool - \a true if all values are \a val.
4473 * \throw If \a this is not allocated.
4474 * \throw If \a this->getNumberOfComponents() != 1
4475 * \sa DataArrayInt::checkUniformAndGuess
4477 bool DataArrayInt::isUniform(int val) const
4480 if(getNumberOfComponents()!=1)
4481 throw INTERP_KERNEL::Exception("DataArrayInt::isUniform : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
4482 const int *w(begin()),*end2(end());
4490 * This method checks that \a this is uniform. If not and exception will be thrown.
4491 * In case of uniformity the corresponding value is returned.
4493 * \return int - the unique value contained in this
4494 * \throw If \a this is not allocated.
4495 * \throw If \a this->getNumberOfComponents() != 1
4496 * \throw If \a this is not uniform.
4497 * \sa DataArrayInt::isUniform
4499 int DataArrayInt::checkUniformAndGuess() const
4502 if(getNumberOfComponents()!=1)
4503 throw INTERP_KERNEL::Exception("DataArrayInt::checkUniformAndGuess : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
4505 throw INTERP_KERNEL::Exception("DataArrayInt::checkUniformAndGuess : this is empty !");
4506 const int *w(begin()),*end2(end());
4510 throw INTERP_KERNEL::Exception("DataArrayInt::checkUniformAndGuess : this is not uniform !");
4515 * Checks if all values in \a this array are unique.
4516 * \return bool - \a true if condition above is true
4517 * \throw If \a this is not allocated.
4518 * \throw If \a this->getNumberOfComponents() != 1
4520 bool DataArrayInt::hasUniqueValues() const
4523 if(getNumberOfComponents()!=1)
4524 throw INTERP_KERNEL::Exception("DataArrayInt::hasOnlyUniqueValues: must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
4525 std::size_t nbOfTuples(getNumberOfTuples());
4526 std::set<int> s(begin(),end()); // in C++11, should use unordered_set (O(1) complexity)
4527 if (s.size() != nbOfTuples)
4533 * Copy all components in a specified order from another DataArrayInt.
4534 * The specified components become the first ones in \a this array.
4535 * Both numerical and textual data is copied. The number of tuples in \a this and
4536 * the other array can be different.
4537 * \param [in] a - the array to copy data from.
4538 * \param [in] compoIds - sequence of zero based indices of components, data of which is
4540 * \throw If \a a is NULL.
4541 * \throw If \a compoIds.size() != \a a->getNumberOfComponents().
4542 * \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
4544 * \if ENABLE_EXAMPLES
4545 * \ref py_mcdataarrayint_setselectedcomponents "Here is a Python example".
4548 void DataArrayInt::setSelectedComponents(const DataArrayInt *a, const std::vector<int>& compoIds)
4551 throw INTERP_KERNEL::Exception("DataArrayInt::setSelectedComponents : input DataArrayInt is NULL !");
4553 a->checkAllocated();
4554 copyPartOfStringInfoFrom2(compoIds,*a);
4555 std::size_t partOfCompoSz=compoIds.size();
4556 int nbOfCompo=getNumberOfComponents();
4557 int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
4558 const int *ac=a->getConstPointer();
4559 int *nc=getPointer();
4560 for(int i=0;i<nbOfTuples;i++)
4561 for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
4562 nc[nbOfCompo*i+compoIds[j]]=*ac;
4565 DataArrayIntIterator *DataArrayInt::iterator()
4567 return new DataArrayIntIterator(this);
4571 * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to a
4572 * given one. The ids are sorted in the ascending order.
4573 * \param [in] val - the value to find within \a this.
4574 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4575 * array using decrRef() as it is no more needed.
4576 * \throw If \a this is not allocated.
4577 * \throw If \a this->getNumberOfComponents() != 1.
4578 * \sa DataArrayInt::findIdsEqualTuple
4580 DataArrayInt *DataArrayInt::findIdsEqual(int val) const
4583 if(getNumberOfComponents()!=1)
4584 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqual : the array must have only one component, you can call 'rearrange' method before !");
4585 const int *cptr(getConstPointer());
4586 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4587 int nbOfTuples=getNumberOfTuples();
4588 for(int i=0;i<nbOfTuples;i++,cptr++)
4590 ret->pushBackSilent(i);
4595 * Creates a new DataArrayInt containing IDs (indices) of tuples holding value \b not
4596 * equal to a given one.
4597 * \param [in] val - the value to ignore within \a this.
4598 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4599 * array using decrRef() as it is no more needed.
4600 * \throw If \a this is not allocated.
4601 * \throw If \a this->getNumberOfComponents() != 1.
4603 DataArrayInt *DataArrayInt::findIdsNotEqual(int val) const
4606 if(getNumberOfComponents()!=1)
4607 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotEqual : the array must have only one component, you can call 'rearrange' method before !");
4608 const int *cptr(getConstPointer());
4609 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4610 int nbOfTuples=getNumberOfTuples();
4611 for(int i=0;i<nbOfTuples;i++,cptr++)
4613 ret->pushBackSilent(i);
4618 * Creates a new DataArrayInt containing IDs (indices) of tuples holding tuple equal to those defined by [ \a tupleBg , \a tupleEnd )
4619 * This method is an extension of DataArrayInt::findIdsEqual method.
4621 * \param [in] tupleBg - the begin (included) of the input tuple to find within \a this.
4622 * \param [in] tupleEnd - the end (excluded) of the input tuple to find within \a this.
4623 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4624 * array using decrRef() as it is no more needed.
4625 * \throw If \a this is not allocated.
4626 * \throw If \a this->getNumberOfComponents() != std::distance(tupleBg,tupleEnd).
4627 * \throw If \a this->getNumberOfComponents() is equal to 0.
4628 * \sa DataArrayInt::findIdsEqual
4630 DataArrayInt *DataArrayInt::findIdsEqualTuple(const int *tupleBg, const int *tupleEnd) const
4632 std::size_t nbOfCompoExp(std::distance(tupleBg,tupleEnd));
4634 if(getNumberOfComponents()!=nbOfCompoExp)
4636 std::ostringstream oss; oss << "DataArrayInt::findIdsEqualTuple : mismatch of number of components. Input tuple has " << nbOfCompoExp << " whereas this array has " << getNumberOfComponents() << " components !";
4637 throw INTERP_KERNEL::Exception(oss.str().c_str());
4640 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqualTuple : number of components should be > 0 !");
4641 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4642 const int *bg(begin()),*end2(end()),*work(begin());
4645 work=std::search(work,end2,tupleBg,tupleEnd);
4648 std::size_t pos(std::distance(bg,work));
4649 if(pos%nbOfCompoExp==0)
4650 ret->pushBackSilent(pos/nbOfCompoExp);
4658 * Assigns \a newValue to all elements holding \a oldValue within \a this
4659 * one-dimensional array.
4660 * \param [in] oldValue - the value to replace.
4661 * \param [in] newValue - the value to assign.
4662 * \return int - number of replacements performed.
4663 * \throw If \a this is not allocated.
4664 * \throw If \a this->getNumberOfComponents() != 1.
4666 int DataArrayInt::changeValue(int oldValue, int newValue)
4669 if(getNumberOfComponents()!=1)
4670 throw INTERP_KERNEL::Exception("DataArrayInt::changeValue : the array must have only one component, you can call 'rearrange' method before !");
4671 if(oldValue==newValue)
4673 int *start(getPointer()),*end2(start+getNbOfElems());
4675 for(int *val=start;val!=end2;val++)
4689 * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to
4690 * one of given values.
4691 * \param [in] valsBg - an array of values to find within \a this array.
4692 * \param [in] valsEnd - specifies the end of the array \a valsBg, so that
4693 * the last value of \a valsBg is \a valsEnd[ -1 ].
4694 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4695 * array using decrRef() as it is no more needed.
4696 * \throw If \a this->getNumberOfComponents() != 1.
4698 DataArrayInt *DataArrayInt::findIdsEqualList(const int *valsBg, const int *valsEnd) const
4700 if(getNumberOfComponents()!=1)
4701 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqualList : the array must have only one component, you can call 'rearrange' method before !");
4702 std::set<int> vals2(valsBg,valsEnd);
4703 const int *cptr(getConstPointer());
4704 std::vector<int> res;
4705 int nbOfTuples(getNumberOfTuples());
4706 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4707 for(int i=0;i<nbOfTuples;i++,cptr++)
4708 if(vals2.find(*cptr)!=vals2.end())
4709 ret->pushBackSilent(i);
4714 * Creates a new DataArrayInt containing IDs (indices) of tuples holding values \b not
4715 * equal to any of given values.
4716 * \param [in] valsBg - an array of values to ignore within \a this array.
4717 * \param [in] valsEnd - specifies the end of the array \a valsBg, so that
4718 * the last value of \a valsBg is \a valsEnd[ -1 ].
4719 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4720 * array using decrRef() as it is no more needed.
4721 * \throw If \a this->getNumberOfComponents() != 1.
4723 DataArrayInt *DataArrayInt::findIdsNotEqualList(const int *valsBg, const int *valsEnd) const
4725 if(getNumberOfComponents()!=1)
4726 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotEqualList : the array must have only one component, you can call 'rearrange' method before !");
4727 std::set<int> vals2(valsBg,valsEnd);
4728 const int *cptr=getConstPointer();
4729 std::vector<int> res;
4730 int nbOfTuples=getNumberOfTuples();
4731 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4732 for(int i=0;i<nbOfTuples;i++,cptr++)
4733 if(vals2.find(*cptr)==vals2.end())
4734 ret->pushBackSilent(i);
4739 * This method is an extension of DataArrayInt::findIdFirstEqual method because this method works for DataArrayInt with
4740 * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
4741 * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
4742 * If any the tuple id is returned. If not -1 is returned.
4744 * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
4745 * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
4747 * \return tuple id where \b tupl is. -1 if no such tuple exists in \b this.
4748 * \sa DataArrayInt::findIdSequence, DataArrayInt::presenceOfTuple.
4750 int DataArrayInt::findIdFirstEqualTuple(const std::vector<int>& tupl) const
4753 int nbOfCompo=getNumberOfComponents();
4755 throw INTERP_KERNEL::Exception("DataArrayInt::findIdFirstEqualTuple : 0 components in 'this' !");
4756 if(nbOfCompo!=(int)tupl.size())
4758 std::ostringstream oss; oss << "DataArrayInt::findIdFirstEqualTuple : 'this' contains " << nbOfCompo << " components and searching for a tuple of length " << tupl.size() << " !";
4759 throw INTERP_KERNEL::Exception(oss.str().c_str());
4761 const int *cptr=getConstPointer();
4762 std::size_t nbOfVals=getNbOfElems();
4763 for(const int *work=cptr;work!=cptr+nbOfVals;)
4765 work=std::search(work,cptr+nbOfVals,tupl.begin(),tupl.end());
4766 if(work!=cptr+nbOfVals)
4768 if(std::distance(cptr,work)%nbOfCompo!=0)
4771 return std::distance(cptr,work)/nbOfCompo;
4778 * This method searches the sequence specified in input parameter \b vals in \b this.
4779 * This works only for DataArrayInt having number of components equal to one (if not an INTERP_KERNEL::Exception will be thrown).
4780 * This method differs from DataArrayInt::findIdFirstEqualTuple in that the position is internal raw data is not considered here contrary to DataArrayInt::findIdFirstEqualTuple.
4781 * \sa DataArrayInt::findIdFirstEqualTuple
4783 int DataArrayInt::findIdSequence(const std::vector<int>& vals) const
4786 int nbOfCompo=getNumberOfComponents();
4788 throw INTERP_KERNEL::Exception("DataArrayInt::findIdSequence : works only for DataArrayInt instance with one component !");
4789 const int *cptr=getConstPointer();
4790 std::size_t nbOfVals=getNbOfElems();
4791 const int *loc=std::search(cptr,cptr+nbOfVals,vals.begin(),vals.end());
4792 if(loc!=cptr+nbOfVals)
4793 return std::distance(cptr,loc);
4798 * This method expects to be called when number of components of this is equal to one.
4799 * This method returns the tuple id, if it exists, of the first tuple equal to \b value.
4800 * If not any tuple contains \b value -1 is returned.
4801 * \sa DataArrayInt::presenceOfValue
4803 int DataArrayInt::findIdFirstEqual(int value) const
4806 if(getNumberOfComponents()!=1)
4807 throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
4808 const int *cptr=getConstPointer();
4809 int nbOfTuples=getNumberOfTuples();
4810 const int *ret=std::find(cptr,cptr+nbOfTuples,value);
4811 if(ret!=cptr+nbOfTuples)
4812 return std::distance(cptr,ret);
4817 * This method expects to be called when number of components of this is equal to one.
4818 * This method returns the tuple id, if it exists, of the first tuple so that the value is contained in \b vals.
4819 * If not any tuple contains one of the values contained in 'vals' -1 is returned.
4820 * \sa DataArrayInt::presenceOfValue
4822 int DataArrayInt::findIdFirstEqual(const std::vector<int>& vals) const
4825 if(getNumberOfComponents()!=1)
4826 throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
4827 std::set<int> vals2(vals.begin(),vals.end());
4828 const int *cptr=getConstPointer();
4829 int nbOfTuples=getNumberOfTuples();
4830 for(const int *w=cptr;w!=cptr+nbOfTuples;w++)
4831 if(vals2.find(*w)!=vals2.end())
4832 return std::distance(cptr,w);
4837 * This method returns the number of values in \a this that are equals to input parameter \a value.
4838 * This method only works for single component array.
4840 * \return a value in [ 0, \c this->getNumberOfTuples() )
4842 * \throw If \a this is not allocated
4845 int DataArrayInt::count(int value) const
4849 if(getNumberOfComponents()!=1)
4850 throw INTERP_KERNEL::Exception("DataArrayInt::count : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
4851 const int *vals=begin();
4852 int nbOfTuples=getNumberOfTuples();
4853 for(int i=0;i<nbOfTuples;i++,vals++)
4860 * This method is an extension of DataArrayInt::presenceOfValue method because this method works for DataArrayInt with
4861 * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
4862 * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
4863 * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
4864 * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
4865 * \sa DataArrayInt::findIdFirstEqualTuple
4867 bool DataArrayInt::presenceOfTuple(const std::vector<int>& tupl) const
4869 return findIdFirstEqualTuple(tupl)!=-1;
4874 * Returns \a true if a given value is present within \a this one-dimensional array.
4875 * \param [in] value - the value to find within \a this array.
4876 * \return bool - \a true in case if \a value is present within \a this array.
4877 * \throw If \a this is not allocated.
4878 * \throw If \a this->getNumberOfComponents() != 1.
4879 * \sa findIdFirstEqual()
4881 bool DataArrayInt::presenceOfValue(int value) const
4883 return findIdFirstEqual(value)!=-1;
4887 * This method expects to be called when number of components of this is equal to one.
4888 * This method returns true if it exists a tuple so that the value is contained in \b vals.
4889 * If not any tuple contains one of the values contained in 'vals' false is returned.
4890 * \sa DataArrayInt::findIdFirstEqual
4892 bool DataArrayInt::presenceOfValue(const std::vector<int>& vals) const
4894 return findIdFirstEqual(vals)!=-1;
4898 * Accumulates values of each component of \a this array.
4899 * \param [out] res - an array of length \a this->getNumberOfComponents(), allocated
4900 * by the caller, that is filled by this method with sum value for each
4902 * \throw If \a this is not allocated.
4904 void DataArrayInt::accumulate(int *res) const
4907 const int *ptr=getConstPointer();
4908 int nbTuple=getNumberOfTuples();
4909 int nbComps=getNumberOfComponents();
4910 std::fill(res,res+nbComps,0);
4911 for(int i=0;i<nbTuple;i++)
4912 std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<int>());
4915 int DataArrayInt::accumulate(int compId) const
4918 const int *ptr=getConstPointer();
4919 int nbTuple=getNumberOfTuples();
4920 int nbComps=getNumberOfComponents();
4921 if(compId<0 || compId>=nbComps)
4922 throw INTERP_KERNEL::Exception("DataArrayInt::accumulate : Invalid compId specified : No such nb of components !");
4924 for(int i=0;i<nbTuple;i++)
4925 ret+=ptr[i*nbComps+compId];
4930 * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
4931 * The returned array will have same number of components than \a this and number of tuples equal to
4932 * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
4934 * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
4936 * \param [in] bgOfIndex - begin (included) of the input index array.
4937 * \param [in] endOfIndex - end (excluded) of the input index array.
4938 * \return DataArrayInt * - the new instance having the same number of components than \a this.
4940 * \throw If bgOfIndex or end is NULL.
4941 * \throw If input index array is not ascendingly sorted.
4942 * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
4943 * \throw If std::distance(bgOfIndex,endOfIndex)==0.
4945 DataArrayInt *DataArrayInt::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
4947 if(!bgOfIndex || !endOfIndex)
4948 throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : input pointer NULL !");
4950 int nbCompo=getNumberOfComponents();
4951 int nbOfTuples=getNumberOfTuples();
4952 int sz=(int)std::distance(bgOfIndex,endOfIndex);
4954 throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : invalid size of input index array !");
4956 MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(sz,nbCompo);
4957 const int *w=bgOfIndex;
4958 if(*w<0 || *w>=nbOfTuples)
4959 throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
4960 const int *srcPt=begin()+(*w)*nbCompo;
4961 int *tmp=ret->getPointer();
4962 for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
4964 std::fill(tmp,tmp+nbCompo,0);
4967 for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
4969 if(j>=0 && j<nbOfTuples)
4970 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<int>());
4973 std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
4974 throw INTERP_KERNEL::Exception(oss.str().c_str());
4980 std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
4981 throw INTERP_KERNEL::Exception(oss.str().c_str());
4984 ret->copyStringInfoFrom(*this);
4989 * Returns a new DataArrayInt by concatenating two given arrays, so that (1) the number
4990 * of tuples in the result array is <em> a1->getNumberOfTuples() + a2->getNumberOfTuples() -
4991 * offsetA2</em> and (2)
4992 * the number of component in the result array is same as that of each of given arrays.
4993 * First \a offsetA2 tuples of \a a2 are skipped and thus are missing from the result array.
4994 * Info on components is copied from the first of the given arrays. Number of components
4995 * in the given arrays must be the same.
4996 * \param [in] a1 - an array to include in the result array.
4997 * \param [in] a2 - another array to include in the result array.
4998 * \param [in] offsetA2 - number of tuples of \a a2 to skip.
4999 * \return DataArrayInt * - the new instance of DataArrayInt.
5000 * The caller is to delete this result array using decrRef() as it is no more
5002 * \throw If either \a a1 or \a a2 is NULL.
5003 * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
5005 DataArrayInt *DataArrayInt::Aggregate(const DataArrayInt *a1, const DataArrayInt *a2, int offsetA2)
5008 throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input DataArrayInt instance is NULL !");
5009 std::size_t nbOfComp(a1->getNumberOfComponents());
5010 if(nbOfComp!=a2->getNumberOfComponents())
5011 throw INTERP_KERNEL::Exception("Nb of components mismatch for array Aggregation !");
5012 std::size_t nbOfTuple1(a1->getNumberOfTuples()),nbOfTuple2(a2->getNumberOfTuples());
5013 MCAuto<DataArrayInt> ret(DataArrayInt::New());
5014 ret->alloc(nbOfTuple1+nbOfTuple2-offsetA2,nbOfComp);
5015 int *pt=std::copy(a1->begin(),a1->end(),ret->getPointer());
5016 std::copy(a2->getConstPointer()+offsetA2*nbOfComp,a2->getConstPointer()+nbOfTuple2*nbOfComp,pt);
5017 ret->copyStringInfoFrom(*a1);
5022 * Returns a new DataArrayInt by concatenating all given arrays, so that (1) the number
5023 * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
5024 * the number of component in the result array is same as that of each of given arrays.
5025 * Info on components is copied from the first of the given arrays. Number of components
5026 * in the given arrays must be the same.
5027 * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it
5028 * not the object itself.
5029 * \param [in] arr - a sequence of arrays to include in the result array.
5030 * \return DataArrayInt * - the new instance of DataArrayInt.
5031 * The caller is to delete this result array using decrRef() as it is no more
5033 * \throw If all arrays within \a arr are NULL.
5034 * \throw If getNumberOfComponents() of arrays within \a arr.
5036 DataArrayInt *DataArrayInt::Aggregate(const std::vector<const DataArrayInt *>& arr)
5038 std::vector<const DataArrayInt *> a;
5039 for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
5043 throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input list must be NON EMPTY !");
5044 std::vector<const DataArrayInt *>::const_iterator it=a.begin();
5045 std::size_t nbOfComp((*it)->getNumberOfComponents()),nbt((*it++)->getNumberOfTuples());
5046 for(int i=1;it!=a.end();it++,i++)
5048 if((*it)->getNumberOfComponents()!=nbOfComp)
5049 throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : Nb of components mismatch for array aggregation !");
5050 nbt+=(*it)->getNumberOfTuples();
5052 MCAuto<DataArrayInt> ret=DataArrayInt::New();
5053 ret->alloc(nbt,nbOfComp);
5054 int *pt=ret->getPointer();
5055 for(it=a.begin();it!=a.end();it++)
5056 pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
5057 ret->copyStringInfoFrom(*(a[0]));
5062 * This method takes as input a list of DataArrayInt instances \a arrs that represent each a packed index arrays.
5063 * A packed index array is an allocated array with one component, and at least one tuple. The first element
5064 * of each array in \a arrs must be 0. Each array in \a arrs is expected to be increasingly monotonic.
5065 * 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.
5067 * \return DataArrayInt * - a new object to be managed by the caller.
5069 DataArrayInt *DataArrayInt::AggregateIndexes(const std::vector<const DataArrayInt *>& arrs)
5072 for(std::vector<const DataArrayInt *>::const_iterator it4=arrs.begin();it4!=arrs.end();it4++)
5076 (*it4)->checkAllocated();
5077 if((*it4)->getNumberOfComponents()!=1)
5079 std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of compo != 1 at pos " << std::distance(arrs.begin(),it4) << " !";
5080 throw INTERP_KERNEL::Exception(oss.str().c_str());
5082 int nbTupl=(*it4)->getNumberOfTuples();
5085 std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of tuples < 1 at pos " << std::distance(arrs.begin(),it4) << " !";
5086 throw INTERP_KERNEL::Exception(oss.str().c_str());
5088 if((*it4)->front()!=0)
5090 std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with front value != 0 at pos " << std::distance(arrs.begin(),it4) << " !";
5091 throw INTERP_KERNEL::Exception(oss.str().c_str());
5097 std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a null instance at pos " << std::distance(arrs.begin(),it4) << " !";
5098 throw INTERP_KERNEL::Exception(oss.str().c_str());
5102 throw INTERP_KERNEL::Exception("DataArrayInt::AggregateIndexes : input list must be NON EMPTY !");
5103 MCAuto<DataArrayInt> ret=DataArrayInt::New();
5104 ret->alloc(retSz,1);
5105 int *pt=ret->getPointer(); *pt++=0;
5106 for(std::vector<const DataArrayInt *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
5107 pt=std::transform((*it)->begin()+1,(*it)->end(),pt,std::bind2nd(std::plus<int>(),pt[-1]));
5108 ret->copyStringInfoFrom(*(arrs[0]));
5113 * Returns in a single walk in \a this the min value and the max value in \a this.
5114 * \a this is expected to be single component array.
5116 * \param [out] minValue - the min value in \a this.
5117 * \param [out] maxValue - the max value in \a this.
5119 * \sa getMinValueInArray, getMinValue, getMaxValueInArray, getMaxValue
5121 void DataArrayInt::getMinMaxValues(int& minValue, int& maxValue) const
5124 if(getNumberOfComponents()!=1)
5125 throw INTERP_KERNEL::Exception("DataArrayInt::getMinMaxValues : must be applied on DataArrayInt with only one component !");
5126 int nbTuples(getNumberOfTuples());
5127 const int *pt(begin());
5128 minValue=std::numeric_limits<int>::max(); maxValue=-std::numeric_limits<int>::max();
5129 for(int i=0;i<nbTuples;i++,pt++)
5139 * Modify all elements of \a this array, so that
5140 * an element _x_ becomes \f$ numerator / x \f$.
5141 * \warning If an exception is thrown because of presence of 0 element in \a this
5142 * array, all elements processed before detection of the zero element remain
5144 * \param [in] numerator - the numerator used to modify array elements.
5145 * \throw If \a this is not allocated.
5146 * \throw If there is an element equal to 0 in \a this array.
5148 void DataArrayInt::applyInv(int numerator)
5151 int *ptr=getPointer();
5152 std::size_t nbOfElems=getNbOfElems();
5153 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
5157 *ptr=numerator/(*ptr);
5161 std::ostringstream oss; oss << "DataArrayInt::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
5163 throw INTERP_KERNEL::Exception(oss.str().c_str());
5170 * Modify all elements of \a this array, so that
5171 * an element _x_ becomes \f$ x / val \f$.
5172 * \param [in] val - the denominator used to modify array elements.
5173 * \throw If \a this is not allocated.
5174 * \throw If \a val == 0.
5176 void DataArrayInt::applyDivideBy(int val)
5179 throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to divide by 0 !");
5181 int *ptr=getPointer();
5182 std::size_t nbOfElems=getNbOfElems();
5183 std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::divides<int>(),val));
5188 * Modify all elements of \a this array, so that
5189 * an element _x_ becomes <em> x % val </em>.
5190 * \param [in] val - the divisor used to modify array elements.
5191 * \throw If \a this is not allocated.
5192 * \throw If \a val <= 0.
5194 void DataArrayInt::applyModulus(int val)
5197 throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to operate modulus on value <= 0 !");
5199 int *ptr=getPointer();
5200 std::size_t nbOfElems=getNbOfElems();
5201 std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::modulus<int>(),val));
5206 * This method works only on data array with one component.
5207 * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
5208 * this[*id] in [\b vmin,\b vmax)
5210 * \param [in] vmin begin of range. This value is included in range (included).
5211 * \param [in] vmax end of range. This value is \b not included in range (excluded).
5212 * \return a newly allocated data array that the caller should deal with.
5214 * \sa DataArrayInt::findIdsNotInRange , DataArrayInt::findIdsStricltyNegative
5216 DataArrayInt *DataArrayInt::findIdsInRange(int vmin, int vmax) const
5218 InRange<int> ir(vmin,vmax);
5219 MCAuto<DataArrayInt> ret(findIdsAdv(ir));
5224 * This method works only on data array with one component.
5225 * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
5226 * this[*id] \b not in [\b vmin,\b vmax)
5228 * \param [in] vmin begin of range. This value is \b not included in range (excluded).
5229 * \param [in] vmax end of range. This value is included in range (included).
5230 * \return a newly allocated data array that the caller should deal with.
5232 * \sa DataArrayInt::findIdsInRange , DataArrayInt::findIdsStricltyNegative
5234 DataArrayInt *DataArrayInt::findIdsNotInRange(int vmin, int vmax) const
5236 NotInRange<int> nir(vmin,vmax);
5237 MCAuto<DataArrayInt> ret(findIdsAdv(nir));
5242 * This method works only on data array with one component.
5243 * 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.
5245 * \param [in] vmin begin of range. This value is included in range (included).
5246 * \param [in] vmax end of range. This value is \b not included in range (excluded).
5247 * \return if all ids in \a this are so that (*this)[i]==i for all i in [ 0, \c this->getNumberOfTuples() ). */
5248 bool DataArrayInt::checkAllIdsInRange(int vmin, int vmax) const
5251 if(getNumberOfComponents()!=1)
5252 throw INTERP_KERNEL::Exception("DataArrayInt::checkAllIdsInRange : this must have exactly one component !");
5253 int nbOfTuples=getNumberOfTuples();
5255 const int *cptr=getConstPointer();
5256 for(int i=0;i<nbOfTuples;i++,cptr++)
5258 if(*cptr>=vmin && *cptr<vmax)
5259 { ret=ret && *cptr==i; }
5262 std::ostringstream oss; oss << "DataArrayInt::checkAllIdsInRange : tuple #" << i << " has value " << *cptr << " should be in [" << vmin << "," << vmax << ") !";
5263 throw INTERP_KERNEL::Exception(oss.str().c_str());
5270 * Modify all elements of \a this array, so that
5271 * an element _x_ becomes <em> val % x </em>.
5272 * \warning If an exception is thrown because of presence of an element <= 0 in \a this
5273 * array, all elements processed before detection of the zero element remain
5275 * \param [in] val - the divident used to modify array elements.
5276 * \throw If \a this is not allocated.
5277 * \throw If there is an element equal to or less than 0 in \a this array.
5279 void DataArrayInt::applyRModulus(int val)
5282 int *ptr=getPointer();
5283 std::size_t nbOfElems=getNbOfElems();
5284 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
5292 std::ostringstream oss; oss << "DataArrayInt::applyRModulus : presence of value <=0 in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
5294 throw INTERP_KERNEL::Exception(oss.str().c_str());
5301 * Modify all elements of \a this array, so that
5302 * an element _x_ becomes <em> val ^ x </em>.
5303 * \param [in] val - the value used to apply pow on all array elements.
5304 * \throw If \a this is not allocated.
5305 * \throw If \a val < 0.
5307 void DataArrayInt::applyPow(int val)
5311 throw INTERP_KERNEL::Exception("DataArrayInt::applyPow : input pow in < 0 !");
5312 int *ptr=getPointer();
5313 std::size_t nbOfElems=getNbOfElems();
5316 std::fill(ptr,ptr+nbOfElems,1);
5319 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
5322 for(int j=0;j<val;j++)
5330 * Modify all elements of \a this array, so that
5331 * an element _x_ becomes \f$ val ^ x \f$.
5332 * \param [in] val - the value used to apply pow on all array elements.
5333 * \throw If \a this is not allocated.
5334 * \throw If there is an element < 0 in \a this array.
5335 * \warning If an exception is thrown because of presence of 0 element in \a this
5336 * array, all elements processed before detection of the zero element remain
5339 void DataArrayInt::applyRPow(int val)
5342 int *ptr=getPointer();
5343 std::size_t nbOfElems=getNbOfElems();
5344 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
5349 for(int j=0;j<*ptr;j++)
5355 std::ostringstream oss; oss << "DataArrayInt::applyRPow : presence of negative value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
5357 throw INTERP_KERNEL::Exception(oss.str().c_str());
5364 * Returns a new DataArrayInt which is a minimal partition of elements of \a groups.
5365 * The i-th item of the result array is an ID of a set of elements belonging to a
5366 * unique set of groups, which the i-th element is a part of. This set of elements
5367 * belonging to a unique set of groups is called \a family, so the result array contains
5368 * IDs of families each element belongs to.
5370 * \b Example: if we have two groups of elements: \a group1 [0,4] and \a group2 [ 0,1,2 ],
5371 * then there are 3 families:
5372 * - \a family1 (with ID 1) contains element [0] belonging to ( \a group1 + \a group2 ),
5373 * - \a family2 (with ID 2) contains elements [4] belonging to ( \a group1 ),
5374 * - \a family3 (with ID 3) contains element [1,2] belonging to ( \a group2 ), <br>
5375 * and the result array contains IDs of families [ 1,3,3,0,2 ]. <br> Note a family ID 0 which
5376 * stands for the element #3 which is in none of groups.
5378 * \param [in] groups - sequence of groups of element IDs.
5379 * \param [in] newNb - total number of elements; it must be more than max ID of element
5381 * \param [out] fidsOfGroups - IDs of families the elements of each group belong to.
5382 * \return DataArrayInt * - a new instance of DataArrayInt containing IDs of families
5383 * each element with ID from range [0, \a newNb ) belongs to. The caller is to
5384 * delete this array using decrRef() as it is no more needed.
5385 * \throw If any element ID in \a groups violates condition ( 0 <= ID < \a newNb ).
5387 DataArrayInt *DataArrayInt::MakePartition(const std::vector<const DataArrayInt *>& groups, int newNb, std::vector< std::vector<int> >& fidsOfGroups)
5389 std::vector<const DataArrayInt *> groups2;
5390 for(std::vector<const DataArrayInt *>::const_iterator it4=groups.begin();it4!=groups.end();it4++)
5392 groups2.push_back(*it4);
5393 MCAuto<DataArrayInt> ret=DataArrayInt::New();
5394 ret->alloc(newNb,1);
5395 int *retPtr=ret->getPointer();
5396 std::fill(retPtr,retPtr+newNb,0);
5398 for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++)
5400 const int *ptr=(*iter)->getConstPointer();
5401 std::size_t nbOfElem=(*iter)->getNbOfElems();
5403 for(int j=0;j<sfid;j++)
5406 for(std::size_t i=0;i<nbOfElem;i++)
5408 if(ptr[i]>=0 && ptr[i]<newNb)
5410 if(retPtr[ptr[i]]==j)
5418 std::ostringstream oss; oss << "DataArrayInt::MakePartition : In group \"" << (*iter)->getName() << "\" in tuple #" << i << " value = " << ptr[i] << " ! Should be in [0," << newNb;
5420 throw INTERP_KERNEL::Exception(oss.str().c_str());
5427 fidsOfGroups.clear();
5428 fidsOfGroups.resize(groups2.size());
5430 for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++,grId++)
5433 const int *ptr=(*iter)->getConstPointer();
5434 std::size_t nbOfElem=(*iter)->getNbOfElems();
5435 for(const int *p=ptr;p!=ptr+nbOfElem;p++)
5436 tmp.insert(retPtr[*p]);
5437 fidsOfGroups[grId].insert(fidsOfGroups[grId].end(),tmp.begin(),tmp.end());
5443 * Returns a new DataArrayInt which contains all elements of given one-dimensional
5444 * arrays. The result array does not contain any duplicates and its values
5445 * are sorted in ascending order.
5446 * \param [in] arr - sequence of DataArrayInt's to unite.
5447 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5448 * array using decrRef() as it is no more needed.
5449 * \throw If any \a arr[i] is not allocated.
5450 * \throw If \a arr[i]->getNumberOfComponents() != 1.
5452 DataArrayInt *DataArrayInt::BuildUnion(const std::vector<const DataArrayInt *>& arr)
5454 std::vector<const DataArrayInt *> a;
5455 for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
5458 for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
5460 (*it)->checkAllocated();
5461 if((*it)->getNumberOfComponents()!=1)
5462 throw INTERP_KERNEL::Exception("DataArrayInt::BuildUnion : only single component allowed !");
5466 for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
5468 const int *pt=(*it)->getConstPointer();
5469 int nbOfTuples=(*it)->getNumberOfTuples();
5470 r.insert(pt,pt+nbOfTuples);
5472 DataArrayInt *ret=DataArrayInt::New();
5473 ret->alloc((int)r.size(),1);
5474 std::copy(r.begin(),r.end(),ret->getPointer());
5479 * Returns a new DataArrayInt which contains elements present in each of given one-dimensional
5480 * arrays. The result array does not contain any duplicates and its values
5481 * are sorted in ascending order.
5482 * \param [in] arr - sequence of DataArrayInt's to intersect.
5483 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5484 * array using decrRef() as it is no more needed.
5485 * \throw If any \a arr[i] is not allocated.
5486 * \throw If \a arr[i]->getNumberOfComponents() != 1.
5488 DataArrayInt *DataArrayInt::BuildIntersection(const std::vector<const DataArrayInt *>& arr)
5490 std::vector<const DataArrayInt *> a;
5491 for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
5494 for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
5496 (*it)->checkAllocated();
5497 if((*it)->getNumberOfComponents()!=1)
5498 throw INTERP_KERNEL::Exception("DataArrayInt::BuildIntersection : only single component allowed !");
5502 for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
5504 const int *pt=(*it)->getConstPointer();
5505 int nbOfTuples=(*it)->getNumberOfTuples();
5506 std::set<int> s1(pt,pt+nbOfTuples);
5510 std::set_intersection(r.begin(),r.end(),s1.begin(),s1.end(),inserter(r2,r2.end()));
5516 DataArrayInt *ret(DataArrayInt::New());
5517 ret->alloc((int)r.size(),1);
5518 std::copy(r.begin(),r.end(),ret->getPointer());
5523 namespace MEDCouplingImpl
5528 OpSwitchedOn(int *pt):_pt(pt),_cnt(0) { }
5529 void operator()(const bool& b) { if(b) *_pt++=_cnt; _cnt++; }
5538 OpSwitchedOff(int *pt):_pt(pt),_cnt(0) { }
5539 void operator()(const bool& b) { if(!b) *_pt++=_cnt; _cnt++; }
5548 * This method returns the list of ids in ascending mode so that v[id]==true.
5550 DataArrayInt *DataArrayInt::BuildListOfSwitchedOn(const std::vector<bool>& v)
5552 int sz((int)std::count(v.begin(),v.end(),true));
5553 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
5554 std::for_each(v.begin(),v.end(),MEDCouplingImpl::OpSwitchedOn(ret->getPointer()));
5559 * This method returns the list of ids in ascending mode so that v[id]==false.
5561 DataArrayInt *DataArrayInt::BuildListOfSwitchedOff(const std::vector<bool>& v)
5563 int sz((int)std::count(v.begin(),v.end(),false));
5564 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
5565 std::for_each(v.begin(),v.end(),MEDCouplingImpl::OpSwitchedOff(ret->getPointer()));
5570 * This method allows to put a vector of vector of integer into a more compact data stucture (skyline).
5571 * This method is not available into python because no available optimized data structure available to map std::vector< std::vector<int> >.
5573 * \param [in] v the input data structure to be translate into skyline format.
5574 * \param [out] data the first element of the skyline format. The user is expected to deal with newly allocated array.
5575 * \param [out] dataIndex the second element of the skyline format.
5577 void DataArrayInt::PutIntoToSkylineFrmt(const std::vector< std::vector<int> >& v, DataArrayInt *& data, DataArrayInt *& dataIndex)
5579 int sz((int)v.size());
5580 MCAuto<DataArrayInt> ret0(DataArrayInt::New()),ret1(DataArrayInt::New());
5581 ret1->alloc(sz+1,1);
5582 int *pt(ret1->getPointer()); *pt=0;
5583 for(int i=0;i<sz;i++,pt++)
5584 pt[1]=pt[0]+(int)v[i].size();
5585 ret0->alloc(ret1->back(),1);
5586 pt=ret0->getPointer();
5587 for(int i=0;i<sz;i++)
5588 pt=std::copy(v[i].begin(),v[i].end(),pt);
5589 data=ret0.retn(); dataIndex=ret1.retn();
5593 * Returns a new DataArrayInt which contains a complement of elements of \a this
5594 * one-dimensional array. I.e. the result array contains all elements from the range [0,
5595 * \a nbOfElement) not present in \a this array.
5596 * \param [in] nbOfElement - maximal size of the result array.
5597 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5598 * array using decrRef() as it is no more needed.
5599 * \throw If \a this is not allocated.
5600 * \throw If \a this->getNumberOfComponents() != 1.
5601 * \throw If any element \a x of \a this array violates condition ( 0 <= \a x < \a
5604 DataArrayInt *DataArrayInt::buildComplement(int nbOfElement) const
5607 if(getNumberOfComponents()!=1)
5608 throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : only single component allowed !");
5609 std::vector<bool> tmp(nbOfElement);
5610 const int *pt=getConstPointer();
5611 int nbOfTuples=getNumberOfTuples();
5612 for(const int *w=pt;w!=pt+nbOfTuples;w++)
5613 if(*w>=0 && *w<nbOfElement)
5616 throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : an element is not in valid range : [0,nbOfElement) !");
5617 int nbOfRetVal=(int)std::count(tmp.begin(),tmp.end(),false);
5618 DataArrayInt *ret=DataArrayInt::New();
5619 ret->alloc(nbOfRetVal,1);
5621 int *retPtr=ret->getPointer();
5622 for(int i=0;i<nbOfElement;i++)
5629 * Returns a new DataArrayInt containing elements of \a this one-dimensional missing
5630 * from an \a other one-dimensional array.
5631 * \param [in] other - a DataArrayInt containing elements not to include in the result array.
5632 * \return DataArrayInt * - a new instance of DataArrayInt with one component. The
5633 * caller is to delete this array using decrRef() as it is no more needed.
5634 * \throw If \a other is NULL.
5635 * \throw If \a other is not allocated.
5636 * \throw If \a other->getNumberOfComponents() != 1.
5637 * \throw If \a this is not allocated.
5638 * \throw If \a this->getNumberOfComponents() != 1.
5639 * \sa DataArrayInt::buildSubstractionOptimized()
5641 DataArrayInt *DataArrayInt::buildSubstraction(const DataArrayInt *other) const
5644 throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : DataArrayInt pointer in input is NULL !");
5646 other->checkAllocated();
5647 if(getNumberOfComponents()!=1)
5648 throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed !");
5649 if(other->getNumberOfComponents()!=1)
5650 throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed for other type !");
5651 const int *pt=getConstPointer();
5652 int nbOfTuples=getNumberOfTuples();
5653 std::set<int> s1(pt,pt+nbOfTuples);
5654 pt=other->getConstPointer();
5655 nbOfTuples=other->getNumberOfTuples();
5656 std::set<int> s2(pt,pt+nbOfTuples);
5658 std::set_difference(s1.begin(),s1.end(),s2.begin(),s2.end(),std::back_insert_iterator< std::vector<int> >(r));
5659 DataArrayInt *ret=DataArrayInt::New();
5660 ret->alloc((int)r.size(),1);
5661 std::copy(r.begin(),r.end(),ret->getPointer());
5666 * \a this is expected to have one component and to be sorted ascendingly (as for \a other).
5667 * \a other is expected to be a part of \a this. If not DataArrayInt::buildSubstraction should be called instead.
5669 * \param [in] other an array with one component and expected to be sorted ascendingly.
5670 * \ret list of ids in \a this but not in \a other.
5671 * \sa DataArrayInt::buildSubstraction
5673 DataArrayInt *DataArrayInt::buildSubstractionOptimized(const DataArrayInt *other) const
5675 static const char *MSG="DataArrayInt::buildSubstractionOptimized : only single component allowed !";
5676 if(!other) throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstractionOptimized : NULL input array !");
5677 checkAllocated(); other->checkAllocated();
5678 if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
5679 if(other->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
5680 const int *pt1Bg(begin()),*pt1End(end()),*pt2Bg(other->begin()),*pt2End(other->end());
5681 const int *work1(pt1Bg),*work2(pt2Bg);
5682 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
5683 for(;work1!=pt1End;work1++)
5685 if(work2!=pt2End && *work1==*work2)
5688 ret->pushBackSilent(*work1);
5695 * Returns a new DataArrayInt which contains all elements of \a this and a given
5696 * one-dimensional arrays. The result array does not contain any duplicates
5697 * and its values are sorted in ascending order.
5698 * \param [in] other - an array to unite with \a this one.
5699 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5700 * array using decrRef() as it is no more needed.
5701 * \throw If \a this or \a other is not allocated.
5702 * \throw If \a this->getNumberOfComponents() != 1.
5703 * \throw If \a other->getNumberOfComponents() != 1.
5705 DataArrayInt *DataArrayInt::buildUnion(const DataArrayInt *other) const
5707 std::vector<const DataArrayInt *>arrs(2);
5708 arrs[0]=this; arrs[1]=other;
5709 return BuildUnion(arrs);
5714 * Returns a new DataArrayInt which contains elements present in both \a this and a given
5715 * one-dimensional arrays. The result array does not contain any duplicates
5716 * and its values are sorted in ascending order.
5717 * \param [in] other - an array to intersect with \a this one.
5718 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5719 * array using decrRef() as it is no more needed.
5720 * \throw If \a this or \a other is not allocated.
5721 * \throw If \a this->getNumberOfComponents() != 1.
5722 * \throw If \a other->getNumberOfComponents() != 1.
5724 DataArrayInt *DataArrayInt::buildIntersection(const DataArrayInt *other) const
5726 std::vector<const DataArrayInt *>arrs(2);
5727 arrs[0]=this; arrs[1]=other;
5728 return BuildIntersection(arrs);
5732 * This method can be applied on allocated with one component DataArrayInt instance.
5733 * This method is typically relevant for sorted arrays. All consecutive duplicated items in \a this will appear only once in returned DataArrayInt instance.
5734 * 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]
5736 * \return a newly allocated array that contain the result of the unique operation applied on \a this.
5737 * \throw if \a this is not allocated or if \a this has not exactly one component.
5738 * \sa DataArrayInt::buildUniqueNotSorted
5740 DataArrayInt *DataArrayInt::buildUnique() const
5743 if(getNumberOfComponents()!=1)
5744 throw INTERP_KERNEL::Exception("DataArrayInt::buildUnique : only single component allowed !");
5745 int nbOfTuples=getNumberOfTuples();
5746 MCAuto<DataArrayInt> tmp=deepCopy();
5747 int *data=tmp->getPointer();
5748 int *last=std::unique(data,data+nbOfTuples);
5749 MCAuto<DataArrayInt> ret=DataArrayInt::New();
5750 ret->alloc(std::distance(data,last),1);
5751 std::copy(data,last,ret->getPointer());
5756 * This method can be applied on allocated with one component DataArrayInt instance.
5757 * This method keep elements only once by keeping the same order in \a this that is not expected to be sorted.
5759 * \return a newly allocated array that contain the result of the unique operation applied on \a this.
5761 * \throw if \a this is not allocated or if \a this has not exactly one component.
5763 * \sa DataArrayInt::buildUnique
5765 DataArrayInt *DataArrayInt::buildUniqueNotSorted() const
5768 if(getNumberOfComponents()!=1)
5769 throw INTERP_KERNEL::Exception("DataArrayInt::buildUniqueNotSorted : only single component allowed !");
5771 getMinMaxValues(minVal,maxVal);
5772 std::vector<bool> b(maxVal-minVal+1,false);
5773 const int *ptBg(begin()),*endBg(end());
5774 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
5775 for(const int *pt=ptBg;pt!=endBg;pt++)
5779 ret->pushBackSilent(*pt);
5783 ret->copyStringInfoFrom(*this);
5788 * Returns a new DataArrayInt which contains size of every of groups described by \a this
5789 * "index" array. Such "index" array is returned for example by
5790 * \ref MEDCoupling::MEDCouplingUMesh::buildDescendingConnectivity
5791 * "MEDCouplingUMesh::buildDescendingConnectivity" and
5792 * \ref MEDCoupling::MEDCouplingUMesh::getNodalConnectivityIndex
5793 * "MEDCouplingUMesh::getNodalConnectivityIndex" etc.
5794 * This method preforms the reverse operation of DataArrayInt::computeOffsetsFull.
5795 * \return DataArrayInt * - a new instance of DataArrayInt, whose number of tuples
5796 * equals to \a this->getNumberOfComponents() - 1, and number of components is 1.
5797 * The caller is to delete this array using decrRef() as it is no more needed.
5798 * \throw If \a this is not allocated.
5799 * \throw If \a this->getNumberOfComponents() != 1.
5800 * \throw If \a this->getNumberOfTuples() < 2.
5803 * - this contains [1,3,6,7,7,9,15]
5804 * - result array contains [2,3,1,0,2,6],
5805 * where 2 = 3 - 1, 3 = 6 - 3, 1 = 7 - 6 etc.
5807 * \sa DataArrayInt::computeOffsetsFull
5809 DataArrayInt *DataArrayInt::deltaShiftIndex() const
5812 if(getNumberOfComponents()!=1)
5813 throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : only single component allowed !");
5814 int nbOfTuples=getNumberOfTuples();
5816 throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : 1 tuple at least must be present in 'this' !");
5817 const int *ptr=getConstPointer();
5818 DataArrayInt *ret=DataArrayInt::New();
5819 ret->alloc(nbOfTuples-1,1);
5820 int *out=ret->getPointer();
5821 std::transform(ptr+1,ptr+nbOfTuples,ptr,out,std::minus<int>());
5826 * Modifies \a this one-dimensional array so that value of each element \a x
5827 * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
5828 * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number of tuples
5829 * and components remains the same.<br>
5830 * This method is useful for allToAllV in MPI with contiguous policy. This method
5831 * differs from computeOffsetsFull() in that the number of tuples is \b not changed by
5833 * \throw If \a this is not allocated.
5834 * \throw If \a this->getNumberOfComponents() != 1.
5837 * - Before \a this contains [3,5,1,2,0,8]
5838 * - After \a this contains [0,3,8,9,11,11]<br>
5839 * Note that the last element 19 = 11 + 8 is missing because size of \a this
5840 * array is retained and thus there is no space to store the last element.
5842 void DataArrayInt::computeOffsets()
5845 if(getNumberOfComponents()!=1)
5846 throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets : only single component allowed !");
5847 int nbOfTuples=getNumberOfTuples();
5850 int *work=getPointer();
5853 for(int i=1;i<nbOfTuples;i++)
5856 work[i]=work[i-1]+tmp;
5864 * Modifies \a this one-dimensional array so that value of each element \a x
5865 * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
5866 * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number
5867 * components remains the same and number of tuples is inceamented by one.<br>
5868 * This method is useful for allToAllV in MPI with contiguous policy. This method
5869 * differs from computeOffsets() in that the number of tuples is changed by this one.
5870 * This method preforms the reverse operation of DataArrayInt::deltaShiftIndex.
5871 * \throw If \a this is not allocated.
5872 * \throw If \a this->getNumberOfComponents() != 1.
5875 * - Before \a this contains [3,5,1,2,0,8]
5876 * - After \a this contains [0,3,8,9,11,11,19]<br>
5877 * \sa DataArrayInt::deltaShiftIndex
5879 void DataArrayInt::computeOffsetsFull()
5882 if(getNumberOfComponents()!=1)
5883 throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsetsFull : only single component allowed !");
5884 int nbOfTuples=getNumberOfTuples();
5885 int *ret=(int *)malloc((nbOfTuples+1)*sizeof(int));
5886 const int *work=getConstPointer();
5888 for(int i=0;i<nbOfTuples;i++)
5889 ret[i+1]=work[i]+ret[i];
5890 useArray(ret,true,C_DEALLOC,nbOfTuples+1,1);
5895 * Returns two new DataArrayInt instances whose contents is computed from that of \a this and \a listOfIds arrays as follows.
5896 * \a this is expected to be an offset format ( as returned by DataArrayInt::computeOffsetsFull ) that is to say with one component
5897 * and ** sorted strictly increasingly **. \a listOfIds is expected to be sorted ascendingly (not strictly needed for \a listOfIds).
5898 * This methods searches in \a this, considered as a set of contiguous \c this->getNumberOfComponents() ranges, all ids in \a listOfIds
5899 * filling completely one of the ranges in \a this.
5901 * \param [in] listOfIds a list of ids that has to be sorted ascendingly.
5902 * \param [out] rangeIdsFetched the range ids fetched
5903 * \param [out] idsInInputListThatFetch contains the list of ids in \a listOfIds that are \b fully included in a range in \a this. So
5904 * \a idsInInputListThatFetch is a part of input \a listOfIds.
5906 * \sa DataArrayInt::computeOffsetsFull
5909 * - \a this : [0,3,7,9,15,18]
5910 * - \a listOfIds contains [0,1,2,3,7,8,15,16,17]
5911 * - \a rangeIdsFetched result array: [0,2,4]
5912 * - \a idsInInputListThatFetch result array: [0,1,2,7,8,15,16,17]
5913 * In this example id 3 in input \a listOfIds is alone so it do not appear in output \a idsInInputListThatFetch.
5916 void DataArrayInt::findIdsRangesInListOfIds(const DataArrayInt *listOfIds, DataArrayInt *& rangeIdsFetched, DataArrayInt *& idsInInputListThatFetch) const
5919 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : input list of ids is null !");
5920 listOfIds->checkAllocated(); checkAllocated();
5921 if(listOfIds->getNumberOfComponents()!=1)
5922 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : input list of ids must have exactly one component !");
5923 if(getNumberOfComponents()!=1)
5924 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : this must have exactly one component !");
5925 MCAuto<DataArrayInt> ret0=DataArrayInt::New(); ret0->alloc(0,1);
5926 MCAuto<DataArrayInt> ret1=DataArrayInt::New(); ret1->alloc(0,1);
5927 const int *tupEnd(listOfIds->end()),*offBg(begin()),*offEnd(end()-1);
5928 const int *tupPtr(listOfIds->begin()),*offPtr(offBg);
5929 while(tupPtr!=tupEnd && offPtr!=offEnd)
5931 if(*tupPtr==*offPtr)
5934 while(i<offPtr[1] && *tupPtr==i && tupPtr!=tupEnd) { i++; tupPtr++; }
5937 ret0->pushBackSilent((int)std::distance(offBg,offPtr));
5938 ret1->pushBackValsSilent(tupPtr-(offPtr[1]-offPtr[0]),tupPtr);
5943 { if(*tupPtr<*offPtr) tupPtr++; else offPtr++; }
5945 rangeIdsFetched=ret0.retn();
5946 idsInInputListThatFetch=ret1.retn();
5950 * Returns a new DataArrayInt whose contents is computed from that of \a this and \a
5951 * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
5952 * "index" array of a "iota" array, thus, whose each element gives an index of a group
5953 * beginning within the "iota" array. And \a this is a one-dimensional array
5954 * considered as a selector of groups described by \a offsets to include into the result array.
5955 * \throw If \a offsets is NULL.
5956 * \throw If \a offsets is not allocated.
5957 * \throw If \a offsets->getNumberOfComponents() != 1.
5958 * \throw If \a offsets is not monotonically increasing.
5959 * \throw If \a this is not allocated.
5960 * \throw If \a this->getNumberOfComponents() != 1.
5961 * \throw If any element of \a this is not a valid index for \a offsets array.
5964 * - \a this: [0,2,3]
5965 * - \a offsets: [0,3,6,10,14,20]
5966 * - result array: [0,1,2,6,7,8,9,10,11,12,13] == <br>
5967 * \c range(0,3) + \c range(6,10) + \c range(10,14) ==<br>
5968 * \c range( \a offsets[ \a this[0] ], offsets[ \a this[0]+1 ]) +
5969 * \c range( \a offsets[ \a this[1] ], offsets[ \a this[1]+1 ]) +
5970 * \c range( \a offsets[ \a this[2] ], offsets[ \a this[2]+1 ])
5972 DataArrayInt *DataArrayInt::buildExplicitArrByRanges(const DataArrayInt *offsets) const
5975 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : DataArrayInt pointer in input is NULL !");
5977 if(getNumberOfComponents()!=1)
5978 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : only single component allowed !");
5979 offsets->checkAllocated();
5980 if(offsets->getNumberOfComponents()!=1)
5981 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : input array should have only single component !");
5982 int othNbTuples=offsets->getNumberOfTuples()-1;
5983 int nbOfTuples=getNumberOfTuples();
5984 int retNbOftuples=0;
5985 const int *work=getConstPointer();
5986 const int *offPtr=offsets->getConstPointer();
5987 for(int i=0;i<nbOfTuples;i++)
5990 if(val>=0 && val<othNbTuples)
5992 int delta=offPtr[val+1]-offPtr[val];
5994 retNbOftuples+=delta;
5997 std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << val << " of offset array has a delta < 0 !";
5998 throw INTERP_KERNEL::Exception(oss.str().c_str());
6003 std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << i << " in this contains " << val;
6004 oss << " whereas offsets array is of size " << othNbTuples+1 << " !";
6005 throw INTERP_KERNEL::Exception(oss.str().c_str());
6008 MCAuto<DataArrayInt> ret=DataArrayInt::New();
6009 ret->alloc(retNbOftuples,1);
6010 int *retPtr=ret->getPointer();
6011 for(int i=0;i<nbOfTuples;i++)
6014 int start=offPtr[val];
6015 int off=offPtr[val+1]-start;
6016 for(int j=0;j<off;j++,retPtr++)
6023 * Returns a new DataArrayInt whose contents is computed using \a this that must be a
6024 * scaled array (monotonically increasing).
6025 from that of \a this and \a
6026 * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
6027 * "index" array of a "iota" array, thus, whose each element gives an index of a group
6028 * beginning within the "iota" array. And \a this is a one-dimensional array
6029 * considered as a selector of groups described by \a offsets to include into the result array.
6030 * \throw If \a is NULL.
6031 * \throw If \a this is not allocated.
6032 * \throw If \a this->getNumberOfComponents() != 1.
6033 * \throw If \a this->getNumberOfTuples() == 0.
6034 * \throw If \a this is not monotonically increasing.
6035 * \throw If any element of ids in ( \a bg \a stop \a step ) points outside the scale in \a this.
6038 * - \a bg , \a stop and \a step : (0,5,2)
6039 * - \a this: [0,3,6,10,14,20]
6040 * - result array: [0,0,0, 2,2,2,2, 4,4,4,4,4,4] == <br>
6042 DataArrayInt *DataArrayInt::buildExplicitArrOfSliceOnScaledArr(int bg, int stop, int step) const
6045 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : not allocated array !");
6046 if(getNumberOfComponents()!=1)
6047 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of components is expected to be equal to one !");
6048 int nbOfTuples(getNumberOfTuples());
6050 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of tuples must be != 0 !");
6051 const int *ids(begin());
6052 int nbOfEltsInSlc(GetNumberOfItemGivenBESRelative(bg,stop,step,"DataArrayInt::buildExplicitArrOfSliceOnScaledArr")),sz(0),pos(bg);
6053 for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
6055 if(pos>=0 && pos<nbOfTuples-1)
6057 int delta(ids[pos+1]-ids[pos]);
6061 std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " and at this pos this is not monotonically increasing !";
6062 throw INTERP_KERNEL::Exception(oss.str().c_str());
6067 std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " should be in [0," << nbOfTuples-1 << ") !";
6068 throw INTERP_KERNEL::Exception(oss.str().c_str());
6071 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
6072 int *retPtr(ret->getPointer());
6074 for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
6076 int delta(ids[pos+1]-ids[pos]);
6077 for(int j=0;j<delta;j++,retPtr++)
6084 * 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.
6085 * 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
6086 * in tuple **i** of returned DataArrayInt.
6087 * If ranges overlapped (in theory it should not) this method do not detect it and always returns the first range.
6089 * 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)]
6090 * The return DataArrayInt will contain : **[0,4,1,2,2,3]**
6092 * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
6093 * for lower value included and 2nd component is the upper value of corresponding range **excluded**.
6094 * \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
6095 * is thrown if no ranges in \a ranges contains value in \a this.
6097 * \sa DataArrayInt::findIdInRangeForEachTuple
6099 DataArrayInt *DataArrayInt::findRangeIdForEachTuple(const DataArrayInt *ranges) const
6102 throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : null input pointer !");
6103 if(ranges->getNumberOfComponents()!=2)
6104 throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : input DataArrayInt instance should have 2 components !");
6106 if(getNumberOfComponents()!=1)
6107 throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : this should have only one component !");
6108 int nbTuples=getNumberOfTuples();
6109 MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
6110 int nbOfRanges=ranges->getNumberOfTuples();
6111 const int *rangesPtr=ranges->getConstPointer();
6112 int *retPtr=ret->getPointer();
6113 const int *inPtr=getConstPointer();
6114 for(int i=0;i<nbTuples;i++,retPtr++)
6118 for(int j=0;j<nbOfRanges && !found;j++)
6119 if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
6120 { *retPtr=j; found=true; }
6125 std::ostringstream oss; oss << "DataArrayInt::findRangeIdForEachTuple : tuple #" << i << " not found by any ranges !";
6126 throw INTERP_KERNEL::Exception(oss.str().c_str());
6133 * 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.
6134 * 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
6135 * in tuple **i** of returned DataArrayInt.
6136 * If ranges overlapped (in theory it should not) this method do not detect it and always returns the sub position of the first range.
6138 * 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)]
6139 * The return DataArrayInt will contain : **[1,2,4,0,2,2]**
6140 * This method is often called in pair with DataArrayInt::findRangeIdForEachTuple method.
6142 * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
6143 * for lower value included and 2nd component is the upper value of corresponding range **excluded**.
6144 * \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
6145 * is thrown if no ranges in \a ranges contains value in \a this.
6146 * \sa DataArrayInt::findRangeIdForEachTuple
6148 DataArrayInt *DataArrayInt::findIdInRangeForEachTuple(const DataArrayInt *ranges) const
6151 throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : null input pointer !");
6152 if(ranges->getNumberOfComponents()!=2)
6153 throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : input DataArrayInt instance should have 2 components !");
6155 if(getNumberOfComponents()!=1)
6156 throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : this should have only one component !");
6157 int nbTuples=getNumberOfTuples();
6158 MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
6159 int nbOfRanges=ranges->getNumberOfTuples();
6160 const int *rangesPtr=ranges->getConstPointer();
6161 int *retPtr=ret->getPointer();
6162 const int *inPtr=getConstPointer();
6163 for(int i=0;i<nbTuples;i++,retPtr++)
6167 for(int j=0;j<nbOfRanges && !found;j++)
6168 if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
6169 { *retPtr=val-rangesPtr[2*j]; found=true; }
6174 std::ostringstream oss; oss << "DataArrayInt::findIdInRangeForEachTuple : tuple #" << i << " not found by any ranges !";
6175 throw INTERP_KERNEL::Exception(oss.str().c_str());
6182 * \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).
6183 * 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).
6184 * 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 !
6185 * If this method has correctly worked, \a this will be able to be considered as a linked list.
6186 * This method does nothing if number of tuples is lower of equal to 1.
6188 * This method is useful for users having an unstructured mesh having only SEG2 to rearrange internaly the connectibity without any coordinates consideration.
6190 * \sa MEDCouplingUMesh::orderConsecutiveCells1D, DataArrayInt::fromLinkedListOfPairToList
6192 void DataArrayInt::sortEachPairToMakeALinkedList()
6195 if(getNumberOfComponents()!=2)
6196 throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : Only works on DataArrayInt instance with nb of components equal to 2 !");
6197 int nbOfTuples(getNumberOfTuples());
6200 int *conn(getPointer());
6201 for(int i=1;i<nbOfTuples;i++,conn+=2)
6205 if(conn[2]==conn[3])
6207 std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " presence of a pair filled with same ids !";
6208 throw INTERP_KERNEL::Exception(oss.str().c_str());
6210 if(conn[2]!=conn[1] && conn[3]==conn[1] && conn[2]!=conn[0])
6211 std::swap(conn[2],conn[3]);
6212 //not(conn[2]==conn[1] && conn[3]!=conn[1] && conn[3]!=conn[0])
6213 if(conn[2]!=conn[1] || conn[3]==conn[1] || conn[3]==conn[0])
6215 std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " something is invalid !";
6216 throw INTERP_KERNEL::Exception(oss.str().c_str());
6221 if(conn[0]==conn[1] || conn[2]==conn[3])
6222 throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : In the 2 first tuples presence of a pair filled with same ids !");
6225 s.insert(conn,conn+4);
6227 throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : This can't be considered as a linked list regarding 2 first tuples !");
6228 if(std::count(conn,conn+4,conn[0])==2)
6233 if(conn[2]==conn[0])
6237 std::copy(tmp,tmp+4,conn);
6240 {//here we are sure to have (std::count(conn,conn+4,conn[1])==2)
6241 if(conn[1]==conn[3])
6242 std::swap(conn[2],conn[3]);
6249 * \a this is expected to be a correctly linked list of pairs.
6251 * \sa DataArrayInt::sortEachPairToMakeALinkedList
6253 MCAuto<DataArrayInt> DataArrayInt::fromLinkedListOfPairToList() const
6256 checkNbOfComps(2,"DataArrayInt::fromLinkedListOfPairToList : this is expected to have 2 components");
6257 int nbTuples(getNumberOfTuples());
6259 throw INTERP_KERNEL::Exception("DataArrayInt::fromLinkedListOfPairToList : no tuples in this ! Not a linked list !");
6260 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbTuples+1,1);
6261 const int *thisPtr(begin());
6262 int *retPtr(ret->getPointer());
6263 retPtr[0]=thisPtr[0];
6264 for(int i=0;i<nbTuples;i++)
6266 retPtr[i+1]=thisPtr[2*i+1];
6268 if(thisPtr[2*i+1]!=thisPtr[2*(i+1)+0])
6270 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 ?";
6271 throw INTERP_KERNEL::Exception(oss.str());
6278 * This method returns all different values found in \a this. This method throws if \a this has not been allocated.
6279 * But the number of components can be different from one.
6280 * \return a newly allocated array (that should be dealt by the caller) containing different values in \a this.
6282 DataArrayInt *DataArrayInt::getDifferentValues() const
6286 ret.insert(begin(),end());
6287 MCAuto<DataArrayInt> ret2=DataArrayInt::New(); ret2->alloc((int)ret.size(),1);
6288 std::copy(ret.begin(),ret.end(),ret2->getPointer());
6293 * This method is a refinement of DataArrayInt::getDifferentValues because it returns not only different values in \a this but also, for each of
6294 * them it tells which tuple id have this id.
6295 * This method works only on arrays with one component (if it is not the case call DataArrayInt::rearrange(1) ).
6296 * This method returns two arrays having same size.
6297 * 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.
6298 * 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]]
6300 std::vector<DataArrayInt *> DataArrayInt::partitionByDifferentValues(std::vector<int>& differentIds) const
6303 if(getNumberOfComponents()!=1)
6304 throw INTERP_KERNEL::Exception("DataArrayInt::partitionByDifferentValues : this should have only one component !");
6306 std::map<int,int> m,m2,m3;
6307 for(const int *w=begin();w!=end();w++)
6309 differentIds.resize(m.size());
6310 std::vector<DataArrayInt *> ret(m.size());
6311 std::vector<int *> retPtr(m.size());
6312 for(std::map<int,int>::const_iterator it=m.begin();it!=m.end();it++,id++)
6315 ret[id]=DataArrayInt::New();
6316 ret[id]->alloc((*it).second,1);
6317 retPtr[id]=ret[id]->getPointer();
6318 differentIds[id]=(*it).first;
6321 for(const int *w=begin();w!=end();w++,id++)
6323 retPtr[m2[*w]][m3[*w]++]=id;
6329 * This method split ids in [0, \c this->getNumberOfTuples() ) using \a this array as a field of weight (>=0 each).
6330 * The aim of this method is to return a set of \a nbOfSlices chunk of contiguous ids as balanced as possible.
6332 * \param [in] nbOfSlices - number of slices expected.
6333 * \return - a vector having a size equal to \a nbOfSlices giving the start (included) and the stop (excluded) of each chunks.
6335 * \sa DataArray::GetSlice
6336 * \throw If \a this is not allocated or not with exactly one component.
6337 * \throw If an element in \a this if < 0.
6339 std::vector< std::pair<int,int> > DataArrayInt::splitInBalancedSlices(int nbOfSlices) const
6341 if(!isAllocated() || getNumberOfComponents()!=1)
6342 throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : this array should have number of components equal to one and must be allocated !");
6344 throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : number of slices must be >= 1 !");
6345 int sum(accumulate(0)),nbOfTuples(getNumberOfTuples());
6346 int sumPerSlc(sum/nbOfSlices),pos(0);
6347 const int *w(begin());
6348 std::vector< std::pair<int,int> > ret(nbOfSlices);
6349 for(int i=0;i<nbOfSlices;i++)
6351 std::pair<int,int> p(pos,-1);
6353 while(locSum<sumPerSlc && pos<nbOfTuples) { pos++; locSum+=*w++; }
6357 p.second=nbOfTuples;
6364 * Returns a new DataArrayInt that is a modulus of two given arrays. There are 3
6366 * 1. The arrays have same number of tuples and components. Then each value of
6367 * the result array (_a_) is a division of the corresponding values of \a a1 and
6368 * \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, j ].
6369 * 2. The arrays have same number of tuples and one array, say _a2_, has one
6371 * _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, 0 ].
6372 * 3. The arrays have same number of components and one array, say _a2_, has one
6374 * _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ 0, j ].
6376 * Info on components is copied either from the first array (in the first case) or from
6377 * the array with maximal number of elements (getNbOfElems()).
6378 * \warning No check of division by zero is performed!
6379 * \param [in] a1 - a dividend array.
6380 * \param [in] a2 - a divisor array.
6381 * \return DataArrayInt * - the new instance of DataArrayInt.
6382 * The caller is to delete this result array using decrRef() as it is no more
6384 * \throw If either \a a1 or \a a2 is NULL.
6385 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
6386 * \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
6387 * none of them has number of tuples or components equal to 1.
6389 DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt *a2)
6392 throw INTERP_KERNEL::Exception("DataArrayInt::Modulus : input DataArrayInt instance is NULL !");
6393 int nbOfTuple1=a1->getNumberOfTuples();
6394 int nbOfTuple2=a2->getNumberOfTuples();
6395 int nbOfComp1=a1->getNumberOfComponents();
6396 int nbOfComp2=a2->getNumberOfComponents();
6397 if(nbOfTuple2==nbOfTuple1)
6399 if(nbOfComp1==nbOfComp2)
6401 MCAuto<DataArrayInt> ret=DataArrayInt::New();
6402 ret->alloc(nbOfTuple2,nbOfComp1);
6403 std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::modulus<int>());
6404 ret->copyStringInfoFrom(*a1);
6407 else if(nbOfComp2==1)
6409 MCAuto<DataArrayInt> ret=DataArrayInt::New();
6410 ret->alloc(nbOfTuple1,nbOfComp1);
6411 const int *a2Ptr=a2->getConstPointer();
6412 const int *a1Ptr=a1->getConstPointer();
6413 int *res=ret->getPointer();
6414 for(int i=0;i<nbOfTuple1;i++)
6415 res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::modulus<int>(),a2Ptr[i]));
6416 ret->copyStringInfoFrom(*a1);
6421 a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
6425 else if(nbOfTuple2==1)
6427 a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
6428 MCAuto<DataArrayInt> ret=DataArrayInt::New();
6429 ret->alloc(nbOfTuple1,nbOfComp1);
6430 const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
6431 int *pt=ret->getPointer();
6432 for(int i=0;i<nbOfTuple1;i++)
6433 pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::modulus<int>());
6434 ret->copyStringInfoFrom(*a1);
6439 a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Modulus !");//will always throw an exception
6445 * Modify \a this array so that each value becomes a modulus of division of this value by
6446 * a value of another DataArrayInt. There are 3 valid cases.
6447 * 1. The arrays have same number of tuples and components. Then each value of
6448 * \a this array is divided by the corresponding value of \a other one, i.e.:
6449 * _a_ [ i, j ] %= _other_ [ i, j ].
6450 * 2. The arrays have same number of tuples and \a other array has one component. Then
6451 * _a_ [ i, j ] %= _other_ [ i, 0 ].
6452 * 3. The arrays have same number of components and \a other array has one tuple. Then
6453 * _a_ [ i, j ] %= _a2_ [ 0, j ].
6455 * \warning No check of division by zero is performed!
6456 * \param [in] other - a divisor array.
6457 * \throw If \a other is NULL.
6458 * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
6459 * \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
6460 * \a other has number of both tuples and components not equal to 1.
6462 void DataArrayInt::modulusEqual(const DataArrayInt *other)
6465 throw INTERP_KERNEL::Exception("DataArrayInt::modulusEqual : input DataArrayInt instance is NULL !");
6466 const char *msg="Nb of tuples mismatch for DataArrayInt::modulusEqual !";
6467 checkAllocated(); other->checkAllocated();
6468 int nbOfTuple=getNumberOfTuples();
6469 int nbOfTuple2=other->getNumberOfTuples();
6470 int nbOfComp=getNumberOfComponents();
6471 int nbOfComp2=other->getNumberOfComponents();
6472 if(nbOfTuple==nbOfTuple2)
6474 if(nbOfComp==nbOfComp2)
6476 std::transform(begin(),end(),other->begin(),getPointer(),std::modulus<int>());
6478 else if(nbOfComp2==1)
6480 if(nbOfComp2==nbOfComp)
6482 int *ptr=getPointer();
6483 const int *ptrc=other->getConstPointer();
6484 for(int i=0;i<nbOfTuple;i++)
6485 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::modulus<int>(),*ptrc++));
6488 throw INTERP_KERNEL::Exception(msg);
6491 throw INTERP_KERNEL::Exception(msg);
6493 else if(nbOfTuple2==1)
6495 int *ptr=getPointer();
6496 const int *ptrc=other->getConstPointer();
6497 for(int i=0;i<nbOfTuple;i++)
6498 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::modulus<int>());
6501 throw INTERP_KERNEL::Exception(msg);
6506 * Returns a new DataArrayInt that is the result of pow of two given arrays. There are 3
6509 * \param [in] a1 - an array to pow up.
6510 * \param [in] a2 - another array to sum up.
6511 * \return DataArrayInt * - the new instance of DataArrayInt.
6512 * The caller is to delete this result array using decrRef() as it is no more
6514 * \throw If either \a a1 or \a a2 is NULL.
6515 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
6516 * \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
6517 * \throw If there is a negative value in \a a2.
6519 DataArrayInt *DataArrayInt::Pow(const DataArrayInt *a1, const DataArrayInt *a2)
6522 throw INTERP_KERNEL::Exception("DataArrayInt::Pow : at least one of input instances is null !");
6523 int nbOfTuple=a1->getNumberOfTuples();
6524 int nbOfTuple2=a2->getNumberOfTuples();
6525 int nbOfComp=a1->getNumberOfComponents();
6526 int nbOfComp2=a2->getNumberOfComponents();
6527 if(nbOfTuple!=nbOfTuple2)
6528 throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of tuples mismatches !");
6529 if(nbOfComp!=1 || nbOfComp2!=1)
6530 throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of components of both arrays must be equal to 1 !");
6531 MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuple,1);
6532 const int *ptr1(a1->begin()),*ptr2(a2->begin());
6533 int *ptr=ret->getPointer();
6534 for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
6539 for(int j=0;j<*ptr2;j++)
6545 std::ostringstream oss; oss << "DataArrayInt::Pow : on tuple #" << i << " of a2 value is < 0 (" << *ptr2 << ") !";
6546 throw INTERP_KERNEL::Exception(oss.str().c_str());
6553 * Apply pow on values of another DataArrayInt to values of \a this one.
6555 * \param [in] other - an array to pow to \a this one.
6556 * \throw If \a other is NULL.
6557 * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
6558 * \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
6559 * \throw If there is a negative value in \a other.
6561 void DataArrayInt::powEqual(const DataArrayInt *other)
6564 throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : input instance is null !");
6565 int nbOfTuple=getNumberOfTuples();
6566 int nbOfTuple2=other->getNumberOfTuples();
6567 int nbOfComp=getNumberOfComponents();
6568 int nbOfComp2=other->getNumberOfComponents();
6569 if(nbOfTuple!=nbOfTuple2)
6570 throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of tuples mismatches !");
6571 if(nbOfComp!=1 || nbOfComp2!=1)
6572 throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of components of both arrays must be equal to 1 !");
6573 int *ptr=getPointer();
6574 const int *ptrc=other->begin();
6575 for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
6580 for(int j=0;j<*ptrc;j++)
6586 std::ostringstream oss; oss << "DataArrayInt::powEqual : on tuple #" << i << " of other value is < 0 (" << *ptrc << ") !";
6587 throw INTERP_KERNEL::Exception(oss.str().c_str());
6594 * Returns a C array which is a renumbering map in "Old to New" mode for the input array.
6595 * This map, if applied to \a start array, would make it sorted. For example, if
6596 * \a start array contents are [9,10,0,6,4,11,3,7] then the contents of the result array is
6597 * [5,6,0,3,2,7,1,4].
6598 * \param [in] start - pointer to the first element of the array for which the
6599 * permutation map is computed.
6600 * \param [in] end - pointer specifying the end of the array \a start, so that
6601 * the last value of \a start is \a end[ -1 ].
6602 * \return int * - the result permutation array that the caller is to delete as it is no
6604 * \throw If there are equal values in the input array.
6606 int *DataArrayInt::CheckAndPreparePermutation(const int *start, const int *end)
6608 std::size_t sz=std::distance(start,end);
6609 int *ret=(int *)malloc(sz*sizeof(int));
6610 int *work=new int[sz];
6611 std::copy(start,end,work);
6612 std::sort(work,work+sz);
6613 if(std::unique(work,work+sz)!=work+sz)
6617 throw INTERP_KERNEL::Exception("Some elements are equals in the specified array !");
6619 std::map<int,int> m;
6620 for(int *workPt=work;workPt!=work+sz;workPt++)
6621 m[*workPt]=(int)std::distance(work,workPt);
6623 for(const int *iter=start;iter!=end;iter++,iter2++)
6630 * Returns a new DataArrayInt containing an arithmetic progression
6631 * that is equal to the sequence returned by Python \c range(\a begin,\a end,\a step )
6633 * \param [in] begin - the start value of the result sequence.
6634 * \param [in] end - limiting value, so that every value of the result array is less than
6636 * \param [in] step - specifies the increment or decrement.
6637 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6638 * array using decrRef() as it is no more needed.
6639 * \throw If \a step == 0.
6640 * \throw If \a end < \a begin && \a step > 0.
6641 * \throw If \a end > \a begin && \a step < 0.
6643 DataArrayInt *DataArrayInt::Range(int begin, int end, int step)
6645 int nbOfTuples=GetNumberOfItemGivenBESRelative(begin,end,step,"DataArrayInt::Range");
6646 MCAuto<DataArrayInt> ret=DataArrayInt::New();
6647 ret->alloc(nbOfTuples,1);
6648 int *ptr=ret->getPointer();
6651 for(int i=begin;i<end;i+=step,ptr++)
6656 for(int i=begin;i>end;i+=step,ptr++)
6663 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
6666 void DataArrayInt::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
6671 tinyInfo[0]=getNumberOfTuples();
6672 tinyInfo[1]=getNumberOfComponents();
6682 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
6685 void DataArrayInt::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
6689 int nbOfCompo=getNumberOfComponents();
6690 tinyInfo.resize(nbOfCompo+1);
6691 tinyInfo[0]=getName();
6692 for(int i=0;i<nbOfCompo;i++)
6693 tinyInfo[i+1]=getInfoOnComponent(i);
6698 tinyInfo[0]=getName();
6703 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
6704 * This method returns if a feeding is needed.
6706 bool DataArrayInt::resizeForUnserialization(const std::vector<int>& tinyInfoI)
6708 int nbOfTuple=tinyInfoI[0];
6709 int nbOfComp=tinyInfoI[1];
6710 if(nbOfTuple!=-1 || nbOfComp!=-1)
6712 alloc(nbOfTuple,nbOfComp);
6719 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
6720 * This method returns if a feeding is needed.
6722 void DataArrayInt::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
6724 setName(tinyInfoS[0]);
6727 int nbOfCompo=tinyInfoI[1];
6728 for(int i=0;i<nbOfCompo;i++)
6729 setInfoOnComponent(i,tinyInfoS[i+1]);
6733 DataArrayIntIterator::DataArrayIntIterator(DataArrayInt *da):DataArrayIterator<int>(da)
6737 DataArrayInt32Tuple::DataArrayInt32Tuple(int *pt, int nbOfComp):DataArrayTuple<int>(pt,nbOfComp)
6741 std::string DataArrayIntTuple::repr() const
6743 std::ostringstream oss; oss << "(";
6744 for(int i=0;i<_nb_of_compo-1;i++)
6745 oss << _pt[i] << ", ";
6746 oss << _pt[_nb_of_compo-1] << ")";
6750 int DataArrayIntTuple::intValue() const
6752 return this->zeValue();
6756 * This method returns a newly allocated instance the caller should dealed with by a MEDCoupling::DataArrayInt::decrRef.
6757 * This method performs \b no copy of data. The content is only referenced using MEDCoupling::DataArrayInt::useArray with ownership set to \b false.
6758 * 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
6759 * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
6761 DataArrayInt *DataArrayIntTuple::buildDAInt(int nbOfTuples, int nbOfCompo) const
6763 return this->buildDA(nbOfTuples,nbOfCompo);