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 int nbOfCompo=getNumberOfComponents();
200 std::size_t partOfCompoToSet=compoIds.size();
201 if((int)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]>=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()!=(int)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()!=(int)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(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(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 int 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 int 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(int 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(int 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(int 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 int 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 int 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 int nbOfComp=a1->getNumberOfComponents();
3149 if(nbOfComp!=a2->getNumberOfComponents())
3150 throw INTERP_KERNEL::Exception("Nb of components mismatch for array Dot !");
3151 int 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->getConstPointer();
3158 const double *a2Ptr=a2->getConstPointer();
3159 for(int i=0;i<nbOfTuple;i++)
3162 for(int j=0;j<nbOfComp;j++)
3163 sum+=a1Ptr[i*nbOfComp+j]*a2Ptr[i*nbOfComp+j];
3166 ret->setInfoOnComponent(0,a1->getInfoOnComponent(0));
3167 ret->setName(a1->getName());
3172 * Returns a new DataArrayDouble containing a cross product of two given arrays, so that
3173 * the i-th tuple of the result array contains 3 components of a vector which is a cross
3174 * product of two vectors defined by the i-th tuples of given arrays.
3175 * Info on components is copied from the first of the given arrays.
3176 * Number of tuples in the given arrays must be the same.
3177 * Number of components in the given arrays must be 3.
3178 * \param [in] a1 - a given array.
3179 * \param [in] a2 - another given array.
3180 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3181 * The caller is to delete this result array using decrRef() as it is no more
3183 * \throw If either \a a1 or \a a2 is NULL.
3184 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3185 * \throw If \a a1->getNumberOfComponents() != 3
3186 * \throw If \a a2->getNumberOfComponents() != 3
3188 DataArrayDouble *DataArrayDouble::CrossProduct(const DataArrayDouble *a1, const DataArrayDouble *a2)
3191 throw INTERP_KERNEL::Exception("DataArrayDouble::CrossProduct : input DataArrayDouble instance is NULL !");
3192 int nbOfComp=a1->getNumberOfComponents();
3193 if(nbOfComp!=a2->getNumberOfComponents())
3194 throw INTERP_KERNEL::Exception("Nb of components mismatch for array crossProduct !");
3196 throw INTERP_KERNEL::Exception("Nb of components must be equal to 3 for array crossProduct !");
3197 int nbOfTuple=a1->getNumberOfTuples();
3198 if(nbOfTuple!=a2->getNumberOfTuples())
3199 throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array crossProduct !");
3200 DataArrayDouble *ret=DataArrayDouble::New();
3201 ret->alloc(nbOfTuple,3);
3202 double *retPtr=ret->getPointer();
3203 const double *a1Ptr=a1->getConstPointer();
3204 const double *a2Ptr=a2->getConstPointer();
3205 for(int i=0;i<nbOfTuple;i++)
3207 retPtr[3*i]=a1Ptr[3*i+1]*a2Ptr[3*i+2]-a1Ptr[3*i+2]*a2Ptr[3*i+1];
3208 retPtr[3*i+1]=a1Ptr[3*i+2]*a2Ptr[3*i]-a1Ptr[3*i]*a2Ptr[3*i+2];
3209 retPtr[3*i+2]=a1Ptr[3*i]*a2Ptr[3*i+1]-a1Ptr[3*i+1]*a2Ptr[3*i];
3211 ret->copyStringInfoFrom(*a1);
3216 * Returns a new DataArrayDouble containing maximal values of two given arrays.
3217 * Info on components is copied from the first of the given arrays.
3218 * Number of tuples and components in the given arrays must be the same.
3219 * \param [in] a1 - an array to compare values with another one.
3220 * \param [in] a2 - another array to compare values with the first one.
3221 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3222 * The caller is to delete this result array using decrRef() as it is no more
3224 * \throw If either \a a1 or \a a2 is NULL.
3225 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3226 * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
3228 DataArrayDouble *DataArrayDouble::Max(const DataArrayDouble *a1, const DataArrayDouble *a2)
3231 throw INTERP_KERNEL::Exception("DataArrayDouble::Max : input DataArrayDouble instance is NULL !");
3232 int nbOfComp=a1->getNumberOfComponents();
3233 if(nbOfComp!=a2->getNumberOfComponents())
3234 throw INTERP_KERNEL::Exception("Nb of components mismatch for array Max !");
3235 int nbOfTuple=a1->getNumberOfTuples();
3236 if(nbOfTuple!=a2->getNumberOfTuples())
3237 throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Max !");
3238 DataArrayDouble *ret=DataArrayDouble::New();
3239 ret->alloc(nbOfTuple,nbOfComp);
3240 double *retPtr=ret->getPointer();
3241 const double *a1Ptr=a1->getConstPointer();
3242 const double *a2Ptr=a2->getConstPointer();
3243 int nbElem=nbOfTuple*nbOfComp;
3244 for(int i=0;i<nbElem;i++)
3245 retPtr[i]=std::max(a1Ptr[i],a2Ptr[i]);
3246 ret->copyStringInfoFrom(*a1);
3251 * Returns a new DataArrayDouble containing minimal values of two given arrays.
3252 * Info on components is copied from the first of the given arrays.
3253 * Number of tuples and components in the given arrays must be the same.
3254 * \param [in] a1 - an array to compare values with another one.
3255 * \param [in] a2 - another array to compare values with the first one.
3256 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3257 * The caller is to delete this result array using decrRef() as it is no more
3259 * \throw If either \a a1 or \a a2 is NULL.
3260 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3261 * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
3263 DataArrayDouble *DataArrayDouble::Min(const DataArrayDouble *a1, const DataArrayDouble *a2)
3266 throw INTERP_KERNEL::Exception("DataArrayDouble::Min : input DataArrayDouble instance is NULL !");
3267 int nbOfComp=a1->getNumberOfComponents();
3268 if(nbOfComp!=a2->getNumberOfComponents())
3269 throw INTERP_KERNEL::Exception("Nb of components mismatch for array min !");
3270 int nbOfTuple=a1->getNumberOfTuples();
3271 if(nbOfTuple!=a2->getNumberOfTuples())
3272 throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array min !");
3273 DataArrayDouble *ret=DataArrayDouble::New();
3274 ret->alloc(nbOfTuple,nbOfComp);
3275 double *retPtr=ret->getPointer();
3276 const double *a1Ptr=a1->getConstPointer();
3277 const double *a2Ptr=a2->getConstPointer();
3278 int nbElem=nbOfTuple*nbOfComp;
3279 for(int i=0;i<nbElem;i++)
3280 retPtr[i]=std::min(a1Ptr[i],a2Ptr[i]);
3281 ret->copyStringInfoFrom(*a1);
3286 * Returns a new DataArrayDouble that is the result of pow of two given arrays. There are 3
3289 * \param [in] a1 - an array to pow up.
3290 * \param [in] a2 - another array to sum up.
3291 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3292 * The caller is to delete this result array using decrRef() as it is no more
3294 * \throw If either \a a1 or \a a2 is NULL.
3295 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3296 * \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
3297 * \throw If there is a negative value in \a a1.
3299 DataArrayDouble *DataArrayDouble::Pow(const DataArrayDouble *a1, const DataArrayDouble *a2)
3302 throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : at least one of input instances is null !");
3303 int nbOfTuple=a1->getNumberOfTuples();
3304 int nbOfTuple2=a2->getNumberOfTuples();
3305 int nbOfComp=a1->getNumberOfComponents();
3306 int nbOfComp2=a2->getNumberOfComponents();
3307 if(nbOfTuple!=nbOfTuple2)
3308 throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of tuples mismatches !");
3309 if(nbOfComp!=1 || nbOfComp2!=1)
3310 throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of components of both arrays must be equal to 1 !");
3311 MCAuto<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbOfTuple,1);
3312 const double *ptr1(a1->begin()),*ptr2(a2->begin());
3313 double *ptr=ret->getPointer();
3314 for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
3318 *ptr=pow(*ptr1,*ptr2);
3322 std::ostringstream oss; oss << "DataArrayDouble::Pow : on tuple #" << i << " of a1 value is < 0 (" << *ptr1 << ") !";
3323 throw INTERP_KERNEL::Exception(oss.str().c_str());
3330 * Apply pow on values of another DataArrayDouble to values of \a this one.
3332 * \param [in] other - an array to pow to \a this one.
3333 * \throw If \a other is NULL.
3334 * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
3335 * \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
3336 * \throw If there is a negative value in \a this.
3338 void DataArrayDouble::powEqual(const DataArrayDouble *other)
3341 throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : input instance is null !");
3342 int nbOfTuple=getNumberOfTuples();
3343 int nbOfTuple2=other->getNumberOfTuples();
3344 int nbOfComp=getNumberOfComponents();
3345 int nbOfComp2=other->getNumberOfComponents();
3346 if(nbOfTuple!=nbOfTuple2)
3347 throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of tuples mismatches !");
3348 if(nbOfComp!=1 || nbOfComp2!=1)
3349 throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of components of both arrays must be equal to 1 !");
3350 double *ptr=getPointer();
3351 const double *ptrc=other->begin();
3352 for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
3355 *ptr=pow(*ptr,*ptrc);
3358 std::ostringstream oss; oss << "DataArrayDouble::powEqual : on tuple #" << i << " of this value is < 0 (" << *ptr << ") !";
3359 throw INTERP_KERNEL::Exception(oss.str().c_str());
3366 * This method is \b NOT wrapped into python because it can be useful only for performance reasons in C++ context.
3367 * All values in \a this must be 0. or 1. within eps error. 0 means false, 1 means true.
3368 * If an another value than 0 or 1 appear (within eps precision) an INTERP_KERNEL::Exception will be thrown.
3370 * \throw if \a this is not allocated.
3371 * \throw if \a this has not exactly one component.
3373 std::vector<bool> DataArrayDouble::toVectorOfBool(double eps) const
3376 if(getNumberOfComponents()!=1)
3377 throw INTERP_KERNEL::Exception("DataArrayDouble::toVectorOfBool : must be applied on single component array !");
3378 int nbt(getNumberOfTuples());
3379 std::vector<bool> ret(nbt);
3380 const double *pt(begin());
3381 for(int i=0;i<nbt;i++)
3385 else if(fabs(pt[i]-1.)<eps)
3389 std::ostringstream oss; oss << "DataArrayDouble::toVectorOfBool : the tuple #" << i << " has value " << pt[i] << " is invalid ! must be 0. or 1. !";
3390 throw INTERP_KERNEL::Exception(oss.str().c_str());
3397 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
3400 void DataArrayDouble::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
3405 tinyInfo[0]=getNumberOfTuples();
3406 tinyInfo[1]=getNumberOfComponents();
3416 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
3419 void DataArrayDouble::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
3423 int nbOfCompo=getNumberOfComponents();
3424 tinyInfo.resize(nbOfCompo+1);
3425 tinyInfo[0]=getName();
3426 for(int i=0;i<nbOfCompo;i++)
3427 tinyInfo[i+1]=getInfoOnComponent(i);
3432 tinyInfo[0]=getName();
3437 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
3438 * This method returns if a feeding is needed.
3440 bool DataArrayDouble::resizeForUnserialization(const std::vector<int>& tinyInfoI)
3442 int nbOfTuple=tinyInfoI[0];
3443 int nbOfComp=tinyInfoI[1];
3444 if(nbOfTuple!=-1 || nbOfComp!=-1)
3446 alloc(nbOfTuple,nbOfComp);
3453 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
3455 void DataArrayDouble::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
3457 setName(tinyInfoS[0]);
3460 int nbOfCompo=getNumberOfComponents();
3461 for(int i=0;i<nbOfCompo;i++)
3462 setInfoOnComponent(i,tinyInfoS[i+1]);
3467 * Low static method that operates 3D rotation of 'nbNodes' 3D nodes whose coordinates are arranged in \a coordsIn
3468 * around an axe ( \a center, \a vect) and with angle \a angle.
3470 void DataArrayDouble::Rotate3DAlg(const double *center, const double *vect, double angle, int nbNodes, const double *coordsIn, double *coordsOut)
3472 if(!center || !vect)
3473 throw INTERP_KERNEL::Exception("DataArrayDouble::Rotate3DAlg : null vector in input !");
3474 double sina(sin(angle));
3475 double cosa(cos(angle));
3476 double vectorNorm[3];
3478 double matrixTmp[9];
3479 double norm(sqrt(vect[0]*vect[0]+vect[1]*vect[1]+vect[2]*vect[2]));
3480 if(norm<std::numeric_limits<double>::min())
3481 throw INTERP_KERNEL::Exception("DataArrayDouble::Rotate3DAlg : magnitude of input vector is too close of 0. !");
3482 std::transform(vect,vect+3,vectorNorm,std::bind2nd(std::multiplies<double>(),1/norm));
3483 //rotation matrix computation
3484 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;
3485 matrixTmp[0]=vectorNorm[0]*vectorNorm[0]; matrixTmp[1]=vectorNorm[0]*vectorNorm[1]; matrixTmp[2]=vectorNorm[0]*vectorNorm[2];
3486 matrixTmp[3]=vectorNorm[1]*vectorNorm[0]; matrixTmp[4]=vectorNorm[1]*vectorNorm[1]; matrixTmp[5]=vectorNorm[1]*vectorNorm[2];
3487 matrixTmp[6]=vectorNorm[2]*vectorNorm[0]; matrixTmp[7]=vectorNorm[2]*vectorNorm[1]; matrixTmp[8]=vectorNorm[2]*vectorNorm[2];
3488 std::transform(matrixTmp,matrixTmp+9,matrixTmp,std::bind2nd(std::multiplies<double>(),1-cosa));
3489 std::transform(matrix,matrix+9,matrixTmp,matrix,std::plus<double>());
3490 matrixTmp[0]=0.; matrixTmp[1]=-vectorNorm[2]; matrixTmp[2]=vectorNorm[1];
3491 matrixTmp[3]=vectorNorm[2]; matrixTmp[4]=0.; matrixTmp[5]=-vectorNorm[0];
3492 matrixTmp[6]=-vectorNorm[1]; matrixTmp[7]=vectorNorm[0]; matrixTmp[8]=0.;
3493 std::transform(matrixTmp,matrixTmp+9,matrixTmp,std::bind2nd(std::multiplies<double>(),sina));
3494 std::transform(matrix,matrix+9,matrixTmp,matrix,std::plus<double>());
3495 //rotation matrix computed.
3497 for(int i=0; i<nbNodes; i++)
3499 std::transform(coordsIn+i*3,coordsIn+(i+1)*3,center,tmp,std::minus<double>());
3500 coordsOut[i*3]=matrix[0]*tmp[0]+matrix[1]*tmp[1]+matrix[2]*tmp[2]+center[0];
3501 coordsOut[i*3+1]=matrix[3]*tmp[0]+matrix[4]*tmp[1]+matrix[5]*tmp[2]+center[1];
3502 coordsOut[i*3+2]=matrix[6]*tmp[0]+matrix[7]*tmp[1]+matrix[8]*tmp[2]+center[2];
3506 void DataArrayDouble::Symmetry3DPlane(const double point[3], const double normalVector[3], int nbNodes, const double *coordsIn, double *coordsOut)
3508 double matrix[9],matrix2[9],matrix3[9];
3509 double vect[3],crossVect[3];
3510 INTERP_KERNEL::orthogonalVect3(normalVector,vect);
3511 crossVect[0]=normalVector[1]*vect[2]-normalVector[2]*vect[1];
3512 crossVect[1]=normalVector[2]*vect[0]-normalVector[0]*vect[2];
3513 crossVect[2]=normalVector[0]*vect[1]-normalVector[1]*vect[0];
3514 double nv(INTERP_KERNEL::norm<3>(vect)),ni(INTERP_KERNEL::norm<3>(normalVector)),nc(INTERP_KERNEL::norm<3>(crossVect));
3515 matrix[0]=vect[0]/nv; matrix[1]=crossVect[0]/nc; matrix[2]=-normalVector[0]/ni;
3516 matrix[3]=vect[1]/nv; matrix[4]=crossVect[1]/nc; matrix[5]=-normalVector[1]/ni;
3517 matrix[6]=vect[2]/nv; matrix[7]=crossVect[2]/nc; matrix[8]=-normalVector[2]/ni;
3518 matrix2[0]=vect[0]/nv; matrix2[1]=vect[1]/nv; matrix2[2]=vect[2]/nv;
3519 matrix2[3]=crossVect[0]/nc; matrix2[4]=crossVect[1]/nc; matrix2[5]=crossVect[2]/nc;
3520 matrix2[6]=normalVector[0]/ni; matrix2[7]=normalVector[1]/ni; matrix2[8]=normalVector[2]/ni;
3521 for(int i=0;i<3;i++)
3522 for(int j=0;j<3;j++)
3525 for(int k=0;k<3;k++)
3526 val+=matrix[3*i+k]*matrix2[3*k+j];
3529 //rotation matrix computed.
3531 for(int i=0; i<nbNodes; i++)
3533 std::transform(coordsIn+i*3,coordsIn+(i+1)*3,point,tmp,std::minus<double>());
3534 coordsOut[i*3]=matrix3[0]*tmp[0]+matrix3[1]*tmp[1]+matrix3[2]*tmp[2]+point[0];
3535 coordsOut[i*3+1]=matrix3[3]*tmp[0]+matrix3[4]*tmp[1]+matrix3[5]*tmp[2]+point[1];
3536 coordsOut[i*3+2]=matrix3[6]*tmp[0]+matrix3[7]*tmp[1]+matrix3[8]*tmp[2]+point[2];
3540 void DataArrayDouble::GiveBaseForPlane(const double normalVector[3], double baseOfPlane[9])
3542 double vect[3],crossVect[3];
3543 INTERP_KERNEL::orthogonalVect3(normalVector,vect);
3544 crossVect[0]=normalVector[1]*vect[2]-normalVector[2]*vect[1];
3545 crossVect[1]=normalVector[2]*vect[0]-normalVector[0]*vect[2];
3546 crossVect[2]=normalVector[0]*vect[1]-normalVector[1]*vect[0];
3547 double nv(INTERP_KERNEL::norm<3>(vect)),ni(INTERP_KERNEL::norm<3>(normalVector)),nc(INTERP_KERNEL::norm<3>(crossVect));
3548 baseOfPlane[0]=vect[0]/nv; baseOfPlane[1]=vect[1]/nv; baseOfPlane[2]=vect[2]/nv;
3549 baseOfPlane[3]=crossVect[0]/nc; baseOfPlane[4]=crossVect[1]/nc; baseOfPlane[5]=crossVect[2]/nc;
3550 baseOfPlane[6]=normalVector[0]/ni; baseOfPlane[7]=normalVector[1]/ni; baseOfPlane[8]=normalVector[2]/ni;
3554 * Low static method that operates 3D rotation of \a nbNodes 3D nodes whose coordinates are arranged in \a coords
3555 * around the center point \a center and with angle \a angle.
3557 void DataArrayDouble::Rotate2DAlg(const double *center, double angle, int nbNodes, const double *coordsIn, double *coordsOut)
3559 double cosa=cos(angle);
3560 double sina=sin(angle);
3562 matrix[0]=cosa; matrix[1]=-sina; matrix[2]=sina; matrix[3]=cosa;
3564 for(int i=0; i<nbNodes; i++)
3566 std::transform(coordsIn+i*2,coordsIn+(i+1)*2,center,tmp,std::minus<double>());
3567 coordsOut[i*2]=matrix[0]*tmp[0]+matrix[1]*tmp[1]+center[0];
3568 coordsOut[i*2+1]=matrix[2]*tmp[0]+matrix[3]*tmp[1]+center[1];
3572 DataArrayDoubleIterator::DataArrayDoubleIterator(DataArrayDouble *da):DataArrayIterator<double>(da)
3576 DataArrayDoubleTuple::DataArrayDoubleTuple(double *pt, int nbOfComp):DataArrayTuple<double>(pt,nbOfComp)
3581 std::string DataArrayDoubleTuple::repr() const
3583 std::ostringstream oss; oss.precision(17); oss << "(";
3584 for(int i=0;i<_nb_of_compo-1;i++)
3585 oss << _pt[i] << ", ";
3586 oss << _pt[_nb_of_compo-1] << ")";
3590 double DataArrayDoubleTuple::doubleValue() const
3592 return this->zeValue();
3596 * This method returns a newly allocated instance the caller should dealed with by a MEDCoupling::DataArrayDouble::decrRef.
3597 * This method performs \b no copy of data. The content is only referenced using MEDCoupling::DataArrayDouble::useArray with ownership set to \b false.
3598 * 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
3599 * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
3601 DataArrayDouble *DataArrayDoubleTuple::buildDADouble(int nbOfTuples, int nbOfCompo) const
3603 return this->buildDA(nbOfTuples,nbOfCompo);
3607 * Returns a new instance of DataArrayInt. The caller is to delete this array
3608 * using decrRef() as it is no more needed.
3610 DataArrayInt *DataArrayInt::New()
3612 return new DataArrayInt;
3616 * Returns the only one value in \a this, if and only if number of elements
3617 * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
3618 * \return double - the sole value stored in \a this array.
3619 * \throw If at least one of conditions stated above is not fulfilled.
3621 int DataArrayInt::intValue() const
3625 if(getNbOfElems()==1)
3627 return *getConstPointer();
3630 throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is allocated but number of elements is not equal to 1 !");
3633 throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is not allocated !");
3637 * Returns an integer value characterizing \a this array, which is useful for a quick
3638 * comparison of many instances of DataArrayInt.
3639 * \return int - the hash value.
3640 * \throw If \a this is not allocated.
3642 int DataArrayInt::getHashCode() const
3645 std::size_t nbOfElems=getNbOfElems();
3646 int ret=nbOfElems*65536;
3651 const int *pt=begin();
3652 for(std::size_t i=0;i<nbOfElems;i+=delta)
3653 ret0+=pt[i] & 0x1FFF;
3658 * Returns a full copy of \a this. For more info on copying data arrays see
3659 * \ref MEDCouplingArrayBasicsCopyDeep.
3660 * \return DataArrayInt * - a new instance of DataArrayInt.
3662 DataArrayInt32 *DataArrayInt32::deepCopy() const
3664 return new DataArrayInt32(*this);
3668 * Returns a textual and human readable representation of \a this instance of
3669 * DataArrayInt. This text is shown when a DataArrayInt is printed in Python.
3670 * \return std::string - text describing \a this DataArrayInt.
3672 * \sa reprNotTooLong, reprZip
3674 std::string DataArrayInt::repr() const
3676 std::ostringstream ret;
3681 std::string DataArrayInt::reprZip() const
3683 std::ostringstream ret;
3688 void DataArrayInt::writeVTK(std::ostream& ofs, int indent, const std::string& type, const std::string& nameInFile, DataArrayByte *byteArr) const
3690 static const char SPACE[4]={' ',' ',' ',' '};
3692 std::string idt(indent,' ');
3693 ofs << idt << "<DataArray type=\"" << type << "\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
3696 ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
3697 if(std::string(type)=="Int32")
3699 const char *data(reinterpret_cast<const char *>(begin()));
3700 std::size_t sz(getNbOfElems()*sizeof(int));
3701 byteArr->insertAtTheEnd(data,data+sz);
3702 byteArr->insertAtTheEnd(SPACE,SPACE+4);
3704 else if(std::string(type)=="Int8")
3706 INTERP_KERNEL::AutoPtr<char> tmp(new char[getNbOfElems()]);
3707 std::copy(begin(),end(),(char *)tmp);
3708 byteArr->insertAtTheEnd((char *)tmp,(char *)tmp+getNbOfElems());
3709 byteArr->insertAtTheEnd(SPACE,SPACE+4);
3711 else if(std::string(type)=="UInt8")
3713 INTERP_KERNEL::AutoPtr<unsigned char> tmp(new unsigned char[getNbOfElems()]);
3714 std::copy(begin(),end(),(unsigned char *)tmp);
3715 byteArr->insertAtTheEnd((unsigned char *)tmp,(unsigned char *)tmp+getNbOfElems());
3716 byteArr->insertAtTheEnd(SPACE,SPACE+4);
3719 throw INTERP_KERNEL::Exception("DataArrayInt::writeVTK : Only Int32, Int8 and UInt8 supported !");
3723 ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
3724 std::copy(begin(),end(),std::ostream_iterator<int>(ofs," "));
3726 ofs << std::endl << idt << "</DataArray>\n";
3729 void DataArrayInt::reprCppStream(const std::string& varName, std::ostream& stream) const
3731 int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
3732 const int *data=getConstPointer();
3733 stream << "DataArrayInt *" << varName << "=DataArrayInt::New();" << std::endl;
3734 if(nbTuples*nbComp>=1)
3736 stream << "const int " << varName << "Data[" << nbTuples*nbComp << "]={";
3737 std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<int>(stream,","));
3738 stream << data[nbTuples*nbComp-1] << "};" << std::endl;
3739 stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
3742 stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
3743 stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
3747 * Method that gives a quick overvien of \a this for python.
3749 void DataArrayInt::reprQuickOverview(std::ostream& stream) const
3751 static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
3752 stream << "DataArrayInt C++ instance at " << this << ". ";
3755 int nbOfCompo=(int)_info_on_compo.size();
3758 int nbOfTuples=getNumberOfTuples();
3759 stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
3760 reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
3763 stream << "Number of components : 0.";
3766 stream << "*** No data allocated ****";
3769 void DataArrayInt::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
3771 const int *data=begin();
3772 int nbOfTuples=getNumberOfTuples();
3773 int nbOfCompo=(int)_info_on_compo.size();
3774 std::ostringstream oss2; oss2 << "[";
3775 std::string oss2Str(oss2.str());
3776 bool isFinished=true;
3777 for(int i=0;i<nbOfTuples && isFinished;i++)
3782 for(int j=0;j<nbOfCompo;j++,data++)
3785 if(j!=nbOfCompo-1) oss2 << ", ";
3791 if(i!=nbOfTuples-1) oss2 << ", ";
3792 std::string oss3Str(oss2.str());
3793 if(oss3Str.length()<maxNbOfByteInRepr)
3805 * Computes distribution of values of \a this one-dimensional array between given value
3806 * ranges (casts). This method is typically useful for entity number spliting by types,
3808 * \warning The values contained in \a arrBg should be sorted ascendently. No
3809 * check of this is be done. If not, the result is not warranted.
3810 * \param [in] arrBg - the array of ascending values defining the value ranges. The i-th
3811 * value of \a arrBg (\a arrBg[ i ]) gives the lowest value of the i-th range,
3812 * and the greatest value of the i-th range equals to \a arrBg[ i+1 ] - 1. \a
3813 * arrBg containing \a n values defines \a n-1 ranges. The last value of \a arrBg
3814 * should be more than every value in \a this array.
3815 * \param [in] arrEnd - specifies the end of the array \a arrBg, so that
3816 * the last value of \a arrBg is \a arrEnd[ -1 ].
3817 * \param [out] castArr - a new instance of DataArrayInt, of same size as \a this array
3818 * (same number of tuples and components), the caller is to delete
3819 * using decrRef() as it is no more needed.
3820 * This array contains indices of ranges for every value of \a this array. I.e.
3821 * the i-th value of \a castArr gives the index of range the i-th value of \a this
3822 * belongs to. Or, in other words, this parameter contains for each tuple in \a
3823 * this in which cast it holds.
3824 * \param [out] rankInsideCast - a new instance of DataArrayInt, of same size as \a this
3825 * array, the caller is to delete using decrRef() as it is no more needed.
3826 * This array contains ranks of values of \a this array within ranges
3827 * they belongs to. I.e. the i-th value of \a rankInsideCast gives the rank of
3828 * the i-th value of \a this array within the \a castArr[ i ]-th range, to which
3829 * the i-th value of \a this belongs to. Or, in other words, this param contains
3830 * for each tuple its rank inside its cast. The rank is computed as difference
3831 * between the value and the lowest value of range.
3832 * \param [out] castsPresent - a new instance of DataArrayInt, containing indices of
3833 * ranges (casts) to which at least one value of \a this array belongs.
3834 * Or, in other words, this param contains the casts that \a this contains.
3835 * The caller is to delete this array using decrRef() as it is no more needed.
3837 * \b Example: If \a this contains [6,5,0,3,2,7,8,1,4] and \a arrBg contains [0,4,9] then
3838 * the output of this method will be :
3839 * - \a castArr : [1,1,0,0,0,1,1,0,1]
3840 * - \a rankInsideCast: [2,1,0,3,2,3,4,1,0]
3841 * - \a castsPresent : [0,1]
3843 * I.e. values of \a this array belong to 2 ranges: #0 and #1. Value 6 belongs to the
3844 * range #1 and its rank within this range is 2; etc.
3846 * \throw If \a this->getNumberOfComponents() != 1.
3847 * \throw If \a arrEnd - arrBg < 2.
3848 * \throw If any value of \a this is not less than \a arrEnd[-1].
3850 void DataArrayInt::splitByValueRange(const int *arrBg, const int *arrEnd,
3851 DataArrayInt *& castArr, DataArrayInt *& rankInsideCast, DataArrayInt *& castsPresent) const
3854 if(getNumberOfComponents()!=1)
3855 throw INTERP_KERNEL::Exception("Call splitByValueRange method on DataArrayInt with only one component, you can call 'rearrange' method before !");
3856 int nbOfTuples=getNumberOfTuples();
3857 std::size_t nbOfCast=std::distance(arrBg,arrEnd);
3859 throw INTERP_KERNEL::Exception("DataArrayInt::splitByValueRange : The input array giving the cast range values should be of size >=2 !");
3861 const int *work=getConstPointer();
3862 typedef std::reverse_iterator<const int *> rintstart;
3863 rintstart bg(arrEnd);//OK no problem because size of 'arr' is greater or equal 2
3864 rintstart end2(arrBg);
3865 MCAuto<DataArrayInt> ret1=DataArrayInt::New();
3866 MCAuto<DataArrayInt> ret2=DataArrayInt::New();
3867 MCAuto<DataArrayInt> ret3=DataArrayInt::New();
3868 ret1->alloc(nbOfTuples,1);
3869 ret2->alloc(nbOfTuples,1);
3870 int *ret1Ptr=ret1->getPointer();
3871 int *ret2Ptr=ret2->getPointer();
3872 std::set<std::size_t> castsDetected;
3873 for(int i=0;i<nbOfTuples;i++)
3875 rintstart res=std::find_if(bg,end2,std::bind2nd(std::less_equal<int>(), work[i]));
3876 std::size_t pos=std::distance(bg,res);
3877 std::size_t pos2=nbOfCast-pos;
3880 ret1Ptr[i]=(int)pos2;
3881 ret2Ptr[i]=work[i]-arrBg[pos2];
3882 castsDetected.insert(pos2);
3886 std::ostringstream oss; oss << "DataArrayInt::splitByValueRange : At rank #" << i << " the value is " << work[i] << " should be in [0," << *bg << ") !";
3887 throw INTERP_KERNEL::Exception(oss.str().c_str());
3890 ret3->alloc((int)castsDetected.size(),1);
3891 std::copy(castsDetected.begin(),castsDetected.end(),ret3->getPointer());
3892 castArr=ret1.retn();
3893 rankInsideCast=ret2.retn();
3894 castsPresent=ret3.retn();
3898 * 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 ).
3899 * 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 ).
3900 * This method works only if \a this is allocated and single component. If not an exception will be thrown.
3902 * \param [out] strt - the start of the range (included) if true is returned.
3903 * \param [out] sttoopp - the end of the range (not included) if true is returned.
3904 * \param [out] stteepp - the step of the range if true is returned.
3905 * \return the verdict of the check.
3907 * \sa DataArray::GetNumberOfItemGivenBES
3909 bool DataArrayInt::isRange(int& strt, int& sttoopp, int& stteepp) const
3912 if(getNumberOfComponents()!=1)
3913 throw INTERP_KERNEL::Exception("DataArrayInt::isRange : this must be single component array !");
3914 int nbTuples(getNumberOfTuples());
3916 { strt=0; sttoopp=0; stteepp=1; return true; }
3917 const int *pt(begin());
3920 { sttoopp=strt+1; stteepp=1; return true; }
3921 strt=*pt; sttoopp=pt[nbTuples-1];
3927 int a(sttoopp-1-strt),tmp(strt);
3928 if(a%(nbTuples-1)!=0)
3930 stteepp=a/(nbTuples-1);
3931 for(int i=0;i<nbTuples;i++,tmp+=stteepp)
3939 int a(strt-sttoopp-1),tmp(strt);
3940 if(a%(nbTuples-1)!=0)
3942 stteepp=-(a/(nbTuples-1));
3943 for(int i=0;i<nbTuples;i++,tmp+=stteepp)
3952 * Modifies in place \a this one-dimensional array so that each value \a v = \a indArrBg[ \a v ],
3953 * i.e. a current value is used as in index to get a new value from \a indArrBg.
3954 * \param [in] indArrBg - pointer to the first element of array of new values to assign
3956 * \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
3957 * the last value of \a indArrBg is \a indArrEnd[ -1 ].
3958 * \throw If \a this->getNumberOfComponents() != 1
3959 * \throw If any value of \a this can't be used as a valid index for
3960 * [\a indArrBg, \a indArrEnd).
3964 void DataArrayInt::transformWithIndArr(const int *indArrBg, const int *indArrEnd)
3966 this->checkAllocated();
3967 if(this->getNumberOfComponents()!=1)
3968 throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
3969 int nbElemsIn((int)std::distance(indArrBg,indArrEnd)),nbOfTuples(getNumberOfTuples()),*pt(getPointer());
3970 for(int i=0;i<nbOfTuples;i++,pt++)
3972 if(*pt>=0 && *pt<nbElemsIn)
3976 std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " of this value is " << *pt << ", should be in [0," << nbElemsIn << ") !";
3977 throw INTERP_KERNEL::Exception(oss.str().c_str());
3980 this->declareAsNew();
3983 void DataArrayInt::transformWithIndArr(const MapKeyVal<int>& m)
3985 this->checkAllocated();
3986 if(this->getNumberOfComponents()!=1)
3987 throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
3988 const std::map<int,int> dat(m.data());
3989 int nbOfTuples(getNumberOfTuples()),*pt(getPointer());
3990 for(int i=0;i<nbOfTuples;i++,pt++)
3992 std::map<int,int>::const_iterator it(dat.find(*pt));
3997 std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " of this value is " << *pt << " not in map !";
3998 throw INTERP_KERNEL::Exception(oss.str().c_str());
4001 this->declareAsNew();
4005 * Creates a one-dimensional DataArrayInt (\a res) whose contents are computed from
4006 * values of \a this (\a a) and the given (\a indArr) arrays as follows:
4007 * \a res[ \a indArr[ \a a[ i ]]] = i. I.e. for each value in place i \a v = \a a[ i ],
4008 * new value in place \a indArr[ \a v ] is i.
4009 * \param [in] indArrBg - the array holding indices within the result array to assign
4010 * indices of values of \a this array pointing to values of \a indArrBg.
4011 * \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
4012 * the last value of \a indArrBg is \a indArrEnd[ -1 ].
4013 * \return DataArrayInt * - the new instance of DataArrayInt.
4014 * The caller is to delete this result array using decrRef() as it is no more
4016 * \throw If \a this->getNumberOfComponents() != 1.
4017 * \throw If any value of \a this array is not a valid index for \a indArrBg array.
4018 * \throw If any value of \a indArrBg is not a valid index for \a this array.
4020 DataArrayInt *DataArrayInt::transformWithIndArrR(const int *indArrBg, const int *indArrEnd) const
4023 if(getNumberOfComponents()!=1)
4024 throw INTERP_KERNEL::Exception("Call transformWithIndArrR method on DataArrayInt with only one component, you can call 'rearrange' method before !");
4025 int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
4026 int nbOfTuples=getNumberOfTuples();
4027 const int *pt=getConstPointer();
4028 MCAuto<DataArrayInt> ret=DataArrayInt::New();
4029 ret->alloc(nbOfTuples,1);
4030 ret->fillWithValue(-1);
4031 int *tmp=ret->getPointer();
4032 for(int i=0;i<nbOfTuples;i++,pt++)
4034 if(*pt>=0 && *pt<nbElemsIn)
4036 int pos=indArrBg[*pt];
4037 if(pos>=0 && pos<nbOfTuples)
4041 std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value of new pos is " << pos << " ( indArrBg[" << *pt << "]) ! Should be in [0," << nbOfTuples << ") !";
4042 throw INTERP_KERNEL::Exception(oss.str().c_str());
4047 std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn << " !";
4048 throw INTERP_KERNEL::Exception(oss.str().c_str());
4055 * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
4056 * from values of \a this array, which is supposed to contain a renumbering map in
4057 * "Old to New" mode. The result array contains a renumbering map in "New to Old" mode.
4058 * To know how to use the renumbering maps see \ref numbering.
4059 * \param [in] newNbOfElem - the number of tuples in the result array.
4060 * \return DataArrayInt * - the new instance of DataArrayInt.
4061 * The caller is to delete this result array using decrRef() as it is no more
4064 * \if ENABLE_EXAMPLES
4065 * \ref cpp_mcdataarrayint_invertarrayo2n2n2o "Here is a C++ example".<br>
4066 * \ref py_mcdataarrayint_invertarrayo2n2n2o "Here is a Python example".
4069 DataArrayInt *DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const
4071 MCAuto<DataArrayInt> ret(DataArrayInt::New());
4072 ret->alloc(newNbOfElem,1);
4073 int nbOfOldNodes(this->getNumberOfTuples());
4074 const int *old2New(begin());
4075 int *pt(ret->getPointer());
4076 for(int i=0;i!=nbOfOldNodes;i++)
4078 int newp(old2New[i]);
4081 if(newp>=0 && newp<newNbOfElem)
4085 std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2O : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
4086 throw INTERP_KERNEL::Exception(oss.str().c_str());
4094 * This method is similar to DataArrayInt::invertArrayO2N2N2O except that
4095 * 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]
4097 DataArrayInt *DataArrayInt::invertArrayO2N2N2OBis(int newNbOfElem) const
4099 MCAuto<DataArrayInt> ret=DataArrayInt::New();
4100 ret->alloc(newNbOfElem,1);
4101 int nbOfOldNodes=getNumberOfTuples();
4102 const int *old2New=getConstPointer();
4103 int *pt=ret->getPointer();
4104 for(int i=nbOfOldNodes-1;i>=0;i--)
4106 int newp(old2New[i]);
4109 if(newp>=0 && newp<newNbOfElem)
4113 std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2OBis : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
4114 throw INTERP_KERNEL::Exception(oss.str().c_str());
4122 * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
4123 * from values of \a this array, which is supposed to contain a renumbering map in
4124 * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
4125 * To know how to use the renumbering maps see \ref numbering.
4126 * \param [in] newNbOfElem - the number of tuples in the result array.
4127 * \return DataArrayInt * - the new instance of DataArrayInt.
4128 * The caller is to delete this result array using decrRef() as it is no more
4131 * \if ENABLE_EXAMPLES
4132 * \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
4134 * \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
4135 * \sa invertArrayN2O2O2NOptimized
4138 DataArrayInt *DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const
4141 MCAuto<DataArrayInt> ret=DataArrayInt::New();
4142 ret->alloc(oldNbOfElem,1);
4143 const int *new2Old=getConstPointer();
4144 int *pt=ret->getPointer();
4145 std::fill(pt,pt+oldNbOfElem,-1);
4146 int nbOfNewElems=getNumberOfTuples();
4147 for(int i=0;i<nbOfNewElems;i++)
4150 if(v>=0 && v<oldNbOfElem)
4154 std::ostringstream oss; oss << "DataArrayInt::invertArrayN2O2O2N : in new id #" << i << " old value is " << v << " expected to be in [0," << oldNbOfElem << ") !";
4155 throw INTERP_KERNEL::Exception(oss.str().c_str());
4162 * Creates a map, whose contents are computed
4163 * from values of \a this array, which is supposed to contain a renumbering map in
4164 * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
4165 * To know how to use the renumbering maps see \ref numbering.
4166 * \param [in] newNbOfElem - the number of tuples in the result array.
4167 * \return MapII - the new instance of Map.
4169 * \if ENABLE_EXAMPLES
4170 * \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
4172 * \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
4173 * \sa invertArrayN2O2O2N
4176 MCAuto< MapKeyVal<int> > DataArrayInt::invertArrayN2O2O2NOptimized() const
4179 MCAuto< MapKeyVal<int> > ret(MapKeyVal<int>::New());
4180 std::map<int,int>& m(ret->data());
4181 const int *new2Old(begin());
4182 int nbOfNewElems(this->getNumberOfTuples());
4183 for(int i=0;i<nbOfNewElems;i++)
4192 * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode.
4193 * This map, if applied to \a this array, would make it sorted. For example, if
4194 * \a this array contents are [9,10,0,6,4,11,3,7] then the contents of the result array
4195 * are [5,6,0,3,2,7,1,4]; if this result array (\a res) is used as an argument in call
4196 * \a this->renumber(\a res) then the returned array contains [0,3,4,6,7,9,10,11].
4197 * This method is useful for renumbering (in MED file for example). For more info
4198 * on renumbering see \ref numbering.
4199 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4200 * array using decrRef() as it is no more needed.
4201 * \throw If \a this is not allocated.
4202 * \throw If \a this->getNumberOfComponents() != 1.
4203 * \throw If there are equal values in \a this array.
4205 DataArrayInt *DataArrayInt::checkAndPreparePermutation() const
4208 if(getNumberOfComponents()!=1)
4209 throw INTERP_KERNEL::Exception("DataArrayInt::checkAndPreparePermutation : number of components must == 1 !");
4210 int nbTuples=getNumberOfTuples();
4211 const int *pt=getConstPointer();
4212 int *pt2=CheckAndPreparePermutation(pt,pt+nbTuples);
4213 DataArrayInt *ret=DataArrayInt::New();
4214 ret->useArray(pt2,true,C_DEALLOC,nbTuples,1);
4219 * 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
4220 * input array \a ids2.
4221 * \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.
4222 * 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
4224 * In case of success (no throw) : \c ids1->renumber(ret)->isEqual(ids2) where \a ret is the return of this method.
4226 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4227 * array using decrRef() as it is no more needed.
4228 * \throw If either ids1 or ids2 is null not allocated or not with one components.
4231 DataArrayInt *DataArrayInt::FindPermutationFromFirstToSecond(const DataArrayInt *ids1, const DataArrayInt *ids2)
4234 throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be not null !");
4235 if(!ids1->isAllocated() || !ids2->isAllocated())
4236 throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be allocated !");
4237 if(ids1->getNumberOfComponents()!=1 || ids2->getNumberOfComponents()!=1)
4238 throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays have exactly one component !");
4239 if(ids1->getNumberOfTuples()!=ids2->getNumberOfTuples())
4241 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 !";
4242 throw INTERP_KERNEL::Exception(oss.str().c_str());
4244 MCAuto<DataArrayInt> p1(ids1->deepCopy());
4245 MCAuto<DataArrayInt> p2(ids2->deepCopy());
4246 p1->sort(true); p2->sort(true);
4247 if(!p1->isEqualWithoutConsideringStr(*p2))
4248 throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two arrays are not lying on same ids ! Impossible to find a permutation between the 2 arrays !");
4249 p1=ids1->checkAndPreparePermutation();
4250 p2=ids2->checkAndPreparePermutation();
4251 p2=p2->invertArrayO2N2N2O(p2->getNumberOfTuples());
4252 p2=p2->selectByTupleIdSafe(p1->begin(),p1->end());
4257 * Returns two arrays describing a surjective mapping from \a this set of values (\a A)
4258 * onto a set of values of size \a targetNb (\a B). The surjective function is
4259 * \a B[ \a A[ i ]] = i. That is to say that for each \a id in [0,\a targetNb), where \a
4260 * targetNb < \a this->getNumberOfTuples(), there exists at least one tupleId (\a tid) so
4261 * that <em> this->getIJ( tid, 0 ) == id</em>. <br>
4262 * The first of out arrays returns indices of elements of \a this array, grouped by their
4263 * place in the set \a B. The second out array is the index of the first one; it shows how
4264 * many elements of \a A are mapped into each element of \a B. <br>
4266 * mapping and its usage in renumbering see \ref numbering. <br>
4268 * - \a this: [0,3,2,3,2,2,1,2]
4270 * - \a arr: [0, 6, 2,4,5,7, 1,3]
4271 * - \a arrI: [0,1,2,6,8]
4273 * This result means: <br>
4274 * the element of \a B 0 encounters within \a A once (\a arrI[ 0+1 ] - \a arrI[ 0 ]) and
4275 * its index within \a A is 0 ( \a arr[ 0:1 ] == \a arr[ \a arrI[ 0 ] : \a arrI[ 0+1 ]]);<br>
4276 * the element of \a B 2 encounters within \a A 4 times (\a arrI[ 2+1 ] - \a arrI[ 2 ]) and
4277 * its indices within \a A are [2,4,5,7] ( \a arr[ 2:6 ] == \a arr[ \a arrI[ 2 ] :
4278 * \a arrI[ 2+1 ]]); <br> etc.
4279 * \param [in] targetNb - the size of the set \a B. \a targetNb must be equal or more
4280 * than the maximal value of \a A.
4281 * \param [out] arr - a new instance of DataArrayInt returning indices of
4282 * elements of \a this, grouped by their place in the set \a B. The caller is to delete
4283 * this array using decrRef() as it is no more needed.
4284 * \param [out] arrI - a new instance of DataArrayInt returning size of groups of equal
4285 * elements of \a this. The caller is to delete this array using decrRef() as it
4286 * is no more needed.
4287 * \throw If \a this is not allocated.
4288 * \throw If \a this->getNumberOfComponents() != 1.
4289 * \throw If any value in \a this is more or equal to \a targetNb.
4291 void DataArrayInt::changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, DataArrayInt *&arrI) const
4294 if(getNumberOfComponents()!=1)
4295 throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : number of components must == 1 !");
4296 int nbOfTuples=getNumberOfTuples();
4297 MCAuto<DataArrayInt> ret(DataArrayInt::New());
4298 MCAuto<DataArrayInt> retI(DataArrayInt::New());
4299 retI->alloc(targetNb+1,1);
4300 const int *input=getConstPointer();
4301 std::vector< std::vector<int> > tmp(targetNb);
4302 for(int i=0;i<nbOfTuples;i++)
4305 if(tmp2>=0 && tmp2<targetNb)
4306 tmp[tmp2].push_back(i);
4309 std::ostringstream oss; oss << "DataArrayInt::changeSurjectiveFormat : At pos " << i << " presence of element " << tmp2 << " ! should be in [0," << targetNb << ") !";
4310 throw INTERP_KERNEL::Exception(oss.str().c_str());
4313 int *retIPtr=retI->getPointer();
4315 for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++,retIPtr++)
4316 retIPtr[1]=retIPtr[0]+(int)((*it1).size());
4317 if(nbOfTuples!=retI->getIJ(targetNb,0))
4318 throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : big problem should never happen !");
4319 ret->alloc(nbOfTuples,1);
4320 int *retPtr=ret->getPointer();
4321 for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++)
4322 retPtr=std::copy((*it1).begin(),(*it1).end(),retPtr);
4329 * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode computed
4330 * from a zip representation of a surjective format (returned e.g. by
4331 * \ref MEDCoupling::DataArrayDouble::findCommonTuples() "DataArrayDouble::findCommonTuples()"
4332 * for example). The result array minimizes the permutation. <br>
4333 * For more info on renumbering see \ref numbering. <br>
4335 * - \a nbOfOldTuples: 10
4336 * - \a arr : [0,3, 5,7,9]
4337 * - \a arrIBg : [0,2,5]
4338 * - \a newNbOfTuples: 7
4339 * - result array : [0,1,2,0,3,4,5,4,6,4]
4341 * \param [in] nbOfOldTuples - number of tuples in the initial array \a arr.
4342 * \param [in] arr - the array of tuple indices grouped by \a arrIBg array.
4343 * \param [in] arrIBg - the array dividing all indices stored in \a arr into groups of
4344 * (indices of) equal values. Its every element (except the last one) points to
4345 * the first element of a group of equal values.
4346 * \param [in] arrIEnd - specifies the end of \a arrIBg, so that the last element of \a
4347 * arrIBg is \a arrIEnd[ -1 ].
4348 * \param [out] newNbOfTuples - number of tuples after surjection application.
4349 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4350 * array using decrRef() as it is no more needed.
4351 * \throw If any value of \a arr breaks condition ( 0 <= \a arr[ i ] < \a nbOfOldTuples ).
4353 DataArrayInt *DataArrayInt::ConvertIndexArrayToO2N(int nbOfOldTuples, const int *arr, const int *arrIBg, const int *arrIEnd, int &newNbOfTuples)
4355 MCAuto<DataArrayInt> ret=DataArrayInt::New();
4356 ret->alloc(nbOfOldTuples,1);
4357 int *pt=ret->getPointer();
4358 std::fill(pt,pt+nbOfOldTuples,-1);
4359 int nbOfGrps=((int)std::distance(arrIBg,arrIEnd))-1;
4360 const int *cIPtr=arrIBg;
4361 for(int i=0;i<nbOfGrps;i++)
4362 pt[arr[cIPtr[i]]]=-(i+2);
4364 for(int iNode=0;iNode<nbOfOldTuples;iNode++)
4372 int grpId=-(pt[iNode]+2);
4373 for(int j=cIPtr[grpId];j<cIPtr[grpId+1];j++)
4375 if(arr[j]>=0 && arr[j]<nbOfOldTuples)
4379 std::ostringstream oss; oss << "DataArrayInt::ConvertIndexArrayToO2N : With element #" << j << " value is " << arr[j] << " should be in [0," << nbOfOldTuples << ") !";
4380 throw INTERP_KERNEL::Exception(oss.str().c_str());
4387 newNbOfTuples=newNb;
4392 * Returns a new DataArrayInt containing a renumbering map in "New to Old" mode,
4393 * which if applied to \a this array would make it sorted ascendingly.
4394 * For more info on renumbering see \ref numbering. <br>
4396 * - \a this: [2,0,1,1,0,1,2,0,1,1,0,0]
4397 * - result: [10,0,5,6,1,7,11,2,8,9,3,4]
4398 * - after applying result to \a this: [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2]
4400 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4401 * array using decrRef() as it is no more needed.
4402 * \throw If \a this is not allocated.
4403 * \throw If \a this->getNumberOfComponents() != 1.
4405 DataArrayInt *DataArrayInt::buildPermArrPerLevel() const
4408 if(getNumberOfComponents()!=1)
4409 throw INTERP_KERNEL::Exception("DataArrayInt::buildPermArrPerLevel : number of components must == 1 !");
4410 int nbOfTuples=getNumberOfTuples();
4411 const int *pt=getConstPointer();
4412 std::map<int,int> m;
4413 MCAuto<DataArrayInt> ret=DataArrayInt::New();
4414 ret->alloc(nbOfTuples,1);
4415 int *opt=ret->getPointer();
4416 for(int i=0;i<nbOfTuples;i++,pt++,opt++)
4419 std::map<int,int>::iterator it=m.find(val);
4428 m.insert(std::pair<int,int>(val,1));
4432 for(std::map<int,int>::iterator it=m.begin();it!=m.end();it++)
4434 int vt=(*it).second;
4438 pt=getConstPointer();
4439 opt=ret->getPointer();
4440 for(int i=0;i<nbOfTuples;i++,pt++,opt++)
4447 * Checks if \a this array has the given size, and if its contents is equal to an array filled with
4448 * iota(). This method is particularly useful for DataArrayInt instances that represent
4449 * a renumbering array, to check if there is a real need in renumbering.
4450 * This method checks than \a this can be considered as an identity mapping
4451 * of a set having \a sizeExpected elements into itself.
4453 * \param [in] sizeExpected - The number of elements expected.
4454 * \return bool - \a true if \a this array contents == \a range( \a this->getNumberOfTuples())
4455 * \throw If \a this is not allocated.
4456 * \throw If \a this->getNumberOfComponents() != 1.
4458 bool DataArrayInt::isIota(int sizeExpected) const
4461 if(getNumberOfComponents()!=1)
4463 int nbOfTuples(getNumberOfTuples());
4464 if(nbOfTuples!=sizeExpected)
4466 const int *pt=getConstPointer();
4467 for(int i=0;i<nbOfTuples;i++,pt++)
4474 * Checks if all values in \a this array are equal to \a val.
4475 * \param [in] val - value to check equality of array values to.
4476 * \return bool - \a true if all values are \a val.
4477 * \throw If \a this is not allocated.
4478 * \throw If \a this->getNumberOfComponents() != 1
4479 * \sa DataArrayInt::checkUniformAndGuess
4481 bool DataArrayInt::isUniform(int val) const
4484 if(getNumberOfComponents()!=1)
4485 throw INTERP_KERNEL::Exception("DataArrayInt::isUniform : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
4486 const int *w(begin()),*end2(end());
4494 * This method checks that \a this is uniform. If not and exception will be thrown.
4495 * In case of uniformity the corresponding value is returned.
4497 * \return int - the unique value contained in this
4498 * \throw If \a this is not allocated.
4499 * \throw If \a this->getNumberOfComponents() != 1
4500 * \throw If \a this is not uniform.
4501 * \sa DataArrayInt::isUniform
4503 int DataArrayInt::checkUniformAndGuess() const
4506 if(getNumberOfComponents()!=1)
4507 throw INTERP_KERNEL::Exception("DataArrayInt::checkUniformAndGuess : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
4509 throw INTERP_KERNEL::Exception("DataArrayInt::checkUniformAndGuess : this is empty !");
4510 const int *w(begin()),*end2(end());
4514 throw INTERP_KERNEL::Exception("DataArrayInt::checkUniformAndGuess : this is not uniform !");
4519 * Checks if all values in \a this array are unique.
4520 * \return bool - \a true if condition above is true
4521 * \throw If \a this is not allocated.
4522 * \throw If \a this->getNumberOfComponents() != 1
4524 bool DataArrayInt::hasUniqueValues() const
4527 if(getNumberOfComponents()!=1)
4528 throw INTERP_KERNEL::Exception("DataArrayInt::hasOnlyUniqueValues: must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
4529 int nbOfTuples(getNumberOfTuples());
4530 std::set<int> s(begin(),end()); // in C++11, should use unordered_set (O(1) complexity)
4531 if (s.size() != nbOfTuples)
4537 * Copy all components in a specified order from another DataArrayInt.
4538 * The specified components become the first ones in \a this array.
4539 * Both numerical and textual data is copied. The number of tuples in \a this and
4540 * the other array can be different.
4541 * \param [in] a - the array to copy data from.
4542 * \param [in] compoIds - sequence of zero based indices of components, data of which is
4544 * \throw If \a a is NULL.
4545 * \throw If \a compoIds.size() != \a a->getNumberOfComponents().
4546 * \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
4548 * \if ENABLE_EXAMPLES
4549 * \ref py_mcdataarrayint_setselectedcomponents "Here is a Python example".
4552 void DataArrayInt::setSelectedComponents(const DataArrayInt *a, const std::vector<int>& compoIds)
4555 throw INTERP_KERNEL::Exception("DataArrayInt::setSelectedComponents : input DataArrayInt is NULL !");
4557 a->checkAllocated();
4558 copyPartOfStringInfoFrom2(compoIds,*a);
4559 std::size_t partOfCompoSz=compoIds.size();
4560 int nbOfCompo=getNumberOfComponents();
4561 int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
4562 const int *ac=a->getConstPointer();
4563 int *nc=getPointer();
4564 for(int i=0;i<nbOfTuples;i++)
4565 for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
4566 nc[nbOfCompo*i+compoIds[j]]=*ac;
4569 DataArrayIntIterator *DataArrayInt::iterator()
4571 return new DataArrayIntIterator(this);
4575 * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to a
4576 * given one. The ids are sorted in the ascending order.
4577 * \param [in] val - the value to find within \a this.
4578 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4579 * array using decrRef() as it is no more needed.
4580 * \throw If \a this is not allocated.
4581 * \throw If \a this->getNumberOfComponents() != 1.
4582 * \sa DataArrayInt::findIdsEqualTuple
4584 DataArrayInt *DataArrayInt::findIdsEqual(int val) const
4587 if(getNumberOfComponents()!=1)
4588 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqual : the array must have only one component, you can call 'rearrange' method before !");
4589 const int *cptr(getConstPointer());
4590 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4591 int nbOfTuples=getNumberOfTuples();
4592 for(int i=0;i<nbOfTuples;i++,cptr++)
4594 ret->pushBackSilent(i);
4599 * Creates a new DataArrayInt containing IDs (indices) of tuples holding value \b not
4600 * equal to a given one.
4601 * \param [in] val - the value to ignore within \a this.
4602 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4603 * array using decrRef() as it is no more needed.
4604 * \throw If \a this is not allocated.
4605 * \throw If \a this->getNumberOfComponents() != 1.
4607 DataArrayInt *DataArrayInt::findIdsNotEqual(int val) const
4610 if(getNumberOfComponents()!=1)
4611 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotEqual : the array must have only one component, you can call 'rearrange' method before !");
4612 const int *cptr(getConstPointer());
4613 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4614 int nbOfTuples=getNumberOfTuples();
4615 for(int i=0;i<nbOfTuples;i++,cptr++)
4617 ret->pushBackSilent(i);
4622 * Creates a new DataArrayInt containing IDs (indices) of tuples holding tuple equal to those defined by [ \a tupleBg , \a tupleEnd )
4623 * This method is an extension of DataArrayInt::findIdsEqual method.
4625 * \param [in] tupleBg - the begin (included) of the input tuple to find within \a this.
4626 * \param [in] tupleEnd - the end (excluded) of the input tuple to find within \a this.
4627 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4628 * array using decrRef() as it is no more needed.
4629 * \throw If \a this is not allocated.
4630 * \throw If \a this->getNumberOfComponents() != std::distance(tupleBg,tupleEnd).
4631 * \throw If \a this->getNumberOfComponents() is equal to 0.
4632 * \sa DataArrayInt::findIdsEqual
4634 DataArrayInt *DataArrayInt::findIdsEqualTuple(const int *tupleBg, const int *tupleEnd) const
4636 std::size_t nbOfCompoExp(std::distance(tupleBg,tupleEnd));
4638 if(getNumberOfComponents()!=(int)nbOfCompoExp)
4640 std::ostringstream oss; oss << "DataArrayInt::findIdsEqualTuple : mismatch of number of components. Input tuple has " << nbOfCompoExp << " whereas this array has " << getNumberOfComponents() << " components !";
4641 throw INTERP_KERNEL::Exception(oss.str().c_str());
4644 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqualTuple : number of components should be > 0 !");
4645 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4646 const int *bg(begin()),*end2(end()),*work(begin());
4649 work=std::search(work,end2,tupleBg,tupleEnd);
4652 std::size_t pos(std::distance(bg,work));
4653 if(pos%nbOfCompoExp==0)
4654 ret->pushBackSilent(pos/nbOfCompoExp);
4662 * Assigns \a newValue to all elements holding \a oldValue within \a this
4663 * one-dimensional array.
4664 * \param [in] oldValue - the value to replace.
4665 * \param [in] newValue - the value to assign.
4666 * \return int - number of replacements performed.
4667 * \throw If \a this is not allocated.
4668 * \throw If \a this->getNumberOfComponents() != 1.
4670 int DataArrayInt::changeValue(int oldValue, int newValue)
4673 if(getNumberOfComponents()!=1)
4674 throw INTERP_KERNEL::Exception("DataArrayInt::changeValue : the array must have only one component, you can call 'rearrange' method before !");
4675 if(oldValue==newValue)
4677 int *start(getPointer()),*end2(start+getNbOfElems());
4679 for(int *val=start;val!=end2;val++)
4693 * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to
4694 * one of given values.
4695 * \param [in] valsBg - an array of values to find within \a this array.
4696 * \param [in] valsEnd - specifies the end of the array \a valsBg, so that
4697 * the last value of \a valsBg is \a valsEnd[ -1 ].
4698 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4699 * array using decrRef() as it is no more needed.
4700 * \throw If \a this->getNumberOfComponents() != 1.
4702 DataArrayInt *DataArrayInt::findIdsEqualList(const int *valsBg, const int *valsEnd) const
4704 if(getNumberOfComponents()!=1)
4705 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqualList : the array must have only one component, you can call 'rearrange' method before !");
4706 std::set<int> vals2(valsBg,valsEnd);
4707 const int *cptr(getConstPointer());
4708 std::vector<int> res;
4709 int nbOfTuples(getNumberOfTuples());
4710 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4711 for(int i=0;i<nbOfTuples;i++,cptr++)
4712 if(vals2.find(*cptr)!=vals2.end())
4713 ret->pushBackSilent(i);
4718 * Creates a new DataArrayInt containing IDs (indices) of tuples holding values \b not
4719 * equal to any of given values.
4720 * \param [in] valsBg - an array of values to ignore within \a this array.
4721 * \param [in] valsEnd - specifies the end of the array \a valsBg, so that
4722 * the last value of \a valsBg is \a valsEnd[ -1 ].
4723 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4724 * array using decrRef() as it is no more needed.
4725 * \throw If \a this->getNumberOfComponents() != 1.
4727 DataArrayInt *DataArrayInt::findIdsNotEqualList(const int *valsBg, const int *valsEnd) const
4729 if(getNumberOfComponents()!=1)
4730 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotEqualList : the array must have only one component, you can call 'rearrange' method before !");
4731 std::set<int> vals2(valsBg,valsEnd);
4732 const int *cptr=getConstPointer();
4733 std::vector<int> res;
4734 int nbOfTuples=getNumberOfTuples();
4735 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4736 for(int i=0;i<nbOfTuples;i++,cptr++)
4737 if(vals2.find(*cptr)==vals2.end())
4738 ret->pushBackSilent(i);
4743 * This method is an extension of DataArrayInt::findIdFirstEqual method because this method works for DataArrayInt with
4744 * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
4745 * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
4746 * If any the tuple id is returned. If not -1 is returned.
4748 * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
4749 * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
4751 * \return tuple id where \b tupl is. -1 if no such tuple exists in \b this.
4752 * \sa DataArrayInt::findIdSequence, DataArrayInt::presenceOfTuple.
4754 int DataArrayInt::findIdFirstEqualTuple(const std::vector<int>& tupl) const
4757 int nbOfCompo=getNumberOfComponents();
4759 throw INTERP_KERNEL::Exception("DataArrayInt::findIdFirstEqualTuple : 0 components in 'this' !");
4760 if(nbOfCompo!=(int)tupl.size())
4762 std::ostringstream oss; oss << "DataArrayInt::findIdFirstEqualTuple : 'this' contains " << nbOfCompo << " components and searching for a tuple of length " << tupl.size() << " !";
4763 throw INTERP_KERNEL::Exception(oss.str().c_str());
4765 const int *cptr=getConstPointer();
4766 std::size_t nbOfVals=getNbOfElems();
4767 for(const int *work=cptr;work!=cptr+nbOfVals;)
4769 work=std::search(work,cptr+nbOfVals,tupl.begin(),tupl.end());
4770 if(work!=cptr+nbOfVals)
4772 if(std::distance(cptr,work)%nbOfCompo!=0)
4775 return std::distance(cptr,work)/nbOfCompo;
4782 * This method searches the sequence specified in input parameter \b vals in \b this.
4783 * This works only for DataArrayInt having number of components equal to one (if not an INTERP_KERNEL::Exception will be thrown).
4784 * This method differs from DataArrayInt::findIdFirstEqualTuple in that the position is internal raw data is not considered here contrary to DataArrayInt::findIdFirstEqualTuple.
4785 * \sa DataArrayInt::findIdFirstEqualTuple
4787 int DataArrayInt::findIdSequence(const std::vector<int>& vals) const
4790 int nbOfCompo=getNumberOfComponents();
4792 throw INTERP_KERNEL::Exception("DataArrayInt::findIdSequence : works only for DataArrayInt instance with one component !");
4793 const int *cptr=getConstPointer();
4794 std::size_t nbOfVals=getNbOfElems();
4795 const int *loc=std::search(cptr,cptr+nbOfVals,vals.begin(),vals.end());
4796 if(loc!=cptr+nbOfVals)
4797 return std::distance(cptr,loc);
4802 * This method expects to be called when number of components of this is equal to one.
4803 * This method returns the tuple id, if it exists, of the first tuple equal to \b value.
4804 * If not any tuple contains \b value -1 is returned.
4805 * \sa DataArrayInt::presenceOfValue
4807 int DataArrayInt::findIdFirstEqual(int value) const
4810 if(getNumberOfComponents()!=1)
4811 throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
4812 const int *cptr=getConstPointer();
4813 int nbOfTuples=getNumberOfTuples();
4814 const int *ret=std::find(cptr,cptr+nbOfTuples,value);
4815 if(ret!=cptr+nbOfTuples)
4816 return std::distance(cptr,ret);
4821 * This method expects to be called when number of components of this is equal to one.
4822 * This method returns the tuple id, if it exists, of the first tuple so that the value is contained in \b vals.
4823 * If not any tuple contains one of the values contained in 'vals' -1 is returned.
4824 * \sa DataArrayInt::presenceOfValue
4826 int DataArrayInt::findIdFirstEqual(const std::vector<int>& vals) const
4829 if(getNumberOfComponents()!=1)
4830 throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
4831 std::set<int> vals2(vals.begin(),vals.end());
4832 const int *cptr=getConstPointer();
4833 int nbOfTuples=getNumberOfTuples();
4834 for(const int *w=cptr;w!=cptr+nbOfTuples;w++)
4835 if(vals2.find(*w)!=vals2.end())
4836 return std::distance(cptr,w);
4841 * This method returns the number of values in \a this that are equals to input parameter \a value.
4842 * This method only works for single component array.
4844 * \return a value in [ 0, \c this->getNumberOfTuples() )
4846 * \throw If \a this is not allocated
4849 int DataArrayInt::count(int value) const
4853 if(getNumberOfComponents()!=1)
4854 throw INTERP_KERNEL::Exception("DataArrayInt::count : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
4855 const int *vals=begin();
4856 int nbOfTuples=getNumberOfTuples();
4857 for(int i=0;i<nbOfTuples;i++,vals++)
4864 * This method is an extension of DataArrayInt::presenceOfValue method because this method works for DataArrayInt with
4865 * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
4866 * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
4867 * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
4868 * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
4869 * \sa DataArrayInt::findIdFirstEqualTuple
4871 bool DataArrayInt::presenceOfTuple(const std::vector<int>& tupl) const
4873 return findIdFirstEqualTuple(tupl)!=-1;
4878 * Returns \a true if a given value is present within \a this one-dimensional array.
4879 * \param [in] value - the value to find within \a this array.
4880 * \return bool - \a true in case if \a value is present within \a this array.
4881 * \throw If \a this is not allocated.
4882 * \throw If \a this->getNumberOfComponents() != 1.
4883 * \sa findIdFirstEqual()
4885 bool DataArrayInt::presenceOfValue(int value) const
4887 return findIdFirstEqual(value)!=-1;
4891 * This method expects to be called when number of components of this is equal to one.
4892 * This method returns true if it exists a tuple so that the value is contained in \b vals.
4893 * If not any tuple contains one of the values contained in 'vals' false is returned.
4894 * \sa DataArrayInt::findIdFirstEqual
4896 bool DataArrayInt::presenceOfValue(const std::vector<int>& vals) const
4898 return findIdFirstEqual(vals)!=-1;
4902 * Accumulates values of each component of \a this array.
4903 * \param [out] res - an array of length \a this->getNumberOfComponents(), allocated
4904 * by the caller, that is filled by this method with sum value for each
4906 * \throw If \a this is not allocated.
4908 void DataArrayInt::accumulate(int *res) const
4911 const int *ptr=getConstPointer();
4912 int nbTuple=getNumberOfTuples();
4913 int nbComps=getNumberOfComponents();
4914 std::fill(res,res+nbComps,0);
4915 for(int i=0;i<nbTuple;i++)
4916 std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<int>());
4919 int DataArrayInt::accumulate(int compId) const
4922 const int *ptr=getConstPointer();
4923 int nbTuple=getNumberOfTuples();
4924 int nbComps=getNumberOfComponents();
4925 if(compId<0 || compId>=nbComps)
4926 throw INTERP_KERNEL::Exception("DataArrayInt::accumulate : Invalid compId specified : No such nb of components !");
4928 for(int i=0;i<nbTuple;i++)
4929 ret+=ptr[i*nbComps+compId];
4934 * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
4935 * The returned array will have same number of components than \a this and number of tuples equal to
4936 * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
4938 * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
4940 * \param [in] bgOfIndex - begin (included) of the input index array.
4941 * \param [in] endOfIndex - end (excluded) of the input index array.
4942 * \return DataArrayInt * - the new instance having the same number of components than \a this.
4944 * \throw If bgOfIndex or end is NULL.
4945 * \throw If input index array is not ascendingly sorted.
4946 * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
4947 * \throw If std::distance(bgOfIndex,endOfIndex)==0.
4949 DataArrayInt *DataArrayInt::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
4951 if(!bgOfIndex || !endOfIndex)
4952 throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : input pointer NULL !");
4954 int nbCompo=getNumberOfComponents();
4955 int nbOfTuples=getNumberOfTuples();
4956 int sz=(int)std::distance(bgOfIndex,endOfIndex);
4958 throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : invalid size of input index array !");
4960 MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(sz,nbCompo);
4961 const int *w=bgOfIndex;
4962 if(*w<0 || *w>=nbOfTuples)
4963 throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
4964 const int *srcPt=begin()+(*w)*nbCompo;
4965 int *tmp=ret->getPointer();
4966 for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
4968 std::fill(tmp,tmp+nbCompo,0);
4971 for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
4973 if(j>=0 && j<nbOfTuples)
4974 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<int>());
4977 std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
4978 throw INTERP_KERNEL::Exception(oss.str().c_str());
4984 std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
4985 throw INTERP_KERNEL::Exception(oss.str().c_str());
4988 ret->copyStringInfoFrom(*this);
4993 * Returns a new DataArrayInt by concatenating two given arrays, so that (1) the number
4994 * of tuples in the result array is <em> a1->getNumberOfTuples() + a2->getNumberOfTuples() -
4995 * offsetA2</em> and (2)
4996 * the number of component in the result array is same as that of each of given arrays.
4997 * First \a offsetA2 tuples of \a a2 are skipped and thus are missing from the result array.
4998 * Info on components is copied from the first of the given arrays. Number of components
4999 * in the given arrays must be the same.
5000 * \param [in] a1 - an array to include in the result array.
5001 * \param [in] a2 - another array to include in the result array.
5002 * \param [in] offsetA2 - number of tuples of \a a2 to skip.
5003 * \return DataArrayInt * - the new instance of DataArrayInt.
5004 * The caller is to delete this result array using decrRef() as it is no more
5006 * \throw If either \a a1 or \a a2 is NULL.
5007 * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
5009 DataArrayInt *DataArrayInt::Aggregate(const DataArrayInt *a1, const DataArrayInt *a2, int offsetA2)
5012 throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input DataArrayInt instance is NULL !");
5013 int nbOfComp=a1->getNumberOfComponents();
5014 if(nbOfComp!=a2->getNumberOfComponents())
5015 throw INTERP_KERNEL::Exception("Nb of components mismatch for array Aggregation !");
5016 int nbOfTuple1=a1->getNumberOfTuples();
5017 int nbOfTuple2=a2->getNumberOfTuples();
5018 DataArrayInt *ret=DataArrayInt::New();
5019 ret->alloc(nbOfTuple1+nbOfTuple2-offsetA2,nbOfComp);
5020 int *pt=std::copy(a1->getConstPointer(),a1->getConstPointer()+nbOfTuple1*nbOfComp,ret->getPointer());
5021 std::copy(a2->getConstPointer()+offsetA2*nbOfComp,a2->getConstPointer()+nbOfTuple2*nbOfComp,pt);
5022 ret->copyStringInfoFrom(*a1);
5027 * Returns a new DataArrayInt by concatenating all given arrays, so that (1) the number
5028 * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
5029 * the number of component in the result array is same as that of each of given arrays.
5030 * Info on components is copied from the first of the given arrays. Number of components
5031 * in the given arrays must be the same.
5032 * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it
5033 * not the object itself.
5034 * \param [in] arr - a sequence of arrays to include in the result array.
5035 * \return DataArrayInt * - the new instance of DataArrayInt.
5036 * The caller is to delete this result array using decrRef() as it is no more
5038 * \throw If all arrays within \a arr are NULL.
5039 * \throw If getNumberOfComponents() of arrays within \a arr.
5041 DataArrayInt *DataArrayInt::Aggregate(const std::vector<const DataArrayInt *>& arr)
5043 std::vector<const DataArrayInt *> a;
5044 for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
5048 throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input list must be NON EMPTY !");
5049 std::vector<const DataArrayInt *>::const_iterator it=a.begin();
5050 int nbOfComp=(*it)->getNumberOfComponents();
5051 int nbt=(*it++)->getNumberOfTuples();
5052 for(int i=1;it!=a.end();it++,i++)
5054 if((*it)->getNumberOfComponents()!=nbOfComp)
5055 throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : Nb of components mismatch for array aggregation !");
5056 nbt+=(*it)->getNumberOfTuples();
5058 MCAuto<DataArrayInt> ret=DataArrayInt::New();
5059 ret->alloc(nbt,nbOfComp);
5060 int *pt=ret->getPointer();
5061 for(it=a.begin();it!=a.end();it++)
5062 pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
5063 ret->copyStringInfoFrom(*(a[0]));
5068 * This method takes as input a list of DataArrayInt instances \a arrs that represent each a packed index arrays.
5069 * A packed index array is an allocated array with one component, and at least one tuple. The first element
5070 * of each array in \a arrs must be 0. Each array in \a arrs is expected to be increasingly monotonic.
5071 * 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.
5073 * \return DataArrayInt * - a new object to be managed by the caller.
5075 DataArrayInt *DataArrayInt::AggregateIndexes(const std::vector<const DataArrayInt *>& arrs)
5078 for(std::vector<const DataArrayInt *>::const_iterator it4=arrs.begin();it4!=arrs.end();it4++)
5082 (*it4)->checkAllocated();
5083 if((*it4)->getNumberOfComponents()!=1)
5085 std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of compo != 1 at pos " << std::distance(arrs.begin(),it4) << " !";
5086 throw INTERP_KERNEL::Exception(oss.str().c_str());
5088 int nbTupl=(*it4)->getNumberOfTuples();
5091 std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of tuples < 1 at pos " << std::distance(arrs.begin(),it4) << " !";
5092 throw INTERP_KERNEL::Exception(oss.str().c_str());
5094 if((*it4)->front()!=0)
5096 std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with front value != 0 at pos " << std::distance(arrs.begin(),it4) << " !";
5097 throw INTERP_KERNEL::Exception(oss.str().c_str());
5103 std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a null instance at pos " << std::distance(arrs.begin(),it4) << " !";
5104 throw INTERP_KERNEL::Exception(oss.str().c_str());
5108 throw INTERP_KERNEL::Exception("DataArrayInt::AggregateIndexes : input list must be NON EMPTY !");
5109 MCAuto<DataArrayInt> ret=DataArrayInt::New();
5110 ret->alloc(retSz,1);
5111 int *pt=ret->getPointer(); *pt++=0;
5112 for(std::vector<const DataArrayInt *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
5113 pt=std::transform((*it)->begin()+1,(*it)->end(),pt,std::bind2nd(std::plus<int>(),pt[-1]));
5114 ret->copyStringInfoFrom(*(arrs[0]));
5119 * Returns in a single walk in \a this the min value and the max value in \a this.
5120 * \a this is expected to be single component array.
5122 * \param [out] minValue - the min value in \a this.
5123 * \param [out] maxValue - the max value in \a this.
5125 * \sa getMinValueInArray, getMinValue, getMaxValueInArray, getMaxValue
5127 void DataArrayInt::getMinMaxValues(int& minValue, int& maxValue) const
5130 if(getNumberOfComponents()!=1)
5131 throw INTERP_KERNEL::Exception("DataArrayInt::getMinMaxValues : must be applied on DataArrayInt with only one component !");
5132 int nbTuples(getNumberOfTuples());
5133 const int *pt(begin());
5134 minValue=std::numeric_limits<int>::max(); maxValue=-std::numeric_limits<int>::max();
5135 for(int i=0;i<nbTuples;i++,pt++)
5145 * Modify all elements of \a this array, so that
5146 * an element _x_ becomes \f$ numerator / x \f$.
5147 * \warning If an exception is thrown because of presence of 0 element in \a this
5148 * array, all elements processed before detection of the zero element remain
5150 * \param [in] numerator - the numerator used to modify array elements.
5151 * \throw If \a this is not allocated.
5152 * \throw If there is an element equal to 0 in \a this array.
5154 void DataArrayInt::applyInv(int numerator)
5157 int *ptr=getPointer();
5158 std::size_t nbOfElems=getNbOfElems();
5159 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
5163 *ptr=numerator/(*ptr);
5167 std::ostringstream oss; oss << "DataArrayInt::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
5169 throw INTERP_KERNEL::Exception(oss.str().c_str());
5176 * Modify all elements of \a this array, so that
5177 * an element _x_ becomes \f$ x / val \f$.
5178 * \param [in] val - the denominator used to modify array elements.
5179 * \throw If \a this is not allocated.
5180 * \throw If \a val == 0.
5182 void DataArrayInt::applyDivideBy(int val)
5185 throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to divide by 0 !");
5187 int *ptr=getPointer();
5188 std::size_t nbOfElems=getNbOfElems();
5189 std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::divides<int>(),val));
5194 * Modify all elements of \a this array, so that
5195 * an element _x_ becomes <em> x % val </em>.
5196 * \param [in] val - the divisor used to modify array elements.
5197 * \throw If \a this is not allocated.
5198 * \throw If \a val <= 0.
5200 void DataArrayInt::applyModulus(int val)
5203 throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to operate modulus on value <= 0 !");
5205 int *ptr=getPointer();
5206 std::size_t nbOfElems=getNbOfElems();
5207 std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::modulus<int>(),val));
5212 * This method works only on data array with one component.
5213 * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
5214 * this[*id] in [\b vmin,\b vmax)
5216 * \param [in] vmin begin of range. This value is included in range (included).
5217 * \param [in] vmax end of range. This value is \b not included in range (excluded).
5218 * \return a newly allocated data array that the caller should deal with.
5220 * \sa DataArrayInt::findIdsNotInRange , DataArrayInt::findIdsStricltyNegative
5222 DataArrayInt *DataArrayInt::findIdsInRange(int vmin, int vmax) const
5224 InRange<int> ir(vmin,vmax);
5225 MCAuto<DataArrayInt> ret(findIdsAdv(ir));
5230 * This method works only on data array with one component.
5231 * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
5232 * this[*id] \b not in [\b vmin,\b vmax)
5234 * \param [in] vmin begin of range. This value is \b not included in range (excluded).
5235 * \param [in] vmax end of range. This value is included in range (included).
5236 * \return a newly allocated data array that the caller should deal with.
5238 * \sa DataArrayInt::findIdsInRange , DataArrayInt::findIdsStricltyNegative
5240 DataArrayInt *DataArrayInt::findIdsNotInRange(int vmin, int vmax) const
5242 NotInRange<int> nir(vmin,vmax);
5243 MCAuto<DataArrayInt> ret(findIdsAdv(nir));
5248 * This method works only on data array with one component.
5249 * 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.
5251 * \param [in] vmin begin of range. This value is included in range (included).
5252 * \param [in] vmax end of range. This value is \b not included in range (excluded).
5253 * \return if all ids in \a this are so that (*this)[i]==i for all i in [ 0, \c this->getNumberOfTuples() ). */
5254 bool DataArrayInt::checkAllIdsInRange(int vmin, int vmax) const
5257 if(getNumberOfComponents()!=1)
5258 throw INTERP_KERNEL::Exception("DataArrayInt::checkAllIdsInRange : this must have exactly one component !");
5259 int nbOfTuples=getNumberOfTuples();
5261 const int *cptr=getConstPointer();
5262 for(int i=0;i<nbOfTuples;i++,cptr++)
5264 if(*cptr>=vmin && *cptr<vmax)
5265 { ret=ret && *cptr==i; }
5268 std::ostringstream oss; oss << "DataArrayInt::checkAllIdsInRange : tuple #" << i << " has value " << *cptr << " should be in [" << vmin << "," << vmax << ") !";
5269 throw INTERP_KERNEL::Exception(oss.str().c_str());
5276 * Modify all elements of \a this array, so that
5277 * an element _x_ becomes <em> val % x </em>.
5278 * \warning If an exception is thrown because of presence of an element <= 0 in \a this
5279 * array, all elements processed before detection of the zero element remain
5281 * \param [in] val - the divident used to modify array elements.
5282 * \throw If \a this is not allocated.
5283 * \throw If there is an element equal to or less than 0 in \a this array.
5285 void DataArrayInt::applyRModulus(int val)
5288 int *ptr=getPointer();
5289 std::size_t nbOfElems=getNbOfElems();
5290 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
5298 std::ostringstream oss; oss << "DataArrayInt::applyRModulus : presence of value <=0 in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
5300 throw INTERP_KERNEL::Exception(oss.str().c_str());
5307 * Modify all elements of \a this array, so that
5308 * an element _x_ becomes <em> val ^ x </em>.
5309 * \param [in] val - the value used to apply pow on all array elements.
5310 * \throw If \a this is not allocated.
5311 * \throw If \a val < 0.
5313 void DataArrayInt::applyPow(int val)
5317 throw INTERP_KERNEL::Exception("DataArrayInt::applyPow : input pow in < 0 !");
5318 int *ptr=getPointer();
5319 std::size_t nbOfElems=getNbOfElems();
5322 std::fill(ptr,ptr+nbOfElems,1);
5325 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
5328 for(int j=0;j<val;j++)
5336 * Modify all elements of \a this array, so that
5337 * an element _x_ becomes \f$ val ^ x \f$.
5338 * \param [in] val - the value used to apply pow on all array elements.
5339 * \throw If \a this is not allocated.
5340 * \throw If there is an element < 0 in \a this array.
5341 * \warning If an exception is thrown because of presence of 0 element in \a this
5342 * array, all elements processed before detection of the zero element remain
5345 void DataArrayInt::applyRPow(int val)
5348 int *ptr=getPointer();
5349 std::size_t nbOfElems=getNbOfElems();
5350 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
5355 for(int j=0;j<*ptr;j++)
5361 std::ostringstream oss; oss << "DataArrayInt::applyRPow : presence of negative value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
5363 throw INTERP_KERNEL::Exception(oss.str().c_str());
5370 * Returns a new DataArrayInt which is a minimal partition of elements of \a groups.
5371 * The i-th item of the result array is an ID of a set of elements belonging to a
5372 * unique set of groups, which the i-th element is a part of. This set of elements
5373 * belonging to a unique set of groups is called \a family, so the result array contains
5374 * IDs of families each element belongs to.
5376 * \b Example: if we have two groups of elements: \a group1 [0,4] and \a group2 [ 0,1,2 ],
5377 * then there are 3 families:
5378 * - \a family1 (with ID 1) contains element [0] belonging to ( \a group1 + \a group2 ),
5379 * - \a family2 (with ID 2) contains elements [4] belonging to ( \a group1 ),
5380 * - \a family3 (with ID 3) contains element [1,2] belonging to ( \a group2 ), <br>
5381 * and the result array contains IDs of families [ 1,3,3,0,2 ]. <br> Note a family ID 0 which
5382 * stands for the element #3 which is in none of groups.
5384 * \param [in] groups - sequence of groups of element IDs.
5385 * \param [in] newNb - total number of elements; it must be more than max ID of element
5387 * \param [out] fidsOfGroups - IDs of families the elements of each group belong to.
5388 * \return DataArrayInt * - a new instance of DataArrayInt containing IDs of families
5389 * each element with ID from range [0, \a newNb ) belongs to. The caller is to
5390 * delete this array using decrRef() as it is no more needed.
5391 * \throw If any element ID in \a groups violates condition ( 0 <= ID < \a newNb ).
5393 DataArrayInt *DataArrayInt::MakePartition(const std::vector<const DataArrayInt *>& groups, int newNb, std::vector< std::vector<int> >& fidsOfGroups)
5395 std::vector<const DataArrayInt *> groups2;
5396 for(std::vector<const DataArrayInt *>::const_iterator it4=groups.begin();it4!=groups.end();it4++)
5398 groups2.push_back(*it4);
5399 MCAuto<DataArrayInt> ret=DataArrayInt::New();
5400 ret->alloc(newNb,1);
5401 int *retPtr=ret->getPointer();
5402 std::fill(retPtr,retPtr+newNb,0);
5404 for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++)
5406 const int *ptr=(*iter)->getConstPointer();
5407 std::size_t nbOfElem=(*iter)->getNbOfElems();
5409 for(int j=0;j<sfid;j++)
5412 for(std::size_t i=0;i<nbOfElem;i++)
5414 if(ptr[i]>=0 && ptr[i]<newNb)
5416 if(retPtr[ptr[i]]==j)
5424 std::ostringstream oss; oss << "DataArrayInt::MakePartition : In group \"" << (*iter)->getName() << "\" in tuple #" << i << " value = " << ptr[i] << " ! Should be in [0," << newNb;
5426 throw INTERP_KERNEL::Exception(oss.str().c_str());
5433 fidsOfGroups.clear();
5434 fidsOfGroups.resize(groups2.size());
5436 for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++,grId++)
5439 const int *ptr=(*iter)->getConstPointer();
5440 std::size_t nbOfElem=(*iter)->getNbOfElems();
5441 for(const int *p=ptr;p!=ptr+nbOfElem;p++)
5442 tmp.insert(retPtr[*p]);
5443 fidsOfGroups[grId].insert(fidsOfGroups[grId].end(),tmp.begin(),tmp.end());
5449 * Returns a new DataArrayInt which contains all elements of given one-dimensional
5450 * arrays. The result array does not contain any duplicates and its values
5451 * are sorted in ascending order.
5452 * \param [in] arr - sequence of DataArrayInt's to unite.
5453 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5454 * array using decrRef() as it is no more needed.
5455 * \throw If any \a arr[i] is not allocated.
5456 * \throw If \a arr[i]->getNumberOfComponents() != 1.
5458 DataArrayInt *DataArrayInt::BuildUnion(const std::vector<const DataArrayInt *>& arr)
5460 std::vector<const DataArrayInt *> a;
5461 for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
5464 for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
5466 (*it)->checkAllocated();
5467 if((*it)->getNumberOfComponents()!=1)
5468 throw INTERP_KERNEL::Exception("DataArrayInt::BuildUnion : only single component allowed !");
5472 for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
5474 const int *pt=(*it)->getConstPointer();
5475 int nbOfTuples=(*it)->getNumberOfTuples();
5476 r.insert(pt,pt+nbOfTuples);
5478 DataArrayInt *ret=DataArrayInt::New();
5479 ret->alloc((int)r.size(),1);
5480 std::copy(r.begin(),r.end(),ret->getPointer());
5485 * Returns a new DataArrayInt which contains elements present in each of given one-dimensional
5486 * arrays. The result array does not contain any duplicates and its values
5487 * are sorted in ascending order.
5488 * \param [in] arr - sequence of DataArrayInt's to intersect.
5489 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5490 * array using decrRef() as it is no more needed.
5491 * \throw If any \a arr[i] is not allocated.
5492 * \throw If \a arr[i]->getNumberOfComponents() != 1.
5494 DataArrayInt *DataArrayInt::BuildIntersection(const std::vector<const DataArrayInt *>& arr)
5496 std::vector<const DataArrayInt *> a;
5497 for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
5500 for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
5502 (*it)->checkAllocated();
5503 if((*it)->getNumberOfComponents()!=1)
5504 throw INTERP_KERNEL::Exception("DataArrayInt::BuildIntersection : only single component allowed !");
5508 for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
5510 const int *pt=(*it)->getConstPointer();
5511 int nbOfTuples=(*it)->getNumberOfTuples();
5512 std::set<int> s1(pt,pt+nbOfTuples);
5516 std::set_intersection(r.begin(),r.end(),s1.begin(),s1.end(),inserter(r2,r2.end()));
5522 DataArrayInt *ret(DataArrayInt::New());
5523 ret->alloc((int)r.size(),1);
5524 std::copy(r.begin(),r.end(),ret->getPointer());
5529 namespace MEDCouplingImpl
5534 OpSwitchedOn(int *pt):_pt(pt),_cnt(0) { }
5535 void operator()(const bool& b) { if(b) *_pt++=_cnt; _cnt++; }
5544 OpSwitchedOff(int *pt):_pt(pt),_cnt(0) { }
5545 void operator()(const bool& b) { if(!b) *_pt++=_cnt; _cnt++; }
5554 * This method returns the list of ids in ascending mode so that v[id]==true.
5556 DataArrayInt *DataArrayInt::BuildListOfSwitchedOn(const std::vector<bool>& v)
5558 int sz((int)std::count(v.begin(),v.end(),true));
5559 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
5560 std::for_each(v.begin(),v.end(),MEDCouplingImpl::OpSwitchedOn(ret->getPointer()));
5565 * This method returns the list of ids in ascending mode so that v[id]==false.
5567 DataArrayInt *DataArrayInt::BuildListOfSwitchedOff(const std::vector<bool>& v)
5569 int sz((int)std::count(v.begin(),v.end(),false));
5570 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
5571 std::for_each(v.begin(),v.end(),MEDCouplingImpl::OpSwitchedOff(ret->getPointer()));
5576 * This method allows to put a vector of vector of integer into a more compact data stucture (skyline).
5577 * This method is not available into python because no available optimized data structure available to map std::vector< std::vector<int> >.
5579 * \param [in] v the input data structure to be translate into skyline format.
5580 * \param [out] data the first element of the skyline format. The user is expected to deal with newly allocated array.
5581 * \param [out] dataIndex the second element of the skyline format.
5583 void DataArrayInt::PutIntoToSkylineFrmt(const std::vector< std::vector<int> >& v, DataArrayInt *& data, DataArrayInt *& dataIndex)
5585 int sz((int)v.size());
5586 MCAuto<DataArrayInt> ret0(DataArrayInt::New()),ret1(DataArrayInt::New());
5587 ret1->alloc(sz+1,1);
5588 int *pt(ret1->getPointer()); *pt=0;
5589 for(int i=0;i<sz;i++,pt++)
5590 pt[1]=pt[0]+(int)v[i].size();
5591 ret0->alloc(ret1->back(),1);
5592 pt=ret0->getPointer();
5593 for(int i=0;i<sz;i++)
5594 pt=std::copy(v[i].begin(),v[i].end(),pt);
5595 data=ret0.retn(); dataIndex=ret1.retn();
5599 * Returns a new DataArrayInt which contains a complement of elements of \a this
5600 * one-dimensional array. I.e. the result array contains all elements from the range [0,
5601 * \a nbOfElement) not present in \a this array.
5602 * \param [in] nbOfElement - maximal size of the result array.
5603 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5604 * array using decrRef() as it is no more needed.
5605 * \throw If \a this is not allocated.
5606 * \throw If \a this->getNumberOfComponents() != 1.
5607 * \throw If any element \a x of \a this array violates condition ( 0 <= \a x < \a
5610 DataArrayInt *DataArrayInt::buildComplement(int nbOfElement) const
5613 if(getNumberOfComponents()!=1)
5614 throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : only single component allowed !");
5615 std::vector<bool> tmp(nbOfElement);
5616 const int *pt=getConstPointer();
5617 int nbOfTuples=getNumberOfTuples();
5618 for(const int *w=pt;w!=pt+nbOfTuples;w++)
5619 if(*w>=0 && *w<nbOfElement)
5622 throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : an element is not in valid range : [0,nbOfElement) !");
5623 int nbOfRetVal=(int)std::count(tmp.begin(),tmp.end(),false);
5624 DataArrayInt *ret=DataArrayInt::New();
5625 ret->alloc(nbOfRetVal,1);
5627 int *retPtr=ret->getPointer();
5628 for(int i=0;i<nbOfElement;i++)
5635 * Returns a new DataArrayInt containing elements of \a this one-dimensional missing
5636 * from an \a other one-dimensional array.
5637 * \param [in] other - a DataArrayInt containing elements not to include in the result array.
5638 * \return DataArrayInt * - a new instance of DataArrayInt with one component. The
5639 * caller is to delete this array using decrRef() as it is no more needed.
5640 * \throw If \a other is NULL.
5641 * \throw If \a other is not allocated.
5642 * \throw If \a other->getNumberOfComponents() != 1.
5643 * \throw If \a this is not allocated.
5644 * \throw If \a this->getNumberOfComponents() != 1.
5645 * \sa DataArrayInt::buildSubstractionOptimized()
5647 DataArrayInt *DataArrayInt::buildSubstraction(const DataArrayInt *other) const
5650 throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : DataArrayInt pointer in input is NULL !");
5652 other->checkAllocated();
5653 if(getNumberOfComponents()!=1)
5654 throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed !");
5655 if(other->getNumberOfComponents()!=1)
5656 throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed for other type !");
5657 const int *pt=getConstPointer();
5658 int nbOfTuples=getNumberOfTuples();
5659 std::set<int> s1(pt,pt+nbOfTuples);
5660 pt=other->getConstPointer();
5661 nbOfTuples=other->getNumberOfTuples();
5662 std::set<int> s2(pt,pt+nbOfTuples);
5664 std::set_difference(s1.begin(),s1.end(),s2.begin(),s2.end(),std::back_insert_iterator< std::vector<int> >(r));
5665 DataArrayInt *ret=DataArrayInt::New();
5666 ret->alloc((int)r.size(),1);
5667 std::copy(r.begin(),r.end(),ret->getPointer());
5672 * \a this is expected to have one component and to be sorted ascendingly (as for \a other).
5673 * \a other is expected to be a part of \a this. If not DataArrayInt::buildSubstraction should be called instead.
5675 * \param [in] other an array with one component and expected to be sorted ascendingly.
5676 * \ret list of ids in \a this but not in \a other.
5677 * \sa DataArrayInt::buildSubstraction
5679 DataArrayInt *DataArrayInt::buildSubstractionOptimized(const DataArrayInt *other) const
5681 static const char *MSG="DataArrayInt::buildSubstractionOptimized : only single component allowed !";
5682 if(!other) throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstractionOptimized : NULL input array !");
5683 checkAllocated(); other->checkAllocated();
5684 if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
5685 if(other->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
5686 const int *pt1Bg(begin()),*pt1End(end()),*pt2Bg(other->begin()),*pt2End(other->end());
5687 const int *work1(pt1Bg),*work2(pt2Bg);
5688 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
5689 for(;work1!=pt1End;work1++)
5691 if(work2!=pt2End && *work1==*work2)
5694 ret->pushBackSilent(*work1);
5701 * Returns a new DataArrayInt which contains all elements of \a this and a given
5702 * one-dimensional arrays. The result array does not contain any duplicates
5703 * and its values are sorted in ascending order.
5704 * \param [in] other - an array to unite with \a this one.
5705 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5706 * array using decrRef() as it is no more needed.
5707 * \throw If \a this or \a other is not allocated.
5708 * \throw If \a this->getNumberOfComponents() != 1.
5709 * \throw If \a other->getNumberOfComponents() != 1.
5711 DataArrayInt *DataArrayInt::buildUnion(const DataArrayInt *other) const
5713 std::vector<const DataArrayInt *>arrs(2);
5714 arrs[0]=this; arrs[1]=other;
5715 return BuildUnion(arrs);
5720 * Returns a new DataArrayInt which contains elements present in both \a this and a given
5721 * one-dimensional arrays. The result array does not contain any duplicates
5722 * and its values are sorted in ascending order.
5723 * \param [in] other - an array to intersect with \a this one.
5724 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5725 * array using decrRef() as it is no more needed.
5726 * \throw If \a this or \a other is not allocated.
5727 * \throw If \a this->getNumberOfComponents() != 1.
5728 * \throw If \a other->getNumberOfComponents() != 1.
5730 DataArrayInt *DataArrayInt::buildIntersection(const DataArrayInt *other) const
5732 std::vector<const DataArrayInt *>arrs(2);
5733 arrs[0]=this; arrs[1]=other;
5734 return BuildIntersection(arrs);
5738 * This method can be applied on allocated with one component DataArrayInt instance.
5739 * This method is typically relevant for sorted arrays. All consecutive duplicated items in \a this will appear only once in returned DataArrayInt instance.
5740 * 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]
5742 * \return a newly allocated array that contain the result of the unique operation applied on \a this.
5743 * \throw if \a this is not allocated or if \a this has not exactly one component.
5744 * \sa DataArrayInt::buildUniqueNotSorted
5746 DataArrayInt *DataArrayInt::buildUnique() const
5749 if(getNumberOfComponents()!=1)
5750 throw INTERP_KERNEL::Exception("DataArrayInt::buildUnique : only single component allowed !");
5751 int nbOfTuples=getNumberOfTuples();
5752 MCAuto<DataArrayInt> tmp=deepCopy();
5753 int *data=tmp->getPointer();
5754 int *last=std::unique(data,data+nbOfTuples);
5755 MCAuto<DataArrayInt> ret=DataArrayInt::New();
5756 ret->alloc(std::distance(data,last),1);
5757 std::copy(data,last,ret->getPointer());
5762 * This method can be applied on allocated with one component DataArrayInt instance.
5763 * This method keep elements only once by keeping the same order in \a this that is not expected to be sorted.
5765 * \return a newly allocated array that contain the result of the unique operation applied on \a this.
5767 * \throw if \a this is not allocated or if \a this has not exactly one component.
5769 * \sa DataArrayInt::buildUnique
5771 DataArrayInt *DataArrayInt::buildUniqueNotSorted() const
5774 if(getNumberOfComponents()!=1)
5775 throw INTERP_KERNEL::Exception("DataArrayInt::buildUniqueNotSorted : only single component allowed !");
5777 getMinMaxValues(minVal,maxVal);
5778 std::vector<bool> b(maxVal-minVal+1,false);
5779 const int *ptBg(begin()),*endBg(end());
5780 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
5781 for(const int *pt=ptBg;pt!=endBg;pt++)
5785 ret->pushBackSilent(*pt);
5789 ret->copyStringInfoFrom(*this);
5794 * Returns a new DataArrayInt which contains size of every of groups described by \a this
5795 * "index" array. Such "index" array is returned for example by
5796 * \ref MEDCoupling::MEDCouplingUMesh::buildDescendingConnectivity
5797 * "MEDCouplingUMesh::buildDescendingConnectivity" and
5798 * \ref MEDCoupling::MEDCouplingUMesh::getNodalConnectivityIndex
5799 * "MEDCouplingUMesh::getNodalConnectivityIndex" etc.
5800 * This method preforms the reverse operation of DataArrayInt::computeOffsetsFull.
5801 * \return DataArrayInt * - a new instance of DataArrayInt, whose number of tuples
5802 * equals to \a this->getNumberOfComponents() - 1, and number of components is 1.
5803 * The caller is to delete this array using decrRef() as it is no more needed.
5804 * \throw If \a this is not allocated.
5805 * \throw If \a this->getNumberOfComponents() != 1.
5806 * \throw If \a this->getNumberOfTuples() < 2.
5809 * - this contains [1,3,6,7,7,9,15]
5810 * - result array contains [2,3,1,0,2,6],
5811 * where 2 = 3 - 1, 3 = 6 - 3, 1 = 7 - 6 etc.
5813 * \sa DataArrayInt::computeOffsetsFull
5815 DataArrayInt *DataArrayInt::deltaShiftIndex() const
5818 if(getNumberOfComponents()!=1)
5819 throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : only single component allowed !");
5820 int nbOfTuples=getNumberOfTuples();
5822 throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : 1 tuple at least must be present in 'this' !");
5823 const int *ptr=getConstPointer();
5824 DataArrayInt *ret=DataArrayInt::New();
5825 ret->alloc(nbOfTuples-1,1);
5826 int *out=ret->getPointer();
5827 std::transform(ptr+1,ptr+nbOfTuples,ptr,out,std::minus<int>());
5832 * Modifies \a this one-dimensional array so that value of each element \a x
5833 * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
5834 * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number of tuples
5835 * and components remains the same.<br>
5836 * This method is useful for allToAllV in MPI with contiguous policy. This method
5837 * differs from computeOffsetsFull() in that the number of tuples is \b not changed by
5839 * \throw If \a this is not allocated.
5840 * \throw If \a this->getNumberOfComponents() != 1.
5843 * - Before \a this contains [3,5,1,2,0,8]
5844 * - After \a this contains [0,3,8,9,11,11]<br>
5845 * Note that the last element 19 = 11 + 8 is missing because size of \a this
5846 * array is retained and thus there is no space to store the last element.
5848 void DataArrayInt::computeOffsets()
5851 if(getNumberOfComponents()!=1)
5852 throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets : only single component allowed !");
5853 int nbOfTuples=getNumberOfTuples();
5856 int *work=getPointer();
5859 for(int i=1;i<nbOfTuples;i++)
5862 work[i]=work[i-1]+tmp;
5870 * Modifies \a this one-dimensional array so that value of each element \a x
5871 * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
5872 * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number
5873 * components remains the same and number of tuples is inceamented by one.<br>
5874 * This method is useful for allToAllV in MPI with contiguous policy. This method
5875 * differs from computeOffsets() in that the number of tuples is changed by this one.
5876 * This method preforms the reverse operation of DataArrayInt::deltaShiftIndex.
5877 * \throw If \a this is not allocated.
5878 * \throw If \a this->getNumberOfComponents() != 1.
5881 * - Before \a this contains [3,5,1,2,0,8]
5882 * - After \a this contains [0,3,8,9,11,11,19]<br>
5883 * \sa DataArrayInt::deltaShiftIndex
5885 void DataArrayInt::computeOffsetsFull()
5888 if(getNumberOfComponents()!=1)
5889 throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsetsFull : only single component allowed !");
5890 int nbOfTuples=getNumberOfTuples();
5891 int *ret=(int *)malloc((nbOfTuples+1)*sizeof(int));
5892 const int *work=getConstPointer();
5894 for(int i=0;i<nbOfTuples;i++)
5895 ret[i+1]=work[i]+ret[i];
5896 useArray(ret,true,C_DEALLOC,nbOfTuples+1,1);
5901 * Returns two new DataArrayInt instances whose contents is computed from that of \a this and \a listOfIds arrays as follows.
5902 * \a this is expected to be an offset format ( as returned by DataArrayInt::computeOffsetsFull ) that is to say with one component
5903 * and ** sorted strictly increasingly **. \a listOfIds is expected to be sorted ascendingly (not strictly needed for \a listOfIds).
5904 * This methods searches in \a this, considered as a set of contiguous \c this->getNumberOfComponents() ranges, all ids in \a listOfIds
5905 * filling completely one of the ranges in \a this.
5907 * \param [in] listOfIds a list of ids that has to be sorted ascendingly.
5908 * \param [out] rangeIdsFetched the range ids fetched
5909 * \param [out] idsInInputListThatFetch contains the list of ids in \a listOfIds that are \b fully included in a range in \a this. So
5910 * \a idsInInputListThatFetch is a part of input \a listOfIds.
5912 * \sa DataArrayInt::computeOffsetsFull
5915 * - \a this : [0,3,7,9,15,18]
5916 * - \a listOfIds contains [0,1,2,3,7,8,15,16,17]
5917 * - \a rangeIdsFetched result array: [0,2,4]
5918 * - \a idsInInputListThatFetch result array: [0,1,2,7,8,15,16,17]
5919 * In this example id 3 in input \a listOfIds is alone so it do not appear in output \a idsInInputListThatFetch.
5922 void DataArrayInt::findIdsRangesInListOfIds(const DataArrayInt *listOfIds, DataArrayInt *& rangeIdsFetched, DataArrayInt *& idsInInputListThatFetch) const
5925 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : input list of ids is null !");
5926 listOfIds->checkAllocated(); checkAllocated();
5927 if(listOfIds->getNumberOfComponents()!=1)
5928 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : input list of ids must have exactly one component !");
5929 if(getNumberOfComponents()!=1)
5930 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : this must have exactly one component !");
5931 MCAuto<DataArrayInt> ret0=DataArrayInt::New(); ret0->alloc(0,1);
5932 MCAuto<DataArrayInt> ret1=DataArrayInt::New(); ret1->alloc(0,1);
5933 const int *tupEnd(listOfIds->end()),*offBg(begin()),*offEnd(end()-1);
5934 const int *tupPtr(listOfIds->begin()),*offPtr(offBg);
5935 while(tupPtr!=tupEnd && offPtr!=offEnd)
5937 if(*tupPtr==*offPtr)
5940 while(i<offPtr[1] && *tupPtr==i && tupPtr!=tupEnd) { i++; tupPtr++; }
5943 ret0->pushBackSilent((int)std::distance(offBg,offPtr));
5944 ret1->pushBackValsSilent(tupPtr-(offPtr[1]-offPtr[0]),tupPtr);
5949 { if(*tupPtr<*offPtr) tupPtr++; else offPtr++; }
5951 rangeIdsFetched=ret0.retn();
5952 idsInInputListThatFetch=ret1.retn();
5956 * Returns a new DataArrayInt whose contents is computed from that of \a this and \a
5957 * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
5958 * "index" array of a "iota" array, thus, whose each element gives an index of a group
5959 * beginning within the "iota" array. And \a this is a one-dimensional array
5960 * considered as a selector of groups described by \a offsets to include into the result array.
5961 * \throw If \a offsets is NULL.
5962 * \throw If \a offsets is not allocated.
5963 * \throw If \a offsets->getNumberOfComponents() != 1.
5964 * \throw If \a offsets is not monotonically increasing.
5965 * \throw If \a this is not allocated.
5966 * \throw If \a this->getNumberOfComponents() != 1.
5967 * \throw If any element of \a this is not a valid index for \a offsets array.
5970 * - \a this: [0,2,3]
5971 * - \a offsets: [0,3,6,10,14,20]
5972 * - result array: [0,1,2,6,7,8,9,10,11,12,13] == <br>
5973 * \c range(0,3) + \c range(6,10) + \c range(10,14) ==<br>
5974 * \c range( \a offsets[ \a this[0] ], offsets[ \a this[0]+1 ]) +
5975 * \c range( \a offsets[ \a this[1] ], offsets[ \a this[1]+1 ]) +
5976 * \c range( \a offsets[ \a this[2] ], offsets[ \a this[2]+1 ])
5978 DataArrayInt *DataArrayInt::buildExplicitArrByRanges(const DataArrayInt *offsets) const
5981 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : DataArrayInt pointer in input is NULL !");
5983 if(getNumberOfComponents()!=1)
5984 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : only single component allowed !");
5985 offsets->checkAllocated();
5986 if(offsets->getNumberOfComponents()!=1)
5987 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : input array should have only single component !");
5988 int othNbTuples=offsets->getNumberOfTuples()-1;
5989 int nbOfTuples=getNumberOfTuples();
5990 int retNbOftuples=0;
5991 const int *work=getConstPointer();
5992 const int *offPtr=offsets->getConstPointer();
5993 for(int i=0;i<nbOfTuples;i++)
5996 if(val>=0 && val<othNbTuples)
5998 int delta=offPtr[val+1]-offPtr[val];
6000 retNbOftuples+=delta;
6003 std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << val << " of offset array has a delta < 0 !";
6004 throw INTERP_KERNEL::Exception(oss.str().c_str());
6009 std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << i << " in this contains " << val;
6010 oss << " whereas offsets array is of size " << othNbTuples+1 << " !";
6011 throw INTERP_KERNEL::Exception(oss.str().c_str());
6014 MCAuto<DataArrayInt> ret=DataArrayInt::New();
6015 ret->alloc(retNbOftuples,1);
6016 int *retPtr=ret->getPointer();
6017 for(int i=0;i<nbOfTuples;i++)
6020 int start=offPtr[val];
6021 int off=offPtr[val+1]-start;
6022 for(int j=0;j<off;j++,retPtr++)
6029 * Returns a new DataArrayInt whose contents is computed using \a this that must be a
6030 * scaled array (monotonically increasing).
6031 from that of \a this and \a
6032 * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
6033 * "index" array of a "iota" array, thus, whose each element gives an index of a group
6034 * beginning within the "iota" array. And \a this is a one-dimensional array
6035 * considered as a selector of groups described by \a offsets to include into the result array.
6036 * \throw If \a is NULL.
6037 * \throw If \a this is not allocated.
6038 * \throw If \a this->getNumberOfComponents() != 1.
6039 * \throw If \a this->getNumberOfTuples() == 0.
6040 * \throw If \a this is not monotonically increasing.
6041 * \throw If any element of ids in ( \a bg \a stop \a step ) points outside the scale in \a this.
6044 * - \a bg , \a stop and \a step : (0,5,2)
6045 * - \a this: [0,3,6,10,14,20]
6046 * - result array: [0,0,0, 2,2,2,2, 4,4,4,4,4,4] == <br>
6048 DataArrayInt *DataArrayInt::buildExplicitArrOfSliceOnScaledArr(int bg, int stop, int step) const
6051 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : not allocated array !");
6052 if(getNumberOfComponents()!=1)
6053 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of components is expected to be equal to one !");
6054 int nbOfTuples(getNumberOfTuples());
6056 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of tuples must be != 0 !");
6057 const int *ids(begin());
6058 int nbOfEltsInSlc(GetNumberOfItemGivenBESRelative(bg,stop,step,"DataArrayInt::buildExplicitArrOfSliceOnScaledArr")),sz(0),pos(bg);
6059 for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
6061 if(pos>=0 && pos<nbOfTuples-1)
6063 int delta(ids[pos+1]-ids[pos]);
6067 std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " and at this pos this is not monotonically increasing !";
6068 throw INTERP_KERNEL::Exception(oss.str().c_str());
6073 std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " should be in [0," << nbOfTuples-1 << ") !";
6074 throw INTERP_KERNEL::Exception(oss.str().c_str());
6077 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
6078 int *retPtr(ret->getPointer());
6080 for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
6082 int delta(ids[pos+1]-ids[pos]);
6083 for(int j=0;j<delta;j++,retPtr++)
6090 * 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.
6091 * 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
6092 * in tuple **i** of returned DataArrayInt.
6093 * If ranges overlapped (in theory it should not) this method do not detect it and always returns the first range.
6095 * 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)]
6096 * The return DataArrayInt will contain : **[0,4,1,2,2,3]**
6098 * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
6099 * for lower value included and 2nd component is the upper value of corresponding range **excluded**.
6100 * \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
6101 * is thrown if no ranges in \a ranges contains value in \a this.
6103 * \sa DataArrayInt::findIdInRangeForEachTuple
6105 DataArrayInt *DataArrayInt::findRangeIdForEachTuple(const DataArrayInt *ranges) const
6108 throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : null input pointer !");
6109 if(ranges->getNumberOfComponents()!=2)
6110 throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : input DataArrayInt instance should have 2 components !");
6112 if(getNumberOfComponents()!=1)
6113 throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : this should have only one component !");
6114 int nbTuples=getNumberOfTuples();
6115 MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
6116 int nbOfRanges=ranges->getNumberOfTuples();
6117 const int *rangesPtr=ranges->getConstPointer();
6118 int *retPtr=ret->getPointer();
6119 const int *inPtr=getConstPointer();
6120 for(int i=0;i<nbTuples;i++,retPtr++)
6124 for(int j=0;j<nbOfRanges && !found;j++)
6125 if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
6126 { *retPtr=j; found=true; }
6131 std::ostringstream oss; oss << "DataArrayInt::findRangeIdForEachTuple : tuple #" << i << " not found by any ranges !";
6132 throw INTERP_KERNEL::Exception(oss.str().c_str());
6139 * 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.
6140 * 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
6141 * in tuple **i** of returned DataArrayInt.
6142 * If ranges overlapped (in theory it should not) this method do not detect it and always returns the sub position of the first range.
6144 * 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)]
6145 * The return DataArrayInt will contain : **[1,2,4,0,2,2]**
6146 * This method is often called in pair with DataArrayInt::findRangeIdForEachTuple method.
6148 * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
6149 * for lower value included and 2nd component is the upper value of corresponding range **excluded**.
6150 * \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
6151 * is thrown if no ranges in \a ranges contains value in \a this.
6152 * \sa DataArrayInt::findRangeIdForEachTuple
6154 DataArrayInt *DataArrayInt::findIdInRangeForEachTuple(const DataArrayInt *ranges) const
6157 throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : null input pointer !");
6158 if(ranges->getNumberOfComponents()!=2)
6159 throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : input DataArrayInt instance should have 2 components !");
6161 if(getNumberOfComponents()!=1)
6162 throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : this should have only one component !");
6163 int nbTuples=getNumberOfTuples();
6164 MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
6165 int nbOfRanges=ranges->getNumberOfTuples();
6166 const int *rangesPtr=ranges->getConstPointer();
6167 int *retPtr=ret->getPointer();
6168 const int *inPtr=getConstPointer();
6169 for(int i=0;i<nbTuples;i++,retPtr++)
6173 for(int j=0;j<nbOfRanges && !found;j++)
6174 if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
6175 { *retPtr=val-rangesPtr[2*j]; found=true; }
6180 std::ostringstream oss; oss << "DataArrayInt::findIdInRangeForEachTuple : tuple #" << i << " not found by any ranges !";
6181 throw INTERP_KERNEL::Exception(oss.str().c_str());
6188 * \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).
6189 * 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).
6190 * 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 !
6191 * If this method has correctly worked, \a this will be able to be considered as a linked list.
6192 * This method does nothing if number of tuples is lower of equal to 1.
6194 * This method is useful for users having an unstructured mesh having only SEG2 to rearrange internaly the connectibity without any coordinates consideration.
6196 * \sa MEDCouplingUMesh::orderConsecutiveCells1D, DataArrayInt::fromLinkedListOfPairToList
6198 void DataArrayInt::sortEachPairToMakeALinkedList()
6201 if(getNumberOfComponents()!=2)
6202 throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : Only works on DataArrayInt instance with nb of components equal to 2 !");
6203 int nbOfTuples(getNumberOfTuples());
6206 int *conn(getPointer());
6207 for(int i=1;i<nbOfTuples;i++,conn+=2)
6211 if(conn[2]==conn[3])
6213 std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " presence of a pair filled with same ids !";
6214 throw INTERP_KERNEL::Exception(oss.str().c_str());
6216 if(conn[2]!=conn[1] && conn[3]==conn[1] && conn[2]!=conn[0])
6217 std::swap(conn[2],conn[3]);
6218 //not(conn[2]==conn[1] && conn[3]!=conn[1] && conn[3]!=conn[0])
6219 if(conn[2]!=conn[1] || conn[3]==conn[1] || conn[3]==conn[0])
6221 std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " something is invalid !";
6222 throw INTERP_KERNEL::Exception(oss.str().c_str());
6227 if(conn[0]==conn[1] || conn[2]==conn[3])
6228 throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : In the 2 first tuples presence of a pair filled with same ids !");
6231 s.insert(conn,conn+4);
6233 throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : This can't be considered as a linked list regarding 2 first tuples !");
6234 if(std::count(conn,conn+4,conn[0])==2)
6239 if(conn[2]==conn[0])
6243 std::copy(tmp,tmp+4,conn);
6246 {//here we are sure to have (std::count(conn,conn+4,conn[1])==2)
6247 if(conn[1]==conn[3])
6248 std::swap(conn[2],conn[3]);
6255 * \a this is expected to be a correctly linked list of pairs.
6257 * \sa DataArrayInt::sortEachPairToMakeALinkedList
6259 MCAuto<DataArrayInt> DataArrayInt::fromLinkedListOfPairToList() const
6262 checkNbOfComps(2,"DataArrayInt::fromLinkedListOfPairToList : this is expected to have 2 components");
6263 int nbTuples(getNumberOfTuples());
6265 throw INTERP_KERNEL::Exception("DataArrayInt::fromLinkedListOfPairToList : no tuples in this ! Not a linked list !");
6266 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbTuples+1,1);
6267 const int *thisPtr(begin());
6268 int *retPtr(ret->getPointer());
6269 retPtr[0]=thisPtr[0];
6270 for(int i=0;i<nbTuples;i++)
6272 retPtr[i+1]=thisPtr[2*i+1];
6274 if(thisPtr[2*i+1]!=thisPtr[2*(i+1)+0])
6276 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 ?";
6277 throw INTERP_KERNEL::Exception(oss.str());
6284 * This method returns all different values found in \a this. This method throws if \a this has not been allocated.
6285 * But the number of components can be different from one.
6286 * \return a newly allocated array (that should be dealt by the caller) containing different values in \a this.
6288 DataArrayInt *DataArrayInt::getDifferentValues() const
6292 ret.insert(begin(),end());
6293 MCAuto<DataArrayInt> ret2=DataArrayInt::New(); ret2->alloc((int)ret.size(),1);
6294 std::copy(ret.begin(),ret.end(),ret2->getPointer());
6299 * This method is a refinement of DataArrayInt::getDifferentValues because it returns not only different values in \a this but also, for each of
6300 * them it tells which tuple id have this id.
6301 * This method works only on arrays with one component (if it is not the case call DataArrayInt::rearrange(1) ).
6302 * This method returns two arrays having same size.
6303 * 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.
6304 * 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]]
6306 std::vector<DataArrayInt *> DataArrayInt::partitionByDifferentValues(std::vector<int>& differentIds) const
6309 if(getNumberOfComponents()!=1)
6310 throw INTERP_KERNEL::Exception("DataArrayInt::partitionByDifferentValues : this should have only one component !");
6312 std::map<int,int> m,m2,m3;
6313 for(const int *w=begin();w!=end();w++)
6315 differentIds.resize(m.size());
6316 std::vector<DataArrayInt *> ret(m.size());
6317 std::vector<int *> retPtr(m.size());
6318 for(std::map<int,int>::const_iterator it=m.begin();it!=m.end();it++,id++)
6321 ret[id]=DataArrayInt::New();
6322 ret[id]->alloc((*it).second,1);
6323 retPtr[id]=ret[id]->getPointer();
6324 differentIds[id]=(*it).first;
6327 for(const int *w=begin();w!=end();w++,id++)
6329 retPtr[m2[*w]][m3[*w]++]=id;
6335 * This method split ids in [0, \c this->getNumberOfTuples() ) using \a this array as a field of weight (>=0 each).
6336 * The aim of this method is to return a set of \a nbOfSlices chunk of contiguous ids as balanced as possible.
6338 * \param [in] nbOfSlices - number of slices expected.
6339 * \return - a vector having a size equal to \a nbOfSlices giving the start (included) and the stop (excluded) of each chunks.
6341 * \sa DataArray::GetSlice
6342 * \throw If \a this is not allocated or not with exactly one component.
6343 * \throw If an element in \a this if < 0.
6345 std::vector< std::pair<int,int> > DataArrayInt::splitInBalancedSlices(int nbOfSlices) const
6347 if(!isAllocated() || getNumberOfComponents()!=1)
6348 throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : this array should have number of components equal to one and must be allocated !");
6350 throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : number of slices must be >= 1 !");
6351 int sum(accumulate(0)),nbOfTuples(getNumberOfTuples());
6352 int sumPerSlc(sum/nbOfSlices),pos(0);
6353 const int *w(begin());
6354 std::vector< std::pair<int,int> > ret(nbOfSlices);
6355 for(int i=0;i<nbOfSlices;i++)
6357 std::pair<int,int> p(pos,-1);
6359 while(locSum<sumPerSlc && pos<nbOfTuples) { pos++; locSum+=*w++; }
6363 p.second=nbOfTuples;
6370 * Returns a new DataArrayInt that is a modulus of two given arrays. There are 3
6372 * 1. The arrays have same number of tuples and components. Then each value of
6373 * the result array (_a_) is a division of the corresponding values of \a a1 and
6374 * \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, j ].
6375 * 2. The arrays have same number of tuples and one array, say _a2_, has one
6377 * _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, 0 ].
6378 * 3. The arrays have same number of components and one array, say _a2_, has one
6380 * _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ 0, j ].
6382 * Info on components is copied either from the first array (in the first case) or from
6383 * the array with maximal number of elements (getNbOfElems()).
6384 * \warning No check of division by zero is performed!
6385 * \param [in] a1 - a dividend array.
6386 * \param [in] a2 - a divisor array.
6387 * \return DataArrayInt * - the new instance of DataArrayInt.
6388 * The caller is to delete this result array using decrRef() as it is no more
6390 * \throw If either \a a1 or \a a2 is NULL.
6391 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
6392 * \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
6393 * none of them has number of tuples or components equal to 1.
6395 DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt *a2)
6398 throw INTERP_KERNEL::Exception("DataArrayInt::Modulus : input DataArrayInt instance is NULL !");
6399 int nbOfTuple1=a1->getNumberOfTuples();
6400 int nbOfTuple2=a2->getNumberOfTuples();
6401 int nbOfComp1=a1->getNumberOfComponents();
6402 int nbOfComp2=a2->getNumberOfComponents();
6403 if(nbOfTuple2==nbOfTuple1)
6405 if(nbOfComp1==nbOfComp2)
6407 MCAuto<DataArrayInt> ret=DataArrayInt::New();
6408 ret->alloc(nbOfTuple2,nbOfComp1);
6409 std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::modulus<int>());
6410 ret->copyStringInfoFrom(*a1);
6413 else if(nbOfComp2==1)
6415 MCAuto<DataArrayInt> ret=DataArrayInt::New();
6416 ret->alloc(nbOfTuple1,nbOfComp1);
6417 const int *a2Ptr=a2->getConstPointer();
6418 const int *a1Ptr=a1->getConstPointer();
6419 int *res=ret->getPointer();
6420 for(int i=0;i<nbOfTuple1;i++)
6421 res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::modulus<int>(),a2Ptr[i]));
6422 ret->copyStringInfoFrom(*a1);
6427 a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
6431 else if(nbOfTuple2==1)
6433 a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
6434 MCAuto<DataArrayInt> ret=DataArrayInt::New();
6435 ret->alloc(nbOfTuple1,nbOfComp1);
6436 const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
6437 int *pt=ret->getPointer();
6438 for(int i=0;i<nbOfTuple1;i++)
6439 pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::modulus<int>());
6440 ret->copyStringInfoFrom(*a1);
6445 a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Modulus !");//will always throw an exception
6451 * Modify \a this array so that each value becomes a modulus of division of this value by
6452 * a value of another DataArrayInt. There are 3 valid cases.
6453 * 1. The arrays have same number of tuples and components. Then each value of
6454 * \a this array is divided by the corresponding value of \a other one, i.e.:
6455 * _a_ [ i, j ] %= _other_ [ i, j ].
6456 * 2. The arrays have same number of tuples and \a other array has one component. Then
6457 * _a_ [ i, j ] %= _other_ [ i, 0 ].
6458 * 3. The arrays have same number of components and \a other array has one tuple. Then
6459 * _a_ [ i, j ] %= _a2_ [ 0, j ].
6461 * \warning No check of division by zero is performed!
6462 * \param [in] other - a divisor array.
6463 * \throw If \a other is NULL.
6464 * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
6465 * \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
6466 * \a other has number of both tuples and components not equal to 1.
6468 void DataArrayInt::modulusEqual(const DataArrayInt *other)
6471 throw INTERP_KERNEL::Exception("DataArrayInt::modulusEqual : input DataArrayInt instance is NULL !");
6472 const char *msg="Nb of tuples mismatch for DataArrayInt::modulusEqual !";
6473 checkAllocated(); other->checkAllocated();
6474 int nbOfTuple=getNumberOfTuples();
6475 int nbOfTuple2=other->getNumberOfTuples();
6476 int nbOfComp=getNumberOfComponents();
6477 int nbOfComp2=other->getNumberOfComponents();
6478 if(nbOfTuple==nbOfTuple2)
6480 if(nbOfComp==nbOfComp2)
6482 std::transform(begin(),end(),other->begin(),getPointer(),std::modulus<int>());
6484 else if(nbOfComp2==1)
6486 if(nbOfComp2==nbOfComp)
6488 int *ptr=getPointer();
6489 const int *ptrc=other->getConstPointer();
6490 for(int i=0;i<nbOfTuple;i++)
6491 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::modulus<int>(),*ptrc++));
6494 throw INTERP_KERNEL::Exception(msg);
6497 throw INTERP_KERNEL::Exception(msg);
6499 else if(nbOfTuple2==1)
6501 int *ptr=getPointer();
6502 const int *ptrc=other->getConstPointer();
6503 for(int i=0;i<nbOfTuple;i++)
6504 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::modulus<int>());
6507 throw INTERP_KERNEL::Exception(msg);
6512 * Returns a new DataArrayInt that is the result of pow of two given arrays. There are 3
6515 * \param [in] a1 - an array to pow up.
6516 * \param [in] a2 - another array to sum up.
6517 * \return DataArrayInt * - the new instance of DataArrayInt.
6518 * The caller is to delete this result array using decrRef() as it is no more
6520 * \throw If either \a a1 or \a a2 is NULL.
6521 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
6522 * \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
6523 * \throw If there is a negative value in \a a2.
6525 DataArrayInt *DataArrayInt::Pow(const DataArrayInt *a1, const DataArrayInt *a2)
6528 throw INTERP_KERNEL::Exception("DataArrayInt::Pow : at least one of input instances is null !");
6529 int nbOfTuple=a1->getNumberOfTuples();
6530 int nbOfTuple2=a2->getNumberOfTuples();
6531 int nbOfComp=a1->getNumberOfComponents();
6532 int nbOfComp2=a2->getNumberOfComponents();
6533 if(nbOfTuple!=nbOfTuple2)
6534 throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of tuples mismatches !");
6535 if(nbOfComp!=1 || nbOfComp2!=1)
6536 throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of components of both arrays must be equal to 1 !");
6537 MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuple,1);
6538 const int *ptr1(a1->begin()),*ptr2(a2->begin());
6539 int *ptr=ret->getPointer();
6540 for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
6545 for(int j=0;j<*ptr2;j++)
6551 std::ostringstream oss; oss << "DataArrayInt::Pow : on tuple #" << i << " of a2 value is < 0 (" << *ptr2 << ") !";
6552 throw INTERP_KERNEL::Exception(oss.str().c_str());
6559 * Apply pow on values of another DataArrayInt to values of \a this one.
6561 * \param [in] other - an array to pow to \a this one.
6562 * \throw If \a other is NULL.
6563 * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
6564 * \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
6565 * \throw If there is a negative value in \a other.
6567 void DataArrayInt::powEqual(const DataArrayInt *other)
6570 throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : input instance is null !");
6571 int nbOfTuple=getNumberOfTuples();
6572 int nbOfTuple2=other->getNumberOfTuples();
6573 int nbOfComp=getNumberOfComponents();
6574 int nbOfComp2=other->getNumberOfComponents();
6575 if(nbOfTuple!=nbOfTuple2)
6576 throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of tuples mismatches !");
6577 if(nbOfComp!=1 || nbOfComp2!=1)
6578 throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of components of both arrays must be equal to 1 !");
6579 int *ptr=getPointer();
6580 const int *ptrc=other->begin();
6581 for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
6586 for(int j=0;j<*ptrc;j++)
6592 std::ostringstream oss; oss << "DataArrayInt::powEqual : on tuple #" << i << " of other value is < 0 (" << *ptrc << ") !";
6593 throw INTERP_KERNEL::Exception(oss.str().c_str());
6600 * Returns a C array which is a renumbering map in "Old to New" mode for the input array.
6601 * This map, if applied to \a start array, would make it sorted. For example, if
6602 * \a start array contents are [9,10,0,6,4,11,3,7] then the contents of the result array is
6603 * [5,6,0,3,2,7,1,4].
6604 * \param [in] start - pointer to the first element of the array for which the
6605 * permutation map is computed.
6606 * \param [in] end - pointer specifying the end of the array \a start, so that
6607 * the last value of \a start is \a end[ -1 ].
6608 * \return int * - the result permutation array that the caller is to delete as it is no
6610 * \throw If there are equal values in the input array.
6612 int *DataArrayInt::CheckAndPreparePermutation(const int *start, const int *end)
6614 std::size_t sz=std::distance(start,end);
6615 int *ret=(int *)malloc(sz*sizeof(int));
6616 int *work=new int[sz];
6617 std::copy(start,end,work);
6618 std::sort(work,work+sz);
6619 if(std::unique(work,work+sz)!=work+sz)
6623 throw INTERP_KERNEL::Exception("Some elements are equals in the specified array !");
6625 std::map<int,int> m;
6626 for(int *workPt=work;workPt!=work+sz;workPt++)
6627 m[*workPt]=(int)std::distance(work,workPt);
6629 for(const int *iter=start;iter!=end;iter++,iter2++)
6636 * Returns a new DataArrayInt containing an arithmetic progression
6637 * that is equal to the sequence returned by Python \c range(\a begin,\a end,\a step )
6639 * \param [in] begin - the start value of the result sequence.
6640 * \param [in] end - limiting value, so that every value of the result array is less than
6642 * \param [in] step - specifies the increment or decrement.
6643 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6644 * array using decrRef() as it is no more needed.
6645 * \throw If \a step == 0.
6646 * \throw If \a end < \a begin && \a step > 0.
6647 * \throw If \a end > \a begin && \a step < 0.
6649 DataArrayInt *DataArrayInt::Range(int begin, int end, int step)
6651 int nbOfTuples=GetNumberOfItemGivenBESRelative(begin,end,step,"DataArrayInt::Range");
6652 MCAuto<DataArrayInt> ret=DataArrayInt::New();
6653 ret->alloc(nbOfTuples,1);
6654 int *ptr=ret->getPointer();
6657 for(int i=begin;i<end;i+=step,ptr++)
6662 for(int i=begin;i>end;i+=step,ptr++)
6669 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
6672 void DataArrayInt::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
6677 tinyInfo[0]=getNumberOfTuples();
6678 tinyInfo[1]=getNumberOfComponents();
6688 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
6691 void DataArrayInt::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
6695 int nbOfCompo=getNumberOfComponents();
6696 tinyInfo.resize(nbOfCompo+1);
6697 tinyInfo[0]=getName();
6698 for(int i=0;i<nbOfCompo;i++)
6699 tinyInfo[i+1]=getInfoOnComponent(i);
6704 tinyInfo[0]=getName();
6709 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
6710 * This method returns if a feeding is needed.
6712 bool DataArrayInt::resizeForUnserialization(const std::vector<int>& tinyInfoI)
6714 int nbOfTuple=tinyInfoI[0];
6715 int nbOfComp=tinyInfoI[1];
6716 if(nbOfTuple!=-1 || nbOfComp!=-1)
6718 alloc(nbOfTuple,nbOfComp);
6725 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
6726 * This method returns if a feeding is needed.
6728 void DataArrayInt::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
6730 setName(tinyInfoS[0]);
6733 int nbOfCompo=tinyInfoI[1];
6734 for(int i=0;i<nbOfCompo;i++)
6735 setInfoOnComponent(i,tinyInfoS[i+1]);
6739 DataArrayIntIterator::DataArrayIntIterator(DataArrayInt *da):DataArrayIterator<int>(da)
6743 DataArrayInt32Tuple::DataArrayInt32Tuple(int *pt, int nbOfComp):DataArrayTuple<int>(pt,nbOfComp)
6747 std::string DataArrayIntTuple::repr() const
6749 std::ostringstream oss; oss << "(";
6750 for(int i=0;i<_nb_of_compo-1;i++)
6751 oss << _pt[i] << ", ";
6752 oss << _pt[_nb_of_compo-1] << ")";
6756 int DataArrayIntTuple::intValue() const
6758 return this->zeValue();
6762 * This method returns a newly allocated instance the caller should dealed with by a MEDCoupling::DataArrayInt::decrRef.
6763 * This method performs \b no copy of data. The content is only referenced using MEDCoupling::DataArrayInt::useArray with ownership set to \b false.
6764 * 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
6765 * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
6767 DataArrayInt *DataArrayIntTuple::buildDAInt(int nbOfTuples, int nbOfCompo) const
6769 return this->buildDA(nbOfTuples,nbOfCompo);