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;
900 * This method is close to repr method except that when \a this has more than 1000 tuples, all tuples are not
901 * printed out to avoid to consume too much space in interpretor.
904 std::string DataArrayDouble::reprNotTooLong() const
906 std::ostringstream ret;
907 reprNotTooLongStream(ret);
911 void DataArrayDouble::writeVTK(std::ostream& ofs, int indent, const std::string& nameInFile, DataArrayByte *byteArr) const
913 static const char SPACE[4]={' ',' ',' ',' '};
915 std::string idt(indent,' ');
917 ofs << idt << "<DataArray type=\"Float32\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
919 bool areAllEmpty(true);
920 for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
924 for(std::size_t i=0;i<_info_on_compo.size();i++)
925 ofs << " ComponentName" << i << "=\"" << _info_on_compo[i] << "\"";
929 ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
930 INTERP_KERNEL::AutoPtr<float> tmp(new float[getNbOfElems()]);
932 // to make Visual C++ happy : instead of std::copy(begin(),end(),(float *)tmp);
933 for(const double *src=begin();src!=end();src++,pt++)
935 const char *data(reinterpret_cast<const char *>((float *)tmp));
936 std::size_t sz(getNbOfElems()*sizeof(float));
937 byteArr->insertAtTheEnd(data,data+sz);
938 byteArr->insertAtTheEnd(SPACE,SPACE+4);
942 ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
943 std::copy(begin(),end(),std::ostream_iterator<double>(ofs," "));
945 ofs << std::endl << idt << "</DataArray>\n";
948 void DataArrayDouble::reprStream(std::ostream& stream) const
950 stream << "Name of double array : \"" << _name << "\"\n";
951 reprWithoutNameStream(stream);
954 void DataArrayDouble::reprZipStream(std::ostream& stream) const
956 stream << "Name of double array : \"" << _name << "\"\n";
957 reprZipWithoutNameStream(stream);
960 void DataArrayDouble::reprNotTooLongStream(std::ostream& stream) const
962 stream << "Name of double array : \"" << _name << "\"\n";
963 reprNotTooLongWithoutNameStream(stream);
966 void DataArrayDouble::reprWithoutNameStream(std::ostream& stream) const
968 DataArray::reprWithoutNameStream(stream);
969 stream.precision(17);
970 _mem.repr(getNumberOfComponents(),stream);
973 void DataArrayDouble::reprZipWithoutNameStream(std::ostream& stream) const
975 DataArray::reprWithoutNameStream(stream);
976 stream.precision(17);
977 _mem.reprZip(getNumberOfComponents(),stream);
980 void DataArrayDouble::reprNotTooLongWithoutNameStream(std::ostream& stream) const
982 DataArray::reprWithoutNameStream(stream);
983 stream.precision(17);
984 _mem.reprNotTooLong(getNumberOfComponents(),stream);
987 void DataArrayDouble::reprCppStream(const std::string& varName, std::ostream& stream) const
989 int nbTuples(getNumberOfTuples()),nbComp(getNumberOfComponents());
990 const double *data(getConstPointer());
991 stream.precision(17);
992 stream << "DataArrayDouble *" << varName << "=DataArrayDouble::New();" << std::endl;
993 if(nbTuples*nbComp>=1)
995 stream << "const double " << varName << "Data[" << nbTuples*nbComp << "]={";
996 std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<double>(stream,","));
997 stream << data[nbTuples*nbComp-1] << "};" << std::endl;
998 stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
1001 stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
1002 stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
1006 * Method that gives a quick overvien of \a this for python.
1008 void DataArrayDouble::reprQuickOverview(std::ostream& stream) const
1010 static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
1011 stream << "DataArrayDouble C++ instance at " << this << ". ";
1014 int nbOfCompo=(int)_info_on_compo.size();
1017 int nbOfTuples=getNumberOfTuples();
1018 stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
1019 reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
1022 stream << "Number of components : 0.";
1025 stream << "*** No data allocated ****";
1028 void DataArrayDouble::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
1030 const double *data=begin();
1031 int nbOfTuples=getNumberOfTuples();
1032 int nbOfCompo=(int)_info_on_compo.size();
1033 std::ostringstream oss2; oss2 << "[";
1035 std::string oss2Str(oss2.str());
1036 bool isFinished=true;
1037 for(int i=0;i<nbOfTuples && isFinished;i++)
1042 for(int j=0;j<nbOfCompo;j++,data++)
1045 if(j!=nbOfCompo-1) oss2 << ", ";
1051 if(i!=nbOfTuples-1) oss2 << ", ";
1052 std::string oss3Str(oss2.str());
1053 if(oss3Str.length()<maxNbOfByteInRepr)
1065 * Equivalent to DataArrayDouble::isEqual except that if false the reason of
1066 * mismatch is given.
1068 * \param [in] other the instance to be compared with \a this
1069 * \param [in] prec the precision to compare numeric data of the arrays.
1070 * \param [out] reason In case of inequality returns the reason.
1071 * \sa DataArrayDouble::isEqual
1073 bool DataArrayDouble::isEqualIfNotWhy(const DataArrayDouble& other, double prec, std::string& reason) const
1075 if(!areInfoEqualsIfNotWhy(other,reason))
1077 return _mem.isEqual(other._mem,prec,reason);
1081 * Checks if \a this and another DataArrayDouble are fully equal. For more info see
1082 * \ref MEDCouplingArrayBasicsCompare.
1083 * \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1084 * \param [in] prec - precision value to compare numeric data of the arrays.
1085 * \return bool - \a true if the two arrays are equal, \a false else.
1087 bool DataArrayDouble::isEqual(const DataArrayDouble& other, double prec) const
1090 return isEqualIfNotWhy(other,prec,tmp);
1094 * Checks if values of \a this and another DataArrayDouble are equal. For more info see
1095 * \ref MEDCouplingArrayBasicsCompare.
1096 * \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1097 * \param [in] prec - precision value to compare numeric data of the arrays.
1098 * \return bool - \a true if the values of two arrays are equal, \a false else.
1100 bool DataArrayDouble::isEqualWithoutConsideringStr(const DataArrayDouble& other, double prec) const
1103 return _mem.isEqual(other._mem,prec,tmp);
1107 * This method checks that all tuples in \a other are in \a this.
1108 * If true, the output param \a tupleIds contains the tuples ids of \a this that correspond to tupes in \a this.
1109 * 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.
1111 * \param [in] other - the array having the same number of components than \a this.
1112 * \param [out] tupleIds - the tuple ids containing the same number of tuples than \a other has.
1113 * \sa DataArrayDouble::findCommonTuples
1115 bool DataArrayDouble::areIncludedInMe(const DataArrayDouble *other, double prec, DataArrayInt *&tupleIds) const
1118 throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : input array is NULL !");
1119 checkAllocated(); other->checkAllocated();
1120 if(getNumberOfComponents()!=other->getNumberOfComponents())
1121 throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : the number of components does not match !");
1122 MCAuto<DataArrayDouble> a=DataArrayDouble::Aggregate(this,other);
1123 DataArrayInt *c=0,*ci=0;
1124 a->findCommonTuples(prec,getNumberOfTuples(),c,ci);
1125 MCAuto<DataArrayInt> cSafe(c),ciSafe(ci);
1126 int newNbOfTuples=-1;
1127 MCAuto<DataArrayInt> ids=DataArrayInt::ConvertIndexArrayToO2N(a->getNumberOfTuples(),c->begin(),ci->begin(),ci->end(),newNbOfTuples);
1128 MCAuto<DataArrayInt> ret1=ids->selectByTupleIdSafeSlice(getNumberOfTuples(),a->getNumberOfTuples(),1);
1129 tupleIds=ret1.retn();
1130 return newNbOfTuples==getNumberOfTuples();
1134 * Searches for tuples coincident within \a prec tolerance. Each tuple is considered
1135 * as coordinates of a point in getNumberOfComponents()-dimensional space. The
1136 * distance separating two points is computed with the infinite norm.
1138 * Indices of coincident tuples are stored in output arrays.
1139 * A pair of arrays (\a comm, \a commIndex) is called "Surjective Format 2".
1141 * This method is typically used by MEDCouplingPointSet::findCommonNodes() and
1142 * MEDCouplingUMesh::mergeNodes().
1143 * \param [in] prec - minimal absolute distance between two tuples (infinite norm) at which they are
1144 * considered not coincident.
1145 * \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
1146 * tuples have id strictly lower than \a limitTupleId then they are not returned.
1147 * \param [out] comm - the array holding ids (== indices) of coincident tuples.
1148 * \a comm->getNumberOfComponents() == 1.
1149 * \a comm->getNumberOfTuples() == \a commIndex->back().
1150 * \param [out] commIndex - the array dividing all indices stored in \a comm into
1151 * groups of (indices of) coincident tuples. Its every value is a tuple
1152 * index where a next group of tuples begins. For example the second
1153 * group of tuples in \a comm is described by following range of indices:
1154 * [ \a commIndex[1], \a commIndex[2] ). \a commIndex->getNumberOfTuples()-1
1155 * gives the number of groups of coincident tuples.
1156 * \throw If \a this is not allocated.
1157 * \throw If the number of components is not in [1,2,3,4].
1159 * \if ENABLE_EXAMPLES
1160 * \ref cpp_mcdataarraydouble_findcommontuples "Here is a C++ example".
1162 * \ref py_mcdataarraydouble_findcommontuples "Here is a Python example".
1164 * \sa DataArrayInt::ConvertIndexArrayToO2N(), DataArrayDouble::areIncludedInMe
1166 void DataArrayDouble::findCommonTuples(double prec, int limitTupleId, DataArrayInt *&comm, DataArrayInt *&commIndex) const
1169 int nbOfCompo=getNumberOfComponents();
1170 if ((nbOfCompo<1) || (nbOfCompo>4)) //test before work
1171 throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : Unexpected spacedim of coords. Must be 1, 2, 3 or 4.");
1173 int nbOfTuples=getNumberOfTuples();
1175 MCAuto<DataArrayInt> c(DataArrayInt::New()),cI(DataArrayInt::New()); c->alloc(0,1); cI->pushBackSilent(0);
1179 findCommonTuplesAlg<4>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1182 findCommonTuplesAlg<3>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1185 findCommonTuplesAlg<2>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1188 findCommonTuplesAlg<1>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1191 throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : nb of components managed are 1,2,3 and 4 ! not implemented for other number of components !");
1194 commIndex=cI.retn();
1198 * This methods returns the minimal distance between the two set of points \a this and \a other.
1199 * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
1200 * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
1202 * \param [out] thisTupleId the tuple id in \a this corresponding to the returned minimal distance
1203 * \param [out] otherTupleId the tuple id in \a other corresponding to the returned minimal distance
1204 * \return the minimal distance between the two set of points \a this and \a other.
1205 * \sa DataArrayDouble::findClosestTupleId
1207 double DataArrayDouble::minimalDistanceTo(const DataArrayDouble *other, int& thisTupleId, int& otherTupleId) const
1209 MCAuto<DataArrayInt> part1=findClosestTupleId(other);
1210 int nbOfCompo(getNumberOfComponents());
1211 int otherNbTuples(other->getNumberOfTuples());
1212 const double *thisPt(begin()),*otherPt(other->begin());
1213 const int *part1Pt(part1->begin());
1214 double ret=std::numeric_limits<double>::max();
1215 for(int i=0;i<otherNbTuples;i++,part1Pt++,otherPt+=nbOfCompo)
1218 for(int j=0;j<nbOfCompo;j++)
1219 tmp+=(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j])*(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j]);
1221 { ret=tmp; thisTupleId=*part1Pt; otherTupleId=i; }
1227 * This methods returns for each tuple in \a other which tuple in \a this is the closest.
1228 * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
1229 * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
1231 * \return a newly allocated (new object to be dealt by the caller) DataArrayInt having \c other->getNumberOfTuples() tuples and one components.
1232 * \sa DataArrayDouble::minimalDistanceTo
1234 DataArrayInt *DataArrayDouble::findClosestTupleId(const DataArrayDouble *other) const
1237 throw INTERP_KERNEL::Exception("DataArrayDouble::findClosestTupleId : other instance is NULL !");
1238 checkAllocated(); other->checkAllocated();
1239 int nbOfCompo=getNumberOfComponents();
1240 if(nbOfCompo!=other->getNumberOfComponents())
1242 std::ostringstream oss; oss << "DataArrayDouble::findClosestTupleId : number of components in this is " << nbOfCompo;
1243 oss << ", whereas number of components in other is " << other->getNumberOfComponents() << "! Should be equal !";
1244 throw INTERP_KERNEL::Exception(oss.str().c_str());
1246 int nbOfTuples=other->getNumberOfTuples();
1247 int thisNbOfTuples=getNumberOfTuples();
1248 MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuples,1);
1250 getMinMaxPerComponent(bounds);
1255 double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2])),zDelta(fabs(bounds[5]-bounds[4]));
1256 double delta=std::max(xDelta,yDelta); delta=std::max(delta,zDelta);
1257 double characSize=pow((delta*delta*delta)/((double)thisNbOfTuples),1./3.);
1258 BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1259 FindClosestTupleIdAlg<3>(myTree,3.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1264 double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2]));
1265 double delta=std::max(xDelta,yDelta);
1266 double characSize=sqrt(delta/(double)thisNbOfTuples);
1267 BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1268 FindClosestTupleIdAlg<2>(myTree,2.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1273 double characSize=fabs(bounds[1]-bounds[0])/thisNbOfTuples;
1274 BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1275 FindClosestTupleIdAlg<1>(myTree,1.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1279 throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for findClosestTupleId. Must be 1, 2 or 3.");
1285 * This method expects that \a this and \a otherBBoxFrmt arrays are bounding box arrays ( as the output of MEDCouplingPointSet::getBoundingBoxForBBTree method ).
1286 * 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
1287 * how many bounding boxes in \a otherBBoxFrmt.
1288 * So, this method expects that \a this and \a otherBBoxFrmt have the same number of components.
1290 * \param [in] otherBBoxFrmt - It is an array .
1291 * \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.
1292 * \sa MEDCouplingPointSet::getBoundingBoxForBBTree
1293 * \throw If \a this and \a otherBBoxFrmt have not the same number of components.
1294 * \throw If \a this and \a otherBBoxFrmt number of components is not even (BBox format).
1296 DataArrayInt *DataArrayDouble::computeNbOfInteractionsWith(const DataArrayDouble *otherBBoxFrmt, double eps) const
1299 throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : input array is NULL !");
1300 if(!isAllocated() || !otherBBoxFrmt->isAllocated())
1301 throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : this and input array must be allocated !");
1302 int nbOfComp(getNumberOfComponents()),nbOfTuples(getNumberOfTuples());
1303 if(nbOfComp!=otherBBoxFrmt->getNumberOfComponents())
1305 std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : this number of components (" << nbOfComp << ") must be equal to the number of components of input array (" << otherBBoxFrmt->getNumberOfComponents() << ") !";
1306 throw INTERP_KERNEL::Exception(oss.str().c_str());
1310 std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : Number of components (" << nbOfComp << ") is not even ! It should be to be compatible with bbox format !";
1311 throw INTERP_KERNEL::Exception(oss.str().c_str());
1313 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbOfTuples,1);
1314 const double *thisBBPtr(begin());
1315 int *retPtr(ret->getPointer());
1320 BBTree<3,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
1321 for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
1322 *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
1327 BBTree<2,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
1328 for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
1329 *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
1334 BBTree<1,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
1335 for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
1336 *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
1340 throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : space dimension supported are [1,2,3] !");
1347 * Returns a copy of \a this array by excluding coincident tuples. Each tuple is
1348 * considered as coordinates of a point in getNumberOfComponents()-dimensional
1349 * space. The distance between tuples is computed using norm2. If several tuples are
1350 * not far each from other than \a prec, only one of them remains in the result
1351 * array. The order of tuples in the result array is same as in \a this one except
1352 * that coincident tuples are excluded.
1353 * \param [in] prec - minimal absolute distance between two tuples at which they are
1354 * considered not coincident.
1355 * \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
1356 * tuples have id strictly lower than \a limitTupleId then they are not excluded.
1357 * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1358 * is to delete using decrRef() as it is no more needed.
1359 * \throw If \a this is not allocated.
1360 * \throw If the number of components is not in [1,2,3,4].
1362 * \if ENABLE_EXAMPLES
1363 * \ref py_mcdataarraydouble_getdifferentvalues "Here is a Python example".
1366 DataArrayDouble *DataArrayDouble::getDifferentValues(double prec, int limitTupleId) const
1369 DataArrayInt *c0=0,*cI0=0;
1370 findCommonTuples(prec,limitTupleId,c0,cI0);
1371 MCAuto<DataArrayInt> c(c0),cI(cI0);
1372 int newNbOfTuples=-1;
1373 MCAuto<DataArrayInt> o2n=DataArrayInt::ConvertIndexArrayToO2N(getNumberOfTuples(),c0->begin(),cI0->begin(),cI0->end(),newNbOfTuples);
1374 return renumberAndReduce(o2n->getConstPointer(),newNbOfTuples);
1378 * Copy all components in a specified order from another DataArrayDouble.
1379 * Both numerical and textual data is copied. The number of tuples in \a this and
1380 * the other array can be different.
1381 * \param [in] a - the array to copy data from.
1382 * \param [in] compoIds - sequence of zero based indices of components, data of which is
1384 * \throw If \a a is NULL.
1385 * \throw If \a compoIds.size() != \a a->getNumberOfComponents().
1386 * \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
1388 * \if ENABLE_EXAMPLES
1389 * \ref py_mcdataarraydouble_setselectedcomponents "Here is a Python example".
1392 void DataArrayDouble::setSelectedComponents(const DataArrayDouble *a, const std::vector<int>& compoIds)
1395 throw INTERP_KERNEL::Exception("DataArrayDouble::setSelectedComponents : input DataArrayDouble is NULL !");
1397 copyPartOfStringInfoFrom2(compoIds,*a);
1398 std::size_t partOfCompoSz=compoIds.size();
1399 int nbOfCompo=getNumberOfComponents();
1400 int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
1401 const double *ac=a->getConstPointer();
1402 double *nc=getPointer();
1403 for(int i=0;i<nbOfTuples;i++)
1404 for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
1405 nc[nbOfCompo*i+compoIds[j]]=*ac;
1409 * Checks if 0.0 value is present in \a this array. If it is the case, an exception
1411 * \throw If zero is found in \a this array.
1413 void DataArrayDouble::checkNoNullValues() const
1415 const double *tmp=getConstPointer();
1416 std::size_t nbOfElems=getNbOfElems();
1417 const double *where=std::find(tmp,tmp+nbOfElems,0.);
1418 if(where!=tmp+nbOfElems)
1419 throw INTERP_KERNEL::Exception("A value 0.0 have been detected !");
1423 * Computes minimal and maximal value in each component. An output array is filled
1424 * with \c 2 * \a this->getNumberOfComponents() values, so the caller is to allocate
1425 * enough memory before calling this method.
1426 * \param [out] bounds - array of size at least 2 *\a this->getNumberOfComponents().
1427 * It is filled as follows:<br>
1428 * \a bounds[0] = \c min_of_component_0 <br>
1429 * \a bounds[1] = \c max_of_component_0 <br>
1430 * \a bounds[2] = \c min_of_component_1 <br>
1431 * \a bounds[3] = \c max_of_component_1 <br>
1434 void DataArrayDouble::getMinMaxPerComponent(double *bounds) const
1437 int dim=getNumberOfComponents();
1438 for (int idim=0; idim<dim; idim++)
1440 bounds[idim*2]=std::numeric_limits<double>::max();
1441 bounds[idim*2+1]=-std::numeric_limits<double>::max();
1443 const double *ptr=getConstPointer();
1444 int nbOfTuples=getNumberOfTuples();
1445 for(int i=0;i<nbOfTuples;i++)
1447 for(int idim=0;idim<dim;idim++)
1449 if(bounds[idim*2]>ptr[i*dim+idim])
1451 bounds[idim*2]=ptr[i*dim+idim];
1453 if(bounds[idim*2+1]<ptr[i*dim+idim])
1455 bounds[idim*2+1]=ptr[i*dim+idim];
1462 * This method retrieves a newly allocated DataArrayDouble instance having same number of tuples than \a this and twice number of components than \a this
1463 * to store both the min and max per component of each tuples.
1464 * \param [in] epsilon the width of the bbox (identical in each direction) - 0.0 by default
1466 * \return a newly created DataArrayDouble instance having \c this->getNumberOfTuples() tuples and 2 * \c this->getNumberOfComponent() components
1468 * \throw If \a this is not allocated yet.
1470 DataArrayDouble *DataArrayDouble::computeBBoxPerTuple(double epsilon) const
1473 const double *dataPtr=getConstPointer();
1474 int nbOfCompo=getNumberOfComponents();
1475 int nbTuples=getNumberOfTuples();
1476 MCAuto<DataArrayDouble> bbox=DataArrayDouble::New();
1477 bbox->alloc(nbTuples,2*nbOfCompo);
1478 double *bboxPtr=bbox->getPointer();
1479 for(int i=0;i<nbTuples;i++)
1481 for(int j=0;j<nbOfCompo;j++)
1483 bboxPtr[2*nbOfCompo*i+2*j]=dataPtr[nbOfCompo*i+j]-epsilon;
1484 bboxPtr[2*nbOfCompo*i+2*j+1]=dataPtr[nbOfCompo*i+j]+epsilon;
1491 * For each tuples **t** in \a other, this method retrieves tuples in \a this that are equal to **t**.
1492 * Two tuples are considered equal if the euclidian distance between the two tuples is lower than \a eps.
1494 * \param [in] other a DataArrayDouble having same number of components than \a this.
1495 * \param [in] eps absolute precision representing distance (using infinite norm) between 2 tuples behind which 2 tuples are considered equal.
1496 * \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.
1497 * \a cI allows to extract information in \a c.
1498 * \param [out] cI is an indirection array that allows to extract the data contained in \a c.
1500 * \throw In case of:
1501 * - \a this is not allocated
1502 * - \a other is not allocated or null
1503 * - \a this and \a other do not have the same number of components
1504 * - if number of components of \a this is not in [1,2,3]
1506 * \sa MEDCouplingPointSet::getNodeIdsNearPoints, DataArrayDouble::getDifferentValues
1508 void DataArrayDouble::computeTupleIdsNearTuples(const DataArrayDouble *other, double eps, DataArrayInt *& c, DataArrayInt *& cI) const
1511 throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : input pointer other is null !");
1513 other->checkAllocated();
1514 int nbOfCompo=getNumberOfComponents();
1515 int otherNbOfCompo=other->getNumberOfComponents();
1516 if(nbOfCompo!=otherNbOfCompo)
1517 throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : number of components should be equal between this and other !");
1518 int nbOfTuplesOther=other->getNumberOfTuples();
1519 MCAuto<DataArrayInt> cArr(DataArrayInt::New()),cIArr(DataArrayInt::New()); cArr->alloc(0,1); cIArr->pushBackSilent(0);
1524 BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
1525 FindTupleIdsNearTuplesAlg<3>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
1530 BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
1531 FindTupleIdsNearTuplesAlg<2>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
1536 BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
1537 FindTupleIdsNearTuplesAlg<1>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
1541 throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for computeTupleIdsNearTuples. Must be 1, 2 or 3.");
1543 c=cArr.retn(); cI=cIArr.retn();
1547 * 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
1548 * around origin of 'radius' 1.
1550 * \param [in] eps absolute epsilon. under that value of delta between max and min no scale is performed.
1552 void DataArrayDouble::recenterForMaxPrecision(double eps)
1555 int dim=getNumberOfComponents();
1556 std::vector<double> bounds(2*dim);
1557 getMinMaxPerComponent(&bounds[0]);
1558 for(int i=0;i<dim;i++)
1560 double delta=bounds[2*i+1]-bounds[2*i];
1561 double offset=(bounds[2*i]+bounds[2*i+1])/2.;
1563 applyLin(1./delta,-offset/delta,i);
1565 applyLin(1.,-offset,i);
1570 * Returns the maximal value and all its locations within \a this one-dimensional array.
1571 * \param [out] tupleIds - a new instance of DataArrayInt containg indices of
1572 * tuples holding the maximal value. The caller is to delete it using
1573 * decrRef() as it is no more needed.
1574 * \return double - the maximal value among all values of \a this array.
1575 * \throw If \a this->getNumberOfComponents() != 1
1576 * \throw If \a this->getNumberOfTuples() < 1
1578 double DataArrayDouble::getMaxValue2(DataArrayInt*& tupleIds) const
1582 double ret=getMaxValue(tmp);
1583 tupleIds=findIdsInRange(ret,ret);
1588 * Returns the minimal value and all its locations within \a this one-dimensional array.
1589 * \param [out] tupleIds - a new instance of DataArrayInt containg indices of
1590 * tuples holding the minimal value. The caller is to delete it using
1591 * decrRef() as it is no more needed.
1592 * \return double - the minimal value among all values of \a this array.
1593 * \throw If \a this->getNumberOfComponents() != 1
1594 * \throw If \a this->getNumberOfTuples() < 1
1596 double DataArrayDouble::getMinValue2(DataArrayInt*& tupleIds) const
1600 double ret=getMinValue(tmp);
1601 tupleIds=findIdsInRange(ret,ret);
1606 * 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.
1607 * This method only works for single component array.
1609 * \return a value in [ 0, \c this->getNumberOfTuples() )
1611 * \throw If \a this is not allocated
1614 int DataArrayDouble::count(double value, double eps) const
1618 if(getNumberOfComponents()!=1)
1619 throw INTERP_KERNEL::Exception("DataArrayDouble::count : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
1620 const double *vals=begin();
1621 int nbOfTuples=getNumberOfTuples();
1622 for(int i=0;i<nbOfTuples;i++,vals++)
1623 if(fabs(*vals-value)<=eps)
1629 * Returns the average value of \a this one-dimensional array.
1630 * \return double - the average value over all values of \a this array.
1631 * \throw If \a this->getNumberOfComponents() != 1
1632 * \throw If \a this->getNumberOfTuples() < 1
1634 double DataArrayDouble::getAverageValue() const
1636 if(getNumberOfComponents()!=1)
1637 throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
1638 int nbOfTuples=getNumberOfTuples();
1640 throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : array exists but number of tuples must be > 0 !");
1641 const double *vals=getConstPointer();
1642 double ret=std::accumulate(vals,vals+nbOfTuples,0.);
1643 return ret/nbOfTuples;
1647 * Returns the Euclidean norm of the vector defined by \a this array.
1648 * \return double - the value of the Euclidean norm, i.e.
1649 * the square root of the inner product of vector.
1650 * \throw If \a this is not allocated.
1652 double DataArrayDouble::norm2() const
1656 std::size_t nbOfElems=getNbOfElems();
1657 const double *pt=getConstPointer();
1658 for(std::size_t i=0;i<nbOfElems;i++,pt++)
1664 * Returns the maximum norm of the vector defined by \a this array.
1665 * This method works even if the number of components is diferent from one.
1666 * If the number of elements in \a this is 0, -1. is returned.
1667 * \return double - the value of the maximum norm, i.e.
1668 * the maximal absolute value among values of \a this array (whatever its number of components).
1669 * \throw If \a this is not allocated.
1671 double DataArrayDouble::normMax() const
1675 std::size_t nbOfElems(getNbOfElems());
1676 const double *pt(getConstPointer());
1677 for(std::size_t i=0;i<nbOfElems;i++,pt++)
1679 double val(std::abs(*pt));
1687 * Returns the minimum norm (absolute value) of the vector defined by \a this array.
1688 * This method works even if the number of components is diferent from one.
1689 * If the number of elements in \a this is 0, std::numeric_limits<double>::max() is returned.
1690 * \return double - the value of the minimum norm, i.e.
1691 * the minimal absolute value among values of \a this array (whatever its number of components).
1692 * \throw If \a this is not allocated.
1694 double DataArrayDouble::normMin() const
1697 double ret(std::numeric_limits<double>::max());
1698 std::size_t nbOfElems(getNbOfElems());
1699 const double *pt(getConstPointer());
1700 for(std::size_t i=0;i<nbOfElems;i++,pt++)
1702 double val(std::abs(*pt));
1710 * Accumulates values of each component of \a this array.
1711 * \param [out] res - an array of length \a this->getNumberOfComponents(), allocated
1712 * by the caller, that is filled by this method with sum value for each
1714 * \throw If \a this is not allocated.
1716 void DataArrayDouble::accumulate(double *res) const
1719 const double *ptr=getConstPointer();
1720 int nbTuple=getNumberOfTuples();
1721 int nbComps=getNumberOfComponents();
1722 std::fill(res,res+nbComps,0.);
1723 for(int i=0;i<nbTuple;i++)
1724 std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<double>());
1728 * This method returns the min distance from an external tuple defined by [ \a tupleBg , \a tupleEnd ) to \a this and
1729 * the first tuple in \a this that matches the returned distance. If there is no tuples in \a this an exception will be thrown.
1732 * \a this is expected to be allocated and expected to have a number of components equal to the distance from \a tupleBg to
1733 * \a tupleEnd. If not an exception will be thrown.
1735 * \param [in] tupleBg start pointer (included) of input external tuple
1736 * \param [in] tupleEnd end pointer (not included) of input external tuple
1737 * \param [out] tupleId the tuple id in \a this that matches the min of distance between \a this and input external tuple
1738 * \return the min distance.
1739 * \sa MEDCouplingUMesh::distanceToPoint
1741 double DataArrayDouble::distanceToTuple(const double *tupleBg, const double *tupleEnd, int& tupleId) const
1744 int nbTuple=getNumberOfTuples();
1745 int nbComps=getNumberOfComponents();
1746 if(nbComps!=(int)std::distance(tupleBg,tupleEnd))
1747 { 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()); }
1749 throw INTERP_KERNEL::Exception("DataArrayDouble::distanceToTuple : no tuple in this ! No distance to compute !");
1750 double ret0=std::numeric_limits<double>::max();
1752 const double *work=getConstPointer();
1753 for(int i=0;i<nbTuple;i++)
1756 for(int j=0;j<nbComps;j++,work++)
1757 val+=(*work-tupleBg[j])*((*work-tupleBg[j]));
1761 { ret0=val; tupleId=i; }
1767 * Accumulate values of the given component of \a this array.
1768 * \param [in] compId - the index of the component of interest.
1769 * \return double - a sum value of \a compId-th component.
1770 * \throw If \a this is not allocated.
1771 * \throw If \a the condition ( 0 <= \a compId < \a this->getNumberOfComponents() ) is
1774 double DataArrayDouble::accumulate(int compId) const
1777 const double *ptr=getConstPointer();
1778 int nbTuple=getNumberOfTuples();
1779 int nbComps=getNumberOfComponents();
1780 if(compId<0 || compId>=nbComps)
1781 throw INTERP_KERNEL::Exception("DataArrayDouble::accumulate : Invalid compId specified : No such nb of components !");
1783 for(int i=0;i<nbTuple;i++)
1784 ret+=ptr[i*nbComps+compId];
1789 * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
1790 * The returned array will have same number of components than \a this and number of tuples equal to
1791 * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
1793 * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
1794 * 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.
1796 * \param [in] bgOfIndex - begin (included) of the input index array.
1797 * \param [in] endOfIndex - end (excluded) of the input index array.
1798 * \return DataArrayDouble * - the new instance having the same number of components than \a this.
1800 * \throw If bgOfIndex or end is NULL.
1801 * \throw If input index array is not ascendingly sorted.
1802 * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
1803 * \throw If std::distance(bgOfIndex,endOfIndex)==0.
1805 DataArrayDouble *DataArrayDouble::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
1807 if(!bgOfIndex || !endOfIndex)
1808 throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : input pointer NULL !");
1810 int nbCompo=getNumberOfComponents();
1811 int nbOfTuples=getNumberOfTuples();
1812 int sz=(int)std::distance(bgOfIndex,endOfIndex);
1814 throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : invalid size of input index array !");
1816 MCAuto<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(sz,nbCompo);
1817 const int *w=bgOfIndex;
1818 if(*w<0 || *w>=nbOfTuples)
1819 throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
1820 const double *srcPt=begin()+(*w)*nbCompo;
1821 double *tmp=ret->getPointer();
1822 for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
1824 std::fill(tmp,tmp+nbCompo,0.);
1827 for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
1829 if(j>=0 && j<nbOfTuples)
1830 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<double>());
1833 std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
1834 throw INTERP_KERNEL::Exception(oss.str().c_str());
1840 std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
1841 throw INTERP_KERNEL::Exception(oss.str().c_str());
1844 ret->copyStringInfoFrom(*this);
1849 * 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.
1850 * This method expects that \a this as only one component. The returned array will have \a this->getNumberOfTuples()+1 tuple with also one component.
1851 * The ith element of returned array is equal to the sum of elements in \a this with rank strictly lower than i.
1853 * \return DataArrayDouble - A newly built array containing cum sum of \a this.
1855 MCAuto<DataArrayDouble> DataArrayDouble::cumSum() const
1858 checkNbOfComps(1,"DataArrayDouble::cumSum : this is expected to be single component");
1859 int nbOfTuple(getNumberOfTuples());
1860 MCAuto<DataArrayDouble> ret(DataArrayDouble::New()); ret->alloc(nbOfTuple+1,1);
1861 double *ptr(ret->getPointer());
1863 const double *thisPtr(begin());
1864 for(int i=0;i<nbOfTuple;i++)
1865 ptr[i+1]=ptr[i]+thisPtr[i];
1870 * Converts each 2D point defined by the tuple of \a this array from the Polar to the
1871 * Cartesian coordinate system. The two components of the tuple of \a this array are
1872 * considered to contain (1) radius and (2) angle of the point in the Polar CS.
1873 * \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
1874 * contains X and Y coordinates of the point in the Cartesian CS. The caller
1875 * is to delete this array using decrRef() as it is no more needed. The array
1876 * does not contain any textual info on components.
1877 * \throw If \a this->getNumberOfComponents() != 2.
1878 * \sa fromCartToPolar
1880 DataArrayDouble *DataArrayDouble::fromPolarToCart() const
1883 int nbOfComp(getNumberOfComponents());
1885 throw INTERP_KERNEL::Exception("DataArrayDouble::fromPolarToCart : must be an array with exactly 2 components !");
1886 int nbOfTuple(getNumberOfTuples());
1887 DataArrayDouble *ret(DataArrayDouble::New());
1888 ret->alloc(nbOfTuple,2);
1889 double *w(ret->getPointer());
1890 const double *wIn(getConstPointer());
1891 for(int i=0;i<nbOfTuple;i++,w+=2,wIn+=2)
1893 w[0]=wIn[0]*cos(wIn[1]);
1894 w[1]=wIn[0]*sin(wIn[1]);
1900 * Converts each 3D point defined by the tuple of \a this array from the Cylindrical to
1901 * the Cartesian coordinate system. The three components of the tuple of \a this array
1902 * are considered to contain (1) radius, (2) azimuth and (3) altitude of the point in
1903 * the Cylindrical CS.
1904 * \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
1905 * contains X, Y and Z coordinates of the point in the Cartesian CS. The info
1906 * on the third component is copied from \a this array. The caller
1907 * is to delete this array using decrRef() as it is no more needed.
1908 * \throw If \a this->getNumberOfComponents() != 3.
1911 DataArrayDouble *DataArrayDouble::fromCylToCart() const
1914 int nbOfComp(getNumberOfComponents());
1916 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCylToCart : must be an array with exactly 3 components !");
1917 int nbOfTuple(getNumberOfTuples());
1918 DataArrayDouble *ret(DataArrayDouble::New());
1919 ret->alloc(getNumberOfTuples(),3);
1920 double *w(ret->getPointer());
1921 const double *wIn(getConstPointer());
1922 for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
1924 w[0]=wIn[0]*cos(wIn[1]);
1925 w[1]=wIn[0]*sin(wIn[1]);
1928 ret->setInfoOnComponent(2,getInfoOnComponent(2));
1933 * Converts each 3D point defined by the tuple of \a this array from the Spherical to
1934 * the Cartesian coordinate system. The three components of the tuple of \a this array
1935 * are considered to contain (1) radius, (2) polar angle and (3) azimuthal angle of the
1936 * point in the Cylindrical CS.
1937 * \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
1938 * contains X, Y and Z coordinates of the point in the Cartesian CS. The info
1939 * on the third component is copied from \a this array. The caller
1940 * is to delete this array using decrRef() as it is no more needed.
1941 * \throw If \a this->getNumberOfComponents() != 3.
1942 * \sa fromCartToSpher
1944 DataArrayDouble *DataArrayDouble::fromSpherToCart() const
1947 int nbOfComp(getNumberOfComponents());
1949 throw INTERP_KERNEL::Exception("DataArrayDouble::fromSpherToCart : must be an array with exactly 3 components !");
1950 int nbOfTuple(getNumberOfTuples());
1951 DataArrayDouble *ret(DataArrayDouble::New());
1952 ret->alloc(getNumberOfTuples(),3);
1953 double *w(ret->getPointer());
1954 const double *wIn(getConstPointer());
1955 for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
1957 w[0]=wIn[0]*cos(wIn[2])*sin(wIn[1]);
1958 w[1]=wIn[0]*sin(wIn[2])*sin(wIn[1]);
1959 w[2]=wIn[0]*cos(wIn[1]);
1965 * 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.
1966 * 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.
1967 * If \a at equals to AX_CYL the returned array will be the result of operation cylindric to cartesian of \a this...
1969 * \param [in] atOfThis - The axis type of \a this.
1970 * \return DataArrayDouble * - the new instance of DataArrayDouble (that must be dealed by caller) containing the result of the cartesianizification of \a this.
1972 DataArrayDouble *DataArrayDouble::cartesianize(MEDCouplingAxisType atOfThis) const
1975 int nbOfComp(getNumberOfComponents());
1976 MCAuto<DataArrayDouble> ret;
1984 ret=fromCylToCart();
1989 ret=fromPolarToCart();
1993 throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : For AX_CYL, number of components must be in [2,3] !");
1997 ret=fromSpherToCart();
2002 ret=fromPolarToCart();
2006 throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : For AX_CYL, number of components must be in [2,3] !");
2008 throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : not recognized axis type ! Only AX_CART, AX_CYL and AX_SPHER supported !");
2010 ret->copyStringInfoFrom(*this);
2015 * This method returns a newly created array to be deallocated that contains the result of conversion from cartesian to polar.
2016 * This method expects that \a this has exactly 2 components.
2017 * \sa fromPolarToCart
2019 DataArrayDouble *DataArrayDouble::fromCartToPolar() const
2021 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2023 int nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2025 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToPolar : must be an array with exactly 2 components !");
2026 ret->alloc(nbTuples,2);
2027 double *retPtr(ret->getPointer());
2028 const double *ptr(begin());
2029 for(int i=0;i<nbTuples;i++,ptr+=2,retPtr+=2)
2031 retPtr[0]=sqrt(ptr[0]*ptr[0]+ptr[1]*ptr[1]);
2032 retPtr[1]=atan2(ptr[1],ptr[0]);
2038 * This method returns a newly created array to be deallocated that contains the result of conversion from cartesian to cylindrical.
2039 * This method expects that \a this has exactly 3 components.
2042 DataArrayDouble *DataArrayDouble::fromCartToCyl() const
2044 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2046 int nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2048 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCyl : must be an array with exactly 3 components !");
2049 ret->alloc(nbTuples,3);
2050 double *retPtr(ret->getPointer());
2051 const double *ptr(begin());
2052 for(int i=0;i<nbTuples;i++,ptr+=3,retPtr+=3)
2054 retPtr[0]=sqrt(ptr[0]*ptr[0]+ptr[1]*ptr[1]);
2055 retPtr[1]=atan2(ptr[1],ptr[0]);
2062 * This method returns a newly created array to be deallocated that contains the result of conversion from cartesian to spherical coordinates.
2063 * \sa fromSpherToCart
2065 DataArrayDouble *DataArrayDouble::fromCartToSpher() const
2067 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2069 int nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2071 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToSpher : must be an array with exactly 3 components !");
2072 ret->alloc(nbTuples,3);
2073 double *retPtr(ret->getPointer());
2074 const double *ptr(begin());
2075 for(int i=0;i<nbTuples;i++,ptr+=3,retPtr+=3)
2077 retPtr[0]=sqrt(ptr[0]*ptr[0]+ptr[1]*ptr[1]+ptr[2]*ptr[2]);
2078 retPtr[1]=acos(ptr[2]/retPtr[0]);
2079 retPtr[2]=atan2(ptr[1],ptr[0]);
2085 * 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.
2086 * This method expects that \a this has exactly 3 components.
2087 * \sa MEDCouplingFieldDouble::computeVectorFieldCyl
2089 DataArrayDouble *DataArrayDouble::fromCartToCylGiven(const DataArrayDouble *coords, const double center[3], const double vect[3]) const
2092 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : input coords are NULL !");
2093 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2094 checkAllocated(); coords->checkAllocated();
2095 int nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2097 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : must be an array with exactly 3 components !");
2098 if(coords->getNumberOfComponents()!=3)
2099 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : coords array must have exactly 3 components !");
2100 if(coords->getNumberOfTuples()!=nbTuples)
2101 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : coords array must have the same number of tuples !");
2102 ret->alloc(nbTuples,nbOfComp);
2103 double magOfVect(sqrt(vect[0]*vect[0]+vect[1]*vect[1]+vect[2]*vect[2]));
2105 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : magnitude of vect is too low !");
2106 double Ur[3],Uteta[3],Uz[3],*retPtr(ret->getPointer());
2107 const double *coo(coords->begin()),*vectField(begin());
2108 std::transform(vect,vect+3,Uz,std::bind2nd(std::multiplies<double>(),1./magOfVect));
2109 for(int i=0;i<nbTuples;i++,vectField+=3,retPtr+=3,coo+=3)
2111 std::transform(coo,coo+3,center,Ur,std::minus<double>());
2112 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];
2113 double magOfTeta(sqrt(Uteta[0]*Uteta[0]+Uteta[1]*Uteta[1]+Uteta[2]*Uteta[2]));
2114 std::transform(Uteta,Uteta+3,Uteta,std::bind2nd(std::multiplies<double>(),1./magOfTeta));
2115 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];
2116 retPtr[0]=Ur[0]*vectField[0]+Ur[1]*vectField[1]+Ur[2]*vectField[2];
2117 retPtr[1]=Uteta[0]*vectField[0]+Uteta[1]*vectField[1]+Uteta[2]*vectField[2];
2118 retPtr[2]=Uz[0]*vectField[0]+Uz[1]*vectField[1]+Uz[2]*vectField[2];
2120 ret->copyStringInfoFrom(*this);
2125 * Computes the doubly contracted product of every tensor defined by the tuple of \a this
2126 * array contating 6 components.
2127 * \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
2128 * is calculated from the tuple <em>(t)</em> of \a this array as follows:
2129 * \f$ t[0]^2+t[1]^2+t[2]^2+2*t[3]^2+2*t[4]^2+2*t[5]^2\f$.
2130 * The caller is to delete this result array using decrRef() as it is no more needed.
2131 * \throw If \a this->getNumberOfComponents() != 6.
2133 DataArrayDouble *DataArrayDouble::doublyContractedProduct() const
2136 int nbOfComp(getNumberOfComponents());
2138 throw INTERP_KERNEL::Exception("DataArrayDouble::doublyContractedProduct : must be an array with exactly 6 components !");
2139 DataArrayDouble *ret=DataArrayDouble::New();
2140 int nbOfTuple=getNumberOfTuples();
2141 ret->alloc(nbOfTuple,1);
2142 const double *src=getConstPointer();
2143 double *dest=ret->getPointer();
2144 for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
2145 *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];
2150 * Computes the determinant of every square matrix defined by the tuple of \a this
2151 * array, which contains either 4, 6 or 9 components. The case of 6 components
2152 * corresponds to that of the upper triangular matrix.
2153 * \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
2154 * is the determinant of matrix of the corresponding tuple of \a this array.
2155 * The caller is to delete this result array using decrRef() as it is no more
2157 * \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2159 DataArrayDouble *DataArrayDouble::determinant() const
2162 DataArrayDouble *ret=DataArrayDouble::New();
2163 int nbOfTuple=getNumberOfTuples();
2164 ret->alloc(nbOfTuple,1);
2165 const double *src=getConstPointer();
2166 double *dest=ret->getPointer();
2167 switch(getNumberOfComponents())
2170 for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
2171 *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];
2174 for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
2175 *dest=src[0]*src[3]-src[1]*src[2];
2178 for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
2179 *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];
2183 throw INTERP_KERNEL::Exception("DataArrayDouble::determinant : Invalid number of components ! must be in 4,6,9 !");
2188 * Computes 3 eigenvalues of every upper triangular matrix defined by the tuple of
2189 * \a this array, which contains 6 components.
2190 * \return DataArrayDouble * - the new instance of DataArrayDouble containing 3
2191 * components, whose each tuple contains the eigenvalues of the matrix of
2192 * corresponding tuple of \a this array.
2193 * The caller is to delete this result array using decrRef() as it is no more
2195 * \throw If \a this->getNumberOfComponents() != 6.
2197 DataArrayDouble *DataArrayDouble::eigenValues() const
2200 int nbOfComp=getNumberOfComponents();
2202 throw INTERP_KERNEL::Exception("DataArrayDouble::eigenValues : must be an array with exactly 6 components !");
2203 DataArrayDouble *ret=DataArrayDouble::New();
2204 int nbOfTuple=getNumberOfTuples();
2205 ret->alloc(nbOfTuple,3);
2206 const double *src=getConstPointer();
2207 double *dest=ret->getPointer();
2208 for(int i=0;i<nbOfTuple;i++,dest+=3,src+=6)
2209 INTERP_KERNEL::computeEigenValues6(src,dest);
2214 * Computes 3 eigenvectors of every upper triangular matrix defined by the tuple of
2215 * \a this array, which contains 6 components.
2216 * \return DataArrayDouble * - the new instance of DataArrayDouble containing 9
2217 * components, whose each tuple contains 3 eigenvectors of the matrix of
2218 * corresponding tuple of \a this array.
2219 * The caller is to delete this result array using decrRef() as it is no more
2221 * \throw If \a this->getNumberOfComponents() != 6.
2223 DataArrayDouble *DataArrayDouble::eigenVectors() const
2226 int nbOfComp=getNumberOfComponents();
2228 throw INTERP_KERNEL::Exception("DataArrayDouble::eigenVectors : must be an array with exactly 6 components !");
2229 DataArrayDouble *ret=DataArrayDouble::New();
2230 int nbOfTuple=getNumberOfTuples();
2231 ret->alloc(nbOfTuple,9);
2232 const double *src=getConstPointer();
2233 double *dest=ret->getPointer();
2234 for(int i=0;i<nbOfTuple;i++,src+=6)
2237 INTERP_KERNEL::computeEigenValues6(src,tmp);
2238 for(int j=0;j<3;j++,dest+=3)
2239 INTERP_KERNEL::computeEigenVectorForEigenValue6(src,tmp[j],1e-12,dest);
2245 * Computes the inverse matrix of every matrix defined by the tuple of \a this
2246 * array, which contains either 4, 6 or 9 components. The case of 6 components
2247 * corresponds to that of the upper triangular matrix.
2248 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2249 * same number of components as \a this one, whose each tuple is the inverse
2250 * matrix of the matrix of corresponding tuple of \a this array.
2251 * The caller is to delete this result array using decrRef() as it is no more
2253 * \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2255 DataArrayDouble *DataArrayDouble::inverse() const
2258 int nbOfComp=getNumberOfComponents();
2259 if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
2260 throw INTERP_KERNEL::Exception("DataArrayDouble::inversion : must be an array with 4,6 or 9 components !");
2261 DataArrayDouble *ret=DataArrayDouble::New();
2262 int nbOfTuple=getNumberOfTuples();
2263 ret->alloc(nbOfTuple,nbOfComp);
2264 const double *src=getConstPointer();
2265 double *dest=ret->getPointer();
2267 for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
2269 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];
2270 dest[0]=(src[1]*src[2]-src[4]*src[4])/det;
2271 dest[1]=(src[0]*src[2]-src[5]*src[5])/det;
2272 dest[2]=(src[0]*src[1]-src[3]*src[3])/det;
2273 dest[3]=(src[5]*src[4]-src[3]*src[2])/det;
2274 dest[4]=(src[5]*src[3]-src[0]*src[4])/det;
2275 dest[5]=(src[3]*src[4]-src[1]*src[5])/det;
2277 else if(nbOfComp==4)
2278 for(int i=0;i<nbOfTuple;i++,dest+=4,src+=4)
2280 double det=src[0]*src[3]-src[1]*src[2];
2282 dest[1]=-src[1]/det;
2283 dest[2]=-src[2]/det;
2287 for(int i=0;i<nbOfTuple;i++,dest+=9,src+=9)
2289 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];
2290 dest[0]=(src[4]*src[8]-src[7]*src[5])/det;
2291 dest[1]=(src[7]*src[2]-src[1]*src[8])/det;
2292 dest[2]=(src[1]*src[5]-src[4]*src[2])/det;
2293 dest[3]=(src[6]*src[5]-src[3]*src[8])/det;
2294 dest[4]=(src[0]*src[8]-src[6]*src[2])/det;
2295 dest[5]=(src[2]*src[3]-src[0]*src[5])/det;
2296 dest[6]=(src[3]*src[7]-src[6]*src[4])/det;
2297 dest[7]=(src[6]*src[1]-src[0]*src[7])/det;
2298 dest[8]=(src[0]*src[4]-src[1]*src[3])/det;
2304 * Computes the trace of every matrix defined by the tuple of \a this
2305 * array, which contains either 4, 6 or 9 components. The case of 6 components
2306 * corresponds to that of the upper triangular matrix.
2307 * \return DataArrayDouble * - the new instance of DataArrayDouble containing
2308 * 1 component, whose each tuple is the trace of
2309 * the matrix of corresponding tuple of \a this array.
2310 * The caller is to delete this result array using decrRef() as it is no more
2312 * \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2314 DataArrayDouble *DataArrayDouble::trace() const
2317 int nbOfComp=getNumberOfComponents();
2318 if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
2319 throw INTERP_KERNEL::Exception("DataArrayDouble::trace : must be an array with 4,6 or 9 components !");
2320 DataArrayDouble *ret=DataArrayDouble::New();
2321 int nbOfTuple=getNumberOfTuples();
2322 ret->alloc(nbOfTuple,1);
2323 const double *src=getConstPointer();
2324 double *dest=ret->getPointer();
2326 for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
2327 *dest=src[0]+src[1]+src[2];
2328 else if(nbOfComp==4)
2329 for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
2330 *dest=src[0]+src[3];
2332 for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
2333 *dest=src[0]+src[4]+src[8];
2338 * Computes the stress deviator tensor of every stress tensor defined by the tuple of
2339 * \a this array, which contains 6 components.
2340 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2341 * same number of components and tuples as \a this array.
2342 * The caller is to delete this result array using decrRef() as it is no more
2344 * \throw If \a this->getNumberOfComponents() != 6.
2346 DataArrayDouble *DataArrayDouble::deviator() const
2349 int nbOfComp=getNumberOfComponents();
2351 throw INTERP_KERNEL::Exception("DataArrayDouble::deviator : must be an array with exactly 6 components !");
2352 DataArrayDouble *ret=DataArrayDouble::New();
2353 int nbOfTuple=getNumberOfTuples();
2354 ret->alloc(nbOfTuple,6);
2355 const double *src=getConstPointer();
2356 double *dest=ret->getPointer();
2357 for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
2359 double tr=(src[0]+src[1]+src[2])/3.;
2371 * Computes the magnitude of every vector defined by the tuple of
2373 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2374 * same number of tuples as \a this array and one component.
2375 * The caller is to delete this result array using decrRef() as it is no more
2377 * \throw If \a this is not allocated.
2379 DataArrayDouble *DataArrayDouble::magnitude() const
2382 int nbOfComp=getNumberOfComponents();
2383 DataArrayDouble *ret=DataArrayDouble::New();
2384 int nbOfTuple=getNumberOfTuples();
2385 ret->alloc(nbOfTuple,1);
2386 const double *src=getConstPointer();
2387 double *dest=ret->getPointer();
2388 for(int i=0;i<nbOfTuple;i++,dest++)
2391 for(int j=0;j<nbOfComp;j++,src++)
2399 * Computes the maximal value within every tuple of \a this array.
2400 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2401 * same number of tuples as \a this array and one component.
2402 * The caller is to delete this result array using decrRef() as it is no more
2404 * \throw If \a this is not allocated.
2405 * \sa DataArrayDouble::maxPerTupleWithCompoId
2407 DataArrayDouble *DataArrayDouble::maxPerTuple() const
2410 int nbOfComp=getNumberOfComponents();
2411 MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
2412 int nbOfTuple=getNumberOfTuples();
2413 ret->alloc(nbOfTuple,1);
2414 const double *src=getConstPointer();
2415 double *dest=ret->getPointer();
2416 for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
2417 *dest=*std::max_element(src,src+nbOfComp);
2422 * Computes the maximal value within every tuple of \a this array and it returns the first component
2423 * id for each tuple that corresponds to the maximal value within the tuple.
2425 * \param [out] compoIdOfMaxPerTuple - the new new instance of DataArrayInt containing the
2426 * same number of tuples and only one component.
2427 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2428 * same number of tuples as \a this array and one component.
2429 * The caller is to delete this result array using decrRef() as it is no more
2431 * \throw If \a this is not allocated.
2432 * \sa DataArrayDouble::maxPerTuple
2434 DataArrayDouble *DataArrayDouble::maxPerTupleWithCompoId(DataArrayInt* &compoIdOfMaxPerTuple) const
2437 int nbOfComp=getNumberOfComponents();
2438 MCAuto<DataArrayDouble> ret0=DataArrayDouble::New();
2439 MCAuto<DataArrayInt> ret1=DataArrayInt::New();
2440 int nbOfTuple=getNumberOfTuples();
2441 ret0->alloc(nbOfTuple,1); ret1->alloc(nbOfTuple,1);
2442 const double *src=getConstPointer();
2443 double *dest=ret0->getPointer(); int *dest1=ret1->getPointer();
2444 for(int i=0;i<nbOfTuple;i++,dest++,dest1++,src+=nbOfComp)
2446 const double *loc=std::max_element(src,src+nbOfComp);
2448 *dest1=(int)std::distance(src,loc);
2450 compoIdOfMaxPerTuple=ret1.retn();
2455 * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c this->getNumberOfTuples() tuples.
2456 * \n This returned array contains the euclidian distance for each tuple in \a this.
2457 * \n So the returned array can be seen as a dense symmetrical matrix whose diagonal elements are equal to 0.
2458 * \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)
2460 * \warning use this method with care because it can leads to big amount of consumed memory !
2462 * \return A newly allocated (huge) MEDCoupling::DataArrayDouble instance that the caller should deal with.
2464 * \throw If \a this is not allocated.
2466 * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrixWith
2468 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrix() const
2471 int nbOfComp=getNumberOfComponents();
2472 int nbOfTuples=getNumberOfTuples();
2473 const double *inData=getConstPointer();
2474 MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
2475 ret->alloc(nbOfTuples*nbOfTuples,1);
2476 double *outData=ret->getPointer();
2477 for(int i=0;i<nbOfTuples;i++)
2479 outData[i*nbOfTuples+i]=0.;
2480 for(int j=i+1;j<nbOfTuples;j++)
2483 for(int k=0;k<nbOfComp;k++)
2484 { double delta=inData[i*nbOfComp+k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
2486 outData[i*nbOfTuples+j]=dist;
2487 outData[j*nbOfTuples+i]=dist;
2494 * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c other->getNumberOfTuples() tuples.
2495 * \n This returned array contains the euclidian distance for each tuple in \a other with each tuple in \a this.
2496 * \n So the returned array can be seen as a dense rectangular matrix with \c other->getNumberOfTuples() rows and \c this->getNumberOfTuples() columns.
2497 * \n Output rectangular matrix is sorted along rows.
2498 * \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)
2500 * \warning use this method with care because it can leads to big amount of consumed memory !
2502 * \param [in] other DataArrayDouble instance having same number of components than \a this.
2503 * \return A newly allocated (huge) MEDCoupling::DataArrayDouble instance that the caller should deal with.
2505 * \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.
2507 * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrix
2509 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrixWith(const DataArrayDouble *other) const
2512 throw INTERP_KERNEL::Exception("DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : input parameter is null !");
2514 other->checkAllocated();
2515 int nbOfComp=getNumberOfComponents();
2516 int otherNbOfComp=other->getNumberOfComponents();
2517 if(nbOfComp!=otherNbOfComp)
2519 std::ostringstream oss; oss << "DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : this nb of compo=" << nbOfComp << " and other nb of compo=" << otherNbOfComp << ". It should match !";
2520 throw INTERP_KERNEL::Exception(oss.str().c_str());
2522 int nbOfTuples=getNumberOfTuples();
2523 int otherNbOfTuples=other->getNumberOfTuples();
2524 const double *inData=getConstPointer();
2525 const double *inDataOther=other->getConstPointer();
2526 MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
2527 ret->alloc(otherNbOfTuples*nbOfTuples,1);
2528 double *outData=ret->getPointer();
2529 for(int i=0;i<otherNbOfTuples;i++,inDataOther+=nbOfComp)
2531 for(int j=0;j<nbOfTuples;j++)
2534 for(int k=0;k<nbOfComp;k++)
2535 { double delta=inDataOther[k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
2537 outData[i*nbOfTuples+j]=dist;
2544 * Sorts value within every tuple of \a this array.
2545 * \param [in] asc - if \a true, the values are sorted in ascending order, else,
2546 * in descending order.
2547 * \throw If \a this is not allocated.
2549 void DataArrayDouble::sortPerTuple(bool asc)
2552 double *pt=getPointer();
2553 int nbOfTuple=getNumberOfTuples();
2554 int nbOfComp=getNumberOfComponents();
2556 for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
2557 std::sort(pt,pt+nbOfComp);
2559 for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
2560 std::sort(pt,pt+nbOfComp,std::greater<double>());
2565 * Modify all elements of \a this array, so that
2566 * an element _x_ becomes \f$ numerator / x \f$.
2567 * \warning If an exception is thrown because of presence of 0.0 element in \a this
2568 * array, all elements processed before detection of the zero element remain
2570 * \param [in] numerator - the numerator used to modify array elements.
2571 * \throw If \a this is not allocated.
2572 * \throw If there is an element equal to 0.0 in \a this array.
2574 void DataArrayDouble::applyInv(double numerator)
2577 double *ptr=getPointer();
2578 std::size_t nbOfElems=getNbOfElems();
2579 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2581 if(std::abs(*ptr)>std::numeric_limits<double>::min())
2583 *ptr=numerator/(*ptr);
2587 std::ostringstream oss; oss << "DataArrayDouble::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
2589 throw INTERP_KERNEL::Exception(oss.str().c_str());
2596 * Modify all elements of \a this array, so that
2597 * an element _x_ becomes <em> val ^ x </em>. Contrary to DataArrayInt::applyPow
2598 * all values in \a this have to be >= 0 if val is \b not integer.
2599 * \param [in] val - the value used to apply pow on all array elements.
2600 * \throw If \a this is not allocated.
2601 * \warning If an exception is thrown because of presence of 0 element in \a this
2602 * array and \a val is \b not integer, all elements processed before detection of the zero element remain
2605 void DataArrayDouble::applyPow(double val)
2608 double *ptr=getPointer();
2609 std::size_t nbOfElems=getNbOfElems();
2611 bool isInt=((double)val2)==val;
2614 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2620 std::ostringstream oss; oss << "DataArrayDouble::applyPow (double) : At elem # " << i << " value is " << *ptr << " ! must be >=0. !";
2621 throw INTERP_KERNEL::Exception(oss.str().c_str());
2627 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2628 *ptr=pow(*ptr,val2);
2634 * Modify all elements of \a this array, so that
2635 * an element _x_ becomes \f$ val ^ x \f$.
2636 * \param [in] val - the value used to apply pow on all array elements.
2637 * \throw If \a this is not allocated.
2638 * \throw If \a val < 0.
2639 * \warning If an exception is thrown because of presence of 0 element in \a this
2640 * array, all elements processed before detection of the zero element remain
2643 void DataArrayDouble::applyRPow(double val)
2647 throw INTERP_KERNEL::Exception("DataArrayDouble::applyRPow : the input value has to be >= 0 !");
2648 double *ptr=getPointer();
2649 std::size_t nbOfElems=getNbOfElems();
2650 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2656 * Returns a new DataArrayDouble created from \a this one by applying \a
2657 * FunctionToEvaluate to every tuple of \a this array. Textual data is not copied.
2658 * For more info see \ref MEDCouplingArrayApplyFunc
2659 * \param [in] nbOfComp - number of components in the result array.
2660 * \param [in] func - the \a FunctionToEvaluate declared as
2661 * \c bool (*\a func)(\c const \c double *\a pos, \c double *\a res),
2662 * where \a pos points to the first component of a tuple of \a this array
2663 * and \a res points to the first component of a tuple of the result array.
2664 * Note that length (number of components) of \a pos can differ from
2666 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2667 * same number of tuples as \a this array.
2668 * The caller is to delete this result array using decrRef() as it is no more
2670 * \throw If \a this is not allocated.
2671 * \throw If \a func returns \a false.
2673 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, FunctionToEvaluate func) const
2676 DataArrayDouble *newArr=DataArrayDouble::New();
2677 int nbOfTuples=getNumberOfTuples();
2678 int oldNbOfComp=getNumberOfComponents();
2679 newArr->alloc(nbOfTuples,nbOfComp);
2680 const double *ptr=getConstPointer();
2681 double *ptrToFill=newArr->getPointer();
2682 for(int i=0;i<nbOfTuples;i++)
2684 if(!func(ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp))
2686 std::ostringstream oss; oss << "For tuple # " << i << " with value (";
2687 std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
2688 oss << ") : Evaluation of function failed !";
2690 throw INTERP_KERNEL::Exception(oss.str().c_str());
2697 * Returns a new DataArrayDouble created from \a this one by applying a function to every
2698 * tuple of \a this array. Textual data is not copied.
2699 * For more info see \ref MEDCouplingArrayApplyFunc1.
2700 * \param [in] nbOfComp - number of components in the result array.
2701 * \param [in] func - the expression defining how to transform a tuple of \a this array.
2702 * Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
2703 * \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
2704 * If false the computation is carried on without any notification. When false the evaluation is a little faster.
2705 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2706 * same number of tuples as \a this array and \a nbOfComp components.
2707 * The caller is to delete this result array using decrRef() as it is no more
2709 * \throw If \a this is not allocated.
2710 * \throw If computing \a func fails.
2712 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, const std::string& func, bool isSafe) const
2714 INTERP_KERNEL::ExprParser expr(func);
2716 std::set<std::string> vars;
2717 expr.getTrueSetOfVars(vars);
2718 std::vector<std::string> varsV(vars.begin(),vars.end());
2719 return applyFuncNamedCompo(nbOfComp,varsV,func,isSafe);
2723 * Returns a new DataArrayDouble created from \a this one by applying a function to every
2724 * tuple of \a this array. Textual data is not copied. This method works by tuples (whatever its size).
2725 * If \a this is a one component array, call applyFuncOnThis instead that performs the same work faster.
2727 * For more info see \ref MEDCouplingArrayApplyFunc0.
2728 * \param [in] func - the expression defining how to transform a tuple of \a this array.
2729 * Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
2730 * \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
2731 * If false the computation is carried on without any notification. When false the evaluation is a little faster.
2732 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2733 * same number of tuples and components as \a this array.
2734 * The caller is to delete this result array using decrRef() as it is no more
2736 * \sa applyFuncOnThis
2737 * \throw If \a this is not allocated.
2738 * \throw If computing \a func fails.
2740 DataArrayDouble *DataArrayDouble::applyFunc(const std::string& func, bool isSafe) const
2742 int nbOfComp(getNumberOfComponents());
2744 throw INTERP_KERNEL::Exception("DataArrayDouble::applyFunc : output number of component must be > 0 !");
2746 int nbOfTuples(getNumberOfTuples());
2747 MCAuto<DataArrayDouble> newArr(DataArrayDouble::New());
2748 newArr->alloc(nbOfTuples,nbOfComp);
2749 INTERP_KERNEL::ExprParser expr(func);
2751 std::set<std::string> vars;
2752 expr.getTrueSetOfVars(vars);
2753 if((int)vars.size()>1)
2755 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 : ";
2756 std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
2757 throw INTERP_KERNEL::Exception(oss.str().c_str());
2761 expr.prepareFastEvaluator();
2762 newArr->rearrange(1);
2763 newArr->fillWithValue(expr.evaluateDouble());
2764 newArr->rearrange(nbOfComp);
2765 return newArr.retn();
2767 std::vector<std::string> vars2(vars.begin(),vars.end());
2768 double buff,*ptrToFill(newArr->getPointer());
2769 const double *ptr(begin());
2770 std::vector<double> stck;
2771 expr.prepareExprEvaluationDouble(vars2,1,1,0,&buff,&buff+1);
2772 expr.prepareFastEvaluator();
2775 for(int i=0;i<nbOfTuples;i++)
2777 for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
2780 expr.evaluateDoubleInternal(stck);
2781 *ptrToFill=stck.back();
2788 for(int i=0;i<nbOfTuples;i++)
2790 for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
2795 expr.evaluateDoubleInternalSafe(stck);
2797 catch(INTERP_KERNEL::Exception& e)
2799 std::ostringstream oss; oss << "For tuple # " << i << " component # " << iComp << " with value (";
2801 oss << ") : Evaluation of function failed !" << e.what();
2802 throw INTERP_KERNEL::Exception(oss.str().c_str());
2804 *ptrToFill=stck.back();
2809 return newArr.retn();
2813 * This method is a non const method that modify the array in \a this.
2814 * This method only works on one component array. It means that function \a func must
2815 * contain at most one variable.
2816 * This method is a specialization of applyFunc method with one parameter on one component array.
2818 * \param [in] func - the expression defining how to transform a tuple of \a this array.
2819 * Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
2820 * \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
2821 * If false the computation is carried on without any notification. When false the evaluation is a little faster.
2825 void DataArrayDouble::applyFuncOnThis(const std::string& func, bool isSafe)
2827 int nbOfComp(getNumberOfComponents());
2829 throw INTERP_KERNEL::Exception("DataArrayDouble::applyFuncOnThis : output number of component must be > 0 !");
2831 int nbOfTuples(getNumberOfTuples());
2832 INTERP_KERNEL::ExprParser expr(func);
2834 std::set<std::string> vars;
2835 expr.getTrueSetOfVars(vars);
2836 if((int)vars.size()>1)
2838 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 : ";
2839 std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
2840 throw INTERP_KERNEL::Exception(oss.str().c_str());
2844 expr.prepareFastEvaluator();
2845 std::vector<std::string> compInfo(getInfoOnComponents());
2847 fillWithValue(expr.evaluateDouble());
2848 rearrange(nbOfComp);
2849 setInfoOnComponents(compInfo);
2852 std::vector<std::string> vars2(vars.begin(),vars.end());
2853 double buff,*ptrToFill(getPointer());
2854 const double *ptr(begin());
2855 std::vector<double> stck;
2856 expr.prepareExprEvaluationDouble(vars2,1,1,0,&buff,&buff+1);
2857 expr.prepareFastEvaluator();
2860 for(int i=0;i<nbOfTuples;i++)
2862 for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
2865 expr.evaluateDoubleInternal(stck);
2866 *ptrToFill=stck.back();
2873 for(int i=0;i<nbOfTuples;i++)
2875 for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
2880 expr.evaluateDoubleInternalSafe(stck);
2882 catch(INTERP_KERNEL::Exception& e)
2884 std::ostringstream oss; oss << "For tuple # " << i << " component # " << iComp << " with value (";
2886 oss << ") : Evaluation of function failed !" << e.what();
2887 throw INTERP_KERNEL::Exception(oss.str().c_str());
2889 *ptrToFill=stck.back();
2897 * Returns a new DataArrayDouble created from \a this one by applying a function to every
2898 * tuple of \a this array. Textual data is not copied.
2899 * For more info see \ref MEDCouplingArrayApplyFunc2.
2900 * \param [in] nbOfComp - number of components in the result array.
2901 * \param [in] func - the expression defining how to transform a tuple of \a this array.
2902 * Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
2903 * \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
2904 * If false the computation is carried on without any notification. When false the evaluation is a little faster.
2905 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2906 * same number of tuples as \a this array.
2907 * The caller is to delete this result array using decrRef() as it is no more
2909 * \throw If \a this is not allocated.
2910 * \throw If \a func contains vars that are not in \a this->getInfoOnComponent().
2911 * \throw If computing \a func fails.
2913 DataArrayDouble *DataArrayDouble::applyFuncCompo(int nbOfComp, const std::string& func, bool isSafe) const
2915 return applyFuncNamedCompo(nbOfComp,getVarsOnComponent(),func,isSafe);
2919 * Returns a new DataArrayDouble created from \a this one by applying a function to every
2920 * tuple of \a this array. Textual data is not copied.
2921 * For more info see \ref MEDCouplingArrayApplyFunc3.
2922 * \param [in] nbOfComp - number of components in the result array.
2923 * \param [in] varsOrder - sequence of vars defining their order.
2924 * \param [in] func - the expression defining how to transform a tuple of \a this array.
2925 * Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
2926 * \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
2927 * If false the computation is carried on without any notification. When false the evaluation is a little faster.
2928 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2929 * same number of tuples as \a this array.
2930 * The caller is to delete this result array using decrRef() as it is no more
2932 * \throw If \a this is not allocated.
2933 * \throw If \a func contains vars not in \a varsOrder.
2934 * \throw If computing \a func fails.
2936 DataArrayDouble *DataArrayDouble::applyFuncNamedCompo(int nbOfComp, const std::vector<std::string>& varsOrder, const std::string& func, bool isSafe) const
2939 throw INTERP_KERNEL::Exception("DataArrayDouble::applyFuncNamedCompo : output number of component must be > 0 !");
2940 std::vector<std::string> varsOrder2(varsOrder);
2941 int oldNbOfComp(getNumberOfComponents());
2942 for(int i=(int)varsOrder.size();i<oldNbOfComp;i++)
2943 varsOrder2.push_back(std::string());
2945 int nbOfTuples(getNumberOfTuples());
2946 INTERP_KERNEL::ExprParser expr(func);
2948 std::set<std::string> vars;
2949 expr.getTrueSetOfVars(vars);
2950 if((int)vars.size()>oldNbOfComp)
2952 std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
2953 oss << vars.size() << " variables : ";
2954 std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
2955 throw INTERP_KERNEL::Exception(oss.str().c_str());
2957 MCAuto<DataArrayDouble> newArr(DataArrayDouble::New());
2958 newArr->alloc(nbOfTuples,nbOfComp);
2959 INTERP_KERNEL::AutoPtr<double> buff(new double[oldNbOfComp]);
2960 double *buffPtr(buff),*ptrToFill;
2961 std::vector<double> stck;
2962 for(int iComp=0;iComp<nbOfComp;iComp++)
2964 expr.prepareExprEvaluationDouble(varsOrder2,oldNbOfComp,nbOfComp,iComp,buffPtr,buffPtr+oldNbOfComp);
2965 expr.prepareFastEvaluator();
2966 const double *ptr(getConstPointer());
2967 ptrToFill=newArr->getPointer()+iComp;
2970 for(int i=0;i<nbOfTuples;i++,ptrToFill+=nbOfComp,ptr+=oldNbOfComp)
2972 std::copy(ptr,ptr+oldNbOfComp,buffPtr);
2973 expr.evaluateDoubleInternal(stck);
2974 *ptrToFill=stck.back();
2980 for(int i=0;i<nbOfTuples;i++,ptrToFill+=nbOfComp,ptr+=oldNbOfComp)
2982 std::copy(ptr,ptr+oldNbOfComp,buffPtr);
2985 expr.evaluateDoubleInternalSafe(stck);
2986 *ptrToFill=stck.back();
2989 catch(INTERP_KERNEL::Exception& e)
2991 std::ostringstream oss; oss << "For tuple # " << i << " with value (";
2992 std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
2993 oss << ") : Evaluation of function failed !" << e.what();
2994 throw INTERP_KERNEL::Exception(oss.str().c_str());
2999 return newArr.retn();
3002 void DataArrayDouble::applyFuncFast32(const std::string& func)
3005 INTERP_KERNEL::ExprParser expr(func);
3007 char *funcStr=expr.compileX86();
3009 *((void **)&funcPtr)=funcStr;//he he...
3011 double *ptr=getPointer();
3012 int nbOfComp=getNumberOfComponents();
3013 int nbOfTuples=getNumberOfTuples();
3014 int nbOfElems=nbOfTuples*nbOfComp;
3015 for(int i=0;i<nbOfElems;i++,ptr++)
3020 void DataArrayDouble::applyFuncFast64(const std::string& func)
3023 INTERP_KERNEL::ExprParser expr(func);
3025 char *funcStr=expr.compileX86_64();
3027 *((void **)&funcPtr)=funcStr;//he he...
3029 double *ptr=getPointer();
3030 int nbOfComp=getNumberOfComponents();
3031 int nbOfTuples=getNumberOfTuples();
3032 int nbOfElems=nbOfTuples*nbOfComp;
3033 for(int i=0;i<nbOfElems;i++,ptr++)
3039 * \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.
3041 MCAuto<DataArrayDouble> DataArrayDouble::symmetry3DPlane(const double point[3], const double normalVector[3]) const
3044 if(getNumberOfComponents()!=3)
3045 throw INTERP_KERNEL::Exception("DataArrayDouble::symmetry3DPlane : this is excepted to have 3 components !");
3046 int nbTuples(getNumberOfTuples());
3047 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
3048 ret->alloc(nbTuples,3);
3049 Symmetry3DPlane(point,normalVector,nbTuples,begin(),ret->getPointer());
3053 DataArrayDoubleIterator *DataArrayDouble::iterator()
3055 return new DataArrayDoubleIterator(this);
3059 * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional
3060 * array whose values are within a given range. Textual data is not copied.
3061 * \param [in] vmin - a lowest acceptable value (included).
3062 * \param [in] vmax - a greatest acceptable value (included).
3063 * \return DataArrayInt * - the new instance of DataArrayInt.
3064 * The caller is to delete this result array using decrRef() as it is no more
3066 * \throw If \a this->getNumberOfComponents() != 1.
3068 * \sa DataArrayDouble::findIdsNotInRange
3070 * \if ENABLE_EXAMPLES
3071 * \ref cpp_mcdataarraydouble_getidsinrange "Here is a C++ example".<br>
3072 * \ref py_mcdataarraydouble_getidsinrange "Here is a Python example".
3075 DataArrayInt *DataArrayDouble::findIdsInRange(double vmin, double vmax) const
3078 if(getNumberOfComponents()!=1)
3079 throw INTERP_KERNEL::Exception("DataArrayDouble::findIdsInRange : this must have exactly one component !");
3080 const double *cptr(begin());
3081 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
3082 int nbOfTuples(getNumberOfTuples());
3083 for(int i=0;i<nbOfTuples;i++,cptr++)
3084 if(*cptr>=vmin && *cptr<=vmax)
3085 ret->pushBackSilent(i);
3090 * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional
3091 * array whose values are not within a given range. Textual data is not copied.
3092 * \param [in] vmin - a lowest not acceptable value (excluded).
3093 * \param [in] vmax - a greatest not acceptable value (excluded).
3094 * \return DataArrayInt * - the new instance of DataArrayInt.
3095 * The caller is to delete this result array using decrRef() as it is no more
3097 * \throw If \a this->getNumberOfComponents() != 1.
3099 * \sa DataArrayDouble::findIdsInRange
3101 DataArrayInt *DataArrayDouble::findIdsNotInRange(double vmin, double vmax) const
3104 if(getNumberOfComponents()!=1)
3105 throw INTERP_KERNEL::Exception("DataArrayDouble::findIdsNotInRange : this must have exactly one component !");
3106 const double *cptr(begin());
3107 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
3108 int nbOfTuples(getNumberOfTuples());
3109 for(int i=0;i<nbOfTuples;i++,cptr++)
3110 if(*cptr<vmin || *cptr>vmax)
3111 ret->pushBackSilent(i);
3116 * Returns a new DataArrayDouble by concatenating two given arrays, so that (1) the number
3117 * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
3118 * the number of component in the result array is same as that of each of given arrays.
3119 * Info on components is copied from the first of the given arrays. Number of components
3120 * in the given arrays must be the same.
3121 * \param [in] a1 - an array to include in the result array.
3122 * \param [in] a2 - another array to include in the result array.
3123 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3124 * The caller is to delete this result array using decrRef() as it is no more
3126 * \throw If both \a a1 and \a a2 are NULL.
3127 * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
3129 DataArrayDouble *DataArrayDouble::Aggregate(const DataArrayDouble *a1, const DataArrayDouble *a2)
3131 std::vector<const DataArrayDouble *> tmp(2);
3132 tmp[0]=a1; tmp[1]=a2;
3133 return Aggregate(tmp);
3137 * Returns a new DataArrayDouble by concatenating all given arrays, so that (1) the number
3138 * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
3139 * the number of component in the result array is same as that of each of given arrays.
3140 * Info on components is copied from the first of the given arrays. Number of components
3141 * in the given arrays must be the same.
3142 * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it
3143 * not the object itself.
3144 * \param [in] arr - a sequence of arrays to include in the result array.
3145 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3146 * The caller is to delete this result array using decrRef() as it is no more
3148 * \throw If all arrays within \a arr are NULL.
3149 * \throw If getNumberOfComponents() of arrays within \a arr.
3151 DataArrayDouble *DataArrayDouble::Aggregate(const std::vector<const DataArrayDouble *>& arr)
3153 std::vector<const DataArrayDouble *> a;
3154 for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
3158 throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : input list must contain at least one NON EMPTY DataArrayDouble !");
3159 std::vector<const DataArrayDouble *>::const_iterator it=a.begin();
3160 int nbOfComp=(*it)->getNumberOfComponents();
3161 int nbt=(*it++)->getNumberOfTuples();
3162 for(int i=1;it!=a.end();it++,i++)
3164 if((*it)->getNumberOfComponents()!=nbOfComp)
3165 throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : Nb of components mismatch for array aggregation !");
3166 nbt+=(*it)->getNumberOfTuples();
3168 MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
3169 ret->alloc(nbt,nbOfComp);
3170 double *pt=ret->getPointer();
3171 for(it=a.begin();it!=a.end();it++)
3172 pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
3173 ret->copyStringInfoFrom(*(a[0]));
3178 * Returns a new DataArrayDouble containing a dot product of two given arrays, so that
3179 * the i-th tuple of the result array is a sum of products of j-th components of i-th
3180 * tuples of given arrays (\f$ a_i = \sum_{j=1}^n a1_j * a2_j \f$).
3181 * Info on components and name is copied from the first of the given arrays.
3182 * Number of tuples and components in the given arrays must be the same.
3183 * \param [in] a1 - a given array.
3184 * \param [in] a2 - another given array.
3185 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3186 * The caller is to delete this result array using decrRef() as it is no more
3188 * \throw If either \a a1 or \a a2 is NULL.
3189 * \throw If any given array is not allocated.
3190 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3191 * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
3193 DataArrayDouble *DataArrayDouble::Dot(const DataArrayDouble *a1, const DataArrayDouble *a2)
3196 throw INTERP_KERNEL::Exception("DataArrayDouble::Dot : input DataArrayDouble instance is NULL !");
3197 a1->checkAllocated();
3198 a2->checkAllocated();
3199 int nbOfComp=a1->getNumberOfComponents();
3200 if(nbOfComp!=a2->getNumberOfComponents())
3201 throw INTERP_KERNEL::Exception("Nb of components mismatch for array Dot !");
3202 int nbOfTuple=a1->getNumberOfTuples();
3203 if(nbOfTuple!=a2->getNumberOfTuples())
3204 throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Dot !");
3205 DataArrayDouble *ret=DataArrayDouble::New();
3206 ret->alloc(nbOfTuple,1);
3207 double *retPtr=ret->getPointer();
3208 const double *a1Ptr=a1->getConstPointer();
3209 const double *a2Ptr=a2->getConstPointer();
3210 for(int i=0;i<nbOfTuple;i++)
3213 for(int j=0;j<nbOfComp;j++)
3214 sum+=a1Ptr[i*nbOfComp+j]*a2Ptr[i*nbOfComp+j];
3217 ret->setInfoOnComponent(0,a1->getInfoOnComponent(0));
3218 ret->setName(a1->getName());
3223 * Returns a new DataArrayDouble containing a cross product of two given arrays, so that
3224 * the i-th tuple of the result array contains 3 components of a vector which is a cross
3225 * product of two vectors defined by the i-th tuples of given arrays.
3226 * Info on components is copied from the first of the given arrays.
3227 * Number of tuples in the given arrays must be the same.
3228 * Number of components in the given arrays must be 3.
3229 * \param [in] a1 - a given array.
3230 * \param [in] a2 - another given array.
3231 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3232 * The caller is to delete this result array using decrRef() as it is no more
3234 * \throw If either \a a1 or \a a2 is NULL.
3235 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3236 * \throw If \a a1->getNumberOfComponents() != 3
3237 * \throw If \a a2->getNumberOfComponents() != 3
3239 DataArrayDouble *DataArrayDouble::CrossProduct(const DataArrayDouble *a1, const DataArrayDouble *a2)
3242 throw INTERP_KERNEL::Exception("DataArrayDouble::CrossProduct : input DataArrayDouble instance is NULL !");
3243 int nbOfComp=a1->getNumberOfComponents();
3244 if(nbOfComp!=a2->getNumberOfComponents())
3245 throw INTERP_KERNEL::Exception("Nb of components mismatch for array crossProduct !");
3247 throw INTERP_KERNEL::Exception("Nb of components must be equal to 3 for array crossProduct !");
3248 int nbOfTuple=a1->getNumberOfTuples();
3249 if(nbOfTuple!=a2->getNumberOfTuples())
3250 throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array crossProduct !");
3251 DataArrayDouble *ret=DataArrayDouble::New();
3252 ret->alloc(nbOfTuple,3);
3253 double *retPtr=ret->getPointer();
3254 const double *a1Ptr=a1->getConstPointer();
3255 const double *a2Ptr=a2->getConstPointer();
3256 for(int i=0;i<nbOfTuple;i++)
3258 retPtr[3*i]=a1Ptr[3*i+1]*a2Ptr[3*i+2]-a1Ptr[3*i+2]*a2Ptr[3*i+1];
3259 retPtr[3*i+1]=a1Ptr[3*i+2]*a2Ptr[3*i]-a1Ptr[3*i]*a2Ptr[3*i+2];
3260 retPtr[3*i+2]=a1Ptr[3*i]*a2Ptr[3*i+1]-a1Ptr[3*i+1]*a2Ptr[3*i];
3262 ret->copyStringInfoFrom(*a1);
3267 * Returns a new DataArrayDouble containing maximal values of two given arrays.
3268 * Info on components is copied from the first of the given arrays.
3269 * Number of tuples and components in the given arrays must be the same.
3270 * \param [in] a1 - an array to compare values with another one.
3271 * \param [in] a2 - another array to compare values with the first one.
3272 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3273 * The caller is to delete this result array using decrRef() as it is no more
3275 * \throw If either \a a1 or \a a2 is NULL.
3276 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3277 * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
3279 DataArrayDouble *DataArrayDouble::Max(const DataArrayDouble *a1, const DataArrayDouble *a2)
3282 throw INTERP_KERNEL::Exception("DataArrayDouble::Max : input DataArrayDouble instance is NULL !");
3283 int nbOfComp=a1->getNumberOfComponents();
3284 if(nbOfComp!=a2->getNumberOfComponents())
3285 throw INTERP_KERNEL::Exception("Nb of components mismatch for array Max !");
3286 int nbOfTuple=a1->getNumberOfTuples();
3287 if(nbOfTuple!=a2->getNumberOfTuples())
3288 throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Max !");
3289 DataArrayDouble *ret=DataArrayDouble::New();
3290 ret->alloc(nbOfTuple,nbOfComp);
3291 double *retPtr=ret->getPointer();
3292 const double *a1Ptr=a1->getConstPointer();
3293 const double *a2Ptr=a2->getConstPointer();
3294 int nbElem=nbOfTuple*nbOfComp;
3295 for(int i=0;i<nbElem;i++)
3296 retPtr[i]=std::max(a1Ptr[i],a2Ptr[i]);
3297 ret->copyStringInfoFrom(*a1);
3302 * Returns a new DataArrayDouble containing minimal values of two given arrays.
3303 * Info on components is copied from the first of the given arrays.
3304 * Number of tuples and components in the given arrays must be the same.
3305 * \param [in] a1 - an array to compare values with another one.
3306 * \param [in] a2 - another array to compare values with the first one.
3307 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3308 * The caller is to delete this result array using decrRef() as it is no more
3310 * \throw If either \a a1 or \a a2 is NULL.
3311 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3312 * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
3314 DataArrayDouble *DataArrayDouble::Min(const DataArrayDouble *a1, const DataArrayDouble *a2)
3317 throw INTERP_KERNEL::Exception("DataArrayDouble::Min : input DataArrayDouble instance is NULL !");
3318 int nbOfComp=a1->getNumberOfComponents();
3319 if(nbOfComp!=a2->getNumberOfComponents())
3320 throw INTERP_KERNEL::Exception("Nb of components mismatch for array min !");
3321 int nbOfTuple=a1->getNumberOfTuples();
3322 if(nbOfTuple!=a2->getNumberOfTuples())
3323 throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array min !");
3324 DataArrayDouble *ret=DataArrayDouble::New();
3325 ret->alloc(nbOfTuple,nbOfComp);
3326 double *retPtr=ret->getPointer();
3327 const double *a1Ptr=a1->getConstPointer();
3328 const double *a2Ptr=a2->getConstPointer();
3329 int nbElem=nbOfTuple*nbOfComp;
3330 for(int i=0;i<nbElem;i++)
3331 retPtr[i]=std::min(a1Ptr[i],a2Ptr[i]);
3332 ret->copyStringInfoFrom(*a1);
3337 * Returns a new DataArrayDouble that is the result of pow of two given arrays. There are 3
3340 * \param [in] a1 - an array to pow up.
3341 * \param [in] a2 - another array to sum up.
3342 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3343 * The caller is to delete this result array using decrRef() as it is no more
3345 * \throw If either \a a1 or \a a2 is NULL.
3346 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3347 * \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
3348 * \throw If there is a negative value in \a a1.
3350 DataArrayDouble *DataArrayDouble::Pow(const DataArrayDouble *a1, const DataArrayDouble *a2)
3353 throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : at least one of input instances is null !");
3354 int nbOfTuple=a1->getNumberOfTuples();
3355 int nbOfTuple2=a2->getNumberOfTuples();
3356 int nbOfComp=a1->getNumberOfComponents();
3357 int nbOfComp2=a2->getNumberOfComponents();
3358 if(nbOfTuple!=nbOfTuple2)
3359 throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of tuples mismatches !");
3360 if(nbOfComp!=1 || nbOfComp2!=1)
3361 throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of components of both arrays must be equal to 1 !");
3362 MCAuto<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbOfTuple,1);
3363 const double *ptr1(a1->begin()),*ptr2(a2->begin());
3364 double *ptr=ret->getPointer();
3365 for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
3369 *ptr=pow(*ptr1,*ptr2);
3373 std::ostringstream oss; oss << "DataArrayDouble::Pow : on tuple #" << i << " of a1 value is < 0 (" << *ptr1 << ") !";
3374 throw INTERP_KERNEL::Exception(oss.str().c_str());
3381 * Apply pow on values of another DataArrayDouble to values of \a this one.
3383 * \param [in] other - an array to pow to \a this one.
3384 * \throw If \a other is NULL.
3385 * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
3386 * \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
3387 * \throw If there is a negative value in \a this.
3389 void DataArrayDouble::powEqual(const DataArrayDouble *other)
3392 throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : input instance is null !");
3393 int nbOfTuple=getNumberOfTuples();
3394 int nbOfTuple2=other->getNumberOfTuples();
3395 int nbOfComp=getNumberOfComponents();
3396 int nbOfComp2=other->getNumberOfComponents();
3397 if(nbOfTuple!=nbOfTuple2)
3398 throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of tuples mismatches !");
3399 if(nbOfComp!=1 || nbOfComp2!=1)
3400 throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of components of both arrays must be equal to 1 !");
3401 double *ptr=getPointer();
3402 const double *ptrc=other->begin();
3403 for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
3406 *ptr=pow(*ptr,*ptrc);
3409 std::ostringstream oss; oss << "DataArrayDouble::powEqual : on tuple #" << i << " of this value is < 0 (" << *ptr << ") !";
3410 throw INTERP_KERNEL::Exception(oss.str().c_str());
3417 * This method is \b NOT wrapped into python because it can be useful only for performance reasons in C++ context.
3418 * All values in \a this must be 0. or 1. within eps error. 0 means false, 1 means true.
3419 * If an another value than 0 or 1 appear (within eps precision) an INTERP_KERNEL::Exception will be thrown.
3421 * \throw if \a this is not allocated.
3422 * \throw if \a this has not exactly one component.
3424 std::vector<bool> DataArrayDouble::toVectorOfBool(double eps) const
3427 if(getNumberOfComponents()!=1)
3428 throw INTERP_KERNEL::Exception("DataArrayDouble::toVectorOfBool : must be applied on single component array !");
3429 int nbt(getNumberOfTuples());
3430 std::vector<bool> ret(nbt);
3431 const double *pt(begin());
3432 for(int i=0;i<nbt;i++)
3436 else if(fabs(pt[i]-1.)<eps)
3440 std::ostringstream oss; oss << "DataArrayDouble::toVectorOfBool : the tuple #" << i << " has value " << pt[i] << " is invalid ! must be 0. or 1. !";
3441 throw INTERP_KERNEL::Exception(oss.str().c_str());
3448 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
3451 void DataArrayDouble::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
3456 tinyInfo[0]=getNumberOfTuples();
3457 tinyInfo[1]=getNumberOfComponents();
3467 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
3470 void DataArrayDouble::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
3474 int nbOfCompo=getNumberOfComponents();
3475 tinyInfo.resize(nbOfCompo+1);
3476 tinyInfo[0]=getName();
3477 for(int i=0;i<nbOfCompo;i++)
3478 tinyInfo[i+1]=getInfoOnComponent(i);
3483 tinyInfo[0]=getName();
3488 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
3489 * This method returns if a feeding is needed.
3491 bool DataArrayDouble::resizeForUnserialization(const std::vector<int>& tinyInfoI)
3493 int nbOfTuple=tinyInfoI[0];
3494 int nbOfComp=tinyInfoI[1];
3495 if(nbOfTuple!=-1 || nbOfComp!=-1)
3497 alloc(nbOfTuple,nbOfComp);
3504 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
3506 void DataArrayDouble::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
3508 setName(tinyInfoS[0]);
3511 int nbOfCompo=getNumberOfComponents();
3512 for(int i=0;i<nbOfCompo;i++)
3513 setInfoOnComponent(i,tinyInfoS[i+1]);
3518 * Low static method that operates 3D rotation of 'nbNodes' 3D nodes whose coordinates are arranged in \a coordsIn
3519 * around an axe ( \a center, \a vect) and with angle \a angle.
3521 void DataArrayDouble::Rotate3DAlg(const double *center, const double *vect, double angle, int nbNodes, const double *coordsIn, double *coordsOut)
3523 if(!center || !vect)
3524 throw INTERP_KERNEL::Exception("DataArrayDouble::Rotate3DAlg : null vector in input !");
3525 double sina(sin(angle));
3526 double cosa(cos(angle));
3527 double vectorNorm[3];
3529 double matrixTmp[9];
3530 double norm(sqrt(vect[0]*vect[0]+vect[1]*vect[1]+vect[2]*vect[2]));
3531 if(norm<std::numeric_limits<double>::min())
3532 throw INTERP_KERNEL::Exception("DataArrayDouble::Rotate3DAlg : magnitude of input vector is too close of 0. !");
3533 std::transform(vect,vect+3,vectorNorm,std::bind2nd(std::multiplies<double>(),1/norm));
3534 //rotation matrix computation
3535 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;
3536 matrixTmp[0]=vectorNorm[0]*vectorNorm[0]; matrixTmp[1]=vectorNorm[0]*vectorNorm[1]; matrixTmp[2]=vectorNorm[0]*vectorNorm[2];
3537 matrixTmp[3]=vectorNorm[1]*vectorNorm[0]; matrixTmp[4]=vectorNorm[1]*vectorNorm[1]; matrixTmp[5]=vectorNorm[1]*vectorNorm[2];
3538 matrixTmp[6]=vectorNorm[2]*vectorNorm[0]; matrixTmp[7]=vectorNorm[2]*vectorNorm[1]; matrixTmp[8]=vectorNorm[2]*vectorNorm[2];
3539 std::transform(matrixTmp,matrixTmp+9,matrixTmp,std::bind2nd(std::multiplies<double>(),1-cosa));
3540 std::transform(matrix,matrix+9,matrixTmp,matrix,std::plus<double>());
3541 matrixTmp[0]=0.; matrixTmp[1]=-vectorNorm[2]; matrixTmp[2]=vectorNorm[1];
3542 matrixTmp[3]=vectorNorm[2]; matrixTmp[4]=0.; matrixTmp[5]=-vectorNorm[0];
3543 matrixTmp[6]=-vectorNorm[1]; matrixTmp[7]=vectorNorm[0]; matrixTmp[8]=0.;
3544 std::transform(matrixTmp,matrixTmp+9,matrixTmp,std::bind2nd(std::multiplies<double>(),sina));
3545 std::transform(matrix,matrix+9,matrixTmp,matrix,std::plus<double>());
3546 //rotation matrix computed.
3548 for(int i=0; i<nbNodes; i++)
3550 std::transform(coordsIn+i*3,coordsIn+(i+1)*3,center,tmp,std::minus<double>());
3551 coordsOut[i*3]=matrix[0]*tmp[0]+matrix[1]*tmp[1]+matrix[2]*tmp[2]+center[0];
3552 coordsOut[i*3+1]=matrix[3]*tmp[0]+matrix[4]*tmp[1]+matrix[5]*tmp[2]+center[1];
3553 coordsOut[i*3+2]=matrix[6]*tmp[0]+matrix[7]*tmp[1]+matrix[8]*tmp[2]+center[2];
3557 void DataArrayDouble::Symmetry3DPlane(const double point[3], const double normalVector[3], int nbNodes, const double *coordsIn, double *coordsOut)
3559 double matrix[9],matrix2[9],matrix3[9];
3560 double vect[3],crossVect[3];
3561 INTERP_KERNEL::orthogonalVect3(normalVector,vect);
3562 crossVect[0]=normalVector[1]*vect[2]-normalVector[2]*vect[1];
3563 crossVect[1]=normalVector[2]*vect[0]-normalVector[0]*vect[2];
3564 crossVect[2]=normalVector[0]*vect[1]-normalVector[1]*vect[0];
3565 double nv(INTERP_KERNEL::norm<3>(vect)),ni(INTERP_KERNEL::norm<3>(normalVector)),nc(INTERP_KERNEL::norm<3>(crossVect));
3566 matrix[0]=vect[0]/nv; matrix[1]=crossVect[0]/nc; matrix[2]=-normalVector[0]/ni;
3567 matrix[3]=vect[1]/nv; matrix[4]=crossVect[1]/nc; matrix[5]=-normalVector[1]/ni;
3568 matrix[6]=vect[2]/nv; matrix[7]=crossVect[2]/nc; matrix[8]=-normalVector[2]/ni;
3569 matrix2[0]=vect[0]/nv; matrix2[1]=vect[1]/nv; matrix2[2]=vect[2]/nv;
3570 matrix2[3]=crossVect[0]/nc; matrix2[4]=crossVect[1]/nc; matrix2[5]=crossVect[2]/nc;
3571 matrix2[6]=normalVector[0]/ni; matrix2[7]=normalVector[1]/ni; matrix2[8]=normalVector[2]/ni;
3572 for(int i=0;i<3;i++)
3573 for(int j=0;j<3;j++)
3576 for(int k=0;k<3;k++)
3577 val+=matrix[3*i+k]*matrix2[3*k+j];
3580 //rotation matrix computed.
3582 for(int i=0; i<nbNodes; i++)
3584 std::transform(coordsIn+i*3,coordsIn+(i+1)*3,point,tmp,std::minus<double>());
3585 coordsOut[i*3]=matrix3[0]*tmp[0]+matrix3[1]*tmp[1]+matrix3[2]*tmp[2]+point[0];
3586 coordsOut[i*3+1]=matrix3[3]*tmp[0]+matrix3[4]*tmp[1]+matrix3[5]*tmp[2]+point[1];
3587 coordsOut[i*3+2]=matrix3[6]*tmp[0]+matrix3[7]*tmp[1]+matrix3[8]*tmp[2]+point[2];
3591 void DataArrayDouble::GiveBaseForPlane(const double normalVector[3], double baseOfPlane[9])
3593 double vect[3],crossVect[3];
3594 INTERP_KERNEL::orthogonalVect3(normalVector,vect);
3595 crossVect[0]=normalVector[1]*vect[2]-normalVector[2]*vect[1];
3596 crossVect[1]=normalVector[2]*vect[0]-normalVector[0]*vect[2];
3597 crossVect[2]=normalVector[0]*vect[1]-normalVector[1]*vect[0];
3598 double nv(INTERP_KERNEL::norm<3>(vect)),ni(INTERP_KERNEL::norm<3>(normalVector)),nc(INTERP_KERNEL::norm<3>(crossVect));
3599 baseOfPlane[0]=vect[0]/nv; baseOfPlane[1]=vect[1]/nv; baseOfPlane[2]=vect[2]/nv;
3600 baseOfPlane[3]=crossVect[0]/nc; baseOfPlane[4]=crossVect[1]/nc; baseOfPlane[5]=crossVect[2]/nc;
3601 baseOfPlane[6]=normalVector[0]/ni; baseOfPlane[7]=normalVector[1]/ni; baseOfPlane[8]=normalVector[2]/ni;
3605 * Low static method that operates 3D rotation of \a nbNodes 3D nodes whose coordinates are arranged in \a coords
3606 * around the center point \a center and with angle \a angle.
3608 void DataArrayDouble::Rotate2DAlg(const double *center, double angle, int nbNodes, const double *coordsIn, double *coordsOut)
3610 double cosa=cos(angle);
3611 double sina=sin(angle);
3613 matrix[0]=cosa; matrix[1]=-sina; matrix[2]=sina; matrix[3]=cosa;
3615 for(int i=0; i<nbNodes; i++)
3617 std::transform(coordsIn+i*2,coordsIn+(i+1)*2,center,tmp,std::minus<double>());
3618 coordsOut[i*2]=matrix[0]*tmp[0]+matrix[1]*tmp[1]+center[0];
3619 coordsOut[i*2+1]=matrix[2]*tmp[0]+matrix[3]*tmp[1]+center[1];
3623 DataArrayDoubleIterator::DataArrayDoubleIterator(DataArrayDouble *da):DataArrayIterator<double>(da)
3627 DataArrayDoubleTuple::DataArrayDoubleTuple(double *pt, int nbOfComp):DataArrayTuple<double>(pt,nbOfComp)
3632 std::string DataArrayDoubleTuple::repr() const
3634 std::ostringstream oss; oss.precision(17); oss << "(";
3635 for(int i=0;i<_nb_of_compo-1;i++)
3636 oss << _pt[i] << ", ";
3637 oss << _pt[_nb_of_compo-1] << ")";
3641 double DataArrayDoubleTuple::doubleValue() const
3643 return this->zeValue();
3647 * This method returns a newly allocated instance the caller should dealed with by a MEDCoupling::DataArrayDouble::decrRef.
3648 * This method performs \b no copy of data. The content is only referenced using MEDCoupling::DataArrayDouble::useArray with ownership set to \b false.
3649 * 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
3650 * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
3652 DataArrayDouble *DataArrayDoubleTuple::buildDADouble(int nbOfTuples, int nbOfCompo) const
3654 return this->buildDA(nbOfTuples,nbOfCompo);
3658 * Returns a new instance of DataArrayInt. The caller is to delete this array
3659 * using decrRef() as it is no more needed.
3661 DataArrayInt *DataArrayInt::New()
3663 return new DataArrayInt;
3667 * Returns the only one value in \a this, if and only if number of elements
3668 * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
3669 * \return double - the sole value stored in \a this array.
3670 * \throw If at least one of conditions stated above is not fulfilled.
3672 int DataArrayInt::intValue() const
3676 if(getNbOfElems()==1)
3678 return *getConstPointer();
3681 throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is allocated but number of elements is not equal to 1 !");
3684 throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is not allocated !");
3688 * Returns an integer value characterizing \a this array, which is useful for a quick
3689 * comparison of many instances of DataArrayInt.
3690 * \return int - the hash value.
3691 * \throw If \a this is not allocated.
3693 int DataArrayInt::getHashCode() const
3696 std::size_t nbOfElems=getNbOfElems();
3697 int ret=nbOfElems*65536;
3702 const int *pt=begin();
3703 for(std::size_t i=0;i<nbOfElems;i+=delta)
3704 ret0+=pt[i] & 0x1FFF;
3709 * Returns a full copy of \a this. For more info on copying data arrays see
3710 * \ref MEDCouplingArrayBasicsCopyDeep.
3711 * \return DataArrayInt * - a new instance of DataArrayInt.
3713 DataArrayInt32 *DataArrayInt32::deepCopy() const
3715 return new DataArrayInt32(*this);
3719 * Returns a textual and human readable representation of \a this instance of
3720 * DataArrayInt. This text is shown when a DataArrayInt is printed in Python.
3721 * \return std::string - text describing \a this DataArrayInt.
3723 * \sa reprNotTooLong, reprZip
3725 std::string DataArrayInt::repr() const
3727 std::ostringstream ret;
3732 std::string DataArrayInt::reprZip() const
3734 std::ostringstream ret;
3740 * This method is close to repr method except that when \a this has more than 1000 tuples, all tuples are not
3741 * printed out to avoid to consume too much space in interpretor.
3744 std::string DataArrayInt::reprNotTooLong() const
3746 std::ostringstream ret;
3747 reprNotTooLongStream(ret);
3751 void DataArrayInt::writeVTK(std::ostream& ofs, int indent, const std::string& type, const std::string& nameInFile, DataArrayByte *byteArr) const
3753 static const char SPACE[4]={' ',' ',' ',' '};
3755 std::string idt(indent,' ');
3756 ofs << idt << "<DataArray type=\"" << type << "\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
3759 ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
3760 if(std::string(type)=="Int32")
3762 const char *data(reinterpret_cast<const char *>(begin()));
3763 std::size_t sz(getNbOfElems()*sizeof(int));
3764 byteArr->insertAtTheEnd(data,data+sz);
3765 byteArr->insertAtTheEnd(SPACE,SPACE+4);
3767 else if(std::string(type)=="Int8")
3769 INTERP_KERNEL::AutoPtr<char> tmp(new char[getNbOfElems()]);
3770 std::copy(begin(),end(),(char *)tmp);
3771 byteArr->insertAtTheEnd((char *)tmp,(char *)tmp+getNbOfElems());
3772 byteArr->insertAtTheEnd(SPACE,SPACE+4);
3774 else if(std::string(type)=="UInt8")
3776 INTERP_KERNEL::AutoPtr<unsigned char> tmp(new unsigned char[getNbOfElems()]);
3777 std::copy(begin(),end(),(unsigned char *)tmp);
3778 byteArr->insertAtTheEnd((unsigned char *)tmp,(unsigned char *)tmp+getNbOfElems());
3779 byteArr->insertAtTheEnd(SPACE,SPACE+4);
3782 throw INTERP_KERNEL::Exception("DataArrayInt::writeVTK : Only Int32, Int8 and UInt8 supported !");
3786 ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
3787 std::copy(begin(),end(),std::ostream_iterator<int>(ofs," "));
3789 ofs << std::endl << idt << "</DataArray>\n";
3792 void DataArrayInt::reprStream(std::ostream& stream) const
3794 stream << "Name of int array : \"" << _name << "\"\n";
3795 reprWithoutNameStream(stream);
3798 void DataArrayInt::reprZipStream(std::ostream& stream) const
3800 stream << "Name of int array : \"" << _name << "\"\n";
3801 reprZipWithoutNameStream(stream);
3804 void DataArrayInt::reprNotTooLongStream(std::ostream& stream) const
3806 stream << "Name of int array : \"" << _name << "\"\n";
3807 reprNotTooLongWithoutNameStream(stream);
3810 void DataArrayInt::reprWithoutNameStream(std::ostream& stream) const
3812 DataArray::reprWithoutNameStream(stream);
3813 _mem.repr(getNumberOfComponents(),stream);
3816 void DataArrayInt::reprZipWithoutNameStream(std::ostream& stream) const
3818 DataArray::reprWithoutNameStream(stream);
3819 _mem.reprZip(getNumberOfComponents(),stream);
3822 void DataArrayInt::reprNotTooLongWithoutNameStream(std::ostream& stream) const
3824 DataArray::reprWithoutNameStream(stream);
3825 stream.precision(17);
3826 _mem.reprNotTooLong(getNumberOfComponents(),stream);
3829 void DataArrayInt::reprCppStream(const std::string& varName, std::ostream& stream) const
3831 int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
3832 const int *data=getConstPointer();
3833 stream << "DataArrayInt *" << varName << "=DataArrayInt::New();" << std::endl;
3834 if(nbTuples*nbComp>=1)
3836 stream << "const int " << varName << "Data[" << nbTuples*nbComp << "]={";
3837 std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<int>(stream,","));
3838 stream << data[nbTuples*nbComp-1] << "};" << std::endl;
3839 stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
3842 stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
3843 stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
3847 * Method that gives a quick overvien of \a this for python.
3849 void DataArrayInt::reprQuickOverview(std::ostream& stream) const
3851 static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
3852 stream << "DataArrayInt C++ instance at " << this << ". ";
3855 int nbOfCompo=(int)_info_on_compo.size();
3858 int nbOfTuples=getNumberOfTuples();
3859 stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
3860 reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
3863 stream << "Number of components : 0.";
3866 stream << "*** No data allocated ****";
3869 void DataArrayInt::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
3871 const int *data=begin();
3872 int nbOfTuples=getNumberOfTuples();
3873 int nbOfCompo=(int)_info_on_compo.size();
3874 std::ostringstream oss2; oss2 << "[";
3875 std::string oss2Str(oss2.str());
3876 bool isFinished=true;
3877 for(int i=0;i<nbOfTuples && isFinished;i++)
3882 for(int j=0;j<nbOfCompo;j++,data++)
3885 if(j!=nbOfCompo-1) oss2 << ", ";
3891 if(i!=nbOfTuples-1) oss2 << ", ";
3892 std::string oss3Str(oss2.str());
3893 if(oss3Str.length()<maxNbOfByteInRepr)
3905 * Computes distribution of values of \a this one-dimensional array between given value
3906 * ranges (casts). This method is typically useful for entity number spliting by types,
3908 * \warning The values contained in \a arrBg should be sorted ascendently. No
3909 * check of this is be done. If not, the result is not warranted.
3910 * \param [in] arrBg - the array of ascending values defining the value ranges. The i-th
3911 * value of \a arrBg (\a arrBg[ i ]) gives the lowest value of the i-th range,
3912 * and the greatest value of the i-th range equals to \a arrBg[ i+1 ] - 1. \a
3913 * arrBg containing \a n values defines \a n-1 ranges. The last value of \a arrBg
3914 * should be more than every value in \a this array.
3915 * \param [in] arrEnd - specifies the end of the array \a arrBg, so that
3916 * the last value of \a arrBg is \a arrEnd[ -1 ].
3917 * \param [out] castArr - a new instance of DataArrayInt, of same size as \a this array
3918 * (same number of tuples and components), the caller is to delete
3919 * using decrRef() as it is no more needed.
3920 * This array contains indices of ranges for every value of \a this array. I.e.
3921 * the i-th value of \a castArr gives the index of range the i-th value of \a this
3922 * belongs to. Or, in other words, this parameter contains for each tuple in \a
3923 * this in which cast it holds.
3924 * \param [out] rankInsideCast - a new instance of DataArrayInt, of same size as \a this
3925 * array, the caller is to delete using decrRef() as it is no more needed.
3926 * This array contains ranks of values of \a this array within ranges
3927 * they belongs to. I.e. the i-th value of \a rankInsideCast gives the rank of
3928 * the i-th value of \a this array within the \a castArr[ i ]-th range, to which
3929 * the i-th value of \a this belongs to. Or, in other words, this param contains
3930 * for each tuple its rank inside its cast. The rank is computed as difference
3931 * between the value and the lowest value of range.
3932 * \param [out] castsPresent - a new instance of DataArrayInt, containing indices of
3933 * ranges (casts) to which at least one value of \a this array belongs.
3934 * Or, in other words, this param contains the casts that \a this contains.
3935 * The caller is to delete this array using decrRef() as it is no more needed.
3937 * \b Example: If \a this contains [6,5,0,3,2,7,8,1,4] and \a arrBg contains [0,4,9] then
3938 * the output of this method will be :
3939 * - \a castArr : [1,1,0,0,0,1,1,0,1]
3940 * - \a rankInsideCast: [2,1,0,3,2,3,4,1,0]
3941 * - \a castsPresent : [0,1]
3943 * I.e. values of \a this array belong to 2 ranges: #0 and #1. Value 6 belongs to the
3944 * range #1 and its rank within this range is 2; etc.
3946 * \throw If \a this->getNumberOfComponents() != 1.
3947 * \throw If \a arrEnd - arrBg < 2.
3948 * \throw If any value of \a this is not less than \a arrEnd[-1].
3950 void DataArrayInt::splitByValueRange(const int *arrBg, const int *arrEnd,
3951 DataArrayInt *& castArr, DataArrayInt *& rankInsideCast, DataArrayInt *& castsPresent) const
3954 if(getNumberOfComponents()!=1)
3955 throw INTERP_KERNEL::Exception("Call splitByValueRange method on DataArrayInt with only one component, you can call 'rearrange' method before !");
3956 int nbOfTuples=getNumberOfTuples();
3957 std::size_t nbOfCast=std::distance(arrBg,arrEnd);
3959 throw INTERP_KERNEL::Exception("DataArrayInt::splitByValueRange : The input array giving the cast range values should be of size >=2 !");
3961 const int *work=getConstPointer();
3962 typedef std::reverse_iterator<const int *> rintstart;
3963 rintstart bg(arrEnd);//OK no problem because size of 'arr' is greater or equal 2
3964 rintstart end2(arrBg);
3965 MCAuto<DataArrayInt> ret1=DataArrayInt::New();
3966 MCAuto<DataArrayInt> ret2=DataArrayInt::New();
3967 MCAuto<DataArrayInt> ret3=DataArrayInt::New();
3968 ret1->alloc(nbOfTuples,1);
3969 ret2->alloc(nbOfTuples,1);
3970 int *ret1Ptr=ret1->getPointer();
3971 int *ret2Ptr=ret2->getPointer();
3972 std::set<std::size_t> castsDetected;
3973 for(int i=0;i<nbOfTuples;i++)
3975 rintstart res=std::find_if(bg,end2,std::bind2nd(std::less_equal<int>(), work[i]));
3976 std::size_t pos=std::distance(bg,res);
3977 std::size_t pos2=nbOfCast-pos;
3980 ret1Ptr[i]=(int)pos2;
3981 ret2Ptr[i]=work[i]-arrBg[pos2];
3982 castsDetected.insert(pos2);
3986 std::ostringstream oss; oss << "DataArrayInt::splitByValueRange : At rank #" << i << " the value is " << work[i] << " should be in [0," << *bg << ") !";
3987 throw INTERP_KERNEL::Exception(oss.str().c_str());
3990 ret3->alloc((int)castsDetected.size(),1);
3991 std::copy(castsDetected.begin(),castsDetected.end(),ret3->getPointer());
3992 castArr=ret1.retn();
3993 rankInsideCast=ret2.retn();
3994 castsPresent=ret3.retn();
3998 * 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 ).
3999 * 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 ).
4000 * This method works only if \a this is allocated and single component. If not an exception will be thrown.
4002 * \param [out] strt - the start of the range (included) if true is returned.
4003 * \param [out] sttoopp - the end of the range (not included) if true is returned.
4004 * \param [out] stteepp - the step of the range if true is returned.
4005 * \return the verdict of the check.
4007 * \sa DataArray::GetNumberOfItemGivenBES
4009 bool DataArrayInt::isRange(int& strt, int& sttoopp, int& stteepp) const
4012 if(getNumberOfComponents()!=1)
4013 throw INTERP_KERNEL::Exception("DataArrayInt::isRange : this must be single component array !");
4014 int nbTuples(getNumberOfTuples());
4016 { strt=0; sttoopp=0; stteepp=1; return true; }
4017 const int *pt(begin());
4020 { sttoopp=strt+1; stteepp=1; return true; }
4021 strt=*pt; sttoopp=pt[nbTuples-1];
4027 int a(sttoopp-1-strt),tmp(strt);
4028 if(a%(nbTuples-1)!=0)
4030 stteepp=a/(nbTuples-1);
4031 for(int i=0;i<nbTuples;i++,tmp+=stteepp)
4039 int a(strt-sttoopp-1),tmp(strt);
4040 if(a%(nbTuples-1)!=0)
4042 stteepp=-(a/(nbTuples-1));
4043 for(int i=0;i<nbTuples;i++,tmp+=stteepp)
4052 * Modifies in place \a this one-dimensional array so that each value \a v = \a indArrBg[ \a v ],
4053 * i.e. a current value is used as in index to get a new value from \a indArrBg.
4054 * \param [in] indArrBg - pointer to the first element of array of new values to assign
4056 * \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
4057 * the last value of \a indArrBg is \a indArrEnd[ -1 ].
4058 * \throw If \a this->getNumberOfComponents() != 1
4059 * \throw If any value of \a this can't be used as a valid index for
4060 * [\a indArrBg, \a indArrEnd).
4064 void DataArrayInt::transformWithIndArr(const int *indArrBg, const int *indArrEnd)
4066 this->checkAllocated();
4067 if(this->getNumberOfComponents()!=1)
4068 throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
4069 int nbElemsIn((int)std::distance(indArrBg,indArrEnd)),nbOfTuples(getNumberOfTuples()),*pt(getPointer());
4070 for(int i=0;i<nbOfTuples;i++,pt++)
4072 if(*pt>=0 && *pt<nbElemsIn)
4076 std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " of this value is " << *pt << ", should be in [0," << nbElemsIn << ") !";
4077 throw INTERP_KERNEL::Exception(oss.str().c_str());
4080 this->declareAsNew();
4083 void DataArrayInt::transformWithIndArr(const MapKeyVal<int>& m)
4085 this->checkAllocated();
4086 if(this->getNumberOfComponents()!=1)
4087 throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
4088 const std::map<int,int> dat(m.data());
4089 int nbOfTuples(getNumberOfTuples()),*pt(getPointer());
4090 for(int i=0;i<nbOfTuples;i++,pt++)
4092 std::map<int,int>::const_iterator it(dat.find(*pt));
4097 std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " of this value is " << *pt << " not in map !";
4098 throw INTERP_KERNEL::Exception(oss.str().c_str());
4101 this->declareAsNew();
4105 * Creates a one-dimensional DataArrayInt (\a res) whose contents are computed from
4106 * values of \a this (\a a) and the given (\a indArr) arrays as follows:
4107 * \a res[ \a indArr[ \a a[ i ]]] = i. I.e. for each value in place i \a v = \a a[ i ],
4108 * new value in place \a indArr[ \a v ] is i.
4109 * \param [in] indArrBg - the array holding indices within the result array to assign
4110 * indices of values of \a this array pointing to values of \a indArrBg.
4111 * \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
4112 * the last value of \a indArrBg is \a indArrEnd[ -1 ].
4113 * \return DataArrayInt * - the new instance of DataArrayInt.
4114 * The caller is to delete this result array using decrRef() as it is no more
4116 * \throw If \a this->getNumberOfComponents() != 1.
4117 * \throw If any value of \a this array is not a valid index for \a indArrBg array.
4118 * \throw If any value of \a indArrBg is not a valid index for \a this array.
4120 DataArrayInt *DataArrayInt::transformWithIndArrR(const int *indArrBg, const int *indArrEnd) const
4123 if(getNumberOfComponents()!=1)
4124 throw INTERP_KERNEL::Exception("Call transformWithIndArrR method on DataArrayInt with only one component, you can call 'rearrange' method before !");
4125 int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
4126 int nbOfTuples=getNumberOfTuples();
4127 const int *pt=getConstPointer();
4128 MCAuto<DataArrayInt> ret=DataArrayInt::New();
4129 ret->alloc(nbOfTuples,1);
4130 ret->fillWithValue(-1);
4131 int *tmp=ret->getPointer();
4132 for(int i=0;i<nbOfTuples;i++,pt++)
4134 if(*pt>=0 && *pt<nbElemsIn)
4136 int pos=indArrBg[*pt];
4137 if(pos>=0 && pos<nbOfTuples)
4141 std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value of new pos is " << pos << " ( indArrBg[" << *pt << "]) ! Should be in [0," << nbOfTuples << ") !";
4142 throw INTERP_KERNEL::Exception(oss.str().c_str());
4147 std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn << " !";
4148 throw INTERP_KERNEL::Exception(oss.str().c_str());
4155 * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
4156 * from values of \a this array, which is supposed to contain a renumbering map in
4157 * "Old to New" mode. The result array contains a renumbering map in "New to Old" mode.
4158 * To know how to use the renumbering maps see \ref numbering.
4159 * \param [in] newNbOfElem - the number of tuples in the result array.
4160 * \return DataArrayInt * - the new instance of DataArrayInt.
4161 * The caller is to delete this result array using decrRef() as it is no more
4164 * \if ENABLE_EXAMPLES
4165 * \ref cpp_mcdataarrayint_invertarrayo2n2n2o "Here is a C++ example".<br>
4166 * \ref py_mcdataarrayint_invertarrayo2n2n2o "Here is a Python example".
4169 DataArrayInt *DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const
4171 MCAuto<DataArrayInt> ret(DataArrayInt::New());
4172 ret->alloc(newNbOfElem,1);
4173 int nbOfOldNodes(this->getNumberOfTuples());
4174 const int *old2New(begin());
4175 int *pt(ret->getPointer());
4176 for(int i=0;i!=nbOfOldNodes;i++)
4178 int newp(old2New[i]);
4181 if(newp>=0 && newp<newNbOfElem)
4185 std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2O : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
4186 throw INTERP_KERNEL::Exception(oss.str().c_str());
4194 * This method is similar to DataArrayInt::invertArrayO2N2N2O except that
4195 * 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]
4197 DataArrayInt *DataArrayInt::invertArrayO2N2N2OBis(int newNbOfElem) const
4199 MCAuto<DataArrayInt> ret=DataArrayInt::New();
4200 ret->alloc(newNbOfElem,1);
4201 int nbOfOldNodes=getNumberOfTuples();
4202 const int *old2New=getConstPointer();
4203 int *pt=ret->getPointer();
4204 for(int i=nbOfOldNodes-1;i>=0;i--)
4206 int newp(old2New[i]);
4209 if(newp>=0 && newp<newNbOfElem)
4213 std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2OBis : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
4214 throw INTERP_KERNEL::Exception(oss.str().c_str());
4222 * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
4223 * from values of \a this array, which is supposed to contain a renumbering map in
4224 * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
4225 * To know how to use the renumbering maps see \ref numbering.
4226 * \param [in] newNbOfElem - the number of tuples in the result array.
4227 * \return DataArrayInt * - the new instance of DataArrayInt.
4228 * The caller is to delete this result array using decrRef() as it is no more
4231 * \if ENABLE_EXAMPLES
4232 * \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
4234 * \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
4235 * \sa invertArrayN2O2O2NOptimized
4238 DataArrayInt *DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const
4241 MCAuto<DataArrayInt> ret=DataArrayInt::New();
4242 ret->alloc(oldNbOfElem,1);
4243 const int *new2Old=getConstPointer();
4244 int *pt=ret->getPointer();
4245 std::fill(pt,pt+oldNbOfElem,-1);
4246 int nbOfNewElems=getNumberOfTuples();
4247 for(int i=0;i<nbOfNewElems;i++)
4250 if(v>=0 && v<oldNbOfElem)
4254 std::ostringstream oss; oss << "DataArrayInt::invertArrayN2O2O2N : in new id #" << i << " old value is " << v << " expected to be in [0," << oldNbOfElem << ") !";
4255 throw INTERP_KERNEL::Exception(oss.str().c_str());
4262 * Creates a map, whose contents are computed
4263 * from values of \a this array, which is supposed to contain a renumbering map in
4264 * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
4265 * To know how to use the renumbering maps see \ref numbering.
4266 * \param [in] newNbOfElem - the number of tuples in the result array.
4267 * \return MapII - the new instance of Map.
4269 * \if ENABLE_EXAMPLES
4270 * \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
4272 * \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
4273 * \sa invertArrayN2O2O2N
4276 MCAuto< MapKeyVal<int> > DataArrayInt::invertArrayN2O2O2NOptimized() const
4279 MCAuto< MapKeyVal<int> > ret(MapKeyVal<int>::New());
4280 std::map<int,int>& m(ret->data());
4281 const int *new2Old(begin());
4282 int nbOfNewElems(this->getNumberOfTuples());
4283 for(int i=0;i<nbOfNewElems;i++)
4292 * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode.
4293 * This map, if applied to \a this array, would make it sorted. For example, if
4294 * \a this array contents are [9,10,0,6,4,11,3,7] then the contents of the result array
4295 * are [5,6,0,3,2,7,1,4]; if this result array (\a res) is used as an argument in call
4296 * \a this->renumber(\a res) then the returned array contains [0,3,4,6,7,9,10,11].
4297 * This method is useful for renumbering (in MED file for example). For more info
4298 * on renumbering see \ref numbering.
4299 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4300 * array using decrRef() as it is no more needed.
4301 * \throw If \a this is not allocated.
4302 * \throw If \a this->getNumberOfComponents() != 1.
4303 * \throw If there are equal values in \a this array.
4305 DataArrayInt *DataArrayInt::checkAndPreparePermutation() const
4308 if(getNumberOfComponents()!=1)
4309 throw INTERP_KERNEL::Exception("DataArrayInt::checkAndPreparePermutation : number of components must == 1 !");
4310 int nbTuples=getNumberOfTuples();
4311 const int *pt=getConstPointer();
4312 int *pt2=CheckAndPreparePermutation(pt,pt+nbTuples);
4313 DataArrayInt *ret=DataArrayInt::New();
4314 ret->useArray(pt2,true,C_DEALLOC,nbTuples,1);
4319 * 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
4320 * input array \a ids2.
4321 * \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.
4322 * 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
4324 * In case of success (no throw) : \c ids1->renumber(ret)->isEqual(ids2) where \a ret is the return of this method.
4326 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4327 * array using decrRef() as it is no more needed.
4328 * \throw If either ids1 or ids2 is null not allocated or not with one components.
4331 DataArrayInt *DataArrayInt::FindPermutationFromFirstToSecond(const DataArrayInt *ids1, const DataArrayInt *ids2)
4334 throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be not null !");
4335 if(!ids1->isAllocated() || !ids2->isAllocated())
4336 throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be allocated !");
4337 if(ids1->getNumberOfComponents()!=1 || ids2->getNumberOfComponents()!=1)
4338 throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays have exactly one component !");
4339 if(ids1->getNumberOfTuples()!=ids2->getNumberOfTuples())
4341 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 !";
4342 throw INTERP_KERNEL::Exception(oss.str().c_str());
4344 MCAuto<DataArrayInt> p1(ids1->deepCopy());
4345 MCAuto<DataArrayInt> p2(ids2->deepCopy());
4346 p1->sort(true); p2->sort(true);
4347 if(!p1->isEqualWithoutConsideringStr(*p2))
4348 throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two arrays are not lying on same ids ! Impossible to find a permutation between the 2 arrays !");
4349 p1=ids1->checkAndPreparePermutation();
4350 p2=ids2->checkAndPreparePermutation();
4351 p2=p2->invertArrayO2N2N2O(p2->getNumberOfTuples());
4352 p2=p2->selectByTupleIdSafe(p1->begin(),p1->end());
4357 * Returns two arrays describing a surjective mapping from \a this set of values (\a A)
4358 * onto a set of values of size \a targetNb (\a B). The surjective function is
4359 * \a B[ \a A[ i ]] = i. That is to say that for each \a id in [0,\a targetNb), where \a
4360 * targetNb < \a this->getNumberOfTuples(), there exists at least one tupleId (\a tid) so
4361 * that <em> this->getIJ( tid, 0 ) == id</em>. <br>
4362 * The first of out arrays returns indices of elements of \a this array, grouped by their
4363 * place in the set \a B. The second out array is the index of the first one; it shows how
4364 * many elements of \a A are mapped into each element of \a B. <br>
4366 * mapping and its usage in renumbering see \ref numbering. <br>
4368 * - \a this: [0,3,2,3,2,2,1,2]
4370 * - \a arr: [0, 6, 2,4,5,7, 1,3]
4371 * - \a arrI: [0,1,2,6,8]
4373 * This result means: <br>
4374 * the element of \a B 0 encounters within \a A once (\a arrI[ 0+1 ] - \a arrI[ 0 ]) and
4375 * its index within \a A is 0 ( \a arr[ 0:1 ] == \a arr[ \a arrI[ 0 ] : \a arrI[ 0+1 ]]);<br>
4376 * the element of \a B 2 encounters within \a A 4 times (\a arrI[ 2+1 ] - \a arrI[ 2 ]) and
4377 * its indices within \a A are [2,4,5,7] ( \a arr[ 2:6 ] == \a arr[ \a arrI[ 2 ] :
4378 * \a arrI[ 2+1 ]]); <br> etc.
4379 * \param [in] targetNb - the size of the set \a B. \a targetNb must be equal or more
4380 * than the maximal value of \a A.
4381 * \param [out] arr - a new instance of DataArrayInt returning indices of
4382 * elements of \a this, grouped by their place in the set \a B. The caller is to delete
4383 * this array using decrRef() as it is no more needed.
4384 * \param [out] arrI - a new instance of DataArrayInt returning size of groups of equal
4385 * elements of \a this. The caller is to delete this array using decrRef() as it
4386 * is no more needed.
4387 * \throw If \a this is not allocated.
4388 * \throw If \a this->getNumberOfComponents() != 1.
4389 * \throw If any value in \a this is more or equal to \a targetNb.
4391 void DataArrayInt::changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, DataArrayInt *&arrI) const
4394 if(getNumberOfComponents()!=1)
4395 throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : number of components must == 1 !");
4396 int nbOfTuples=getNumberOfTuples();
4397 MCAuto<DataArrayInt> ret(DataArrayInt::New());
4398 MCAuto<DataArrayInt> retI(DataArrayInt::New());
4399 retI->alloc(targetNb+1,1);
4400 const int *input=getConstPointer();
4401 std::vector< std::vector<int> > tmp(targetNb);
4402 for(int i=0;i<nbOfTuples;i++)
4405 if(tmp2>=0 && tmp2<targetNb)
4406 tmp[tmp2].push_back(i);
4409 std::ostringstream oss; oss << "DataArrayInt::changeSurjectiveFormat : At pos " << i << " presence of element " << tmp2 << " ! should be in [0," << targetNb << ") !";
4410 throw INTERP_KERNEL::Exception(oss.str().c_str());
4413 int *retIPtr=retI->getPointer();
4415 for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++,retIPtr++)
4416 retIPtr[1]=retIPtr[0]+(int)((*it1).size());
4417 if(nbOfTuples!=retI->getIJ(targetNb,0))
4418 throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : big problem should never happen !");
4419 ret->alloc(nbOfTuples,1);
4420 int *retPtr=ret->getPointer();
4421 for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++)
4422 retPtr=std::copy((*it1).begin(),(*it1).end(),retPtr);
4429 * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode computed
4430 * from a zip representation of a surjective format (returned e.g. by
4431 * \ref MEDCoupling::DataArrayDouble::findCommonTuples() "DataArrayDouble::findCommonTuples()"
4432 * for example). The result array minimizes the permutation. <br>
4433 * For more info on renumbering see \ref numbering. <br>
4435 * - \a nbOfOldTuples: 10
4436 * - \a arr : [0,3, 5,7,9]
4437 * - \a arrIBg : [0,2,5]
4438 * - \a newNbOfTuples: 7
4439 * - result array : [0,1,2,0,3,4,5,4,6,4]
4441 * \param [in] nbOfOldTuples - number of tuples in the initial array \a arr.
4442 * \param [in] arr - the array of tuple indices grouped by \a arrIBg array.
4443 * \param [in] arrIBg - the array dividing all indices stored in \a arr into groups of
4444 * (indices of) equal values. Its every element (except the last one) points to
4445 * the first element of a group of equal values.
4446 * \param [in] arrIEnd - specifies the end of \a arrIBg, so that the last element of \a
4447 * arrIBg is \a arrIEnd[ -1 ].
4448 * \param [out] newNbOfTuples - number of tuples after surjection application.
4449 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4450 * array using decrRef() as it is no more needed.
4451 * \throw If any value of \a arr breaks condition ( 0 <= \a arr[ i ] < \a nbOfOldTuples ).
4453 DataArrayInt *DataArrayInt::ConvertIndexArrayToO2N(int nbOfOldTuples, const int *arr, const int *arrIBg, const int *arrIEnd, int &newNbOfTuples)
4455 MCAuto<DataArrayInt> ret=DataArrayInt::New();
4456 ret->alloc(nbOfOldTuples,1);
4457 int *pt=ret->getPointer();
4458 std::fill(pt,pt+nbOfOldTuples,-1);
4459 int nbOfGrps=((int)std::distance(arrIBg,arrIEnd))-1;
4460 const int *cIPtr=arrIBg;
4461 for(int i=0;i<nbOfGrps;i++)
4462 pt[arr[cIPtr[i]]]=-(i+2);
4464 for(int iNode=0;iNode<nbOfOldTuples;iNode++)
4472 int grpId=-(pt[iNode]+2);
4473 for(int j=cIPtr[grpId];j<cIPtr[grpId+1];j++)
4475 if(arr[j]>=0 && arr[j]<nbOfOldTuples)
4479 std::ostringstream oss; oss << "DataArrayInt::ConvertIndexArrayToO2N : With element #" << j << " value is " << arr[j] << " should be in [0," << nbOfOldTuples << ") !";
4480 throw INTERP_KERNEL::Exception(oss.str().c_str());
4487 newNbOfTuples=newNb;
4492 * Returns a new DataArrayInt containing a renumbering map in "New to Old" mode,
4493 * which if applied to \a this array would make it sorted ascendingly.
4494 * For more info on renumbering see \ref numbering. <br>
4496 * - \a this: [2,0,1,1,0,1,2,0,1,1,0,0]
4497 * - result: [10,0,5,6,1,7,11,2,8,9,3,4]
4498 * - after applying result to \a this: [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2]
4500 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4501 * array using decrRef() as it is no more needed.
4502 * \throw If \a this is not allocated.
4503 * \throw If \a this->getNumberOfComponents() != 1.
4505 DataArrayInt *DataArrayInt::buildPermArrPerLevel() const
4508 if(getNumberOfComponents()!=1)
4509 throw INTERP_KERNEL::Exception("DataArrayInt::buildPermArrPerLevel : number of components must == 1 !");
4510 int nbOfTuples=getNumberOfTuples();
4511 const int *pt=getConstPointer();
4512 std::map<int,int> m;
4513 MCAuto<DataArrayInt> ret=DataArrayInt::New();
4514 ret->alloc(nbOfTuples,1);
4515 int *opt=ret->getPointer();
4516 for(int i=0;i<nbOfTuples;i++,pt++,opt++)
4519 std::map<int,int>::iterator it=m.find(val);
4528 m.insert(std::pair<int,int>(val,1));
4532 for(std::map<int,int>::iterator it=m.begin();it!=m.end();it++)
4534 int vt=(*it).second;
4538 pt=getConstPointer();
4539 opt=ret->getPointer();
4540 for(int i=0;i<nbOfTuples;i++,pt++,opt++)
4547 * Checks if \a this array has the given size, and if its contents is equal to an array filled with
4548 * iota(). This method is particularly useful for DataArrayInt instances that represent
4549 * a renumbering array, to check if there is a real need in renumbering.
4550 * This method checks than \a this can be considered as an identity mapping
4551 * of a set having \a sizeExpected elements into itself.
4553 * \param [in] sizeExpected - The number of elements expected.
4554 * \return bool - \a true if \a this array contents == \a range( \a this->getNumberOfTuples())
4555 * \throw If \a this is not allocated.
4556 * \throw If \a this->getNumberOfComponents() != 1.
4558 bool DataArrayInt::isIota(int sizeExpected) const
4561 if(getNumberOfComponents()!=1)
4563 int nbOfTuples(getNumberOfTuples());
4564 if(nbOfTuples!=sizeExpected)
4566 const int *pt=getConstPointer();
4567 for(int i=0;i<nbOfTuples;i++,pt++)
4574 * Checks if all values in \a this array are equal to \a val.
4575 * \param [in] val - value to check equality of array values to.
4576 * \return bool - \a true if all values are \a val.
4577 * \throw If \a this is not allocated.
4578 * \throw If \a this->getNumberOfComponents() != 1
4579 * \sa DataArrayInt::checkUniformAndGuess
4581 bool DataArrayInt::isUniform(int val) const
4584 if(getNumberOfComponents()!=1)
4585 throw INTERP_KERNEL::Exception("DataArrayInt::isUniform : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
4586 const int *w(begin()),*end2(end());
4594 * This method checks that \a this is uniform. If not and exception will be thrown.
4595 * In case of uniformity the corresponding value is returned.
4597 * \return int - the unique value contained in this
4598 * \throw If \a this is not allocated.
4599 * \throw If \a this->getNumberOfComponents() != 1
4600 * \throw If \a this is not uniform.
4601 * \sa DataArrayInt::isUniform
4603 int DataArrayInt::checkUniformAndGuess() const
4606 if(getNumberOfComponents()!=1)
4607 throw INTERP_KERNEL::Exception("DataArrayInt::checkUniformAndGuess : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
4609 throw INTERP_KERNEL::Exception("DataArrayInt::checkUniformAndGuess : this is empty !");
4610 const int *w(begin()),*end2(end());
4614 throw INTERP_KERNEL::Exception("DataArrayInt::checkUniformAndGuess : this is not uniform !");
4619 * Checks if all values in \a this array are unique.
4620 * \return bool - \a true if condition above is true
4621 * \throw If \a this is not allocated.
4622 * \throw If \a this->getNumberOfComponents() != 1
4624 bool DataArrayInt::hasUniqueValues() const
4627 if(getNumberOfComponents()!=1)
4628 throw INTERP_KERNEL::Exception("DataArrayInt::hasOnlyUniqueValues: must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
4629 int nbOfTuples(getNumberOfTuples());
4630 std::set<int> s(begin(),end()); // in C++11, should use unordered_set (O(1) complexity)
4631 if (s.size() != nbOfTuples)
4637 * Copy all components in a specified order from another DataArrayInt.
4638 * The specified components become the first ones in \a this array.
4639 * Both numerical and textual data is copied. The number of tuples in \a this and
4640 * the other array can be different.
4641 * \param [in] a - the array to copy data from.
4642 * \param [in] compoIds - sequence of zero based indices of components, data of which is
4644 * \throw If \a a is NULL.
4645 * \throw If \a compoIds.size() != \a a->getNumberOfComponents().
4646 * \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
4648 * \if ENABLE_EXAMPLES
4649 * \ref py_mcdataarrayint_setselectedcomponents "Here is a Python example".
4652 void DataArrayInt::setSelectedComponents(const DataArrayInt *a, const std::vector<int>& compoIds)
4655 throw INTERP_KERNEL::Exception("DataArrayInt::setSelectedComponents : input DataArrayInt is NULL !");
4657 a->checkAllocated();
4658 copyPartOfStringInfoFrom2(compoIds,*a);
4659 std::size_t partOfCompoSz=compoIds.size();
4660 int nbOfCompo=getNumberOfComponents();
4661 int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
4662 const int *ac=a->getConstPointer();
4663 int *nc=getPointer();
4664 for(int i=0;i<nbOfTuples;i++)
4665 for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
4666 nc[nbOfCompo*i+compoIds[j]]=*ac;
4669 DataArrayIntIterator *DataArrayInt::iterator()
4671 return new DataArrayIntIterator(this);
4675 * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to a
4676 * given one. The ids are sorted in the ascending order.
4677 * \param [in] val - the value to find within \a this.
4678 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4679 * array using decrRef() as it is no more needed.
4680 * \throw If \a this is not allocated.
4681 * \throw If \a this->getNumberOfComponents() != 1.
4682 * \sa DataArrayInt::findIdsEqualTuple
4684 DataArrayInt *DataArrayInt::findIdsEqual(int val) const
4687 if(getNumberOfComponents()!=1)
4688 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqual : the array must have only one component, you can call 'rearrange' method before !");
4689 const int *cptr(getConstPointer());
4690 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4691 int nbOfTuples=getNumberOfTuples();
4692 for(int i=0;i<nbOfTuples;i++,cptr++)
4694 ret->pushBackSilent(i);
4699 * Creates a new DataArrayInt containing IDs (indices) of tuples holding value \b not
4700 * equal to a given one.
4701 * \param [in] val - the value to ignore within \a this.
4702 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4703 * array using decrRef() as it is no more needed.
4704 * \throw If \a this is not allocated.
4705 * \throw If \a this->getNumberOfComponents() != 1.
4707 DataArrayInt *DataArrayInt::findIdsNotEqual(int val) const
4710 if(getNumberOfComponents()!=1)
4711 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotEqual : the array must have only one component, you can call 'rearrange' method before !");
4712 const int *cptr(getConstPointer());
4713 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4714 int nbOfTuples=getNumberOfTuples();
4715 for(int i=0;i<nbOfTuples;i++,cptr++)
4717 ret->pushBackSilent(i);
4722 * Creates a new DataArrayInt containing IDs (indices) of tuples holding tuple equal to those defined by [ \a tupleBg , \a tupleEnd )
4723 * This method is an extension of DataArrayInt::findIdsEqual method.
4725 * \param [in] tupleBg - the begin (included) of the input tuple to find within \a this.
4726 * \param [in] tupleEnd - the end (excluded) of the input tuple to find within \a this.
4727 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4728 * array using decrRef() as it is no more needed.
4729 * \throw If \a this is not allocated.
4730 * \throw If \a this->getNumberOfComponents() != std::distance(tupleBg,tupleEnd).
4731 * \throw If \a this->getNumberOfComponents() is equal to 0.
4732 * \sa DataArrayInt::findIdsEqual
4734 DataArrayInt *DataArrayInt::findIdsEqualTuple(const int *tupleBg, const int *tupleEnd) const
4736 std::size_t nbOfCompoExp(std::distance(tupleBg,tupleEnd));
4738 if(getNumberOfComponents()!=(int)nbOfCompoExp)
4740 std::ostringstream oss; oss << "DataArrayInt::findIdsEqualTuple : mismatch of number of components. Input tuple has " << nbOfCompoExp << " whereas this array has " << getNumberOfComponents() << " components !";
4741 throw INTERP_KERNEL::Exception(oss.str().c_str());
4744 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqualTuple : number of components should be > 0 !");
4745 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4746 const int *bg(begin()),*end2(end()),*work(begin());
4749 work=std::search(work,end2,tupleBg,tupleEnd);
4752 std::size_t pos(std::distance(bg,work));
4753 if(pos%nbOfCompoExp==0)
4754 ret->pushBackSilent(pos/nbOfCompoExp);
4762 * Assigns \a newValue to all elements holding \a oldValue within \a this
4763 * one-dimensional array.
4764 * \param [in] oldValue - the value to replace.
4765 * \param [in] newValue - the value to assign.
4766 * \return int - number of replacements performed.
4767 * \throw If \a this is not allocated.
4768 * \throw If \a this->getNumberOfComponents() != 1.
4770 int DataArrayInt::changeValue(int oldValue, int newValue)
4773 if(getNumberOfComponents()!=1)
4774 throw INTERP_KERNEL::Exception("DataArrayInt::changeValue : the array must have only one component, you can call 'rearrange' method before !");
4775 if(oldValue==newValue)
4777 int *start(getPointer()),*end2(start+getNbOfElems());
4779 for(int *val=start;val!=end2;val++)
4793 * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to
4794 * one of given values.
4795 * \param [in] valsBg - an array of values to find within \a this array.
4796 * \param [in] valsEnd - specifies the end of the array \a valsBg, so that
4797 * the last value of \a valsBg is \a valsEnd[ -1 ].
4798 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4799 * array using decrRef() as it is no more needed.
4800 * \throw If \a this->getNumberOfComponents() != 1.
4802 DataArrayInt *DataArrayInt::findIdsEqualList(const int *valsBg, const int *valsEnd) const
4804 if(getNumberOfComponents()!=1)
4805 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqualList : the array must have only one component, you can call 'rearrange' method before !");
4806 std::set<int> vals2(valsBg,valsEnd);
4807 const int *cptr(getConstPointer());
4808 std::vector<int> res;
4809 int nbOfTuples(getNumberOfTuples());
4810 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4811 for(int i=0;i<nbOfTuples;i++,cptr++)
4812 if(vals2.find(*cptr)!=vals2.end())
4813 ret->pushBackSilent(i);
4818 * Creates a new DataArrayInt containing IDs (indices) of tuples holding values \b not
4819 * equal to any of given values.
4820 * \param [in] valsBg - an array of values to ignore within \a this array.
4821 * \param [in] valsEnd - specifies the end of the array \a valsBg, so that
4822 * the last value of \a valsBg is \a valsEnd[ -1 ].
4823 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4824 * array using decrRef() as it is no more needed.
4825 * \throw If \a this->getNumberOfComponents() != 1.
4827 DataArrayInt *DataArrayInt::findIdsNotEqualList(const int *valsBg, const int *valsEnd) const
4829 if(getNumberOfComponents()!=1)
4830 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotEqualList : the array must have only one component, you can call 'rearrange' method before !");
4831 std::set<int> vals2(valsBg,valsEnd);
4832 const int *cptr=getConstPointer();
4833 std::vector<int> res;
4834 int nbOfTuples=getNumberOfTuples();
4835 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4836 for(int i=0;i<nbOfTuples;i++,cptr++)
4837 if(vals2.find(*cptr)==vals2.end())
4838 ret->pushBackSilent(i);
4843 * This method is an extension of DataArrayInt::findIdFirstEqual method because this method works for DataArrayInt with
4844 * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
4845 * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
4846 * If any the tuple id is returned. If not -1 is returned.
4848 * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
4849 * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
4851 * \return tuple id where \b tupl is. -1 if no such tuple exists in \b this.
4852 * \sa DataArrayInt::findIdSequence, DataArrayInt::presenceOfTuple.
4854 int DataArrayInt::findIdFirstEqualTuple(const std::vector<int>& tupl) const
4857 int nbOfCompo=getNumberOfComponents();
4859 throw INTERP_KERNEL::Exception("DataArrayInt::findIdFirstEqualTuple : 0 components in 'this' !");
4860 if(nbOfCompo!=(int)tupl.size())
4862 std::ostringstream oss; oss << "DataArrayInt::findIdFirstEqualTuple : 'this' contains " << nbOfCompo << " components and searching for a tuple of length " << tupl.size() << " !";
4863 throw INTERP_KERNEL::Exception(oss.str().c_str());
4865 const int *cptr=getConstPointer();
4866 std::size_t nbOfVals=getNbOfElems();
4867 for(const int *work=cptr;work!=cptr+nbOfVals;)
4869 work=std::search(work,cptr+nbOfVals,tupl.begin(),tupl.end());
4870 if(work!=cptr+nbOfVals)
4872 if(std::distance(cptr,work)%nbOfCompo!=0)
4875 return std::distance(cptr,work)/nbOfCompo;
4882 * This method searches the sequence specified in input parameter \b vals in \b this.
4883 * This works only for DataArrayInt having number of components equal to one (if not an INTERP_KERNEL::Exception will be thrown).
4884 * This method differs from DataArrayInt::findIdFirstEqualTuple in that the position is internal raw data is not considered here contrary to DataArrayInt::findIdFirstEqualTuple.
4885 * \sa DataArrayInt::findIdFirstEqualTuple
4887 int DataArrayInt::findIdSequence(const std::vector<int>& vals) const
4890 int nbOfCompo=getNumberOfComponents();
4892 throw INTERP_KERNEL::Exception("DataArrayInt::findIdSequence : works only for DataArrayInt instance with one component !");
4893 const int *cptr=getConstPointer();
4894 std::size_t nbOfVals=getNbOfElems();
4895 const int *loc=std::search(cptr,cptr+nbOfVals,vals.begin(),vals.end());
4896 if(loc!=cptr+nbOfVals)
4897 return std::distance(cptr,loc);
4902 * This method expects to be called when number of components of this is equal to one.
4903 * This method returns the tuple id, if it exists, of the first tuple equal to \b value.
4904 * If not any tuple contains \b value -1 is returned.
4905 * \sa DataArrayInt::presenceOfValue
4907 int DataArrayInt::findIdFirstEqual(int value) const
4910 if(getNumberOfComponents()!=1)
4911 throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
4912 const int *cptr=getConstPointer();
4913 int nbOfTuples=getNumberOfTuples();
4914 const int *ret=std::find(cptr,cptr+nbOfTuples,value);
4915 if(ret!=cptr+nbOfTuples)
4916 return std::distance(cptr,ret);
4921 * This method expects to be called when number of components of this is equal to one.
4922 * This method returns the tuple id, if it exists, of the first tuple so that the value is contained in \b vals.
4923 * If not any tuple contains one of the values contained in 'vals' -1 is returned.
4924 * \sa DataArrayInt::presenceOfValue
4926 int DataArrayInt::findIdFirstEqual(const std::vector<int>& vals) const
4929 if(getNumberOfComponents()!=1)
4930 throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
4931 std::set<int> vals2(vals.begin(),vals.end());
4932 const int *cptr=getConstPointer();
4933 int nbOfTuples=getNumberOfTuples();
4934 for(const int *w=cptr;w!=cptr+nbOfTuples;w++)
4935 if(vals2.find(*w)!=vals2.end())
4936 return std::distance(cptr,w);
4941 * This method returns the number of values in \a this that are equals to input parameter \a value.
4942 * This method only works for single component array.
4944 * \return a value in [ 0, \c this->getNumberOfTuples() )
4946 * \throw If \a this is not allocated
4949 int DataArrayInt::count(int value) const
4953 if(getNumberOfComponents()!=1)
4954 throw INTERP_KERNEL::Exception("DataArrayInt::count : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
4955 const int *vals=begin();
4956 int nbOfTuples=getNumberOfTuples();
4957 for(int i=0;i<nbOfTuples;i++,vals++)
4964 * This method is an extension of DataArrayInt::presenceOfValue method because this method works for DataArrayInt with
4965 * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
4966 * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
4967 * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
4968 * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
4969 * \sa DataArrayInt::findIdFirstEqualTuple
4971 bool DataArrayInt::presenceOfTuple(const std::vector<int>& tupl) const
4973 return findIdFirstEqualTuple(tupl)!=-1;
4978 * Returns \a true if a given value is present within \a this one-dimensional array.
4979 * \param [in] value - the value to find within \a this array.
4980 * \return bool - \a true in case if \a value is present within \a this array.
4981 * \throw If \a this is not allocated.
4982 * \throw If \a this->getNumberOfComponents() != 1.
4983 * \sa findIdFirstEqual()
4985 bool DataArrayInt::presenceOfValue(int value) const
4987 return findIdFirstEqual(value)!=-1;
4991 * This method expects to be called when number of components of this is equal to one.
4992 * This method returns true if it exists a tuple so that the value is contained in \b vals.
4993 * If not any tuple contains one of the values contained in 'vals' false is returned.
4994 * \sa DataArrayInt::findIdFirstEqual
4996 bool DataArrayInt::presenceOfValue(const std::vector<int>& vals) const
4998 return findIdFirstEqual(vals)!=-1;
5002 * Accumulates values of each component of \a this array.
5003 * \param [out] res - an array of length \a this->getNumberOfComponents(), allocated
5004 * by the caller, that is filled by this method with sum value for each
5006 * \throw If \a this is not allocated.
5008 void DataArrayInt::accumulate(int *res) const
5011 const int *ptr=getConstPointer();
5012 int nbTuple=getNumberOfTuples();
5013 int nbComps=getNumberOfComponents();
5014 std::fill(res,res+nbComps,0);
5015 for(int i=0;i<nbTuple;i++)
5016 std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<int>());
5019 int DataArrayInt::accumulate(int compId) const
5022 const int *ptr=getConstPointer();
5023 int nbTuple=getNumberOfTuples();
5024 int nbComps=getNumberOfComponents();
5025 if(compId<0 || compId>=nbComps)
5026 throw INTERP_KERNEL::Exception("DataArrayInt::accumulate : Invalid compId specified : No such nb of components !");
5028 for(int i=0;i<nbTuple;i++)
5029 ret+=ptr[i*nbComps+compId];
5034 * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
5035 * The returned array will have same number of components than \a this and number of tuples equal to
5036 * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
5038 * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
5040 * \param [in] bgOfIndex - begin (included) of the input index array.
5041 * \param [in] endOfIndex - end (excluded) of the input index array.
5042 * \return DataArrayInt * - the new instance having the same number of components than \a this.
5044 * \throw If bgOfIndex or end is NULL.
5045 * \throw If input index array is not ascendingly sorted.
5046 * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
5047 * \throw If std::distance(bgOfIndex,endOfIndex)==0.
5049 DataArrayInt *DataArrayInt::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
5051 if(!bgOfIndex || !endOfIndex)
5052 throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : input pointer NULL !");
5054 int nbCompo=getNumberOfComponents();
5055 int nbOfTuples=getNumberOfTuples();
5056 int sz=(int)std::distance(bgOfIndex,endOfIndex);
5058 throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : invalid size of input index array !");
5060 MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(sz,nbCompo);
5061 const int *w=bgOfIndex;
5062 if(*w<0 || *w>=nbOfTuples)
5063 throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
5064 const int *srcPt=begin()+(*w)*nbCompo;
5065 int *tmp=ret->getPointer();
5066 for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
5068 std::fill(tmp,tmp+nbCompo,0);
5071 for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
5073 if(j>=0 && j<nbOfTuples)
5074 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<int>());
5077 std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
5078 throw INTERP_KERNEL::Exception(oss.str().c_str());
5084 std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
5085 throw INTERP_KERNEL::Exception(oss.str().c_str());
5088 ret->copyStringInfoFrom(*this);
5093 * Returns a new DataArrayInt by concatenating two given arrays, so that (1) the number
5094 * of tuples in the result array is <em> a1->getNumberOfTuples() + a2->getNumberOfTuples() -
5095 * offsetA2</em> and (2)
5096 * the number of component in the result array is same as that of each of given arrays.
5097 * First \a offsetA2 tuples of \a a2 are skipped and thus are missing from the result array.
5098 * Info on components is copied from the first of the given arrays. Number of components
5099 * in the given arrays must be the same.
5100 * \param [in] a1 - an array to include in the result array.
5101 * \param [in] a2 - another array to include in the result array.
5102 * \param [in] offsetA2 - number of tuples of \a a2 to skip.
5103 * \return DataArrayInt * - the new instance of DataArrayInt.
5104 * The caller is to delete this result array using decrRef() as it is no more
5106 * \throw If either \a a1 or \a a2 is NULL.
5107 * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
5109 DataArrayInt *DataArrayInt::Aggregate(const DataArrayInt *a1, const DataArrayInt *a2, int offsetA2)
5112 throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input DataArrayInt instance is NULL !");
5113 int nbOfComp=a1->getNumberOfComponents();
5114 if(nbOfComp!=a2->getNumberOfComponents())
5115 throw INTERP_KERNEL::Exception("Nb of components mismatch for array Aggregation !");
5116 int nbOfTuple1=a1->getNumberOfTuples();
5117 int nbOfTuple2=a2->getNumberOfTuples();
5118 DataArrayInt *ret=DataArrayInt::New();
5119 ret->alloc(nbOfTuple1+nbOfTuple2-offsetA2,nbOfComp);
5120 int *pt=std::copy(a1->getConstPointer(),a1->getConstPointer()+nbOfTuple1*nbOfComp,ret->getPointer());
5121 std::copy(a2->getConstPointer()+offsetA2*nbOfComp,a2->getConstPointer()+nbOfTuple2*nbOfComp,pt);
5122 ret->copyStringInfoFrom(*a1);
5127 * Returns a new DataArrayInt by concatenating all given arrays, so that (1) the number
5128 * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
5129 * the number of component in the result array is same as that of each of given arrays.
5130 * Info on components is copied from the first of the given arrays. Number of components
5131 * in the given arrays must be the same.
5132 * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it
5133 * not the object itself.
5134 * \param [in] arr - a sequence of arrays to include in the result array.
5135 * \return DataArrayInt * - the new instance of DataArrayInt.
5136 * The caller is to delete this result array using decrRef() as it is no more
5138 * \throw If all arrays within \a arr are NULL.
5139 * \throw If getNumberOfComponents() of arrays within \a arr.
5141 DataArrayInt *DataArrayInt::Aggregate(const std::vector<const DataArrayInt *>& arr)
5143 std::vector<const DataArrayInt *> a;
5144 for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
5148 throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input list must be NON EMPTY !");
5149 std::vector<const DataArrayInt *>::const_iterator it=a.begin();
5150 int nbOfComp=(*it)->getNumberOfComponents();
5151 int nbt=(*it++)->getNumberOfTuples();
5152 for(int i=1;it!=a.end();it++,i++)
5154 if((*it)->getNumberOfComponents()!=nbOfComp)
5155 throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : Nb of components mismatch for array aggregation !");
5156 nbt+=(*it)->getNumberOfTuples();
5158 MCAuto<DataArrayInt> ret=DataArrayInt::New();
5159 ret->alloc(nbt,nbOfComp);
5160 int *pt=ret->getPointer();
5161 for(it=a.begin();it!=a.end();it++)
5162 pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
5163 ret->copyStringInfoFrom(*(a[0]));
5168 * This method takes as input a list of DataArrayInt instances \a arrs that represent each a packed index arrays.
5169 * A packed index array is an allocated array with one component, and at least one tuple. The first element
5170 * of each array in \a arrs must be 0. Each array in \a arrs is expected to be increasingly monotonic.
5171 * 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.
5173 * \return DataArrayInt * - a new object to be managed by the caller.
5175 DataArrayInt *DataArrayInt::AggregateIndexes(const std::vector<const DataArrayInt *>& arrs)
5178 for(std::vector<const DataArrayInt *>::const_iterator it4=arrs.begin();it4!=arrs.end();it4++)
5182 (*it4)->checkAllocated();
5183 if((*it4)->getNumberOfComponents()!=1)
5185 std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of compo != 1 at pos " << std::distance(arrs.begin(),it4) << " !";
5186 throw INTERP_KERNEL::Exception(oss.str().c_str());
5188 int nbTupl=(*it4)->getNumberOfTuples();
5191 std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of tuples < 1 at pos " << std::distance(arrs.begin(),it4) << " !";
5192 throw INTERP_KERNEL::Exception(oss.str().c_str());
5194 if((*it4)->front()!=0)
5196 std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with front value != 0 at pos " << std::distance(arrs.begin(),it4) << " !";
5197 throw INTERP_KERNEL::Exception(oss.str().c_str());
5203 std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a null instance at pos " << std::distance(arrs.begin(),it4) << " !";
5204 throw INTERP_KERNEL::Exception(oss.str().c_str());
5208 throw INTERP_KERNEL::Exception("DataArrayInt::AggregateIndexes : input list must be NON EMPTY !");
5209 MCAuto<DataArrayInt> ret=DataArrayInt::New();
5210 ret->alloc(retSz,1);
5211 int *pt=ret->getPointer(); *pt++=0;
5212 for(std::vector<const DataArrayInt *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
5213 pt=std::transform((*it)->begin()+1,(*it)->end(),pt,std::bind2nd(std::plus<int>(),pt[-1]));
5214 ret->copyStringInfoFrom(*(arrs[0]));
5219 * Returns in a single walk in \a this the min value and the max value in \a this.
5220 * \a this is expected to be single component array.
5222 * \param [out] minValue - the min value in \a this.
5223 * \param [out] maxValue - the max value in \a this.
5225 * \sa getMinValueInArray, getMinValue, getMaxValueInArray, getMaxValue
5227 void DataArrayInt::getMinMaxValues(int& minValue, int& maxValue) const
5230 if(getNumberOfComponents()!=1)
5231 throw INTERP_KERNEL::Exception("DataArrayInt::getMinMaxValues : must be applied on DataArrayInt with only one component !");
5232 int nbTuples(getNumberOfTuples());
5233 const int *pt(begin());
5234 minValue=std::numeric_limits<int>::max(); maxValue=-std::numeric_limits<int>::max();
5235 for(int i=0;i<nbTuples;i++,pt++)
5245 * Modify all elements of \a this array, so that
5246 * an element _x_ becomes \f$ numerator / x \f$.
5247 * \warning If an exception is thrown because of presence of 0 element in \a this
5248 * array, all elements processed before detection of the zero element remain
5250 * \param [in] numerator - the numerator used to modify array elements.
5251 * \throw If \a this is not allocated.
5252 * \throw If there is an element equal to 0 in \a this array.
5254 void DataArrayInt::applyInv(int numerator)
5257 int *ptr=getPointer();
5258 std::size_t nbOfElems=getNbOfElems();
5259 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
5263 *ptr=numerator/(*ptr);
5267 std::ostringstream oss; oss << "DataArrayInt::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
5269 throw INTERP_KERNEL::Exception(oss.str().c_str());
5276 * Modify all elements of \a this array, so that
5277 * an element _x_ becomes \f$ x / val \f$.
5278 * \param [in] val - the denominator used to modify array elements.
5279 * \throw If \a this is not allocated.
5280 * \throw If \a val == 0.
5282 void DataArrayInt::applyDivideBy(int val)
5285 throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to divide by 0 !");
5287 int *ptr=getPointer();
5288 std::size_t nbOfElems=getNbOfElems();
5289 std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::divides<int>(),val));
5294 * Modify all elements of \a this array, so that
5295 * an element _x_ becomes <em> x % val </em>.
5296 * \param [in] val - the divisor used to modify array elements.
5297 * \throw If \a this is not allocated.
5298 * \throw If \a val <= 0.
5300 void DataArrayInt::applyModulus(int val)
5303 throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to operate modulus on value <= 0 !");
5305 int *ptr=getPointer();
5306 std::size_t nbOfElems=getNbOfElems();
5307 std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::modulus<int>(),val));
5312 * This method works only on data array with one component.
5313 * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
5314 * this[*id] in [\b vmin,\b vmax)
5316 * \param [in] vmin begin of range. This value is included in range (included).
5317 * \param [in] vmax end of range. This value is \b not included in range (excluded).
5318 * \return a newly allocated data array that the caller should deal with.
5320 * \sa DataArrayInt::findIdsNotInRange , DataArrayInt::findIdsStricltyNegative
5322 DataArrayInt *DataArrayInt::findIdsInRange(int vmin, int vmax) const
5324 InRange<int> ir(vmin,vmax);
5325 MCAuto<DataArrayInt> ret(findIdsAdv(ir));
5330 * This method works only on data array with one component.
5331 * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
5332 * this[*id] \b not in [\b vmin,\b vmax)
5334 * \param [in] vmin begin of range. This value is \b not included in range (excluded).
5335 * \param [in] vmax end of range. This value is included in range (included).
5336 * \return a newly allocated data array that the caller should deal with.
5338 * \sa DataArrayInt::findIdsInRange , DataArrayInt::findIdsStricltyNegative
5340 DataArrayInt *DataArrayInt::findIdsNotInRange(int vmin, int vmax) const
5342 NotInRange<int> nir(vmin,vmax);
5343 MCAuto<DataArrayInt> ret(findIdsAdv(nir));
5348 * This method works only on data array with one component.
5349 * 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.
5351 * \param [in] vmin begin of range. This value is included in range (included).
5352 * \param [in] vmax end of range. This value is \b not included in range (excluded).
5353 * \return if all ids in \a this are so that (*this)[i]==i for all i in [ 0, \c this->getNumberOfTuples() ). */
5354 bool DataArrayInt::checkAllIdsInRange(int vmin, int vmax) const
5357 if(getNumberOfComponents()!=1)
5358 throw INTERP_KERNEL::Exception("DataArrayInt::checkAllIdsInRange : this must have exactly one component !");
5359 int nbOfTuples=getNumberOfTuples();
5361 const int *cptr=getConstPointer();
5362 for(int i=0;i<nbOfTuples;i++,cptr++)
5364 if(*cptr>=vmin && *cptr<vmax)
5365 { ret=ret && *cptr==i; }
5368 std::ostringstream oss; oss << "DataArrayInt::checkAllIdsInRange : tuple #" << i << " has value " << *cptr << " should be in [" << vmin << "," << vmax << ") !";
5369 throw INTERP_KERNEL::Exception(oss.str().c_str());
5376 * Modify all elements of \a this array, so that
5377 * an element _x_ becomes <em> val % x </em>.
5378 * \warning If an exception is thrown because of presence of an element <= 0 in \a this
5379 * array, all elements processed before detection of the zero element remain
5381 * \param [in] val - the divident used to modify array elements.
5382 * \throw If \a this is not allocated.
5383 * \throw If there is an element equal to or less than 0 in \a this array.
5385 void DataArrayInt::applyRModulus(int val)
5388 int *ptr=getPointer();
5389 std::size_t nbOfElems=getNbOfElems();
5390 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
5398 std::ostringstream oss; oss << "DataArrayInt::applyRModulus : presence of value <=0 in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
5400 throw INTERP_KERNEL::Exception(oss.str().c_str());
5407 * Modify all elements of \a this array, so that
5408 * an element _x_ becomes <em> val ^ x </em>.
5409 * \param [in] val - the value used to apply pow on all array elements.
5410 * \throw If \a this is not allocated.
5411 * \throw If \a val < 0.
5413 void DataArrayInt::applyPow(int val)
5417 throw INTERP_KERNEL::Exception("DataArrayInt::applyPow : input pow in < 0 !");
5418 int *ptr=getPointer();
5419 std::size_t nbOfElems=getNbOfElems();
5422 std::fill(ptr,ptr+nbOfElems,1);
5425 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
5428 for(int j=0;j<val;j++)
5436 * Modify all elements of \a this array, so that
5437 * an element _x_ becomes \f$ val ^ x \f$.
5438 * \param [in] val - the value used to apply pow on all array elements.
5439 * \throw If \a this is not allocated.
5440 * \throw If there is an element < 0 in \a this array.
5441 * \warning If an exception is thrown because of presence of 0 element in \a this
5442 * array, all elements processed before detection of the zero element remain
5445 void DataArrayInt::applyRPow(int val)
5448 int *ptr=getPointer();
5449 std::size_t nbOfElems=getNbOfElems();
5450 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
5455 for(int j=0;j<*ptr;j++)
5461 std::ostringstream oss; oss << "DataArrayInt::applyRPow : presence of negative value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
5463 throw INTERP_KERNEL::Exception(oss.str().c_str());
5470 * Returns a new DataArrayInt which is a minimal partition of elements of \a groups.
5471 * The i-th item of the result array is an ID of a set of elements belonging to a
5472 * unique set of groups, which the i-th element is a part of. This set of elements
5473 * belonging to a unique set of groups is called \a family, so the result array contains
5474 * IDs of families each element belongs to.
5476 * \b Example: if we have two groups of elements: \a group1 [0,4] and \a group2 [ 0,1,2 ],
5477 * then there are 3 families:
5478 * - \a family1 (with ID 1) contains element [0] belonging to ( \a group1 + \a group2 ),
5479 * - \a family2 (with ID 2) contains elements [4] belonging to ( \a group1 ),
5480 * - \a family3 (with ID 3) contains element [1,2] belonging to ( \a group2 ), <br>
5481 * and the result array contains IDs of families [ 1,3,3,0,2 ]. <br> Note a family ID 0 which
5482 * stands for the element #3 which is in none of groups.
5484 * \param [in] groups - sequence of groups of element IDs.
5485 * \param [in] newNb - total number of elements; it must be more than max ID of element
5487 * \param [out] fidsOfGroups - IDs of families the elements of each group belong to.
5488 * \return DataArrayInt * - a new instance of DataArrayInt containing IDs of families
5489 * each element with ID from range [0, \a newNb ) belongs to. The caller is to
5490 * delete this array using decrRef() as it is no more needed.
5491 * \throw If any element ID in \a groups violates condition ( 0 <= ID < \a newNb ).
5493 DataArrayInt *DataArrayInt::MakePartition(const std::vector<const DataArrayInt *>& groups, int newNb, std::vector< std::vector<int> >& fidsOfGroups)
5495 std::vector<const DataArrayInt *> groups2;
5496 for(std::vector<const DataArrayInt *>::const_iterator it4=groups.begin();it4!=groups.end();it4++)
5498 groups2.push_back(*it4);
5499 MCAuto<DataArrayInt> ret=DataArrayInt::New();
5500 ret->alloc(newNb,1);
5501 int *retPtr=ret->getPointer();
5502 std::fill(retPtr,retPtr+newNb,0);
5504 for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++)
5506 const int *ptr=(*iter)->getConstPointer();
5507 std::size_t nbOfElem=(*iter)->getNbOfElems();
5509 for(int j=0;j<sfid;j++)
5512 for(std::size_t i=0;i<nbOfElem;i++)
5514 if(ptr[i]>=0 && ptr[i]<newNb)
5516 if(retPtr[ptr[i]]==j)
5524 std::ostringstream oss; oss << "DataArrayInt::MakePartition : In group \"" << (*iter)->getName() << "\" in tuple #" << i << " value = " << ptr[i] << " ! Should be in [0," << newNb;
5526 throw INTERP_KERNEL::Exception(oss.str().c_str());
5533 fidsOfGroups.clear();
5534 fidsOfGroups.resize(groups2.size());
5536 for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++,grId++)
5539 const int *ptr=(*iter)->getConstPointer();
5540 std::size_t nbOfElem=(*iter)->getNbOfElems();
5541 for(const int *p=ptr;p!=ptr+nbOfElem;p++)
5542 tmp.insert(retPtr[*p]);
5543 fidsOfGroups[grId].insert(fidsOfGroups[grId].end(),tmp.begin(),tmp.end());
5549 * Returns a new DataArrayInt which contains all elements of given one-dimensional
5550 * arrays. The result array does not contain any duplicates and its values
5551 * are sorted in ascending order.
5552 * \param [in] arr - sequence of DataArrayInt's to unite.
5553 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5554 * array using decrRef() as it is no more needed.
5555 * \throw If any \a arr[i] is not allocated.
5556 * \throw If \a arr[i]->getNumberOfComponents() != 1.
5558 DataArrayInt *DataArrayInt::BuildUnion(const std::vector<const DataArrayInt *>& arr)
5560 std::vector<const DataArrayInt *> a;
5561 for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
5564 for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
5566 (*it)->checkAllocated();
5567 if((*it)->getNumberOfComponents()!=1)
5568 throw INTERP_KERNEL::Exception("DataArrayInt::BuildUnion : only single component allowed !");
5572 for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
5574 const int *pt=(*it)->getConstPointer();
5575 int nbOfTuples=(*it)->getNumberOfTuples();
5576 r.insert(pt,pt+nbOfTuples);
5578 DataArrayInt *ret=DataArrayInt::New();
5579 ret->alloc((int)r.size(),1);
5580 std::copy(r.begin(),r.end(),ret->getPointer());
5585 * Returns a new DataArrayInt which contains elements present in each of given one-dimensional
5586 * arrays. The result array does not contain any duplicates and its values
5587 * are sorted in ascending order.
5588 * \param [in] arr - sequence of DataArrayInt's to intersect.
5589 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5590 * array using decrRef() as it is no more needed.
5591 * \throw If any \a arr[i] is not allocated.
5592 * \throw If \a arr[i]->getNumberOfComponents() != 1.
5594 DataArrayInt *DataArrayInt::BuildIntersection(const std::vector<const DataArrayInt *>& arr)
5596 std::vector<const DataArrayInt *> a;
5597 for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
5600 for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
5602 (*it)->checkAllocated();
5603 if((*it)->getNumberOfComponents()!=1)
5604 throw INTERP_KERNEL::Exception("DataArrayInt::BuildIntersection : only single component allowed !");
5608 for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
5610 const int *pt=(*it)->getConstPointer();
5611 int nbOfTuples=(*it)->getNumberOfTuples();
5612 std::set<int> s1(pt,pt+nbOfTuples);
5616 std::set_intersection(r.begin(),r.end(),s1.begin(),s1.end(),inserter(r2,r2.end()));
5622 DataArrayInt *ret(DataArrayInt::New());
5623 ret->alloc((int)r.size(),1);
5624 std::copy(r.begin(),r.end(),ret->getPointer());
5629 namespace MEDCouplingImpl
5634 OpSwitchedOn(int *pt):_pt(pt),_cnt(0) { }
5635 void operator()(const bool& b) { if(b) *_pt++=_cnt; _cnt++; }
5644 OpSwitchedOff(int *pt):_pt(pt),_cnt(0) { }
5645 void operator()(const bool& b) { if(!b) *_pt++=_cnt; _cnt++; }
5654 * This method returns the list of ids in ascending mode so that v[id]==true.
5656 DataArrayInt *DataArrayInt::BuildListOfSwitchedOn(const std::vector<bool>& v)
5658 int sz((int)std::count(v.begin(),v.end(),true));
5659 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
5660 std::for_each(v.begin(),v.end(),MEDCouplingImpl::OpSwitchedOn(ret->getPointer()));
5665 * This method returns the list of ids in ascending mode so that v[id]==false.
5667 DataArrayInt *DataArrayInt::BuildListOfSwitchedOff(const std::vector<bool>& v)
5669 int sz((int)std::count(v.begin(),v.end(),false));
5670 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
5671 std::for_each(v.begin(),v.end(),MEDCouplingImpl::OpSwitchedOff(ret->getPointer()));
5676 * This method allows to put a vector of vector of integer into a more compact data stucture (skyline).
5677 * This method is not available into python because no available optimized data structure available to map std::vector< std::vector<int> >.
5679 * \param [in] v the input data structure to be translate into skyline format.
5680 * \param [out] data the first element of the skyline format. The user is expected to deal with newly allocated array.
5681 * \param [out] dataIndex the second element of the skyline format.
5683 void DataArrayInt::PutIntoToSkylineFrmt(const std::vector< std::vector<int> >& v, DataArrayInt *& data, DataArrayInt *& dataIndex)
5685 int sz((int)v.size());
5686 MCAuto<DataArrayInt> ret0(DataArrayInt::New()),ret1(DataArrayInt::New());
5687 ret1->alloc(sz+1,1);
5688 int *pt(ret1->getPointer()); *pt=0;
5689 for(int i=0;i<sz;i++,pt++)
5690 pt[1]=pt[0]+(int)v[i].size();
5691 ret0->alloc(ret1->back(),1);
5692 pt=ret0->getPointer();
5693 for(int i=0;i<sz;i++)
5694 pt=std::copy(v[i].begin(),v[i].end(),pt);
5695 data=ret0.retn(); dataIndex=ret1.retn();
5699 * Returns a new DataArrayInt which contains a complement of elements of \a this
5700 * one-dimensional array. I.e. the result array contains all elements from the range [0,
5701 * \a nbOfElement) not present in \a this array.
5702 * \param [in] nbOfElement - maximal size of the result array.
5703 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5704 * array using decrRef() as it is no more needed.
5705 * \throw If \a this is not allocated.
5706 * \throw If \a this->getNumberOfComponents() != 1.
5707 * \throw If any element \a x of \a this array violates condition ( 0 <= \a x < \a
5710 DataArrayInt *DataArrayInt::buildComplement(int nbOfElement) const
5713 if(getNumberOfComponents()!=1)
5714 throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : only single component allowed !");
5715 std::vector<bool> tmp(nbOfElement);
5716 const int *pt=getConstPointer();
5717 int nbOfTuples=getNumberOfTuples();
5718 for(const int *w=pt;w!=pt+nbOfTuples;w++)
5719 if(*w>=0 && *w<nbOfElement)
5722 throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : an element is not in valid range : [0,nbOfElement) !");
5723 int nbOfRetVal=(int)std::count(tmp.begin(),tmp.end(),false);
5724 DataArrayInt *ret=DataArrayInt::New();
5725 ret->alloc(nbOfRetVal,1);
5727 int *retPtr=ret->getPointer();
5728 for(int i=0;i<nbOfElement;i++)
5735 * Returns a new DataArrayInt containing elements of \a this one-dimensional missing
5736 * from an \a other one-dimensional array.
5737 * \param [in] other - a DataArrayInt containing elements not to include in the result array.
5738 * \return DataArrayInt * - a new instance of DataArrayInt with one component. The
5739 * caller is to delete this array using decrRef() as it is no more needed.
5740 * \throw If \a other is NULL.
5741 * \throw If \a other is not allocated.
5742 * \throw If \a other->getNumberOfComponents() != 1.
5743 * \throw If \a this is not allocated.
5744 * \throw If \a this->getNumberOfComponents() != 1.
5745 * \sa DataArrayInt::buildSubstractionOptimized()
5747 DataArrayInt *DataArrayInt::buildSubstraction(const DataArrayInt *other) const
5750 throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : DataArrayInt pointer in input is NULL !");
5752 other->checkAllocated();
5753 if(getNumberOfComponents()!=1)
5754 throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed !");
5755 if(other->getNumberOfComponents()!=1)
5756 throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed for other type !");
5757 const int *pt=getConstPointer();
5758 int nbOfTuples=getNumberOfTuples();
5759 std::set<int> s1(pt,pt+nbOfTuples);
5760 pt=other->getConstPointer();
5761 nbOfTuples=other->getNumberOfTuples();
5762 std::set<int> s2(pt,pt+nbOfTuples);
5764 std::set_difference(s1.begin(),s1.end(),s2.begin(),s2.end(),std::back_insert_iterator< std::vector<int> >(r));
5765 DataArrayInt *ret=DataArrayInt::New();
5766 ret->alloc((int)r.size(),1);
5767 std::copy(r.begin(),r.end(),ret->getPointer());
5772 * \a this is expected to have one component and to be sorted ascendingly (as for \a other).
5773 * \a other is expected to be a part of \a this. If not DataArrayInt::buildSubstraction should be called instead.
5775 * \param [in] other an array with one component and expected to be sorted ascendingly.
5776 * \ret list of ids in \a this but not in \a other.
5777 * \sa DataArrayInt::buildSubstraction
5779 DataArrayInt *DataArrayInt::buildSubstractionOptimized(const DataArrayInt *other) const
5781 static const char *MSG="DataArrayInt::buildSubstractionOptimized : only single component allowed !";
5782 if(!other) throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstractionOptimized : NULL input array !");
5783 checkAllocated(); other->checkAllocated();
5784 if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
5785 if(other->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
5786 const int *pt1Bg(begin()),*pt1End(end()),*pt2Bg(other->begin()),*pt2End(other->end());
5787 const int *work1(pt1Bg),*work2(pt2Bg);
5788 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
5789 for(;work1!=pt1End;work1++)
5791 if(work2!=pt2End && *work1==*work2)
5794 ret->pushBackSilent(*work1);
5801 * Returns a new DataArrayInt which contains all elements of \a this and a given
5802 * one-dimensional arrays. The result array does not contain any duplicates
5803 * and its values are sorted in ascending order.
5804 * \param [in] other - an array to unite with \a this one.
5805 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5806 * array using decrRef() as it is no more needed.
5807 * \throw If \a this or \a other is not allocated.
5808 * \throw If \a this->getNumberOfComponents() != 1.
5809 * \throw If \a other->getNumberOfComponents() != 1.
5811 DataArrayInt *DataArrayInt::buildUnion(const DataArrayInt *other) const
5813 std::vector<const DataArrayInt *>arrs(2);
5814 arrs[0]=this; arrs[1]=other;
5815 return BuildUnion(arrs);
5820 * Returns a new DataArrayInt which contains elements present in both \a this and a given
5821 * one-dimensional arrays. The result array does not contain any duplicates
5822 * and its values are sorted in ascending order.
5823 * \param [in] other - an array to intersect with \a this one.
5824 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5825 * array using decrRef() as it is no more needed.
5826 * \throw If \a this or \a other is not allocated.
5827 * \throw If \a this->getNumberOfComponents() != 1.
5828 * \throw If \a other->getNumberOfComponents() != 1.
5830 DataArrayInt *DataArrayInt::buildIntersection(const DataArrayInt *other) const
5832 std::vector<const DataArrayInt *>arrs(2);
5833 arrs[0]=this; arrs[1]=other;
5834 return BuildIntersection(arrs);
5838 * This method can be applied on allocated with one component DataArrayInt instance.
5839 * This method is typically relevant for sorted arrays. All consecutive duplicated items in \a this will appear only once in returned DataArrayInt instance.
5840 * 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]
5842 * \return a newly allocated array that contain the result of the unique operation applied on \a this.
5843 * \throw if \a this is not allocated or if \a this has not exactly one component.
5844 * \sa DataArrayInt::buildUniqueNotSorted
5846 DataArrayInt *DataArrayInt::buildUnique() const
5849 if(getNumberOfComponents()!=1)
5850 throw INTERP_KERNEL::Exception("DataArrayInt::buildUnique : only single component allowed !");
5851 int nbOfTuples=getNumberOfTuples();
5852 MCAuto<DataArrayInt> tmp=deepCopy();
5853 int *data=tmp->getPointer();
5854 int *last=std::unique(data,data+nbOfTuples);
5855 MCAuto<DataArrayInt> ret=DataArrayInt::New();
5856 ret->alloc(std::distance(data,last),1);
5857 std::copy(data,last,ret->getPointer());
5862 * This method can be applied on allocated with one component DataArrayInt instance.
5863 * This method keep elements only once by keeping the same order in \a this that is not expected to be sorted.
5865 * \return a newly allocated array that contain the result of the unique operation applied on \a this.
5867 * \throw if \a this is not allocated or if \a this has not exactly one component.
5869 * \sa DataArrayInt::buildUnique
5871 DataArrayInt *DataArrayInt::buildUniqueNotSorted() const
5874 if(getNumberOfComponents()!=1)
5875 throw INTERP_KERNEL::Exception("DataArrayInt::buildUniqueNotSorted : only single component allowed !");
5877 getMinMaxValues(minVal,maxVal);
5878 std::vector<bool> b(maxVal-minVal+1,false);
5879 const int *ptBg(begin()),*endBg(end());
5880 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
5881 for(const int *pt=ptBg;pt!=endBg;pt++)
5885 ret->pushBackSilent(*pt);
5889 ret->copyStringInfoFrom(*this);
5894 * Returns a new DataArrayInt which contains size of every of groups described by \a this
5895 * "index" array. Such "index" array is returned for example by
5896 * \ref MEDCoupling::MEDCouplingUMesh::buildDescendingConnectivity
5897 * "MEDCouplingUMesh::buildDescendingConnectivity" and
5898 * \ref MEDCoupling::MEDCouplingUMesh::getNodalConnectivityIndex
5899 * "MEDCouplingUMesh::getNodalConnectivityIndex" etc.
5900 * This method preforms the reverse operation of DataArrayInt::computeOffsetsFull.
5901 * \return DataArrayInt * - a new instance of DataArrayInt, whose number of tuples
5902 * equals to \a this->getNumberOfComponents() - 1, and number of components is 1.
5903 * The caller is to delete this array using decrRef() as it is no more needed.
5904 * \throw If \a this is not allocated.
5905 * \throw If \a this->getNumberOfComponents() != 1.
5906 * \throw If \a this->getNumberOfTuples() < 2.
5909 * - this contains [1,3,6,7,7,9,15]
5910 * - result array contains [2,3,1,0,2,6],
5911 * where 2 = 3 - 1, 3 = 6 - 3, 1 = 7 - 6 etc.
5913 * \sa DataArrayInt::computeOffsetsFull
5915 DataArrayInt *DataArrayInt::deltaShiftIndex() const
5918 if(getNumberOfComponents()!=1)
5919 throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : only single component allowed !");
5920 int nbOfTuples=getNumberOfTuples();
5922 throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : 1 tuple at least must be present in 'this' !");
5923 const int *ptr=getConstPointer();
5924 DataArrayInt *ret=DataArrayInt::New();
5925 ret->alloc(nbOfTuples-1,1);
5926 int *out=ret->getPointer();
5927 std::transform(ptr+1,ptr+nbOfTuples,ptr,out,std::minus<int>());
5932 * Modifies \a this one-dimensional array so that value of each element \a x
5933 * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
5934 * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number of tuples
5935 * and components remains the same.<br>
5936 * This method is useful for allToAllV in MPI with contiguous policy. This method
5937 * differs from computeOffsetsFull() in that the number of tuples is \b not changed by
5939 * \throw If \a this is not allocated.
5940 * \throw If \a this->getNumberOfComponents() != 1.
5943 * - Before \a this contains [3,5,1,2,0,8]
5944 * - After \a this contains [0,3,8,9,11,11]<br>
5945 * Note that the last element 19 = 11 + 8 is missing because size of \a this
5946 * array is retained and thus there is no space to store the last element.
5948 void DataArrayInt::computeOffsets()
5951 if(getNumberOfComponents()!=1)
5952 throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets : only single component allowed !");
5953 int nbOfTuples=getNumberOfTuples();
5956 int *work=getPointer();
5959 for(int i=1;i<nbOfTuples;i++)
5962 work[i]=work[i-1]+tmp;
5970 * Modifies \a this one-dimensional array so that value of each element \a x
5971 * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
5972 * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number
5973 * components remains the same and number of tuples is inceamented by one.<br>
5974 * This method is useful for allToAllV in MPI with contiguous policy. This method
5975 * differs from computeOffsets() in that the number of tuples is changed by this one.
5976 * This method preforms the reverse operation of DataArrayInt::deltaShiftIndex.
5977 * \throw If \a this is not allocated.
5978 * \throw If \a this->getNumberOfComponents() != 1.
5981 * - Before \a this contains [3,5,1,2,0,8]
5982 * - After \a this contains [0,3,8,9,11,11,19]<br>
5983 * \sa DataArrayInt::deltaShiftIndex
5985 void DataArrayInt::computeOffsetsFull()
5988 if(getNumberOfComponents()!=1)
5989 throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsetsFull : only single component allowed !");
5990 int nbOfTuples=getNumberOfTuples();
5991 int *ret=(int *)malloc((nbOfTuples+1)*sizeof(int));
5992 const int *work=getConstPointer();
5994 for(int i=0;i<nbOfTuples;i++)
5995 ret[i+1]=work[i]+ret[i];
5996 useArray(ret,true,C_DEALLOC,nbOfTuples+1,1);
6001 * Returns two new DataArrayInt instances whose contents is computed from that of \a this and \a listOfIds arrays as follows.
6002 * \a this is expected to be an offset format ( as returned by DataArrayInt::computeOffsetsFull ) that is to say with one component
6003 * and ** sorted strictly increasingly **. \a listOfIds is expected to be sorted ascendingly (not strictly needed for \a listOfIds).
6004 * This methods searches in \a this, considered as a set of contiguous \c this->getNumberOfComponents() ranges, all ids in \a listOfIds
6005 * filling completely one of the ranges in \a this.
6007 * \param [in] listOfIds a list of ids that has to be sorted ascendingly.
6008 * \param [out] rangeIdsFetched the range ids fetched
6009 * \param [out] idsInInputListThatFetch contains the list of ids in \a listOfIds that are \b fully included in a range in \a this. So
6010 * \a idsInInputListThatFetch is a part of input \a listOfIds.
6012 * \sa DataArrayInt::computeOffsetsFull
6015 * - \a this : [0,3,7,9,15,18]
6016 * - \a listOfIds contains [0,1,2,3,7,8,15,16,17]
6017 * - \a rangeIdsFetched result array: [0,2,4]
6018 * - \a idsInInputListThatFetch result array: [0,1,2,7,8,15,16,17]
6019 * In this example id 3 in input \a listOfIds is alone so it do not appear in output \a idsInInputListThatFetch.
6022 void DataArrayInt::findIdsRangesInListOfIds(const DataArrayInt *listOfIds, DataArrayInt *& rangeIdsFetched, DataArrayInt *& idsInInputListThatFetch) const
6025 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : input list of ids is null !");
6026 listOfIds->checkAllocated(); checkAllocated();
6027 if(listOfIds->getNumberOfComponents()!=1)
6028 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : input list of ids must have exactly one component !");
6029 if(getNumberOfComponents()!=1)
6030 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : this must have exactly one component !");
6031 MCAuto<DataArrayInt> ret0=DataArrayInt::New(); ret0->alloc(0,1);
6032 MCAuto<DataArrayInt> ret1=DataArrayInt::New(); ret1->alloc(0,1);
6033 const int *tupEnd(listOfIds->end()),*offBg(begin()),*offEnd(end()-1);
6034 const int *tupPtr(listOfIds->begin()),*offPtr(offBg);
6035 while(tupPtr!=tupEnd && offPtr!=offEnd)
6037 if(*tupPtr==*offPtr)
6040 while(i<offPtr[1] && *tupPtr==i && tupPtr!=tupEnd) { i++; tupPtr++; }
6043 ret0->pushBackSilent((int)std::distance(offBg,offPtr));
6044 ret1->pushBackValsSilent(tupPtr-(offPtr[1]-offPtr[0]),tupPtr);
6049 { if(*tupPtr<*offPtr) tupPtr++; else offPtr++; }
6051 rangeIdsFetched=ret0.retn();
6052 idsInInputListThatFetch=ret1.retn();
6056 * Returns a new DataArrayInt whose contents is computed from that of \a this and \a
6057 * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
6058 * "index" array of a "iota" array, thus, whose each element gives an index of a group
6059 * beginning within the "iota" array. And \a this is a one-dimensional array
6060 * considered as a selector of groups described by \a offsets to include into the result array.
6061 * \throw If \a offsets is NULL.
6062 * \throw If \a offsets is not allocated.
6063 * \throw If \a offsets->getNumberOfComponents() != 1.
6064 * \throw If \a offsets is not monotonically increasing.
6065 * \throw If \a this is not allocated.
6066 * \throw If \a this->getNumberOfComponents() != 1.
6067 * \throw If any element of \a this is not a valid index for \a offsets array.
6070 * - \a this: [0,2,3]
6071 * - \a offsets: [0,3,6,10,14,20]
6072 * - result array: [0,1,2,6,7,8,9,10,11,12,13] == <br>
6073 * \c range(0,3) + \c range(6,10) + \c range(10,14) ==<br>
6074 * \c range( \a offsets[ \a this[0] ], offsets[ \a this[0]+1 ]) +
6075 * \c range( \a offsets[ \a this[1] ], offsets[ \a this[1]+1 ]) +
6076 * \c range( \a offsets[ \a this[2] ], offsets[ \a this[2]+1 ])
6078 DataArrayInt *DataArrayInt::buildExplicitArrByRanges(const DataArrayInt *offsets) const
6081 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : DataArrayInt pointer in input is NULL !");
6083 if(getNumberOfComponents()!=1)
6084 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : only single component allowed !");
6085 offsets->checkAllocated();
6086 if(offsets->getNumberOfComponents()!=1)
6087 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : input array should have only single component !");
6088 int othNbTuples=offsets->getNumberOfTuples()-1;
6089 int nbOfTuples=getNumberOfTuples();
6090 int retNbOftuples=0;
6091 const int *work=getConstPointer();
6092 const int *offPtr=offsets->getConstPointer();
6093 for(int i=0;i<nbOfTuples;i++)
6096 if(val>=0 && val<othNbTuples)
6098 int delta=offPtr[val+1]-offPtr[val];
6100 retNbOftuples+=delta;
6103 std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << val << " of offset array has a delta < 0 !";
6104 throw INTERP_KERNEL::Exception(oss.str().c_str());
6109 std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << i << " in this contains " << val;
6110 oss << " whereas offsets array is of size " << othNbTuples+1 << " !";
6111 throw INTERP_KERNEL::Exception(oss.str().c_str());
6114 MCAuto<DataArrayInt> ret=DataArrayInt::New();
6115 ret->alloc(retNbOftuples,1);
6116 int *retPtr=ret->getPointer();
6117 for(int i=0;i<nbOfTuples;i++)
6120 int start=offPtr[val];
6121 int off=offPtr[val+1]-start;
6122 for(int j=0;j<off;j++,retPtr++)
6129 * Returns a new DataArrayInt whose contents is computed using \a this that must be a
6130 * scaled array (monotonically increasing).
6131 from that of \a this and \a
6132 * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
6133 * "index" array of a "iota" array, thus, whose each element gives an index of a group
6134 * beginning within the "iota" array. And \a this is a one-dimensional array
6135 * considered as a selector of groups described by \a offsets to include into the result array.
6136 * \throw If \a is NULL.
6137 * \throw If \a this is not allocated.
6138 * \throw If \a this->getNumberOfComponents() != 1.
6139 * \throw If \a this->getNumberOfTuples() == 0.
6140 * \throw If \a this is not monotonically increasing.
6141 * \throw If any element of ids in ( \a bg \a stop \a step ) points outside the scale in \a this.
6144 * - \a bg , \a stop and \a step : (0,5,2)
6145 * - \a this: [0,3,6,10,14,20]
6146 * - result array: [0,0,0, 2,2,2,2, 4,4,4,4,4,4] == <br>
6148 DataArrayInt *DataArrayInt::buildExplicitArrOfSliceOnScaledArr(int bg, int stop, int step) const
6151 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : not allocated array !");
6152 if(getNumberOfComponents()!=1)
6153 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of components is expected to be equal to one !");
6154 int nbOfTuples(getNumberOfTuples());
6156 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of tuples must be != 0 !");
6157 const int *ids(begin());
6158 int nbOfEltsInSlc(GetNumberOfItemGivenBESRelative(bg,stop,step,"DataArrayInt::buildExplicitArrOfSliceOnScaledArr")),sz(0),pos(bg);
6159 for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
6161 if(pos>=0 && pos<nbOfTuples-1)
6163 int delta(ids[pos+1]-ids[pos]);
6167 std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " and at this pos this is not monotonically increasing !";
6168 throw INTERP_KERNEL::Exception(oss.str().c_str());
6173 std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " should be in [0," << nbOfTuples-1 << ") !";
6174 throw INTERP_KERNEL::Exception(oss.str().c_str());
6177 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
6178 int *retPtr(ret->getPointer());
6180 for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
6182 int delta(ids[pos+1]-ids[pos]);
6183 for(int j=0;j<delta;j++,retPtr++)
6190 * 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.
6191 * 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
6192 * in tuple **i** of returned DataArrayInt.
6193 * If ranges overlapped (in theory it should not) this method do not detect it and always returns the first range.
6195 * 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)]
6196 * The return DataArrayInt will contain : **[0,4,1,2,2,3]**
6198 * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
6199 * for lower value included and 2nd component is the upper value of corresponding range **excluded**.
6200 * \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
6201 * is thrown if no ranges in \a ranges contains value in \a this.
6203 * \sa DataArrayInt::findIdInRangeForEachTuple
6205 DataArrayInt *DataArrayInt::findRangeIdForEachTuple(const DataArrayInt *ranges) const
6208 throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : null input pointer !");
6209 if(ranges->getNumberOfComponents()!=2)
6210 throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : input DataArrayInt instance should have 2 components !");
6212 if(getNumberOfComponents()!=1)
6213 throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : this should have only one component !");
6214 int nbTuples=getNumberOfTuples();
6215 MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
6216 int nbOfRanges=ranges->getNumberOfTuples();
6217 const int *rangesPtr=ranges->getConstPointer();
6218 int *retPtr=ret->getPointer();
6219 const int *inPtr=getConstPointer();
6220 for(int i=0;i<nbTuples;i++,retPtr++)
6224 for(int j=0;j<nbOfRanges && !found;j++)
6225 if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
6226 { *retPtr=j; found=true; }
6231 std::ostringstream oss; oss << "DataArrayInt::findRangeIdForEachTuple : tuple #" << i << " not found by any ranges !";
6232 throw INTERP_KERNEL::Exception(oss.str().c_str());
6239 * 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.
6240 * 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
6241 * in tuple **i** of returned DataArrayInt.
6242 * If ranges overlapped (in theory it should not) this method do not detect it and always returns the sub position of the first range.
6244 * 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)]
6245 * The return DataArrayInt will contain : **[1,2,4,0,2,2]**
6246 * This method is often called in pair with DataArrayInt::findRangeIdForEachTuple method.
6248 * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
6249 * for lower value included and 2nd component is the upper value of corresponding range **excluded**.
6250 * \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
6251 * is thrown if no ranges in \a ranges contains value in \a this.
6252 * \sa DataArrayInt::findRangeIdForEachTuple
6254 DataArrayInt *DataArrayInt::findIdInRangeForEachTuple(const DataArrayInt *ranges) const
6257 throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : null input pointer !");
6258 if(ranges->getNumberOfComponents()!=2)
6259 throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : input DataArrayInt instance should have 2 components !");
6261 if(getNumberOfComponents()!=1)
6262 throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : this should have only one component !");
6263 int nbTuples=getNumberOfTuples();
6264 MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
6265 int nbOfRanges=ranges->getNumberOfTuples();
6266 const int *rangesPtr=ranges->getConstPointer();
6267 int *retPtr=ret->getPointer();
6268 const int *inPtr=getConstPointer();
6269 for(int i=0;i<nbTuples;i++,retPtr++)
6273 for(int j=0;j<nbOfRanges && !found;j++)
6274 if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
6275 { *retPtr=val-rangesPtr[2*j]; found=true; }
6280 std::ostringstream oss; oss << "DataArrayInt::findIdInRangeForEachTuple : tuple #" << i << " not found by any ranges !";
6281 throw INTERP_KERNEL::Exception(oss.str().c_str());
6288 * \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).
6289 * 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).
6290 * 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 !
6291 * If this method has correctly worked, \a this will be able to be considered as a linked list.
6292 * This method does nothing if number of tuples is lower of equal to 1.
6294 * This method is useful for users having an unstructured mesh having only SEG2 to rearrange internaly the connectibity without any coordinates consideration.
6296 * \sa MEDCouplingUMesh::orderConsecutiveCells1D, DataArrayInt::fromLinkedListOfPairToList
6298 void DataArrayInt::sortEachPairToMakeALinkedList()
6301 if(getNumberOfComponents()!=2)
6302 throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : Only works on DataArrayInt instance with nb of components equal to 2 !");
6303 int nbOfTuples(getNumberOfTuples());
6306 int *conn(getPointer());
6307 for(int i=1;i<nbOfTuples;i++,conn+=2)
6311 if(conn[2]==conn[3])
6313 std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " presence of a pair filled with same ids !";
6314 throw INTERP_KERNEL::Exception(oss.str().c_str());
6316 if(conn[2]!=conn[1] && conn[3]==conn[1] && conn[2]!=conn[0])
6317 std::swap(conn[2],conn[3]);
6318 //not(conn[2]==conn[1] && conn[3]!=conn[1] && conn[3]!=conn[0])
6319 if(conn[2]!=conn[1] || conn[3]==conn[1] || conn[3]==conn[0])
6321 std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " something is invalid !";
6322 throw INTERP_KERNEL::Exception(oss.str().c_str());
6327 if(conn[0]==conn[1] || conn[2]==conn[3])
6328 throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : In the 2 first tuples presence of a pair filled with same ids !");
6331 s.insert(conn,conn+4);
6333 throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : This can't be considered as a linked list regarding 2 first tuples !");
6334 if(std::count(conn,conn+4,conn[0])==2)
6339 if(conn[2]==conn[0])
6343 std::copy(tmp,tmp+4,conn);
6346 {//here we are sure to have (std::count(conn,conn+4,conn[1])==2)
6347 if(conn[1]==conn[3])
6348 std::swap(conn[2],conn[3]);
6355 * \a this is expected to be a correctly linked list of pairs.
6357 * \sa DataArrayInt::sortEachPairToMakeALinkedList
6359 MCAuto<DataArrayInt> DataArrayInt::fromLinkedListOfPairToList() const
6362 checkNbOfComps(2,"DataArrayInt::fromLinkedListOfPairToList : this is expected to have 2 components");
6363 int nbTuples(getNumberOfTuples());
6365 throw INTERP_KERNEL::Exception("DataArrayInt::fromLinkedListOfPairToList : no tuples in this ! Not a linked list !");
6366 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbTuples+1,1);
6367 const int *thisPtr(begin());
6368 int *retPtr(ret->getPointer());
6369 retPtr[0]=thisPtr[0];
6370 for(int i=0;i<nbTuples;i++)
6372 retPtr[i+1]=thisPtr[2*i+1];
6374 if(thisPtr[2*i+1]!=thisPtr[2*(i+1)+0])
6376 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 ?";
6377 throw INTERP_KERNEL::Exception(oss.str());
6384 * This method returns all different values found in \a this. This method throws if \a this has not been allocated.
6385 * But the number of components can be different from one.
6386 * \return a newly allocated array (that should be dealt by the caller) containing different values in \a this.
6388 DataArrayInt *DataArrayInt::getDifferentValues() const
6392 ret.insert(begin(),end());
6393 MCAuto<DataArrayInt> ret2=DataArrayInt::New(); ret2->alloc((int)ret.size(),1);
6394 std::copy(ret.begin(),ret.end(),ret2->getPointer());
6399 * This method is a refinement of DataArrayInt::getDifferentValues because it returns not only different values in \a this but also, for each of
6400 * them it tells which tuple id have this id.
6401 * This method works only on arrays with one component (if it is not the case call DataArrayInt::rearrange(1) ).
6402 * This method returns two arrays having same size.
6403 * 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.
6404 * 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]]
6406 std::vector<DataArrayInt *> DataArrayInt::partitionByDifferentValues(std::vector<int>& differentIds) const
6409 if(getNumberOfComponents()!=1)
6410 throw INTERP_KERNEL::Exception("DataArrayInt::partitionByDifferentValues : this should have only one component !");
6412 std::map<int,int> m,m2,m3;
6413 for(const int *w=begin();w!=end();w++)
6415 differentIds.resize(m.size());
6416 std::vector<DataArrayInt *> ret(m.size());
6417 std::vector<int *> retPtr(m.size());
6418 for(std::map<int,int>::const_iterator it=m.begin();it!=m.end();it++,id++)
6421 ret[id]=DataArrayInt::New();
6422 ret[id]->alloc((*it).second,1);
6423 retPtr[id]=ret[id]->getPointer();
6424 differentIds[id]=(*it).first;
6427 for(const int *w=begin();w!=end();w++,id++)
6429 retPtr[m2[*w]][m3[*w]++]=id;
6435 * This method split ids in [0, \c this->getNumberOfTuples() ) using \a this array as a field of weight (>=0 each).
6436 * The aim of this method is to return a set of \a nbOfSlices chunk of contiguous ids as balanced as possible.
6438 * \param [in] nbOfSlices - number of slices expected.
6439 * \return - a vector having a size equal to \a nbOfSlices giving the start (included) and the stop (excluded) of each chunks.
6441 * \sa DataArray::GetSlice
6442 * \throw If \a this is not allocated or not with exactly one component.
6443 * \throw If an element in \a this if < 0.
6445 std::vector< std::pair<int,int> > DataArrayInt::splitInBalancedSlices(int nbOfSlices) const
6447 if(!isAllocated() || getNumberOfComponents()!=1)
6448 throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : this array should have number of components equal to one and must be allocated !");
6450 throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : number of slices must be >= 1 !");
6451 int sum(accumulate(0)),nbOfTuples(getNumberOfTuples());
6452 int sumPerSlc(sum/nbOfSlices),pos(0);
6453 const int *w(begin());
6454 std::vector< std::pair<int,int> > ret(nbOfSlices);
6455 for(int i=0;i<nbOfSlices;i++)
6457 std::pair<int,int> p(pos,-1);
6459 while(locSum<sumPerSlc && pos<nbOfTuples) { pos++; locSum+=*w++; }
6463 p.second=nbOfTuples;
6470 * Returns a new DataArrayInt that is a modulus of two given arrays. There are 3
6472 * 1. The arrays have same number of tuples and components. Then each value of
6473 * the result array (_a_) is a division of the corresponding values of \a a1 and
6474 * \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, j ].
6475 * 2. The arrays have same number of tuples and one array, say _a2_, has one
6477 * _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, 0 ].
6478 * 3. The arrays have same number of components and one array, say _a2_, has one
6480 * _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ 0, j ].
6482 * Info on components is copied either from the first array (in the first case) or from
6483 * the array with maximal number of elements (getNbOfElems()).
6484 * \warning No check of division by zero is performed!
6485 * \param [in] a1 - a dividend array.
6486 * \param [in] a2 - a divisor array.
6487 * \return DataArrayInt * - the new instance of DataArrayInt.
6488 * The caller is to delete this result array using decrRef() as it is no more
6490 * \throw If either \a a1 or \a a2 is NULL.
6491 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
6492 * \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
6493 * none of them has number of tuples or components equal to 1.
6495 DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt *a2)
6498 throw INTERP_KERNEL::Exception("DataArrayInt::Modulus : input DataArrayInt instance is NULL !");
6499 int nbOfTuple1=a1->getNumberOfTuples();
6500 int nbOfTuple2=a2->getNumberOfTuples();
6501 int nbOfComp1=a1->getNumberOfComponents();
6502 int nbOfComp2=a2->getNumberOfComponents();
6503 if(nbOfTuple2==nbOfTuple1)
6505 if(nbOfComp1==nbOfComp2)
6507 MCAuto<DataArrayInt> ret=DataArrayInt::New();
6508 ret->alloc(nbOfTuple2,nbOfComp1);
6509 std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::modulus<int>());
6510 ret->copyStringInfoFrom(*a1);
6513 else if(nbOfComp2==1)
6515 MCAuto<DataArrayInt> ret=DataArrayInt::New();
6516 ret->alloc(nbOfTuple1,nbOfComp1);
6517 const int *a2Ptr=a2->getConstPointer();
6518 const int *a1Ptr=a1->getConstPointer();
6519 int *res=ret->getPointer();
6520 for(int i=0;i<nbOfTuple1;i++)
6521 res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::modulus<int>(),a2Ptr[i]));
6522 ret->copyStringInfoFrom(*a1);
6527 a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
6531 else if(nbOfTuple2==1)
6533 a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
6534 MCAuto<DataArrayInt> ret=DataArrayInt::New();
6535 ret->alloc(nbOfTuple1,nbOfComp1);
6536 const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
6537 int *pt=ret->getPointer();
6538 for(int i=0;i<nbOfTuple1;i++)
6539 pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::modulus<int>());
6540 ret->copyStringInfoFrom(*a1);
6545 a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Modulus !");//will always throw an exception
6551 * Modify \a this array so that each value becomes a modulus of division of this value by
6552 * a value of another DataArrayInt. There are 3 valid cases.
6553 * 1. The arrays have same number of tuples and components. Then each value of
6554 * \a this array is divided by the corresponding value of \a other one, i.e.:
6555 * _a_ [ i, j ] %= _other_ [ i, j ].
6556 * 2. The arrays have same number of tuples and \a other array has one component. Then
6557 * _a_ [ i, j ] %= _other_ [ i, 0 ].
6558 * 3. The arrays have same number of components and \a other array has one tuple. Then
6559 * _a_ [ i, j ] %= _a2_ [ 0, j ].
6561 * \warning No check of division by zero is performed!
6562 * \param [in] other - a divisor array.
6563 * \throw If \a other is NULL.
6564 * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
6565 * \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
6566 * \a other has number of both tuples and components not equal to 1.
6568 void DataArrayInt::modulusEqual(const DataArrayInt *other)
6571 throw INTERP_KERNEL::Exception("DataArrayInt::modulusEqual : input DataArrayInt instance is NULL !");
6572 const char *msg="Nb of tuples mismatch for DataArrayInt::modulusEqual !";
6573 checkAllocated(); other->checkAllocated();
6574 int nbOfTuple=getNumberOfTuples();
6575 int nbOfTuple2=other->getNumberOfTuples();
6576 int nbOfComp=getNumberOfComponents();
6577 int nbOfComp2=other->getNumberOfComponents();
6578 if(nbOfTuple==nbOfTuple2)
6580 if(nbOfComp==nbOfComp2)
6582 std::transform(begin(),end(),other->begin(),getPointer(),std::modulus<int>());
6584 else if(nbOfComp2==1)
6586 if(nbOfComp2==nbOfComp)
6588 int *ptr=getPointer();
6589 const int *ptrc=other->getConstPointer();
6590 for(int i=0;i<nbOfTuple;i++)
6591 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::modulus<int>(),*ptrc++));
6594 throw INTERP_KERNEL::Exception(msg);
6597 throw INTERP_KERNEL::Exception(msg);
6599 else if(nbOfTuple2==1)
6601 int *ptr=getPointer();
6602 const int *ptrc=other->getConstPointer();
6603 for(int i=0;i<nbOfTuple;i++)
6604 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::modulus<int>());
6607 throw INTERP_KERNEL::Exception(msg);
6612 * Returns a new DataArrayInt that is the result of pow of two given arrays. There are 3
6615 * \param [in] a1 - an array to pow up.
6616 * \param [in] a2 - another array to sum up.
6617 * \return DataArrayInt * - the new instance of DataArrayInt.
6618 * The caller is to delete this result array using decrRef() as it is no more
6620 * \throw If either \a a1 or \a a2 is NULL.
6621 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
6622 * \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
6623 * \throw If there is a negative value in \a a2.
6625 DataArrayInt *DataArrayInt::Pow(const DataArrayInt *a1, const DataArrayInt *a2)
6628 throw INTERP_KERNEL::Exception("DataArrayInt::Pow : at least one of input instances is null !");
6629 int nbOfTuple=a1->getNumberOfTuples();
6630 int nbOfTuple2=a2->getNumberOfTuples();
6631 int nbOfComp=a1->getNumberOfComponents();
6632 int nbOfComp2=a2->getNumberOfComponents();
6633 if(nbOfTuple!=nbOfTuple2)
6634 throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of tuples mismatches !");
6635 if(nbOfComp!=1 || nbOfComp2!=1)
6636 throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of components of both arrays must be equal to 1 !");
6637 MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuple,1);
6638 const int *ptr1(a1->begin()),*ptr2(a2->begin());
6639 int *ptr=ret->getPointer();
6640 for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
6645 for(int j=0;j<*ptr2;j++)
6651 std::ostringstream oss; oss << "DataArrayInt::Pow : on tuple #" << i << " of a2 value is < 0 (" << *ptr2 << ") !";
6652 throw INTERP_KERNEL::Exception(oss.str().c_str());
6659 * Apply pow on values of another DataArrayInt to values of \a this one.
6661 * \param [in] other - an array to pow to \a this one.
6662 * \throw If \a other is NULL.
6663 * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
6664 * \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
6665 * \throw If there is a negative value in \a other.
6667 void DataArrayInt::powEqual(const DataArrayInt *other)
6670 throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : input instance is null !");
6671 int nbOfTuple=getNumberOfTuples();
6672 int nbOfTuple2=other->getNumberOfTuples();
6673 int nbOfComp=getNumberOfComponents();
6674 int nbOfComp2=other->getNumberOfComponents();
6675 if(nbOfTuple!=nbOfTuple2)
6676 throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of tuples mismatches !");
6677 if(nbOfComp!=1 || nbOfComp2!=1)
6678 throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of components of both arrays must be equal to 1 !");
6679 int *ptr=getPointer();
6680 const int *ptrc=other->begin();
6681 for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
6686 for(int j=0;j<*ptrc;j++)
6692 std::ostringstream oss; oss << "DataArrayInt::powEqual : on tuple #" << i << " of other value is < 0 (" << *ptrc << ") !";
6693 throw INTERP_KERNEL::Exception(oss.str().c_str());
6700 * Returns a C array which is a renumbering map in "Old to New" mode for the input array.
6701 * This map, if applied to \a start array, would make it sorted. For example, if
6702 * \a start array contents are [9,10,0,6,4,11,3,7] then the contents of the result array is
6703 * [5,6,0,3,2,7,1,4].
6704 * \param [in] start - pointer to the first element of the array for which the
6705 * permutation map is computed.
6706 * \param [in] end - pointer specifying the end of the array \a start, so that
6707 * the last value of \a start is \a end[ -1 ].
6708 * \return int * - the result permutation array that the caller is to delete as it is no
6710 * \throw If there are equal values in the input array.
6712 int *DataArrayInt::CheckAndPreparePermutation(const int *start, const int *end)
6714 std::size_t sz=std::distance(start,end);
6715 int *ret=(int *)malloc(sz*sizeof(int));
6716 int *work=new int[sz];
6717 std::copy(start,end,work);
6718 std::sort(work,work+sz);
6719 if(std::unique(work,work+sz)!=work+sz)
6723 throw INTERP_KERNEL::Exception("Some elements are equals in the specified array !");
6725 std::map<int,int> m;
6726 for(int *workPt=work;workPt!=work+sz;workPt++)
6727 m[*workPt]=(int)std::distance(work,workPt);
6729 for(const int *iter=start;iter!=end;iter++,iter2++)
6736 * Returns a new DataArrayInt containing an arithmetic progression
6737 * that is equal to the sequence returned by Python \c range(\a begin,\a end,\a step )
6739 * \param [in] begin - the start value of the result sequence.
6740 * \param [in] end - limiting value, so that every value of the result array is less than
6742 * \param [in] step - specifies the increment or decrement.
6743 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6744 * array using decrRef() as it is no more needed.
6745 * \throw If \a step == 0.
6746 * \throw If \a end < \a begin && \a step > 0.
6747 * \throw If \a end > \a begin && \a step < 0.
6749 DataArrayInt *DataArrayInt::Range(int begin, int end, int step)
6751 int nbOfTuples=GetNumberOfItemGivenBESRelative(begin,end,step,"DataArrayInt::Range");
6752 MCAuto<DataArrayInt> ret=DataArrayInt::New();
6753 ret->alloc(nbOfTuples,1);
6754 int *ptr=ret->getPointer();
6757 for(int i=begin;i<end;i+=step,ptr++)
6762 for(int i=begin;i>end;i+=step,ptr++)
6769 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
6772 void DataArrayInt::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
6777 tinyInfo[0]=getNumberOfTuples();
6778 tinyInfo[1]=getNumberOfComponents();
6788 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
6791 void DataArrayInt::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
6795 int nbOfCompo=getNumberOfComponents();
6796 tinyInfo.resize(nbOfCompo+1);
6797 tinyInfo[0]=getName();
6798 for(int i=0;i<nbOfCompo;i++)
6799 tinyInfo[i+1]=getInfoOnComponent(i);
6804 tinyInfo[0]=getName();
6809 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
6810 * This method returns if a feeding is needed.
6812 bool DataArrayInt::resizeForUnserialization(const std::vector<int>& tinyInfoI)
6814 int nbOfTuple=tinyInfoI[0];
6815 int nbOfComp=tinyInfoI[1];
6816 if(nbOfTuple!=-1 || nbOfComp!=-1)
6818 alloc(nbOfTuple,nbOfComp);
6825 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
6826 * This method returns if a feeding is needed.
6828 void DataArrayInt::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
6830 setName(tinyInfoS[0]);
6833 int nbOfCompo=tinyInfoI[1];
6834 for(int i=0;i<nbOfCompo;i++)
6835 setInfoOnComponent(i,tinyInfoS[i+1]);
6839 DataArrayIntIterator::DataArrayIntIterator(DataArrayInt *da):DataArrayIterator<int>(da)
6843 DataArrayInt32Tuple::DataArrayInt32Tuple(int *pt, int nbOfComp):DataArrayTuple<int>(pt,nbOfComp)
6847 std::string DataArrayIntTuple::repr() const
6849 std::ostringstream oss; oss << "(";
6850 for(int i=0;i<_nb_of_compo-1;i++)
6851 oss << _pt[i] << ", ";
6852 oss << _pt[_nb_of_compo-1] << ")";
6856 int DataArrayIntTuple::intValue() const
6858 return this->zeValue();
6862 * This method returns a newly allocated instance the caller should dealed with by a MEDCoupling::DataArrayInt::decrRef.
6863 * This method performs \b no copy of data. The content is only referenced using MEDCoupling::DataArrayInt::useArray with ownership set to \b false.
6864 * 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
6865 * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
6867 DataArrayInt *DataArrayIntTuple::buildDAInt(int nbOfTuples, int nbOfCompo) const
6869 return this->buildDA(nbOfTuples,nbOfCompo);