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"
28 #include "InterpKernelAutoPtr.hxx"
29 #include "InterpKernelGeo2DEdgeArcCircle.hxx"
30 #include "InterpKernelAutoPtr.hxx"
31 #include "InterpKernelGeo2DNode.hxx"
32 #include "InterpKernelGeo2DEdgeLin.hxx"
41 typedef double (*MYFUNCPTR)(double);
43 using namespace MEDCoupling;
45 template class MEDCoupling::MemArray<int>;
46 template class MEDCoupling::MemArray<double>;
47 template class MEDCoupling::DataArrayTemplate<int>;
48 template class MEDCoupling::DataArrayTemplate<double>;
49 template class MEDCoupling::DataArrayTemplateClassic<int>;
50 template class MEDCoupling::DataArrayTemplateClassic<double>;
51 template class MEDCoupling::DataArrayTemplateFP<double>;
52 template class MEDCoupling::DataArrayIterator<double>;
53 template class MEDCoupling::DataArrayIterator<int>;
54 template class MEDCoupling::DataArrayDiscrete<Int32>;
55 template class MEDCoupling::DataArrayDiscreteSigned<Int32>;
57 template<int SPACEDIM>
58 void DataArrayDouble::findCommonTuplesAlg(const double *bbox, int nbNodes, int limitNodeId, double prec, DataArrayInt *c, DataArrayInt *cI) const
60 const double *coordsPtr=getConstPointer();
61 BBTreePts<SPACEDIM,int> myTree(bbox,0,0,nbNodes,prec);
62 std::vector<bool> isDone(nbNodes);
63 for(int i=0;i<nbNodes;i++)
67 std::vector<int> intersectingElems;
68 myTree.getElementsAroundPoint(coordsPtr+i*SPACEDIM,intersectingElems);
69 if(intersectingElems.size()>1)
71 std::vector<int> commonNodes;
72 for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
76 commonNodes.push_back(*it);
79 if(!commonNodes.empty())
81 cI->pushBackSilent(cI->back()+(int)commonNodes.size()+1);
83 c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
90 template<int SPACEDIM>
91 void DataArrayDouble::FindTupleIdsNearTuplesAlg(const BBTreePts<SPACEDIM,int>& myTree, const double *pos, int nbOfTuples, double eps,
92 DataArrayInt *c, DataArrayInt *cI)
94 for(int i=0;i<nbOfTuples;i++)
96 std::vector<int> intersectingElems;
97 myTree.getElementsAroundPoint(pos+i*SPACEDIM,intersectingElems);
98 std::vector<int> commonNodes;
99 for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
100 commonNodes.push_back(*it);
101 cI->pushBackSilent(cI->back()+(int)commonNodes.size());
102 c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
106 template<int SPACEDIM>
107 void DataArrayDouble::FindClosestTupleIdAlg(const BBTreePts<SPACEDIM,int>& myTree, double dist, const double *pos, int nbOfTuples, const double *thisPt, int thisNbOfTuples, int *res)
109 double distOpt(dist);
110 const double *p(pos);
112 for(int i=0;i<nbOfTuples;i++,p+=SPACEDIM,r++)
117 double ret=myTree.getElementsAroundPoint2(p,distOpt,elem);
118 if(ret!=std::numeric_limits<double>::max())
120 distOpt=std::max(ret,1e-4);
125 { distOpt=2*distOpt; continue; }
130 int DataArray::EffectiveCircPerm(int nbOfShift, int nbOfTuples)
133 throw INTERP_KERNEL::Exception("DataArray::EffectiveCircPerm : number of tuples is expected to be > 0 !");
136 return nbOfShift%nbOfTuples;
142 return nbOfTuples-tmp;
146 std::size_t DataArray::getHeapMemorySizeWithoutChildren() const
148 std::size_t sz1=_name.capacity();
149 std::size_t sz2=_info_on_compo.capacity();
151 for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
152 sz3+=(*it).capacity();
156 std::vector<const BigMemoryObject *> DataArray::getDirectChildrenWithNull() const
158 return std::vector<const BigMemoryObject *>();
162 * Sets the attribute \a _name of \a this array.
163 * See \ref MEDCouplingArrayBasicsName "DataArrays infos" for more information.
164 * \param [in] name - new array name
166 void DataArray::setName(const std::string& name)
172 * Copies textual data from an \a other DataArray. The copied data are
173 * - the name attribute,
174 * - the information of components.
176 * For more information on these data see \ref MEDCouplingArrayBasicsName "DataArrays infos".
178 * \param [in] other - another instance of DataArray to copy the textual data from.
179 * \throw If number of components of \a this array differs from that of the \a other.
181 void DataArray::copyStringInfoFrom(const DataArray& other)
183 if(_info_on_compo.size()!=other._info_on_compo.size())
184 throw INTERP_KERNEL::Exception("Size of arrays mismatches on copyStringInfoFrom !");
186 _info_on_compo=other._info_on_compo;
189 void DataArray::copyPartOfStringInfoFrom(const DataArray& other, const std::vector<int>& compoIds)
191 int nbOfCompoOth=other.getNumberOfComponents();
192 std::size_t newNbOfCompo=compoIds.size();
193 for(std::size_t i=0;i<newNbOfCompo;i++)
194 if(compoIds[i]>=nbOfCompoOth || compoIds[i]<0)
196 std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompoOth << ")";
197 throw INTERP_KERNEL::Exception(oss.str().c_str());
199 for(std::size_t i=0;i<newNbOfCompo;i++)
200 setInfoOnComponent((int)i,other.getInfoOnComponent(compoIds[i]));
203 void DataArray::copyPartOfStringInfoFrom2(const std::vector<int>& compoIds, const DataArray& other)
205 std::size_t nbOfCompo(getNumberOfComponents());
206 std::size_t partOfCompoToSet=compoIds.size();
207 if(partOfCompoToSet!=other.getNumberOfComponents())
208 throw INTERP_KERNEL::Exception("Given compoIds has not the same size as number of components of given array !");
209 for(std::size_t i=0;i<partOfCompoToSet;i++)
210 if(compoIds[i]>=(int)nbOfCompo || compoIds[i]<0)
212 std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompo << ")";
213 throw INTERP_KERNEL::Exception(oss.str().c_str());
215 for(std::size_t i=0;i<partOfCompoToSet;i++)
216 setInfoOnComponent(compoIds[i],other.getInfoOnComponent((int)i));
219 bool DataArray::areInfoEqualsIfNotWhy(const DataArray& other, std::string& reason) const
221 std::ostringstream oss;
222 if(_name!=other._name)
224 oss << "Names DataArray mismatch : this name=\"" << _name << " other name=\"" << other._name << "\" !";
228 if(_info_on_compo!=other._info_on_compo)
230 oss << "Components DataArray mismatch : \nThis components=";
231 for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
232 oss << "\"" << *it << "\",";
233 oss << "\nOther components=";
234 for(std::vector<std::string>::const_iterator it=other._info_on_compo.begin();it!=other._info_on_compo.end();it++)
235 oss << "\"" << *it << "\",";
243 * Compares textual information of \a this DataArray with that of an \a other one.
244 * The compared data are
245 * - the name attribute,
246 * - the information of components.
248 * For more information on these data see \ref MEDCouplingArrayBasicsName "DataArrays infos".
249 * \param [in] other - another instance of DataArray to compare the textual data of.
250 * \return bool - \a true if the textual information is same, \a false else.
252 bool DataArray::areInfoEquals(const DataArray& other) const
255 return areInfoEqualsIfNotWhy(other,tmp);
258 void DataArray::reprWithoutNameStream(std::ostream& stream) const
260 stream << "Number of components : "<< getNumberOfComponents() << "\n";
261 stream << "Info of these components : ";
262 for(std::vector<std::string>::const_iterator iter=_info_on_compo.begin();iter!=_info_on_compo.end();iter++)
263 stream << "\"" << *iter << "\" ";
267 std::string DataArray::cppRepr(const std::string& varName) const
269 std::ostringstream ret;
270 reprCppStream(varName,ret);
275 * Sets information on all components. To know more on format of this information
276 * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
277 * \param [in] info - a vector of strings.
278 * \throw If size of \a info differs from the number of components of \a this.
280 void DataArray::setInfoOnComponents(const std::vector<std::string>& info)
282 if(getNumberOfComponents()!=info.size())
284 std::ostringstream oss; oss << "DataArray::setInfoOnComponents : input is of size " << info.size() << " whereas number of components is equal to " << getNumberOfComponents() << " !";
285 throw INTERP_KERNEL::Exception(oss.str().c_str());
291 * This method is only a dispatcher towards DataArrayDouble::setPartOfValues3, DataArrayInt::setPartOfValues3, DataArrayChar::setPartOfValues3 depending on the true
292 * type of \a this and \a aBase.
294 * \throw If \a aBase and \a this do not have the same type.
296 * \sa DataArrayDouble::setPartOfValues3, DataArrayInt::setPartOfValues3, DataArrayChar::setPartOfValues3.
298 void DataArray::setPartOfValuesBase3(const DataArray *aBase, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
301 throw INTERP_KERNEL::Exception("DataArray::setPartOfValuesBase3 : input aBase object is NULL !");
302 DataArrayDouble *this1(dynamic_cast<DataArrayDouble *>(this));
303 DataArrayInt *this2(dynamic_cast<DataArrayInt *>(this));
304 DataArrayChar *this3(dynamic_cast<DataArrayChar *>(this));
305 const DataArrayDouble *a1(dynamic_cast<const DataArrayDouble *>(aBase));
306 const DataArrayInt *a2(dynamic_cast<const DataArrayInt *>(aBase));
307 const DataArrayChar *a3(dynamic_cast<const DataArrayChar *>(aBase));
310 this1->setPartOfValues3(a1,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
315 this2->setPartOfValues3(a2,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
320 this3->setPartOfValues3(a3,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
323 throw INTERP_KERNEL::Exception("DataArray::setPartOfValuesBase3 : input aBase object and this do not have the same type !");
326 std::vector<std::string> DataArray::getVarsOnComponent() const
328 int nbOfCompo=(int)_info_on_compo.size();
329 std::vector<std::string> ret(nbOfCompo);
330 for(int i=0;i<nbOfCompo;i++)
331 ret[i]=getVarOnComponent(i);
335 std::vector<std::string> DataArray::getUnitsOnComponent() const
337 int nbOfCompo=(int)_info_on_compo.size();
338 std::vector<std::string> ret(nbOfCompo);
339 for(int i=0;i<nbOfCompo;i++)
340 ret[i]=getUnitOnComponent(i);
345 * Returns information on a component specified by an index.
346 * To know more on format of this information
347 * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
348 * \param [in] i - the index (zero based) of the component of interest.
349 * \return std::string - a string containing the information on \a i-th component.
350 * \throw If \a i is not a valid component index.
352 std::string DataArray::getInfoOnComponent(int i) const
354 if(i<(int)_info_on_compo.size() && i>=0)
355 return _info_on_compo[i];
358 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();
359 throw INTERP_KERNEL::Exception(oss.str().c_str());
364 * Returns the var part of the full information of the \a i-th component.
365 * For example, if \c getInfoOnComponent(0) returns "SIGXY [N/m^2]", then
366 * \c getVarOnComponent(0) returns "SIGXY".
367 * If a unit part of information is not detected by presence of
368 * two square brackets, then the full information is returned.
369 * To read more about the component information format, see
370 * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
371 * \param [in] i - the index (zero based) of the component of interest.
372 * \return std::string - a string containing the var information, or the full info.
373 * \throw If \a i is not a valid component index.
375 std::string DataArray::getVarOnComponent(int i) const
377 if(i<(int)_info_on_compo.size() && i>=0)
379 return GetVarNameFromInfo(_info_on_compo[i]);
383 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();
384 throw INTERP_KERNEL::Exception(oss.str().c_str());
389 * Returns the unit part of the full information of the \a i-th component.
390 * For example, if \c getInfoOnComponent(0) returns "SIGXY [ N/m^2]", then
391 * \c getUnitOnComponent(0) returns " N/m^2".
392 * If a unit part of information is not detected by presence of
393 * two square brackets, then an empty string is returned.
394 * To read more about the component information format, see
395 * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
396 * \param [in] i - the index (zero based) of the component of interest.
397 * \return std::string - a string containing the unit information, if any, or "".
398 * \throw If \a i is not a valid component index.
400 std::string DataArray::getUnitOnComponent(int i) const
402 if(i<(int)_info_on_compo.size() && i>=0)
404 return GetUnitFromInfo(_info_on_compo[i]);
408 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();
409 throw INTERP_KERNEL::Exception(oss.str().c_str());
414 * Returns the var part of the full component information.
415 * For example, if \a info == "SIGXY [N/m^2]", then this method returns "SIGXY".
416 * If a unit part of information is not detected by presence of
417 * two square brackets, then the whole \a info is returned.
418 * To read more about the component information format, see
419 * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
420 * \param [in] info - the full component information.
421 * \return std::string - a string containing only var information, or the \a info.
423 std::string DataArray::GetVarNameFromInfo(const std::string& info)
425 std::size_t p1=info.find_last_of('[');
426 std::size_t p2=info.find_last_of(']');
427 if(p1==std::string::npos || p2==std::string::npos)
432 return std::string();
433 std::size_t p3=info.find_last_not_of(' ',p1-1);
434 return info.substr(0,p3+1);
438 * Returns the unit part of the full component information.
439 * For example, if \a info == "SIGXY [ N/m^2]", then this method returns " N/m^2".
440 * If a unit part of information is not detected by presence of
441 * two square brackets, then an empty string is returned.
442 * To read more about the component information format, see
443 * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
444 * \param [in] info - the full component information.
445 * \return std::string - a string containing only unit information, if any, or "".
447 std::string DataArray::GetUnitFromInfo(const std::string& info)
449 std::size_t p1=info.find_last_of('[');
450 std::size_t p2=info.find_last_of(']');
451 if(p1==std::string::npos || p2==std::string::npos)
452 return std::string();
454 return std::string();
455 return info.substr(p1+1,p2-p1-1);
459 * This method put in info format the result of the merge of \a var and \a unit.
460 * The standard format for that is "var [unit]".
461 * Inversely you can retrieve the var part or the unit part of info string using resp. GetVarNameFromInfo and GetUnitFromInfo.
463 std::string DataArray::BuildInfoFromVarAndUnit(const std::string& var, const std::string& unit)
465 std::ostringstream oss;
466 oss << var << " [" << unit << "]";
470 std::string DataArray::GetAxisTypeRepr(MEDCouplingAxisType at)
475 return std::string("AX_CART");
477 return std::string("AX_CYL");
479 return std::string("AX_SPHER");
481 throw INTERP_KERNEL::Exception("DataArray::GetAxisTypeRepr : unrecognized axis type enum !");
486 * Returns a new DataArray by concatenating all given arrays, so that (1) the number
487 * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
488 * the number of component in the result array is same as that of each of given arrays.
489 * Info on components is copied from the first of the given arrays. Number of components
490 * in the given arrays must be the same.
491 * \param [in] arrs - a sequence of arrays to include in the result array. All arrays must have the same type.
492 * \return DataArray * - the new instance of DataArray (that can be either DataArrayInt, DataArrayDouble, DataArrayChar).
493 * The caller is to delete this result array using decrRef() as it is no more
495 * \throw If all arrays within \a arrs are NULL.
496 * \throw If all not null arrays in \a arrs have not the same type.
497 * \throw If getNumberOfComponents() of arrays within \a arrs.
499 DataArray *DataArray::Aggregate(const std::vector<const DataArray *>& arrs)
501 std::vector<const DataArray *> arr2;
502 for(std::vector<const DataArray *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
506 throw INTERP_KERNEL::Exception("DataArray::Aggregate : only null instance in input vector !");
507 std::vector<const DataArrayDouble *> arrd;
508 std::vector<const DataArrayInt *> arri;
509 std::vector<const DataArrayChar *> arrc;
510 for(std::vector<const DataArray *>::const_iterator it=arr2.begin();it!=arr2.end();it++)
512 const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(*it);
514 { arrd.push_back(a); continue; }
515 const DataArrayInt *b=dynamic_cast<const DataArrayInt *>(*it);
517 { arri.push_back(b); continue; }
518 const DataArrayChar *c=dynamic_cast<const DataArrayChar *>(*it);
520 { arrc.push_back(c); continue; }
521 throw INTERP_KERNEL::Exception("DataArray::Aggregate : presence of not null instance in inuput that is not in [DataArrayDouble, DataArrayInt, DataArrayChar] !");
523 if(arr2.size()==arrd.size())
524 return DataArrayDouble::Aggregate(arrd);
525 if(arr2.size()==arri.size())
526 return DataArrayInt::Aggregate(arri);
527 if(arr2.size()==arrc.size())
528 return DataArrayChar::Aggregate(arrc);
529 throw INTERP_KERNEL::Exception("DataArray::Aggregate : all input arrays must have the same type !");
533 * Sets information on a component specified by an index.
534 * To know more on format of this information
535 * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
536 * \warning Don't pass NULL as \a info!
537 * \param [in] i - the index (zero based) of the component of interest.
538 * \param [in] info - the string containing the information.
539 * \throw If \a i is not a valid component index.
541 void DataArray::setInfoOnComponent(int i, const std::string& info)
543 if(i<(int)_info_on_compo.size() && i>=0)
544 _info_on_compo[i]=info;
547 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();
548 throw INTERP_KERNEL::Exception(oss.str().c_str());
553 * Sets information on all components. This method can change number of components
554 * at certain conditions; if the conditions are not respected, an exception is thrown.
555 * The number of components can be changed in \a this only if \a this is not allocated.
556 * The condition of number of components must not be changed.
558 * To know more on format of the component information see
559 * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
560 * \param [in] info - a vector of component infos.
561 * \throw If \a this->getNumberOfComponents() != \a info.size() && \a this->isAllocated()
563 void DataArray::setInfoAndChangeNbOfCompo(const std::vector<std::string>& info)
565 if(getNumberOfComponents()!=info.size())
571 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 !";
572 throw INTERP_KERNEL::Exception(oss.str().c_str());
579 void DataArray::checkNbOfTuples(int nbOfTuples, const std::string& msg) const
581 if((int)getNumberOfTuples()!=nbOfTuples)
583 std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " << nbOfTuples << " having " << getNumberOfTuples() << " !";
584 throw INTERP_KERNEL::Exception(oss.str().c_str());
588 void DataArray::checkNbOfComps(int nbOfCompo, const std::string& msg) const
590 if((int)getNumberOfComponents()!=nbOfCompo)
592 std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << nbOfCompo << " having " << getNumberOfComponents() << " !";
593 throw INTERP_KERNEL::Exception(oss.str().c_str());
597 void DataArray::checkNbOfElems(std::size_t nbOfElems, const std::string& msg) const
599 if(getNbOfElems()!=nbOfElems)
601 std::ostringstream oss; oss << msg << " : mismatch number of elems : Expected " << nbOfElems << " having " << getNbOfElems() << " !";
602 throw INTERP_KERNEL::Exception(oss.str().c_str());
606 void DataArray::checkNbOfTuplesAndComp(const DataArray& other, const std::string& msg) const
608 if(getNumberOfTuples()!=other.getNumberOfTuples())
610 std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " << other.getNumberOfTuples() << " having " << getNumberOfTuples() << " !";
611 throw INTERP_KERNEL::Exception(oss.str().c_str());
613 if(getNumberOfComponents()!=other.getNumberOfComponents())
615 std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << other.getNumberOfComponents() << " having " << getNumberOfComponents() << " !";
616 throw INTERP_KERNEL::Exception(oss.str().c_str());
620 void DataArray::checkNbOfTuplesAndComp(int nbOfTuples, int nbOfCompo, const std::string& msg) const
622 checkNbOfTuples(nbOfTuples,msg);
623 checkNbOfComps(nbOfCompo,msg);
627 * Simply this method checks that \b value is in [0,\b ref).
629 void DataArray::CheckValueInRange(int ref, int value, const std::string& msg)
631 if(value<0 || value>=ref)
633 std::ostringstream oss; oss << "DataArray::CheckValueInRange : " << msg << " ! Expected in range [0," << ref << "[ having " << value << " !";
634 throw INTERP_KERNEL::Exception(oss.str().c_str());
639 * This method checks that [\b start, \b end) is compliant with ref length \b value.
640 * typically start in [0,\b value) and end in [0,\b value). If value==start and start==end, it is supported.
642 void DataArray::CheckValueInRangeEx(int value, int start, int end, const std::string& msg)
644 if(start<0 || start>=value)
646 if(value!=start || end!=start)
648 std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg << " ! Expected start " << start << " of input range, in [0," << value << "[ !";
649 throw INTERP_KERNEL::Exception(oss.str().c_str());
652 if(end<0 || end>value)
654 std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg << " ! Expected end " << end << " of input range, in [0," << value << "] !";
655 throw INTERP_KERNEL::Exception(oss.str().c_str());
659 void DataArray::CheckClosingParInRange(int ref, int value, const std::string& msg)
661 if(value<0 || value>ref)
663 std::ostringstream oss; oss << "DataArray::CheckClosingParInRange : " << msg << " ! Expected input range in [0," << ref << "] having closing open parenthesis " << value << " !";
664 throw INTERP_KERNEL::Exception(oss.str().c_str());
669 * 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,
670 * typically it is a whole slice of tuples of DataArray or cells, nodes of a mesh...
672 * The input \a sliceId should be an id in [0, \a nbOfSlices) that specifies the slice of work.
674 * \param [in] start - the start of the input slice of the whole work to perform split into slices.
675 * \param [in] stop - the stop of the input slice of the whole work to perform split into slices.
676 * \param [in] step - the step (that can be <0) of the input slice of the whole work to perform split into slices.
677 * \param [in] sliceId - the slice id considered
678 * \param [in] nbOfSlices - the number of slices (typically the number of cores on which the work is expected to be sliced)
679 * \param [out] startSlice - the start of the slice considered
680 * \param [out] stopSlice - the stop of the slice consided
682 * \throw If \a step == 0
683 * \throw If \a nbOfSlices not > 0
684 * \throw If \a sliceId not in [0,nbOfSlices)
686 void DataArray::GetSlice(int start, int stop, int step, int sliceId, int nbOfSlices, int& startSlice, int& stopSlice)
690 std::ostringstream oss; oss << "DataArray::GetSlice : nbOfSlices (" << nbOfSlices << ") must be > 0 !";
691 throw INTERP_KERNEL::Exception(oss.str().c_str());
693 if(sliceId<0 || sliceId>=nbOfSlices)
695 std::ostringstream oss; oss << "DataArray::GetSlice : sliceId (" << nbOfSlices << ") must be in [0 , nbOfSlices (" << nbOfSlices << ") ) !";
696 throw INTERP_KERNEL::Exception(oss.str().c_str());
698 int nbElems=GetNumberOfItemGivenBESRelative(start,stop,step,"DataArray::GetSlice");
699 int minNbOfElemsPerSlice=nbElems/nbOfSlices;
700 startSlice=start+minNbOfElemsPerSlice*step*sliceId;
701 if(sliceId<nbOfSlices-1)
702 stopSlice=start+minNbOfElemsPerSlice*step*(sliceId+1);
707 int DataArray::GetNumberOfItemGivenBES(int begin, int end, int step, const std::string& msg)
711 std::ostringstream oss; oss << msg << " : end before begin !";
712 throw INTERP_KERNEL::Exception(oss.str().c_str());
718 std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
719 throw INTERP_KERNEL::Exception(oss.str().c_str());
721 return (end-1-begin)/step+1;
724 int DataArray::GetNumberOfItemGivenBESRelative(int begin, int end, int step, const std::string& msg)
727 throw INTERP_KERNEL::Exception("DataArray::GetNumberOfItemGivenBES : step=0 is not allowed !");
728 if(end<begin && step>0)
730 std::ostringstream oss; oss << msg << " : end before begin whereas step is positive !";
731 throw INTERP_KERNEL::Exception(oss.str().c_str());
733 if(begin<end && step<0)
735 std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
736 throw INTERP_KERNEL::Exception(oss.str().c_str());
739 return (std::max(begin,end)-1-std::min(begin,end))/std::abs(step)+1;
744 int DataArray::GetPosOfItemGivenBESRelativeNoThrow(int value, int begin, int end, int step)
750 if(begin<=value && value<end)
752 if((value-begin)%step==0)
753 return (value-begin)/step;
762 if(begin>=value && value>end)
764 if((begin-value)%(-step)==0)
765 return (begin-value)/(-step);
778 * Returns a new instance of DataArrayDouble. The caller is to delete this array
779 * using decrRef() as it is no more needed.
781 DataArrayDouble *DataArrayDouble::New()
783 return new DataArrayDouble;
787 * Returns the only one value in \a this, if and only if number of elements
788 * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
789 * \return double - the sole value stored in \a this array.
790 * \throw If at least one of conditions stated above is not fulfilled.
792 double DataArrayDouble::doubleValue() const
796 if(getNbOfElems()==1)
798 return *getConstPointer();
801 throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is allocated but number of elements is not equal to 1 !");
804 throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is not allocated !");
808 * Returns a full copy of \a this. For more info on copying data arrays see
809 * \ref MEDCouplingArrayBasicsCopyDeep.
810 * \return DataArrayDouble * - a new instance of DataArrayDouble. The caller is to
811 * delete this array using decrRef() as it is no more needed.
813 DataArrayDouble *DataArrayDouble::deepCopy() const
815 return new DataArrayDouble(*this);
819 * Checks that \a this array is consistently **increasing** or **decreasing** in value,
820 * with at least absolute difference value of |\a eps| at each step.
821 * If not an exception is thrown.
822 * \param [in] increasing - if \a true, the array values should be increasing.
823 * \param [in] eps - minimal absolute difference between the neighbor values at which
824 * the values are considered different.
825 * \throw If sequence of values is not strictly monotonic in agreement with \a
827 * \throw If \a this->getNumberOfComponents() != 1.
828 * \throw If \a this is not allocated.
830 void DataArrayDouble::checkMonotonic(bool increasing, double eps) const
832 if(!isMonotonic(increasing,eps))
835 throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not INCREASING monotonic !");
837 throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not DECREASING monotonic !");
842 * Checks that \a this array is consistently **increasing** or **decreasing** in value,
843 * with at least absolute difference value of |\a eps| at each step.
844 * \param [in] increasing - if \a true, array values should be increasing.
845 * \param [in] eps - minimal absolute difference between the neighbor values at which
846 * the values are considered different.
847 * \return bool - \a true if values change in accordance with \a increasing arg.
848 * \throw If \a this->getNumberOfComponents() != 1.
849 * \throw If \a this is not allocated.
851 bool DataArrayDouble::isMonotonic(bool increasing, double eps) const
854 if(getNumberOfComponents()!=1)
855 throw INTERP_KERNEL::Exception("DataArrayDouble::isMonotonic : only supported with 'this' array with ONE component !");
856 int nbOfElements=getNumberOfTuples();
857 const double *ptr=getConstPointer();
861 double absEps=fabs(eps);
864 for(int i=1;i<nbOfElements;i++)
866 if(ptr[i]<(ref+absEps))
874 for(int i=1;i<nbOfElements;i++)
876 if(ptr[i]>(ref-absEps))
885 * Returns a textual and human readable representation of \a this instance of
886 * DataArrayDouble. This text is shown when a DataArrayDouble is printed in Python.
887 * \return std::string - text describing \a this DataArrayDouble.
889 * \sa reprNotTooLong, reprZip
891 std::string DataArrayDouble::repr() const
893 std::ostringstream ret;
898 std::string DataArrayDouble::reprZip() const
900 std::ostringstream ret;
905 void DataArrayDouble::writeVTK(std::ostream& ofs, int indent, const std::string& nameInFile, DataArrayByte *byteArr) const
907 static const char SPACE[4]={' ',' ',' ',' '};
909 std::string idt(indent,' ');
911 ofs << idt << "<DataArray type=\"Float32\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
913 bool areAllEmpty(true);
914 for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
918 for(std::size_t i=0;i<_info_on_compo.size();i++)
919 ofs << " ComponentName" << i << "=\"" << _info_on_compo[i] << "\"";
923 ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
924 INTERP_KERNEL::AutoPtr<float> tmp(new float[getNbOfElems()]);
926 // to make Visual C++ happy : instead of std::copy(begin(),end(),(float *)tmp);
927 for(const double *src=begin();src!=end();src++,pt++)
929 const char *data(reinterpret_cast<const char *>((float *)tmp));
930 std::size_t sz(getNbOfElems()*sizeof(float));
931 byteArr->insertAtTheEnd(data,data+sz);
932 byteArr->insertAtTheEnd(SPACE,SPACE+4);
936 ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
937 std::copy(begin(),end(),std::ostream_iterator<double>(ofs," "));
939 ofs << std::endl << idt << "</DataArray>\n";
942 void DataArrayDouble::reprCppStream(const std::string& varName, std::ostream& stream) const
944 int nbTuples(getNumberOfTuples()),nbComp(getNumberOfComponents());
945 const double *data(getConstPointer());
946 stream.precision(17);
947 stream << "DataArrayDouble *" << varName << "=DataArrayDouble::New();" << std::endl;
948 if(nbTuples*nbComp>=1)
950 stream << "const double " << varName << "Data[" << nbTuples*nbComp << "]={";
951 std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<double>(stream,","));
952 stream << data[nbTuples*nbComp-1] << "};" << std::endl;
953 stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
956 stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
957 stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
961 * Method that gives a quick overvien of \a this for python.
963 void DataArrayDouble::reprQuickOverview(std::ostream& stream) const
965 static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
966 stream << "DataArrayDouble C++ instance at " << this << ". ";
969 int nbOfCompo=(int)_info_on_compo.size();
972 int nbOfTuples=getNumberOfTuples();
973 stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
974 reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
977 stream << "Number of components : 0.";
980 stream << "*** No data allocated ****";
983 void DataArrayDouble::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
985 const double *data=begin();
986 int nbOfTuples=getNumberOfTuples();
987 int nbOfCompo=(int)_info_on_compo.size();
988 std::ostringstream oss2; oss2 << "[";
990 std::string oss2Str(oss2.str());
991 bool isFinished=true;
992 for(int i=0;i<nbOfTuples && isFinished;i++)
997 for(int j=0;j<nbOfCompo;j++,data++)
1000 if(j!=nbOfCompo-1) oss2 << ", ";
1006 if(i!=nbOfTuples-1) oss2 << ", ";
1007 std::string oss3Str(oss2.str());
1008 if(oss3Str.length()<maxNbOfByteInRepr)
1020 * Equivalent to DataArrayDouble::isEqual except that if false the reason of
1021 * mismatch is given.
1023 * \param [in] other the instance to be compared with \a this
1024 * \param [in] prec the precision to compare numeric data of the arrays.
1025 * \param [out] reason In case of inequality returns the reason.
1026 * \sa DataArrayDouble::isEqual
1028 bool DataArrayDouble::isEqualIfNotWhy(const DataArrayDouble& other, double prec, std::string& reason) const
1030 if(!areInfoEqualsIfNotWhy(other,reason))
1032 return _mem.isEqual(other._mem,prec,reason);
1036 * Checks if \a this and another DataArrayDouble are fully equal. For more info see
1037 * \ref MEDCouplingArrayBasicsCompare.
1038 * \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1039 * \param [in] prec - precision value to compare numeric data of the arrays.
1040 * \return bool - \a true if the two arrays are equal, \a false else.
1042 bool DataArrayDouble::isEqual(const DataArrayDouble& other, double prec) const
1045 return isEqualIfNotWhy(other,prec,tmp);
1049 * Checks if values of \a this and another DataArrayDouble are equal. For more info see
1050 * \ref MEDCouplingArrayBasicsCompare.
1051 * \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1052 * \param [in] prec - precision value to compare numeric data of the arrays.
1053 * \return bool - \a true if the values of two arrays are equal, \a false else.
1055 bool DataArrayDouble::isEqualWithoutConsideringStr(const DataArrayDouble& other, double prec) const
1058 return _mem.isEqual(other._mem,prec,tmp);
1062 * This method checks that all tuples in \a other are in \a this.
1063 * If true, the output param \a tupleIds contains the tuples ids of \a this that correspond to tupes in \a this.
1064 * 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.
1066 * \param [in] other - the array having the same number of components than \a this.
1067 * \param [out] tupleIds - the tuple ids containing the same number of tuples than \a other has.
1068 * \sa DataArrayDouble::findCommonTuples
1070 bool DataArrayDouble::areIncludedInMe(const DataArrayDouble *other, double prec, DataArrayInt *&tupleIds) const
1073 throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : input array is NULL !");
1074 checkAllocated(); other->checkAllocated();
1075 if(getNumberOfComponents()!=other->getNumberOfComponents())
1076 throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : the number of components does not match !");
1077 MCAuto<DataArrayDouble> a=DataArrayDouble::Aggregate(this,other);
1078 DataArrayInt *c=0,*ci=0;
1079 a->findCommonTuples(prec,getNumberOfTuples(),c,ci);
1080 MCAuto<DataArrayInt> cSafe(c),ciSafe(ci);
1081 int newNbOfTuples=-1;
1082 MCAuto<DataArrayInt> ids=DataArrayInt::ConvertIndexArrayToO2N(a->getNumberOfTuples(),c->begin(),ci->begin(),ci->end(),newNbOfTuples);
1083 MCAuto<DataArrayInt> ret1=ids->selectByTupleIdSafeSlice(getNumberOfTuples(),a->getNumberOfTuples(),1);
1084 tupleIds=ret1.retn();
1085 return newNbOfTuples==getNumberOfTuples();
1089 * Searches for tuples coincident within \a prec tolerance. Each tuple is considered
1090 * as coordinates of a point in getNumberOfComponents()-dimensional space. The
1091 * distance separating two points is computed with the infinite norm.
1093 * Indices of coincident tuples are stored in output arrays.
1094 * A pair of arrays (\a comm, \a commIndex) is called "Surjective Format 2".
1096 * This method is typically used by MEDCouplingPointSet::findCommonNodes() and
1097 * MEDCouplingUMesh::mergeNodes().
1098 * \param [in] prec - minimal absolute distance between two tuples (infinite norm) at which they are
1099 * considered not coincident.
1100 * \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
1101 * tuples have id strictly lower than \a limitTupleId then they are not returned.
1102 * \param [out] comm - the array holding ids (== indices) of coincident tuples.
1103 * \a comm->getNumberOfComponents() == 1.
1104 * \a comm->getNumberOfTuples() == \a commIndex->back().
1105 * \param [out] commIndex - the array dividing all indices stored in \a comm into
1106 * groups of (indices of) coincident tuples. Its every value is a tuple
1107 * index where a next group of tuples begins. For example the second
1108 * group of tuples in \a comm is described by following range of indices:
1109 * [ \a commIndex[1], \a commIndex[2] ). \a commIndex->getNumberOfTuples()-1
1110 * gives the number of groups of coincident tuples.
1111 * \throw If \a this is not allocated.
1112 * \throw If the number of components is not in [1,2,3,4].
1114 * \if ENABLE_EXAMPLES
1115 * \ref cpp_mcdataarraydouble_findcommontuples "Here is a C++ example".
1117 * \ref py_mcdataarraydouble_findcommontuples "Here is a Python example".
1119 * \sa DataArrayInt::ConvertIndexArrayToO2N(), DataArrayDouble::areIncludedInMe
1121 void DataArrayDouble::findCommonTuples(double prec, int limitTupleId, DataArrayInt *&comm, DataArrayInt *&commIndex) const
1124 int nbOfCompo=getNumberOfComponents();
1125 if ((nbOfCompo<1) || (nbOfCompo>4)) //test before work
1126 throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : Unexpected spacedim of coords. Must be 1, 2, 3 or 4.");
1128 int nbOfTuples=getNumberOfTuples();
1130 MCAuto<DataArrayInt> c(DataArrayInt::New()),cI(DataArrayInt::New()); c->alloc(0,1); cI->pushBackSilent(0);
1134 findCommonTuplesAlg<4>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1137 findCommonTuplesAlg<3>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1140 findCommonTuplesAlg<2>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1143 findCommonTuplesAlg<1>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1146 throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : nb of components managed are 1,2,3 and 4 ! not implemented for other number of components !");
1149 commIndex=cI.retn();
1153 * This methods returns the minimal distance between the two set of points \a this and \a other.
1154 * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
1155 * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
1157 * \param [out] thisTupleId the tuple id in \a this corresponding to the returned minimal distance
1158 * \param [out] otherTupleId the tuple id in \a other corresponding to the returned minimal distance
1159 * \return the minimal distance between the two set of points \a this and \a other.
1160 * \sa DataArrayDouble::findClosestTupleId
1162 double DataArrayDouble::minimalDistanceTo(const DataArrayDouble *other, int& thisTupleId, int& otherTupleId) const
1164 MCAuto<DataArrayInt> part1=findClosestTupleId(other);
1165 int nbOfCompo(getNumberOfComponents());
1166 int otherNbTuples(other->getNumberOfTuples());
1167 const double *thisPt(begin()),*otherPt(other->begin());
1168 const int *part1Pt(part1->begin());
1169 double ret=std::numeric_limits<double>::max();
1170 for(int i=0;i<otherNbTuples;i++,part1Pt++,otherPt+=nbOfCompo)
1173 for(int j=0;j<nbOfCompo;j++)
1174 tmp+=(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j])*(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j]);
1176 { ret=tmp; thisTupleId=*part1Pt; otherTupleId=i; }
1182 * This methods returns for each tuple in \a other which tuple in \a this is the closest.
1183 * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
1184 * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
1186 * \return a newly allocated (new object to be dealt by the caller) DataArrayInt having \c other->getNumberOfTuples() tuples and one components.
1187 * \sa DataArrayDouble::minimalDistanceTo
1189 DataArrayInt *DataArrayDouble::findClosestTupleId(const DataArrayDouble *other) const
1192 throw INTERP_KERNEL::Exception("DataArrayDouble::findClosestTupleId : other instance is NULL !");
1193 checkAllocated(); other->checkAllocated();
1194 std::size_t nbOfCompo(getNumberOfComponents());
1195 if(nbOfCompo!=other->getNumberOfComponents())
1197 std::ostringstream oss; oss << "DataArrayDouble::findClosestTupleId : number of components in this is " << nbOfCompo;
1198 oss << ", whereas number of components in other is " << other->getNumberOfComponents() << "! Should be equal !";
1199 throw INTERP_KERNEL::Exception(oss.str().c_str());
1201 int nbOfTuples=other->getNumberOfTuples();
1202 int thisNbOfTuples=getNumberOfTuples();
1203 MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuples,1);
1205 getMinMaxPerComponent(bounds);
1210 double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2])),zDelta(fabs(bounds[5]-bounds[4]));
1211 double delta=std::max(xDelta,yDelta); delta=std::max(delta,zDelta);
1212 double characSize=pow((delta*delta*delta)/((double)thisNbOfTuples),1./3.);
1213 BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1214 FindClosestTupleIdAlg<3>(myTree,3.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1219 double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2]));
1220 double delta=std::max(xDelta,yDelta);
1221 double characSize=sqrt(delta/(double)thisNbOfTuples);
1222 BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1223 FindClosestTupleIdAlg<2>(myTree,2.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1228 double characSize=fabs(bounds[1]-bounds[0])/thisNbOfTuples;
1229 BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1230 FindClosestTupleIdAlg<1>(myTree,1.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1234 throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for findClosestTupleId. Must be 1, 2 or 3.");
1240 * This method expects that \a this and \a otherBBoxFrmt arrays are bounding box arrays ( as the output of MEDCouplingPointSet::getBoundingBoxForBBTree method ).
1241 * 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
1242 * how many bounding boxes in \a otherBBoxFrmt.
1243 * So, this method expects that \a this and \a otherBBoxFrmt have the same number of components.
1245 * \param [in] otherBBoxFrmt - It is an array .
1246 * \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.
1247 * \sa MEDCouplingPointSet::getBoundingBoxForBBTree
1248 * \throw If \a this and \a otherBBoxFrmt have not the same number of components.
1249 * \throw If \a this and \a otherBBoxFrmt number of components is not even (BBox format).
1251 DataArrayInt *DataArrayDouble::computeNbOfInteractionsWith(const DataArrayDouble *otherBBoxFrmt, double eps) const
1254 throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : input array is NULL !");
1255 if(!isAllocated() || !otherBBoxFrmt->isAllocated())
1256 throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : this and input array must be allocated !");
1257 std::size_t nbOfComp(getNumberOfComponents()),nbOfTuples(getNumberOfTuples());
1258 if(nbOfComp!=otherBBoxFrmt->getNumberOfComponents())
1260 std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : this number of components (" << nbOfComp << ") must be equal to the number of components of input array (" << otherBBoxFrmt->getNumberOfComponents() << ") !";
1261 throw INTERP_KERNEL::Exception(oss.str().c_str());
1265 std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : Number of components (" << nbOfComp << ") is not even ! It should be to be compatible with bbox format !";
1266 throw INTERP_KERNEL::Exception(oss.str().c_str());
1268 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbOfTuples,1);
1269 const double *thisBBPtr(begin());
1270 int *retPtr(ret->getPointer());
1275 BBTree<3,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
1276 for(std::size_t i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
1277 *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
1282 BBTree<2,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
1283 for(std::size_t i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
1284 *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
1289 BBTree<1,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
1290 for(std::size_t i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
1291 *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
1295 throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : space dimension supported are [1,2,3] !");
1302 * Returns a copy of \a this array by excluding coincident tuples. Each tuple is
1303 * considered as coordinates of a point in getNumberOfComponents()-dimensional
1304 * space. The distance between tuples is computed using norm2. If several tuples are
1305 * not far each from other than \a prec, only one of them remains in the result
1306 * array. The order of tuples in the result array is same as in \a this one except
1307 * that coincident tuples are excluded.
1308 * \param [in] prec - minimal absolute distance between two tuples at which they are
1309 * considered not coincident.
1310 * \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
1311 * tuples have id strictly lower than \a limitTupleId then they are not excluded.
1312 * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1313 * is to delete using decrRef() as it is no more needed.
1314 * \throw If \a this is not allocated.
1315 * \throw If the number of components is not in [1,2,3,4].
1317 * \if ENABLE_EXAMPLES
1318 * \ref py_mcdataarraydouble_getdifferentvalues "Here is a Python example".
1321 DataArrayDouble *DataArrayDouble::getDifferentValues(double prec, int limitTupleId) const
1324 DataArrayInt *c0=0,*cI0=0;
1325 findCommonTuples(prec,limitTupleId,c0,cI0);
1326 MCAuto<DataArrayInt> c(c0),cI(cI0);
1327 int newNbOfTuples=-1;
1328 MCAuto<DataArrayInt> o2n=DataArrayInt::ConvertIndexArrayToO2N(getNumberOfTuples(),c0->begin(),cI0->begin(),cI0->end(),newNbOfTuples);
1329 return renumberAndReduce(o2n->getConstPointer(),newNbOfTuples);
1333 * Copy all components in a specified order from another DataArrayDouble.
1334 * Both numerical and textual data is copied. The number of tuples in \a this and
1335 * the other array can be different.
1336 * \param [in] a - the array to copy data from.
1337 * \param [in] compoIds - sequence of zero based indices of components, data of which is
1339 * \throw If \a a is NULL.
1340 * \throw If \a compoIds.size() != \a a->getNumberOfComponents().
1341 * \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
1343 * \if ENABLE_EXAMPLES
1344 * \ref py_mcdataarraydouble_setselectedcomponents "Here is a Python example".
1347 void DataArrayDouble::setSelectedComponents(const DataArrayDouble *a, const std::vector<int>& compoIds)
1350 throw INTERP_KERNEL::Exception("DataArrayDouble::setSelectedComponents : input DataArrayDouble is NULL !");
1352 copyPartOfStringInfoFrom2(compoIds,*a);
1353 std::size_t partOfCompoSz=compoIds.size();
1354 int nbOfCompo=getNumberOfComponents();
1355 int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
1356 const double *ac=a->getConstPointer();
1357 double *nc=getPointer();
1358 for(int i=0;i<nbOfTuples;i++)
1359 for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
1360 nc[nbOfCompo*i+compoIds[j]]=*ac;
1364 * Checks if 0.0 value is present in \a this array. If it is the case, an exception
1366 * \throw If zero is found in \a this array.
1368 void DataArrayDouble::checkNoNullValues() const
1370 const double *tmp=getConstPointer();
1371 std::size_t nbOfElems=getNbOfElems();
1372 const double *where=std::find(tmp,tmp+nbOfElems,0.);
1373 if(where!=tmp+nbOfElems)
1374 throw INTERP_KERNEL::Exception("A value 0.0 have been detected !");
1378 * Computes minimal and maximal value in each component. An output array is filled
1379 * with \c 2 * \a this->getNumberOfComponents() values, so the caller is to allocate
1380 * enough memory before calling this method.
1381 * \param [out] bounds - array of size at least 2 *\a this->getNumberOfComponents().
1382 * It is filled as follows:<br>
1383 * \a bounds[0] = \c min_of_component_0 <br>
1384 * \a bounds[1] = \c max_of_component_0 <br>
1385 * \a bounds[2] = \c min_of_component_1 <br>
1386 * \a bounds[3] = \c max_of_component_1 <br>
1389 void DataArrayDouble::getMinMaxPerComponent(double *bounds) const
1392 int dim=getNumberOfComponents();
1393 for (int idim=0; idim<dim; idim++)
1395 bounds[idim*2]=std::numeric_limits<double>::max();
1396 bounds[idim*2+1]=-std::numeric_limits<double>::max();
1398 const double *ptr=getConstPointer();
1399 int nbOfTuples=getNumberOfTuples();
1400 for(int i=0;i<nbOfTuples;i++)
1402 for(int idim=0;idim<dim;idim++)
1404 if(bounds[idim*2]>ptr[i*dim+idim])
1406 bounds[idim*2]=ptr[i*dim+idim];
1408 if(bounds[idim*2+1]<ptr[i*dim+idim])
1410 bounds[idim*2+1]=ptr[i*dim+idim];
1417 * This method retrieves a newly allocated DataArrayDouble instance having same number of tuples than \a this and twice number of components than \a this
1418 * to store both the min and max per component of each tuples.
1419 * \param [in] epsilon the width of the bbox (identical in each direction) - 0.0 by default
1421 * \return a newly created DataArrayDouble instance having \c this->getNumberOfTuples() tuples and 2 * \c this->getNumberOfComponent() components
1423 * \throw If \a this is not allocated yet.
1425 DataArrayDouble *DataArrayDouble::computeBBoxPerTuple(double epsilon) const
1428 const double *dataPtr=getConstPointer();
1429 int nbOfCompo=getNumberOfComponents();
1430 int nbTuples=getNumberOfTuples();
1431 MCAuto<DataArrayDouble> bbox=DataArrayDouble::New();
1432 bbox->alloc(nbTuples,2*nbOfCompo);
1433 double *bboxPtr=bbox->getPointer();
1434 for(int i=0;i<nbTuples;i++)
1436 for(int j=0;j<nbOfCompo;j++)
1438 bboxPtr[2*nbOfCompo*i+2*j]=dataPtr[nbOfCompo*i+j]-epsilon;
1439 bboxPtr[2*nbOfCompo*i+2*j+1]=dataPtr[nbOfCompo*i+j]+epsilon;
1446 * For each tuples **t** in \a other, this method retrieves tuples in \a this that are equal to **t**.
1447 * Two tuples are considered equal if the euclidian distance between the two tuples is lower than \a eps.
1449 * \param [in] other a DataArrayDouble having same number of components than \a this.
1450 * \param [in] eps absolute precision representing distance (using infinite norm) between 2 tuples behind which 2 tuples are considered equal.
1451 * \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.
1452 * \a cI allows to extract information in \a c.
1453 * \param [out] cI is an indirection array that allows to extract the data contained in \a c.
1455 * \throw In case of:
1456 * - \a this is not allocated
1457 * - \a other is not allocated or null
1458 * - \a this and \a other do not have the same number of components
1459 * - if number of components of \a this is not in [1,2,3]
1461 * \sa MEDCouplingPointSet::getNodeIdsNearPoints, DataArrayDouble::getDifferentValues
1463 void DataArrayDouble::computeTupleIdsNearTuples(const DataArrayDouble *other, double eps, DataArrayInt *& c, DataArrayInt *& cI) const
1466 throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : input pointer other is null !");
1468 other->checkAllocated();
1469 int nbOfCompo=getNumberOfComponents();
1470 int otherNbOfCompo=other->getNumberOfComponents();
1471 if(nbOfCompo!=otherNbOfCompo)
1472 throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : number of components should be equal between this and other !");
1473 int nbOfTuplesOther=other->getNumberOfTuples();
1474 MCAuto<DataArrayInt> cArr(DataArrayInt::New()),cIArr(DataArrayInt::New()); cArr->alloc(0,1); cIArr->pushBackSilent(0);
1479 BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
1480 FindTupleIdsNearTuplesAlg<3>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
1485 BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
1486 FindTupleIdsNearTuplesAlg<2>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
1491 BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
1492 FindTupleIdsNearTuplesAlg<1>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
1496 throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for computeTupleIdsNearTuples. Must be 1, 2 or 3.");
1498 c=cArr.retn(); cI=cIArr.retn();
1502 * 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
1503 * around origin of 'radius' 1.
1505 * \param [in] eps absolute epsilon. under that value of delta between max and min no scale is performed.
1507 void DataArrayDouble::recenterForMaxPrecision(double eps)
1510 int dim=getNumberOfComponents();
1511 std::vector<double> bounds(2*dim);
1512 getMinMaxPerComponent(&bounds[0]);
1513 for(int i=0;i<dim;i++)
1515 double delta=bounds[2*i+1]-bounds[2*i];
1516 double offset=(bounds[2*i]+bounds[2*i+1])/2.;
1518 applyLin(1./delta,-offset/delta,i);
1520 applyLin(1.,-offset,i);
1525 * Returns the maximal value and all its locations within \a this one-dimensional array.
1526 * \param [out] tupleIds - a new instance of DataArrayInt containing indices of
1527 * tuples holding the maximal value. The caller is to delete it using
1528 * decrRef() as it is no more needed.
1529 * \return double - the maximal value among all values of \a this array.
1530 * \throw If \a this->getNumberOfComponents() != 1
1531 * \throw If \a this->getNumberOfTuples() < 1
1533 double DataArrayDouble::getMaxValue2(DataArrayInt*& tupleIds) const
1537 double ret=getMaxValue(tmp);
1538 tupleIds=findIdsInRange(ret,ret);
1543 * Returns the minimal value and all its locations within \a this one-dimensional array.
1544 * \param [out] tupleIds - a new instance of DataArrayInt containing indices of
1545 * tuples holding the minimal value. The caller is to delete it using
1546 * decrRef() as it is no more needed.
1547 * \return double - the minimal value among all values of \a this array.
1548 * \throw If \a this->getNumberOfComponents() != 1
1549 * \throw If \a this->getNumberOfTuples() < 1
1551 double DataArrayDouble::getMinValue2(DataArrayInt*& tupleIds) const
1555 double ret=getMinValue(tmp);
1556 tupleIds=findIdsInRange(ret,ret);
1561 * 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.
1562 * This method only works for single component array.
1564 * \return a value in [ 0, \c this->getNumberOfTuples() )
1566 * \throw If \a this is not allocated
1569 int DataArrayDouble::count(double value, double eps) const
1573 if(getNumberOfComponents()!=1)
1574 throw INTERP_KERNEL::Exception("DataArrayDouble::count : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
1575 const double *vals=begin();
1576 int nbOfTuples=getNumberOfTuples();
1577 for(int i=0;i<nbOfTuples;i++,vals++)
1578 if(fabs(*vals-value)<=eps)
1584 * Returns the average value of \a this one-dimensional array.
1585 * \return double - the average value over all values of \a this array.
1586 * \throw If \a this->getNumberOfComponents() != 1
1587 * \throw If \a this->getNumberOfTuples() < 1
1589 double DataArrayDouble::getAverageValue() const
1591 if(getNumberOfComponents()!=1)
1592 throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
1593 int nbOfTuples=getNumberOfTuples();
1595 throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : array exists but number of tuples must be > 0 !");
1596 const double *vals=getConstPointer();
1597 double ret=std::accumulate(vals,vals+nbOfTuples,0.);
1598 return ret/nbOfTuples;
1602 * Returns the Euclidean norm of the vector defined by \a this array.
1603 * \return double - the value of the Euclidean norm, i.e.
1604 * the square root of the inner product of vector.
1605 * \throw If \a this is not allocated.
1607 double DataArrayDouble::norm2() const
1611 std::size_t nbOfElems=getNbOfElems();
1612 const double *pt=getConstPointer();
1613 for(std::size_t i=0;i<nbOfElems;i++,pt++)
1619 * Returns the maximum norm of the vector defined by \a this array.
1620 * This method works even if the number of components is different from one.
1621 * If the number of elements in \a this is 0, -1. is returned.
1622 * \return double - the value of the maximum norm, i.e.
1623 * the maximal absolute value among values of \a this array (whatever its number of components).
1624 * \throw If \a this is not allocated.
1626 double DataArrayDouble::normMax() const
1630 std::size_t nbOfElems(getNbOfElems());
1631 const double *pt(getConstPointer());
1632 for(std::size_t i=0;i<nbOfElems;i++,pt++)
1634 double val(std::abs(*pt));
1642 * Returns the minimum norm (absolute value) of the vector defined by \a this array.
1643 * This method works even if the number of components is different from one.
1644 * If the number of elements in \a this is 0, std::numeric_limits<double>::max() is returned.
1645 * \return double - the value of the minimum norm, i.e.
1646 * the minimal absolute value among values of \a this array (whatever its number of components).
1647 * \throw If \a this is not allocated.
1649 double DataArrayDouble::normMin() const
1652 double ret(std::numeric_limits<double>::max());
1653 std::size_t nbOfElems(getNbOfElems());
1654 const double *pt(getConstPointer());
1655 for(std::size_t i=0;i<nbOfElems;i++,pt++)
1657 double val(std::abs(*pt));
1665 * Accumulates values of each component of \a this array.
1666 * \param [out] res - an array of length \a this->getNumberOfComponents(), allocated
1667 * by the caller, that is filled by this method with sum value for each
1669 * \throw If \a this is not allocated.
1671 void DataArrayDouble::accumulate(double *res) const
1674 const double *ptr=getConstPointer();
1675 int nbTuple=getNumberOfTuples();
1676 int nbComps=getNumberOfComponents();
1677 std::fill(res,res+nbComps,0.);
1678 for(int i=0;i<nbTuple;i++)
1679 std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<double>());
1683 * This method returns the min distance from an external tuple defined by [ \a tupleBg , \a tupleEnd ) to \a this and
1684 * the first tuple in \a this that matches the returned distance. If there is no tuples in \a this an exception will be thrown.
1687 * \a this is expected to be allocated and expected to have a number of components equal to the distance from \a tupleBg to
1688 * \a tupleEnd. If not an exception will be thrown.
1690 * \param [in] tupleBg start pointer (included) of input external tuple
1691 * \param [in] tupleEnd end pointer (not included) of input external tuple
1692 * \param [out] tupleId the tuple id in \a this that matches the min of distance between \a this and input external tuple
1693 * \return the min distance.
1694 * \sa MEDCouplingUMesh::distanceToPoint
1696 double DataArrayDouble::distanceToTuple(const double *tupleBg, const double *tupleEnd, int& tupleId) const
1699 int nbTuple=getNumberOfTuples();
1700 int nbComps=getNumberOfComponents();
1701 if(nbComps!=(int)std::distance(tupleBg,tupleEnd))
1702 { 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()); }
1704 throw INTERP_KERNEL::Exception("DataArrayDouble::distanceToTuple : no tuple in this ! No distance to compute !");
1705 double ret0=std::numeric_limits<double>::max();
1707 const double *work=getConstPointer();
1708 for(int i=0;i<nbTuple;i++)
1711 for(int j=0;j<nbComps;j++,work++)
1712 val+=(*work-tupleBg[j])*((*work-tupleBg[j]));
1716 { ret0=val; tupleId=i; }
1722 * Accumulate values of the given component of \a this array.
1723 * \param [in] compId - the index of the component of interest.
1724 * \return double - a sum value of \a compId-th component.
1725 * \throw If \a this is not allocated.
1726 * \throw If \a the condition ( 0 <= \a compId < \a this->getNumberOfComponents() ) is
1729 double DataArrayDouble::accumulate(int compId) const
1732 const double *ptr=getConstPointer();
1733 int nbTuple=getNumberOfTuples();
1734 int nbComps=getNumberOfComponents();
1735 if(compId<0 || compId>=nbComps)
1736 throw INTERP_KERNEL::Exception("DataArrayDouble::accumulate : Invalid compId specified : No such nb of components !");
1738 for(int i=0;i<nbTuple;i++)
1739 ret+=ptr[i*nbComps+compId];
1744 * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
1745 * The returned array will have same number of components than \a this and number of tuples equal to
1746 * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
1748 * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
1749 * 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.
1751 * \param [in] bgOfIndex - begin (included) of the input index array.
1752 * \param [in] endOfIndex - end (excluded) of the input index array.
1753 * \return DataArrayDouble * - the new instance having the same number of components than \a this.
1755 * \throw If bgOfIndex or end is NULL.
1756 * \throw If input index array is not ascendingly sorted.
1757 * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
1758 * \throw If std::distance(bgOfIndex,endOfIndex)==0.
1760 DataArrayDouble *DataArrayDouble::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
1762 if(!bgOfIndex || !endOfIndex)
1763 throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : input pointer NULL !");
1765 int nbCompo=getNumberOfComponents();
1766 int nbOfTuples=getNumberOfTuples();
1767 int sz=(int)std::distance(bgOfIndex,endOfIndex);
1769 throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : invalid size of input index array !");
1771 MCAuto<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(sz,nbCompo);
1772 const int *w=bgOfIndex;
1773 if(*w<0 || *w>=nbOfTuples)
1774 throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
1775 const double *srcPt=begin()+(*w)*nbCompo;
1776 double *tmp=ret->getPointer();
1777 for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
1779 std::fill(tmp,tmp+nbCompo,0.);
1782 for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
1784 if(j>=0 && j<nbOfTuples)
1785 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<double>());
1788 std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
1789 throw INTERP_KERNEL::Exception(oss.str().c_str());
1795 std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
1796 throw INTERP_KERNEL::Exception(oss.str().c_str());
1799 ret->copyStringInfoFrom(*this);
1804 * 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.
1805 * This method expects that \a this as only one component. The returned array will have \a this->getNumberOfTuples()+1 tuple with also one component.
1806 * The ith element of returned array is equal to the sum of elements in \a this with rank strictly lower than i.
1808 * \return DataArrayDouble - A newly built array containing cum sum of \a this.
1810 MCAuto<DataArrayDouble> DataArrayDouble::cumSum() const
1813 checkNbOfComps(1,"DataArrayDouble::cumSum : this is expected to be single component");
1814 int nbOfTuple(getNumberOfTuples());
1815 MCAuto<DataArrayDouble> ret(DataArrayDouble::New()); ret->alloc(nbOfTuple+1,1);
1816 double *ptr(ret->getPointer());
1818 const double *thisPtr(begin());
1819 for(int i=0;i<nbOfTuple;i++)
1820 ptr[i+1]=ptr[i]+thisPtr[i];
1825 * Converts each 2D point defined by the tuple of \a this array from the Polar to the
1826 * Cartesian coordinate system. The two components of the tuple of \a this array are
1827 * considered to contain (1) radius and (2) angle of the point in the Polar CS.
1828 * \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
1829 * contains X and Y coordinates of the point in the Cartesian CS. The caller
1830 * is to delete this array using decrRef() as it is no more needed. The array
1831 * does not contain any textual info on components.
1832 * \throw If \a this->getNumberOfComponents() != 2.
1833 * \sa fromCartToPolar
1835 DataArrayDouble *DataArrayDouble::fromPolarToCart() const
1838 int nbOfComp(getNumberOfComponents());
1840 throw INTERP_KERNEL::Exception("DataArrayDouble::fromPolarToCart : must be an array with exactly 2 components !");
1841 int nbOfTuple(getNumberOfTuples());
1842 DataArrayDouble *ret(DataArrayDouble::New());
1843 ret->alloc(nbOfTuple,2);
1844 double *w(ret->getPointer());
1845 const double *wIn(getConstPointer());
1846 for(int i=0;i<nbOfTuple;i++,w+=2,wIn+=2)
1848 w[0]=wIn[0]*cos(wIn[1]);
1849 w[1]=wIn[0]*sin(wIn[1]);
1855 * Converts each 3D point defined by the tuple of \a this array from the Cylindrical to
1856 * the Cartesian coordinate system. The three components of the tuple of \a this array
1857 * are considered to contain (1) radius, (2) azimuth and (3) altitude of the point in
1858 * the Cylindrical CS.
1859 * \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
1860 * contains X, Y and Z coordinates of the point in the Cartesian CS. The info
1861 * on the third component is copied from \a this array. The caller
1862 * is to delete this array using decrRef() as it is no more needed.
1863 * \throw If \a this->getNumberOfComponents() != 3.
1866 DataArrayDouble *DataArrayDouble::fromCylToCart() const
1869 int nbOfComp(getNumberOfComponents());
1871 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCylToCart : must be an array with exactly 3 components !");
1872 int nbOfTuple(getNumberOfTuples());
1873 DataArrayDouble *ret(DataArrayDouble::New());
1874 ret->alloc(getNumberOfTuples(),3);
1875 double *w(ret->getPointer());
1876 const double *wIn(getConstPointer());
1877 for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
1879 w[0]=wIn[0]*cos(wIn[1]);
1880 w[1]=wIn[0]*sin(wIn[1]);
1883 ret->setInfoOnComponent(2,getInfoOnComponent(2));
1888 * Converts each 3D point defined by the tuple of \a this array from the Spherical to
1889 * the Cartesian coordinate system. The three components of the tuple of \a this array
1890 * are considered to contain (1) radius, (2) polar angle and (3) azimuthal angle of the
1891 * point in the Cylindrical CS.
1892 * \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
1893 * contains X, Y and Z coordinates of the point in the Cartesian CS. The info
1894 * on the third component is copied from \a this array. The caller
1895 * is to delete this array using decrRef() as it is no more needed.
1896 * \throw If \a this->getNumberOfComponents() != 3.
1897 * \sa fromCartToSpher
1899 DataArrayDouble *DataArrayDouble::fromSpherToCart() const
1902 int nbOfComp(getNumberOfComponents());
1904 throw INTERP_KERNEL::Exception("DataArrayDouble::fromSpherToCart : must be an array with exactly 3 components !");
1905 int nbOfTuple(getNumberOfTuples());
1906 DataArrayDouble *ret(DataArrayDouble::New());
1907 ret->alloc(getNumberOfTuples(),3);
1908 double *w(ret->getPointer());
1909 const double *wIn(getConstPointer());
1910 for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
1912 w[0]=wIn[0]*cos(wIn[2])*sin(wIn[1]);
1913 w[1]=wIn[0]*sin(wIn[2])*sin(wIn[1]);
1914 w[2]=wIn[0]*cos(wIn[1]);
1920 * 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.
1921 * 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.
1922 * If \a at equals to AX_CYL the returned array will be the result of operation cylindric to cartesian of \a this...
1924 * \param [in] atOfThis - The axis type of \a this.
1925 * \return DataArrayDouble * - the new instance of DataArrayDouble (that must be dealed by caller) containing the result of the cartesianizification of \a this.
1927 DataArrayDouble *DataArrayDouble::cartesianize(MEDCouplingAxisType atOfThis) const
1930 int nbOfComp(getNumberOfComponents());
1931 MCAuto<DataArrayDouble> ret;
1939 ret=fromCylToCart();
1944 ret=fromPolarToCart();
1948 throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : For AX_CYL, number of components must be in [2,3] !");
1952 ret=fromSpherToCart();
1957 ret=fromPolarToCart();
1961 throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : For AX_CYL, number of components must be in [2,3] !");
1963 throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : not recognized axis type ! Only AX_CART, AX_CYL and AX_SPHER supported !");
1965 ret->copyStringInfoFrom(*this);
1970 * This method returns a newly created array to be deallocated that contains the result of conversion from cartesian to polar.
1971 * This method expects that \a this has exactly 2 components.
1972 * \sa fromPolarToCart
1974 DataArrayDouble *DataArrayDouble::fromCartToPolar() const
1976 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
1978 int nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
1980 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToPolar : must be an array with exactly 2 components !");
1981 ret->alloc(nbTuples,2);
1982 double *retPtr(ret->getPointer());
1983 const double *ptr(begin());
1984 for(int i=0;i<nbTuples;i++,ptr+=2,retPtr+=2)
1986 retPtr[0]=sqrt(ptr[0]*ptr[0]+ptr[1]*ptr[1]);
1987 retPtr[1]=atan2(ptr[1],ptr[0]);
1993 * This method returns a newly created array to be deallocated that contains the result of conversion from cartesian to cylindrical.
1994 * This method expects that \a this has exactly 3 components.
1997 DataArrayDouble *DataArrayDouble::fromCartToCyl() const
1999 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2001 int nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2003 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCyl : must be an array with exactly 3 components !");
2004 ret->alloc(nbTuples,3);
2005 double *retPtr(ret->getPointer());
2006 const double *ptr(begin());
2007 for(int i=0;i<nbTuples;i++,ptr+=3,retPtr+=3)
2009 retPtr[0]=sqrt(ptr[0]*ptr[0]+ptr[1]*ptr[1]);
2010 retPtr[1]=atan2(ptr[1],ptr[0]);
2017 * This method returns a newly created array to be deallocated that contains the result of conversion from cartesian to spherical coordinates.
2018 * \sa fromSpherToCart
2020 DataArrayDouble *DataArrayDouble::fromCartToSpher() const
2022 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2024 int nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2026 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToSpher : must be an array with exactly 3 components !");
2027 ret->alloc(nbTuples,3);
2028 double *retPtr(ret->getPointer());
2029 const double *ptr(begin());
2030 for(int i=0;i<nbTuples;i++,ptr+=3,retPtr+=3)
2032 retPtr[0]=sqrt(ptr[0]*ptr[0]+ptr[1]*ptr[1]+ptr[2]*ptr[2]);
2033 retPtr[1]=acos(ptr[2]/retPtr[0]);
2034 retPtr[2]=atan2(ptr[1],ptr[0]);
2040 * 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.
2041 * This method expects that \a this has exactly 3 components.
2042 * \sa MEDCouplingFieldDouble::computeVectorFieldCyl
2044 DataArrayDouble *DataArrayDouble::fromCartToCylGiven(const DataArrayDouble *coords, const double center[3], const double vect[3]) const
2047 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : input coords are NULL !");
2048 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2049 checkAllocated(); coords->checkAllocated();
2050 std::size_t nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2052 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : must be an array with exactly 3 components !");
2053 if(coords->getNumberOfComponents()!=3)
2054 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : coords array must have exactly 3 components !");
2055 if(coords->getNumberOfTuples()!=nbTuples)
2056 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : coords array must have the same number of tuples !");
2057 ret->alloc(nbTuples,nbOfComp);
2058 double magOfVect(sqrt(vect[0]*vect[0]+vect[1]*vect[1]+vect[2]*vect[2]));
2060 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : magnitude of vect is too low !");
2061 double Ur[3],Uteta[3],Uz[3],*retPtr(ret->getPointer());
2062 const double *coo(coords->begin()),*vectField(begin());
2063 std::transform(vect,vect+3,Uz,std::bind2nd(std::multiplies<double>(),1./magOfVect));
2064 for(int i=0;i<nbTuples;i++,vectField+=3,retPtr+=3,coo+=3)
2066 std::transform(coo,coo+3,center,Ur,std::minus<double>());
2067 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];
2068 double magOfTeta(sqrt(Uteta[0]*Uteta[0]+Uteta[1]*Uteta[1]+Uteta[2]*Uteta[2]));
2069 std::transform(Uteta,Uteta+3,Uteta,std::bind2nd(std::multiplies<double>(),1./magOfTeta));
2070 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];
2071 retPtr[0]=Ur[0]*vectField[0]+Ur[1]*vectField[1]+Ur[2]*vectField[2];
2072 retPtr[1]=Uteta[0]*vectField[0]+Uteta[1]*vectField[1]+Uteta[2]*vectField[2];
2073 retPtr[2]=Uz[0]*vectField[0]+Uz[1]*vectField[1]+Uz[2]*vectField[2];
2075 ret->copyStringInfoFrom(*this);
2080 * Computes the doubly contracted product of every tensor defined by the tuple of \a this
2081 * array contating 6 components.
2082 * \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
2083 * is calculated from the tuple <em>(t)</em> of \a this array as follows:
2084 * \f$ t[0]^2+t[1]^2+t[2]^2+2*t[3]^2+2*t[4]^2+2*t[5]^2\f$.
2085 * The caller is to delete this result array using decrRef() as it is no more needed.
2086 * \throw If \a this->getNumberOfComponents() != 6.
2088 DataArrayDouble *DataArrayDouble::doublyContractedProduct() const
2091 int nbOfComp(getNumberOfComponents());
2093 throw INTERP_KERNEL::Exception("DataArrayDouble::doublyContractedProduct : must be an array with exactly 6 components !");
2094 DataArrayDouble *ret=DataArrayDouble::New();
2095 int nbOfTuple=getNumberOfTuples();
2096 ret->alloc(nbOfTuple,1);
2097 const double *src=getConstPointer();
2098 double *dest=ret->getPointer();
2099 for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
2100 *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];
2105 * Computes the determinant of every square matrix defined by the tuple of \a this
2106 * array, which contains either 4, 6 or 9 components. The case of 6 components
2107 * corresponds to that of the upper triangular matrix.
2108 * \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
2109 * is the determinant of matrix of the corresponding tuple of \a this array.
2110 * The caller is to delete this result array using decrRef() as it is no more
2112 * \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2114 DataArrayDouble *DataArrayDouble::determinant() const
2117 DataArrayDouble *ret=DataArrayDouble::New();
2118 int nbOfTuple=getNumberOfTuples();
2119 ret->alloc(nbOfTuple,1);
2120 const double *src=getConstPointer();
2121 double *dest=ret->getPointer();
2122 switch(getNumberOfComponents())
2125 for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
2126 *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];
2129 for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
2130 *dest=src[0]*src[3]-src[1]*src[2];
2133 for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
2134 *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];
2138 throw INTERP_KERNEL::Exception("DataArrayDouble::determinant : Invalid number of components ! must be in 4,6,9 !");
2143 * Computes 3 eigenvalues of every upper triangular matrix defined by the tuple of
2144 * \a this array, which contains 6 components.
2145 * \return DataArrayDouble * - the new instance of DataArrayDouble containing 3
2146 * components, whose each tuple contains the eigenvalues of the matrix of
2147 * corresponding tuple of \a this array.
2148 * The caller is to delete this result array using decrRef() as it is no more
2150 * \throw If \a this->getNumberOfComponents() != 6.
2152 DataArrayDouble *DataArrayDouble::eigenValues() const
2155 int nbOfComp=getNumberOfComponents();
2157 throw INTERP_KERNEL::Exception("DataArrayDouble::eigenValues : must be an array with exactly 6 components !");
2158 DataArrayDouble *ret=DataArrayDouble::New();
2159 int nbOfTuple=getNumberOfTuples();
2160 ret->alloc(nbOfTuple,3);
2161 const double *src=getConstPointer();
2162 double *dest=ret->getPointer();
2163 for(int i=0;i<nbOfTuple;i++,dest+=3,src+=6)
2164 INTERP_KERNEL::computeEigenValues6(src,dest);
2169 * Computes 3 eigenvectors of every upper triangular matrix defined by the tuple of
2170 * \a this array, which contains 6 components.
2171 * \return DataArrayDouble * - the new instance of DataArrayDouble containing 9
2172 * components, whose each tuple contains 3 eigenvectors of the matrix of
2173 * corresponding tuple of \a this array.
2174 * The caller is to delete this result array using decrRef() as it is no more
2176 * \throw If \a this->getNumberOfComponents() != 6.
2178 DataArrayDouble *DataArrayDouble::eigenVectors() const
2181 int nbOfComp=getNumberOfComponents();
2183 throw INTERP_KERNEL::Exception("DataArrayDouble::eigenVectors : must be an array with exactly 6 components !");
2184 DataArrayDouble *ret=DataArrayDouble::New();
2185 int nbOfTuple=getNumberOfTuples();
2186 ret->alloc(nbOfTuple,9);
2187 const double *src=getConstPointer();
2188 double *dest=ret->getPointer();
2189 for(int i=0;i<nbOfTuple;i++,src+=6)
2192 INTERP_KERNEL::computeEigenValues6(src,tmp);
2193 for(int j=0;j<3;j++,dest+=3)
2194 INTERP_KERNEL::computeEigenVectorForEigenValue6(src,tmp[j],1e-12,dest);
2200 * Computes the inverse matrix of every matrix defined by the tuple of \a this
2201 * array, which contains either 4, 6 or 9 components. The case of 6 components
2202 * corresponds to that of the upper triangular matrix.
2203 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2204 * same number of components as \a this one, whose each tuple is the inverse
2205 * matrix of the matrix of corresponding tuple of \a this array.
2206 * The caller is to delete this result array using decrRef() as it is no more
2208 * \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2210 DataArrayDouble *DataArrayDouble::inverse() const
2213 int nbOfComp=getNumberOfComponents();
2214 if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
2215 throw INTERP_KERNEL::Exception("DataArrayDouble::inversion : must be an array with 4,6 or 9 components !");
2216 DataArrayDouble *ret=DataArrayDouble::New();
2217 int nbOfTuple=getNumberOfTuples();
2218 ret->alloc(nbOfTuple,nbOfComp);
2219 const double *src=getConstPointer();
2220 double *dest=ret->getPointer();
2222 for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
2224 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];
2225 dest[0]=(src[1]*src[2]-src[4]*src[4])/det;
2226 dest[1]=(src[0]*src[2]-src[5]*src[5])/det;
2227 dest[2]=(src[0]*src[1]-src[3]*src[3])/det;
2228 dest[3]=(src[5]*src[4]-src[3]*src[2])/det;
2229 dest[4]=(src[5]*src[3]-src[0]*src[4])/det;
2230 dest[5]=(src[3]*src[4]-src[1]*src[5])/det;
2232 else if(nbOfComp==4)
2233 for(int i=0;i<nbOfTuple;i++,dest+=4,src+=4)
2235 double det=src[0]*src[3]-src[1]*src[2];
2237 dest[1]=-src[1]/det;
2238 dest[2]=-src[2]/det;
2242 for(int i=0;i<nbOfTuple;i++,dest+=9,src+=9)
2244 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];
2245 dest[0]=(src[4]*src[8]-src[7]*src[5])/det;
2246 dest[1]=(src[7]*src[2]-src[1]*src[8])/det;
2247 dest[2]=(src[1]*src[5]-src[4]*src[2])/det;
2248 dest[3]=(src[6]*src[5]-src[3]*src[8])/det;
2249 dest[4]=(src[0]*src[8]-src[6]*src[2])/det;
2250 dest[5]=(src[2]*src[3]-src[0]*src[5])/det;
2251 dest[6]=(src[3]*src[7]-src[6]*src[4])/det;
2252 dest[7]=(src[6]*src[1]-src[0]*src[7])/det;
2253 dest[8]=(src[0]*src[4]-src[1]*src[3])/det;
2259 * Computes the trace of every matrix defined by the tuple of \a this
2260 * array, which contains either 4, 6 or 9 components. The case of 6 components
2261 * corresponds to that of the upper triangular matrix.
2262 * \return DataArrayDouble * - the new instance of DataArrayDouble containing
2263 * 1 component, whose each tuple is the trace of
2264 * the matrix of corresponding tuple of \a this array.
2265 * The caller is to delete this result array using decrRef() as it is no more
2267 * \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2269 DataArrayDouble *DataArrayDouble::trace() const
2272 int nbOfComp=getNumberOfComponents();
2273 if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
2274 throw INTERP_KERNEL::Exception("DataArrayDouble::trace : must be an array with 4,6 or 9 components !");
2275 DataArrayDouble *ret=DataArrayDouble::New();
2276 int nbOfTuple=getNumberOfTuples();
2277 ret->alloc(nbOfTuple,1);
2278 const double *src=getConstPointer();
2279 double *dest=ret->getPointer();
2281 for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
2282 *dest=src[0]+src[1]+src[2];
2283 else if(nbOfComp==4)
2284 for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
2285 *dest=src[0]+src[3];
2287 for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
2288 *dest=src[0]+src[4]+src[8];
2293 * Computes the stress deviator tensor of every stress tensor defined by the tuple of
2294 * \a this array, which contains 6 components.
2295 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2296 * same number of components and tuples as \a this array.
2297 * The caller is to delete this result array using decrRef() as it is no more
2299 * \throw If \a this->getNumberOfComponents() != 6.
2301 DataArrayDouble *DataArrayDouble::deviator() const
2304 int nbOfComp=getNumberOfComponents();
2306 throw INTERP_KERNEL::Exception("DataArrayDouble::deviator : must be an array with exactly 6 components !");
2307 DataArrayDouble *ret=DataArrayDouble::New();
2308 int nbOfTuple=getNumberOfTuples();
2309 ret->alloc(nbOfTuple,6);
2310 const double *src=getConstPointer();
2311 double *dest=ret->getPointer();
2312 for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
2314 double tr=(src[0]+src[1]+src[2])/3.;
2326 * Computes the magnitude of every vector defined by the tuple of
2328 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2329 * same number of tuples as \a this array and one component.
2330 * The caller is to delete this result array using decrRef() as it is no more
2332 * \throw If \a this is not allocated.
2334 DataArrayDouble *DataArrayDouble::magnitude() const
2337 int nbOfComp=getNumberOfComponents();
2338 DataArrayDouble *ret=DataArrayDouble::New();
2339 int nbOfTuple=getNumberOfTuples();
2340 ret->alloc(nbOfTuple,1);
2341 const double *src=getConstPointer();
2342 double *dest=ret->getPointer();
2343 for(int i=0;i<nbOfTuple;i++,dest++)
2346 for(int j=0;j<nbOfComp;j++,src++)
2354 * Computes the maximal value within every tuple of \a this array.
2355 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2356 * same number of tuples as \a this array and one component.
2357 * The caller is to delete this result array using decrRef() as it is no more
2359 * \throw If \a this is not allocated.
2360 * \sa DataArrayDouble::maxPerTupleWithCompoId
2362 DataArrayDouble *DataArrayDouble::maxPerTuple() const
2365 int nbOfComp=getNumberOfComponents();
2366 MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
2367 int nbOfTuple=getNumberOfTuples();
2368 ret->alloc(nbOfTuple,1);
2369 const double *src=getConstPointer();
2370 double *dest=ret->getPointer();
2371 for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
2372 *dest=*std::max_element(src,src+nbOfComp);
2377 * Computes the maximal value within every tuple of \a this array and it returns the first component
2378 * id for each tuple that corresponds to the maximal value within the tuple.
2380 * \param [out] compoIdOfMaxPerTuple - the new new instance of DataArrayInt containing the
2381 * same number of tuples and only one component.
2382 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2383 * same number of tuples as \a this array and one component.
2384 * The caller is to delete this result array using decrRef() as it is no more
2386 * \throw If \a this is not allocated.
2387 * \sa DataArrayDouble::maxPerTuple
2389 DataArrayDouble *DataArrayDouble::maxPerTupleWithCompoId(DataArrayInt* &compoIdOfMaxPerTuple) const
2392 int nbOfComp=getNumberOfComponents();
2393 MCAuto<DataArrayDouble> ret0=DataArrayDouble::New();
2394 MCAuto<DataArrayInt> ret1=DataArrayInt::New();
2395 int nbOfTuple=getNumberOfTuples();
2396 ret0->alloc(nbOfTuple,1); ret1->alloc(nbOfTuple,1);
2397 const double *src=getConstPointer();
2398 double *dest=ret0->getPointer(); int *dest1=ret1->getPointer();
2399 for(int i=0;i<nbOfTuple;i++,dest++,dest1++,src+=nbOfComp)
2401 const double *loc=std::max_element(src,src+nbOfComp);
2403 *dest1=(int)std::distance(src,loc);
2405 compoIdOfMaxPerTuple=ret1.retn();
2410 * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c this->getNumberOfTuples() tuples.
2411 * \n This returned array contains the euclidian distance for each tuple in \a this.
2412 * \n So the returned array can be seen as a dense symmetrical matrix whose diagonal elements are equal to 0.
2413 * \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)
2415 * \warning use this method with care because it can leads to big amount of consumed memory !
2417 * \return A newly allocated (huge) MEDCoupling::DataArrayDouble instance that the caller should deal with.
2419 * \throw If \a this is not allocated.
2421 * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrixWith
2423 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrix() const
2426 int nbOfComp=getNumberOfComponents();
2427 int nbOfTuples=getNumberOfTuples();
2428 const double *inData=getConstPointer();
2429 MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
2430 ret->alloc(nbOfTuples*nbOfTuples,1);
2431 double *outData=ret->getPointer();
2432 for(int i=0;i<nbOfTuples;i++)
2434 outData[i*nbOfTuples+i]=0.;
2435 for(int j=i+1;j<nbOfTuples;j++)
2438 for(int k=0;k<nbOfComp;k++)
2439 { double delta=inData[i*nbOfComp+k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
2441 outData[i*nbOfTuples+j]=dist;
2442 outData[j*nbOfTuples+i]=dist;
2449 * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c other->getNumberOfTuples() tuples.
2450 * \n This returned array contains the euclidian distance for each tuple in \a other with each tuple in \a this.
2451 * \n So the returned array can be seen as a dense rectangular matrix with \c other->getNumberOfTuples() rows and \c this->getNumberOfTuples() columns.
2452 * \n Output rectangular matrix is sorted along rows.
2453 * \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)
2455 * \warning use this method with care because it can leads to big amount of consumed memory !
2457 * \param [in] other DataArrayDouble instance having same number of components than \a this.
2458 * \return A newly allocated (huge) MEDCoupling::DataArrayDouble instance that the caller should deal with.
2460 * \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.
2462 * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrix
2464 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrixWith(const DataArrayDouble *other) const
2467 throw INTERP_KERNEL::Exception("DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : input parameter is null !");
2469 other->checkAllocated();
2470 int nbOfComp=getNumberOfComponents();
2471 int otherNbOfComp=other->getNumberOfComponents();
2472 if(nbOfComp!=otherNbOfComp)
2474 std::ostringstream oss; oss << "DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : this nb of compo=" << nbOfComp << " and other nb of compo=" << otherNbOfComp << ". It should match !";
2475 throw INTERP_KERNEL::Exception(oss.str().c_str());
2477 int nbOfTuples=getNumberOfTuples();
2478 int otherNbOfTuples=other->getNumberOfTuples();
2479 const double *inData=getConstPointer();
2480 const double *inDataOther=other->getConstPointer();
2481 MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
2482 ret->alloc(otherNbOfTuples*nbOfTuples,1);
2483 double *outData=ret->getPointer();
2484 for(int i=0;i<otherNbOfTuples;i++,inDataOther+=nbOfComp)
2486 for(int j=0;j<nbOfTuples;j++)
2489 for(int k=0;k<nbOfComp;k++)
2490 { double delta=inDataOther[k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
2492 outData[i*nbOfTuples+j]=dist;
2499 * This method expects that \a this stores 3 tuples containing 2 components each.
2500 * Each of this tuples represent a point into 2D space.
2501 * This method tries to find an arc of circle starting from first point (tuple) to 2nd and middle point (tuple) along 3nd and last point (tuple).
2502 * If such arc of circle exists, the corresponding center, radius of circle is returned. And additionnaly the length of arc expressed with an \a ang output variable in ]0,2*pi[.
2504 * \throw If \a this is not allocated.
2505 * \throw If \a this has not 3 tuples of 2 components
2506 * \throw If tuples/points in \a this are aligned
2508 void DataArrayDouble::asArcOfCircle(double center[2], double& radius, double& ang) const
2511 INTERP_KERNEL::QuadraticPlanarPrecision arcPrec(1e-14);
2512 if(getNumberOfTuples()!=3 && getNumberOfComponents()!=2)
2513 throw INTERP_KERNEL::Exception("DataArrayDouble::asArcCircle : this method expects");
2514 const double *pt(begin());
2515 MCAuto<INTERP_KERNEL::Node> n0(new INTERP_KERNEL::Node(pt[0],pt[1])),n1(new INTERP_KERNEL::Node(pt[2],pt[3])),n2(new INTERP_KERNEL::Node(pt[4],pt[5]));
2517 INTERP_KERNEL::AutoCppPtr<INTERP_KERNEL::EdgeLin> e1(new INTERP_KERNEL::EdgeLin(n0,n2)),e2(new INTERP_KERNEL::EdgeLin(n2,n1));
2518 INTERP_KERNEL::SegSegIntersector inters(*e1,*e2);
2519 bool colinearity(inters.areColinears());
2521 throw INTERP_KERNEL::Exception("DataArrayDouble::asArcOfCircle : 3 points in this have been detected as colinear !");
2523 INTERP_KERNEL::AutoCppPtr<INTERP_KERNEL::EdgeArcCircle> ret(new INTERP_KERNEL::EdgeArcCircle(n0,n2,n1));
2524 const double *c(ret->getCenter());
2525 center[0]=c[0]; center[1]=c[1];
2526 radius=ret->getRadius();
2527 ang=ret->getAngle();
2531 * Sorts value within every tuple of \a this array.
2532 * \param [in] asc - if \a true, the values are sorted in ascending order, else,
2533 * in descending order.
2534 * \throw If \a this is not allocated.
2536 void DataArrayDouble::sortPerTuple(bool asc)
2539 double *pt=getPointer();
2540 int nbOfTuple=getNumberOfTuples();
2541 int nbOfComp=getNumberOfComponents();
2543 for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
2544 std::sort(pt,pt+nbOfComp);
2546 for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
2547 std::sort(pt,pt+nbOfComp,std::greater<double>());
2552 * Modify all elements of \a this array, so that
2553 * an element _x_ becomes \f$ numerator / x \f$.
2554 * \warning If an exception is thrown because of presence of 0.0 element in \a this
2555 * array, all elements processed before detection of the zero element remain
2557 * \param [in] numerator - the numerator used to modify array elements.
2558 * \throw If \a this is not allocated.
2559 * \throw If there is an element equal to 0.0 in \a this array.
2561 void DataArrayDouble::applyInv(double numerator)
2564 double *ptr=getPointer();
2565 std::size_t nbOfElems=getNbOfElems();
2566 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2568 if(std::abs(*ptr)>std::numeric_limits<double>::min())
2570 *ptr=numerator/(*ptr);
2574 std::ostringstream oss; oss << "DataArrayDouble::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
2576 throw INTERP_KERNEL::Exception(oss.str().c_str());
2583 * Modify all elements of \a this array, so that
2584 * an element _x_ becomes <em> val ^ x </em>. Contrary to DataArrayInt::applyPow
2585 * all values in \a this have to be >= 0 if val is \b not integer.
2586 * \param [in] val - the value used to apply pow on all array elements.
2587 * \throw If \a this is not allocated.
2588 * \warning If an exception is thrown because of presence of 0 element in \a this
2589 * array and \a val is \b not integer, all elements processed before detection of the zero element remain
2592 void DataArrayDouble::applyPow(double val)
2595 double *ptr=getPointer();
2596 std::size_t nbOfElems=getNbOfElems();
2598 bool isInt=((double)val2)==val;
2601 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2607 std::ostringstream oss; oss << "DataArrayDouble::applyPow (double) : At elem # " << i << " value is " << *ptr << " ! must be >=0. !";
2608 throw INTERP_KERNEL::Exception(oss.str().c_str());
2614 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2615 *ptr=pow(*ptr,val2);
2621 * Modify all elements of \a this array, so that
2622 * an element _x_ becomes \f$ val ^ x \f$.
2623 * \param [in] val - the value used to apply pow on all array elements.
2624 * \throw If \a this is not allocated.
2625 * \throw If \a val < 0.
2626 * \warning If an exception is thrown because of presence of 0 element in \a this
2627 * array, all elements processed before detection of the zero element remain
2630 void DataArrayDouble::applyRPow(double val)
2634 throw INTERP_KERNEL::Exception("DataArrayDouble::applyRPow : the input value has to be >= 0 !");
2635 double *ptr=getPointer();
2636 std::size_t nbOfElems=getNbOfElems();
2637 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2643 * Returns a new DataArrayDouble created from \a this one by applying \a
2644 * FunctionToEvaluate to every tuple of \a this array. Textual data is not copied.
2645 * For more info see \ref MEDCouplingArrayApplyFunc
2646 * \param [in] nbOfComp - number of components in the result array.
2647 * \param [in] func - the \a FunctionToEvaluate declared as
2648 * \c bool (*\a func)(\c const \c double *\a pos, \c double *\a res),
2649 * where \a pos points to the first component of a tuple of \a this array
2650 * and \a res points to the first component of a tuple of the result array.
2651 * Note that length (number of components) of \a pos can differ from
2653 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2654 * same number of tuples as \a this array.
2655 * The caller is to delete this result array using decrRef() as it is no more
2657 * \throw If \a this is not allocated.
2658 * \throw If \a func returns \a false.
2660 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, FunctionToEvaluate func) const
2663 DataArrayDouble *newArr=DataArrayDouble::New();
2664 int nbOfTuples=getNumberOfTuples();
2665 int oldNbOfComp=getNumberOfComponents();
2666 newArr->alloc(nbOfTuples,nbOfComp);
2667 const double *ptr=getConstPointer();
2668 double *ptrToFill=newArr->getPointer();
2669 for(int i=0;i<nbOfTuples;i++)
2671 if(!func(ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp))
2673 std::ostringstream oss; oss << "For tuple # " << i << " with value (";
2674 std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
2675 oss << ") : Evaluation of function failed !";
2677 throw INTERP_KERNEL::Exception(oss.str().c_str());
2684 * Returns a new DataArrayDouble created from \a this one by applying a function to every
2685 * tuple of \a this array. Textual data is not copied.
2686 * For more info see \ref MEDCouplingArrayApplyFunc1.
2687 * \param [in] nbOfComp - number of components in the result array.
2688 * \param [in] func - the expression defining how to transform a tuple of \a this array.
2689 * Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
2690 * \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
2691 * If false the computation is carried on without any notification. When false the evaluation is a little faster.
2692 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2693 * same number of tuples as \a this array and \a nbOfComp components.
2694 * The caller is to delete this result array using decrRef() as it is no more
2696 * \throw If \a this is not allocated.
2697 * \throw If computing \a func fails.
2699 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, const std::string& func, bool isSafe) const
2701 INTERP_KERNEL::ExprParser expr(func);
2703 std::set<std::string> vars;
2704 expr.getTrueSetOfVars(vars);
2705 std::vector<std::string> varsV(vars.begin(),vars.end());
2706 return applyFuncNamedCompo(nbOfComp,varsV,func,isSafe);
2710 * Returns a new DataArrayDouble created from \a this one by applying a function to every
2711 * tuple of \a this array. Textual data is not copied. This method works by tuples (whatever its size).
2712 * If \a this is a one component array, call applyFuncOnThis instead that performs the same work faster.
2714 * For more info see \ref MEDCouplingArrayApplyFunc0.
2715 * \param [in] func - the expression defining how to transform a tuple of \a this array.
2716 * Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
2717 * \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
2718 * If false the computation is carried on without any notification. When false the evaluation is a little faster.
2719 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2720 * same number of tuples and components as \a this array.
2721 * The caller is to delete this result array using decrRef() as it is no more
2723 * \sa applyFuncOnThis
2724 * \throw If \a this is not allocated.
2725 * \throw If computing \a func fails.
2727 DataArrayDouble *DataArrayDouble::applyFunc(const std::string& func, bool isSafe) const
2729 int nbOfComp(getNumberOfComponents());
2731 throw INTERP_KERNEL::Exception("DataArrayDouble::applyFunc : output number of component must be > 0 !");
2733 int nbOfTuples(getNumberOfTuples());
2734 MCAuto<DataArrayDouble> newArr(DataArrayDouble::New());
2735 newArr->alloc(nbOfTuples,nbOfComp);
2736 INTERP_KERNEL::ExprParser expr(func);
2738 std::set<std::string> vars;
2739 expr.getTrueSetOfVars(vars);
2740 if((int)vars.size()>1)
2742 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 : ";
2743 std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
2744 throw INTERP_KERNEL::Exception(oss.str().c_str());
2748 expr.prepareFastEvaluator();
2749 newArr->rearrange(1);
2750 newArr->fillWithValue(expr.evaluateDouble());
2751 newArr->rearrange(nbOfComp);
2752 return newArr.retn();
2754 std::vector<std::string> vars2(vars.begin(),vars.end());
2755 double buff,*ptrToFill(newArr->getPointer());
2756 const double *ptr(begin());
2757 std::vector<double> stck;
2758 expr.prepareExprEvaluationDouble(vars2,1,1,0,&buff,&buff+1);
2759 expr.prepareFastEvaluator();
2762 for(int i=0;i<nbOfTuples;i++)
2764 for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
2767 expr.evaluateDoubleInternal(stck);
2768 *ptrToFill=stck.back();
2775 for(int i=0;i<nbOfTuples;i++)
2777 for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
2782 expr.evaluateDoubleInternalSafe(stck);
2784 catch(INTERP_KERNEL::Exception& e)
2786 std::ostringstream oss; oss << "For tuple # " << i << " component # " << iComp << " with value (";
2788 oss << ") : Evaluation of function failed !" << e.what();
2789 throw INTERP_KERNEL::Exception(oss.str().c_str());
2791 *ptrToFill=stck.back();
2796 return newArr.retn();
2800 * This method is a non const method that modify the array in \a this.
2801 * This method only works on one component array. It means that function \a func must
2802 * contain at most one variable.
2803 * This method is a specialization of applyFunc method with one parameter on one component array.
2805 * \param [in] func - the expression defining how to transform a tuple of \a this array.
2806 * Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
2807 * \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
2808 * If false the computation is carried on without any notification. When false the evaluation is a little faster.
2812 void DataArrayDouble::applyFuncOnThis(const std::string& func, bool isSafe)
2814 int nbOfComp(getNumberOfComponents());
2816 throw INTERP_KERNEL::Exception("DataArrayDouble::applyFuncOnThis : output number of component must be > 0 !");
2818 int nbOfTuples(getNumberOfTuples());
2819 INTERP_KERNEL::ExprParser expr(func);
2821 std::set<std::string> vars;
2822 expr.getTrueSetOfVars(vars);
2823 if((int)vars.size()>1)
2825 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 : ";
2826 std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
2827 throw INTERP_KERNEL::Exception(oss.str().c_str());
2831 expr.prepareFastEvaluator();
2832 std::vector<std::string> compInfo(getInfoOnComponents());
2834 fillWithValue(expr.evaluateDouble());
2835 rearrange(nbOfComp);
2836 setInfoOnComponents(compInfo);
2839 std::vector<std::string> vars2(vars.begin(),vars.end());
2840 double buff,*ptrToFill(getPointer());
2841 const double *ptr(begin());
2842 std::vector<double> stck;
2843 expr.prepareExprEvaluationDouble(vars2,1,1,0,&buff,&buff+1);
2844 expr.prepareFastEvaluator();
2847 for(int i=0;i<nbOfTuples;i++)
2849 for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
2852 expr.evaluateDoubleInternal(stck);
2853 *ptrToFill=stck.back();
2860 for(int i=0;i<nbOfTuples;i++)
2862 for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
2867 expr.evaluateDoubleInternalSafe(stck);
2869 catch(INTERP_KERNEL::Exception& e)
2871 std::ostringstream oss; oss << "For tuple # " << i << " component # " << iComp << " with value (";
2873 oss << ") : Evaluation of function failed !" << e.what();
2874 throw INTERP_KERNEL::Exception(oss.str().c_str());
2876 *ptrToFill=stck.back();
2884 * Returns a new DataArrayDouble created from \a this one by applying a function to every
2885 * tuple of \a this array. Textual data is not copied.
2886 * For more info see \ref MEDCouplingArrayApplyFunc2.
2887 * \param [in] nbOfComp - number of components in the result array.
2888 * \param [in] func - the expression defining how to transform a tuple of \a this array.
2889 * Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
2890 * \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
2891 * If false the computation is carried on without any notification. When false the evaluation is a little faster.
2892 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2893 * same number of tuples as \a this array.
2894 * The caller is to delete this result array using decrRef() as it is no more
2896 * \throw If \a this is not allocated.
2897 * \throw If \a func contains vars that are not in \a this->getInfoOnComponent().
2898 * \throw If computing \a func fails.
2900 DataArrayDouble *DataArrayDouble::applyFuncCompo(int nbOfComp, const std::string& func, bool isSafe) const
2902 return applyFuncNamedCompo(nbOfComp,getVarsOnComponent(),func,isSafe);
2906 * Returns a new DataArrayDouble created from \a this one by applying a function to every
2907 * tuple of \a this array. Textual data is not copied.
2908 * For more info see \ref MEDCouplingArrayApplyFunc3.
2909 * \param [in] nbOfComp - number of components in the result array.
2910 * \param [in] varsOrder - sequence of vars defining their order.
2911 * \param [in] func - the expression defining how to transform a tuple of \a this array.
2912 * Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
2913 * \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
2914 * If false the computation is carried on without any notification. When false the evaluation is a little faster.
2915 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2916 * same number of tuples as \a this array.
2917 * The caller is to delete this result array using decrRef() as it is no more
2919 * \throw If \a this is not allocated.
2920 * \throw If \a func contains vars not in \a varsOrder.
2921 * \throw If computing \a func fails.
2923 DataArrayDouble *DataArrayDouble::applyFuncNamedCompo(int nbOfComp, const std::vector<std::string>& varsOrder, const std::string& func, bool isSafe) const
2926 throw INTERP_KERNEL::Exception("DataArrayDouble::applyFuncNamedCompo : output number of component must be > 0 !");
2927 std::vector<std::string> varsOrder2(varsOrder);
2928 int oldNbOfComp(getNumberOfComponents());
2929 for(int i=(int)varsOrder.size();i<oldNbOfComp;i++)
2930 varsOrder2.push_back(std::string());
2932 int nbOfTuples(getNumberOfTuples());
2933 INTERP_KERNEL::ExprParser expr(func);
2935 std::set<std::string> vars;
2936 expr.getTrueSetOfVars(vars);
2937 if((int)vars.size()>oldNbOfComp)
2939 std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
2940 oss << vars.size() << " variables : ";
2941 std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
2942 throw INTERP_KERNEL::Exception(oss.str().c_str());
2944 MCAuto<DataArrayDouble> newArr(DataArrayDouble::New());
2945 newArr->alloc(nbOfTuples,nbOfComp);
2946 INTERP_KERNEL::AutoPtr<double> buff(new double[oldNbOfComp]);
2947 double *buffPtr(buff),*ptrToFill;
2948 std::vector<double> stck;
2949 for(int iComp=0;iComp<nbOfComp;iComp++)
2951 expr.prepareExprEvaluationDouble(varsOrder2,oldNbOfComp,nbOfComp,iComp,buffPtr,buffPtr+oldNbOfComp);
2952 expr.prepareFastEvaluator();
2953 const double *ptr(getConstPointer());
2954 ptrToFill=newArr->getPointer()+iComp;
2957 for(int i=0;i<nbOfTuples;i++,ptrToFill+=nbOfComp,ptr+=oldNbOfComp)
2959 std::copy(ptr,ptr+oldNbOfComp,buffPtr);
2960 expr.evaluateDoubleInternal(stck);
2961 *ptrToFill=stck.back();
2967 for(int i=0;i<nbOfTuples;i++,ptrToFill+=nbOfComp,ptr+=oldNbOfComp)
2969 std::copy(ptr,ptr+oldNbOfComp,buffPtr);
2972 expr.evaluateDoubleInternalSafe(stck);
2973 *ptrToFill=stck.back();
2976 catch(INTERP_KERNEL::Exception& e)
2978 std::ostringstream oss; oss << "For tuple # " << i << " with value (";
2979 std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
2980 oss << ") : Evaluation of function failed !" << e.what();
2981 throw INTERP_KERNEL::Exception(oss.str().c_str());
2986 return newArr.retn();
2989 void DataArrayDouble::applyFuncFast32(const std::string& func)
2992 INTERP_KERNEL::ExprParser expr(func);
2994 char *funcStr=expr.compileX86();
2996 *((void **)&funcPtr)=funcStr;//he he...
2998 double *ptr=getPointer();
2999 int nbOfComp=getNumberOfComponents();
3000 int nbOfTuples=getNumberOfTuples();
3001 int nbOfElems=nbOfTuples*nbOfComp;
3002 for(int i=0;i<nbOfElems;i++,ptr++)
3007 void DataArrayDouble::applyFuncFast64(const std::string& func)
3010 INTERP_KERNEL::ExprParser expr(func);
3012 char *funcStr=expr.compileX86_64();
3014 *((void **)&funcPtr)=funcStr;//he he...
3016 double *ptr=getPointer();
3017 int nbOfComp=getNumberOfComponents();
3018 int nbOfTuples=getNumberOfTuples();
3019 int nbOfElems=nbOfTuples*nbOfComp;
3020 for(int i=0;i<nbOfElems;i++,ptr++)
3026 * \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.
3028 MCAuto<DataArrayDouble> DataArrayDouble::symmetry3DPlane(const double point[3], const double normalVector[3]) const
3031 if(getNumberOfComponents()!=3)
3032 throw INTERP_KERNEL::Exception("DataArrayDouble::symmetry3DPlane : this is excepted to have 3 components !");
3033 int nbTuples(getNumberOfTuples());
3034 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
3035 ret->alloc(nbTuples,3);
3036 Symmetry3DPlane(point,normalVector,nbTuples,begin(),ret->getPointer());
3040 DataArrayDoubleIterator *DataArrayDouble::iterator()
3042 return new DataArrayDoubleIterator(this);
3046 * Returns a new DataArrayInt containing indices of tuples of \a this one-dimensional
3047 * array whose values are within a given range. Textual data is not copied.
3048 * \param [in] vmin - a lowest acceptable value (included).
3049 * \param [in] vmax - a greatest acceptable value (included).
3050 * \return DataArrayInt * - the new instance of DataArrayInt.
3051 * The caller is to delete this result array using decrRef() as it is no more
3053 * \throw If \a this->getNumberOfComponents() != 1.
3055 * \sa DataArrayDouble::findIdsNotInRange
3057 * \if ENABLE_EXAMPLES
3058 * \ref cpp_mcdataarraydouble_getidsinrange "Here is a C++ example".<br>
3059 * \ref py_mcdataarraydouble_getidsinrange "Here is a Python example".
3062 DataArrayInt *DataArrayDouble::findIdsInRange(double vmin, double vmax) const
3065 if(getNumberOfComponents()!=1)
3066 throw INTERP_KERNEL::Exception("DataArrayDouble::findIdsInRange : this must have exactly one component !");
3067 const double *cptr(begin());
3068 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
3069 int nbOfTuples(getNumberOfTuples());
3070 for(int i=0;i<nbOfTuples;i++,cptr++)
3071 if(*cptr>=vmin && *cptr<=vmax)
3072 ret->pushBackSilent(i);
3077 * Returns a new DataArrayInt containing indices of tuples of \a this one-dimensional
3078 * array whose values are not within a given range. Textual data is not copied.
3079 * \param [in] vmin - a lowest not acceptable value (excluded).
3080 * \param [in] vmax - a greatest not acceptable value (excluded).
3081 * \return DataArrayInt * - the new instance of DataArrayInt.
3082 * The caller is to delete this result array using decrRef() as it is no more
3084 * \throw If \a this->getNumberOfComponents() != 1.
3086 * \sa DataArrayDouble::findIdsInRange
3088 DataArrayInt *DataArrayDouble::findIdsNotInRange(double vmin, double vmax) const
3091 if(getNumberOfComponents()!=1)
3092 throw INTERP_KERNEL::Exception("DataArrayDouble::findIdsNotInRange : this must have exactly one component !");
3093 const double *cptr(begin());
3094 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
3095 int nbOfTuples(getNumberOfTuples());
3096 for(int i=0;i<nbOfTuples;i++,cptr++)
3097 if(*cptr<vmin || *cptr>vmax)
3098 ret->pushBackSilent(i);
3103 * Returns a new DataArrayDouble by concatenating two given arrays, so that (1) the number
3104 * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
3105 * the number of component in the result array is same as that of each of given arrays.
3106 * Info on components is copied from the first of the given arrays. Number of components
3107 * in the given arrays must be the same.
3108 * \param [in] a1 - an array to include in the result array.
3109 * \param [in] a2 - another array to include in the result array.
3110 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3111 * The caller is to delete this result array using decrRef() as it is no more
3113 * \throw If both \a a1 and \a a2 are NULL.
3114 * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
3116 DataArrayDouble *DataArrayDouble::Aggregate(const DataArrayDouble *a1, const DataArrayDouble *a2)
3118 std::vector<const DataArrayDouble *> tmp(2);
3119 tmp[0]=a1; tmp[1]=a2;
3120 return Aggregate(tmp);
3124 * Returns a new DataArrayDouble by concatenating all given arrays, so that (1) the number
3125 * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
3126 * the number of component in the result array is same as that of each of given arrays.
3127 * Info on components is copied from the first of the given arrays. Number of components
3128 * in the given arrays must be the same.
3129 * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it
3130 * not the object itself.
3131 * \param [in] arr - a sequence of arrays to include in the result array.
3132 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3133 * The caller is to delete this result array using decrRef() as it is no more
3135 * \throw If all arrays within \a arr are NULL.
3136 * \throw If getNumberOfComponents() of arrays within \a arr.
3138 DataArrayDouble *DataArrayDouble::Aggregate(const std::vector<const DataArrayDouble *>& arr)
3140 std::vector<const DataArrayDouble *> a;
3141 for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
3145 throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : input list must contain at least one NON EMPTY DataArrayDouble !");
3146 std::vector<const DataArrayDouble *>::const_iterator it=a.begin();
3147 std::size_t nbOfComp((*it)->getNumberOfComponents());
3148 int nbt=(*it++)->getNumberOfTuples();
3149 for(int i=1;it!=a.end();it++,i++)
3151 if((*it)->getNumberOfComponents()!=nbOfComp)
3152 throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : Nb of components mismatch for array aggregation !");
3153 nbt+=(*it)->getNumberOfTuples();
3155 MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
3156 ret->alloc(nbt,nbOfComp);
3157 double *pt=ret->getPointer();
3158 for(it=a.begin();it!=a.end();it++)
3159 pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
3160 ret->copyStringInfoFrom(*(a[0]));
3165 * Returns a new DataArrayDouble containing a dot product of two given arrays, so that
3166 * the i-th tuple of the result array is a sum of products of j-th components of i-th
3167 * tuples of given arrays (\f$ a_i = \sum_{j=1}^n a1_j * a2_j \f$).
3168 * Info on components and name is copied from the first of the given arrays.
3169 * Number of tuples and components in the given arrays must be the same.
3170 * \param [in] a1 - a given array.
3171 * \param [in] a2 - another given array.
3172 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3173 * The caller is to delete this result array using decrRef() as it is no more
3175 * \throw If either \a a1 or \a a2 is NULL.
3176 * \throw If any given array is not allocated.
3177 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3178 * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
3180 DataArrayDouble *DataArrayDouble::Dot(const DataArrayDouble *a1, const DataArrayDouble *a2)
3183 throw INTERP_KERNEL::Exception("DataArrayDouble::Dot : input DataArrayDouble instance is NULL !");
3184 a1->checkAllocated();
3185 a2->checkAllocated();
3186 std::size_t nbOfComp(a1->getNumberOfComponents());
3187 if(nbOfComp!=a2->getNumberOfComponents())
3188 throw INTERP_KERNEL::Exception("Nb of components mismatch for array Dot !");
3189 std::size_t nbOfTuple(a1->getNumberOfTuples());
3190 if(nbOfTuple!=a2->getNumberOfTuples())
3191 throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Dot !");
3192 DataArrayDouble *ret=DataArrayDouble::New();
3193 ret->alloc(nbOfTuple,1);
3194 double *retPtr=ret->getPointer();
3195 const double *a1Ptr=a1->begin(),*a2Ptr(a2->begin());
3196 for(std::size_t i=0;i<nbOfTuple;i++)
3199 for(std::size_t j=0;j<nbOfComp;j++)
3200 sum+=a1Ptr[i*nbOfComp+j]*a2Ptr[i*nbOfComp+j];
3203 ret->setInfoOnComponent(0,a1->getInfoOnComponent(0));
3204 ret->setName(a1->getName());
3209 * Returns a new DataArrayDouble containing a cross product of two given arrays, so that
3210 * the i-th tuple of the result array contains 3 components of a vector which is a cross
3211 * product of two vectors defined by the i-th tuples of given arrays.
3212 * Info on components is copied from the first of the given arrays.
3213 * Number of tuples in the given arrays must be the same.
3214 * Number of components in the given arrays must be 3.
3215 * \param [in] a1 - a given array.
3216 * \param [in] a2 - another given array.
3217 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3218 * The caller is to delete this result array using decrRef() as it is no more
3220 * \throw If either \a a1 or \a a2 is NULL.
3221 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3222 * \throw If \a a1->getNumberOfComponents() != 3
3223 * \throw If \a a2->getNumberOfComponents() != 3
3225 DataArrayDouble *DataArrayDouble::CrossProduct(const DataArrayDouble *a1, const DataArrayDouble *a2)
3228 throw INTERP_KERNEL::Exception("DataArrayDouble::CrossProduct : input DataArrayDouble instance is NULL !");
3229 std::size_t nbOfComp(a1->getNumberOfComponents());
3230 if(nbOfComp!=a2->getNumberOfComponents())
3231 throw INTERP_KERNEL::Exception("Nb of components mismatch for array crossProduct !");
3233 throw INTERP_KERNEL::Exception("Nb of components must be equal to 3 for array crossProduct !");
3234 std::size_t nbOfTuple(a1->getNumberOfTuples());
3235 if(nbOfTuple!=a2->getNumberOfTuples())
3236 throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array crossProduct !");
3237 DataArrayDouble *ret=DataArrayDouble::New();
3238 ret->alloc(nbOfTuple,3);
3239 double *retPtr=ret->getPointer();
3240 const double *a1Ptr(a1->begin()),*a2Ptr(a2->begin());
3241 for(std::size_t i=0;i<nbOfTuple;i++)
3243 retPtr[3*i]=a1Ptr[3*i+1]*a2Ptr[3*i+2]-a1Ptr[3*i+2]*a2Ptr[3*i+1];
3244 retPtr[3*i+1]=a1Ptr[3*i+2]*a2Ptr[3*i]-a1Ptr[3*i]*a2Ptr[3*i+2];
3245 retPtr[3*i+2]=a1Ptr[3*i]*a2Ptr[3*i+1]-a1Ptr[3*i+1]*a2Ptr[3*i];
3247 ret->copyStringInfoFrom(*a1);
3252 * Returns a new DataArrayDouble containing maximal values of two given arrays.
3253 * Info on components is copied from the first of the given arrays.
3254 * Number of tuples and components in the given arrays must be the same.
3255 * \param [in] a1 - an array to compare values with another one.
3256 * \param [in] a2 - another array to compare values with the first one.
3257 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3258 * The caller is to delete this result array using decrRef() as it is no more
3260 * \throw If either \a a1 or \a a2 is NULL.
3261 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3262 * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
3264 DataArrayDouble *DataArrayDouble::Max(const DataArrayDouble *a1, const DataArrayDouble *a2)
3267 throw INTERP_KERNEL::Exception("DataArrayDouble::Max : input DataArrayDouble instance is NULL !");
3268 std::size_t nbOfComp(a1->getNumberOfComponents());
3269 if(nbOfComp!=a2->getNumberOfComponents())
3270 throw INTERP_KERNEL::Exception("Nb of components mismatch for array Max !");
3271 std::size_t nbOfTuple(a1->getNumberOfTuples());
3272 if(nbOfTuple!=a2->getNumberOfTuples())
3273 throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Max !");
3274 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
3275 ret->alloc(nbOfTuple,nbOfComp);
3276 double *retPtr(ret->getPointer());
3277 const double *a1Ptr(a1->begin()),*a2Ptr(a2->begin());
3278 std::size_t nbElem(nbOfTuple*nbOfComp);
3279 for(std::size_t i=0;i<nbElem;i++)
3280 retPtr[i]=std::max(a1Ptr[i],a2Ptr[i]);
3281 ret->copyStringInfoFrom(*a1);
3286 * Returns a new DataArrayDouble containing minimal values of two given arrays.
3287 * Info on components is copied from the first of the given arrays.
3288 * Number of tuples and components in the given arrays must be the same.
3289 * \param [in] a1 - an array to compare values with another one.
3290 * \param [in] a2 - another array to compare values with the first one.
3291 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3292 * The caller is to delete this result array using decrRef() as it is no more
3294 * \throw If either \a a1 or \a a2 is NULL.
3295 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3296 * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
3298 DataArrayDouble *DataArrayDouble::Min(const DataArrayDouble *a1, const DataArrayDouble *a2)
3301 throw INTERP_KERNEL::Exception("DataArrayDouble::Min : input DataArrayDouble instance is NULL !");
3302 std::size_t nbOfComp(a1->getNumberOfComponents());
3303 if(nbOfComp!=a2->getNumberOfComponents())
3304 throw INTERP_KERNEL::Exception("Nb of components mismatch for array min !");
3305 std::size_t nbOfTuple(a1->getNumberOfTuples());
3306 if(nbOfTuple!=a2->getNumberOfTuples())
3307 throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array min !");
3308 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
3309 ret->alloc(nbOfTuple,nbOfComp);
3310 double *retPtr(ret->getPointer());
3311 const double *a1Ptr(a1->begin()),*a2Ptr(a2->begin());
3312 std::size_t nbElem(nbOfTuple*nbOfComp);
3313 for(std::size_t i=0;i<nbElem;i++)
3314 retPtr[i]=std::min(a1Ptr[i],a2Ptr[i]);
3315 ret->copyStringInfoFrom(*a1);
3320 * Returns a new DataArrayDouble that is the result of pow of two given arrays. There are 3
3323 * \param [in] a1 - an array to pow up.
3324 * \param [in] a2 - another array to sum up.
3325 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3326 * The caller is to delete this result array using decrRef() as it is no more
3328 * \throw If either \a a1 or \a a2 is NULL.
3329 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3330 * \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
3331 * \throw If there is a negative value in \a a1.
3333 DataArrayDouble *DataArrayDouble::Pow(const DataArrayDouble *a1, const DataArrayDouble *a2)
3336 throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : at least one of input instances is null !");
3337 int nbOfTuple=a1->getNumberOfTuples();
3338 int nbOfTuple2=a2->getNumberOfTuples();
3339 int nbOfComp=a1->getNumberOfComponents();
3340 int nbOfComp2=a2->getNumberOfComponents();
3341 if(nbOfTuple!=nbOfTuple2)
3342 throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of tuples mismatches !");
3343 if(nbOfComp!=1 || nbOfComp2!=1)
3344 throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of components of both arrays must be equal to 1 !");
3345 MCAuto<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbOfTuple,1);
3346 const double *ptr1(a1->begin()),*ptr2(a2->begin());
3347 double *ptr=ret->getPointer();
3348 for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
3352 *ptr=pow(*ptr1,*ptr2);
3356 std::ostringstream oss; oss << "DataArrayDouble::Pow : on tuple #" << i << " of a1 value is < 0 (" << *ptr1 << ") !";
3357 throw INTERP_KERNEL::Exception(oss.str().c_str());
3364 * Apply pow on values of another DataArrayDouble to values of \a this one.
3366 * \param [in] other - an array to pow to \a this one.
3367 * \throw If \a other is NULL.
3368 * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
3369 * \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
3370 * \throw If there is a negative value in \a this.
3372 void DataArrayDouble::powEqual(const DataArrayDouble *other)
3375 throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : input instance is null !");
3376 int nbOfTuple=getNumberOfTuples();
3377 int nbOfTuple2=other->getNumberOfTuples();
3378 int nbOfComp=getNumberOfComponents();
3379 int nbOfComp2=other->getNumberOfComponents();
3380 if(nbOfTuple!=nbOfTuple2)
3381 throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of tuples mismatches !");
3382 if(nbOfComp!=1 || nbOfComp2!=1)
3383 throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of components of both arrays must be equal to 1 !");
3384 double *ptr=getPointer();
3385 const double *ptrc=other->begin();
3386 for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
3389 *ptr=pow(*ptr,*ptrc);
3392 std::ostringstream oss; oss << "DataArrayDouble::powEqual : on tuple #" << i << " of this value is < 0 (" << *ptr << ") !";
3393 throw INTERP_KERNEL::Exception(oss.str().c_str());
3400 * This method is \b NOT wrapped into python because it can be useful only for performance reasons in C++ context.
3401 * All values in \a this must be 0. or 1. within eps error. 0 means false, 1 means true.
3402 * If an another value than 0 or 1 appear (within eps precision) an INTERP_KERNEL::Exception will be thrown.
3404 * \throw if \a this is not allocated.
3405 * \throw if \a this has not exactly one component.
3407 std::vector<bool> DataArrayDouble::toVectorOfBool(double eps) const
3410 if(getNumberOfComponents()!=1)
3411 throw INTERP_KERNEL::Exception("DataArrayDouble::toVectorOfBool : must be applied on single component array !");
3412 int nbt(getNumberOfTuples());
3413 std::vector<bool> ret(nbt);
3414 const double *pt(begin());
3415 for(int i=0;i<nbt;i++)
3419 else if(fabs(pt[i]-1.)<eps)
3423 std::ostringstream oss; oss << "DataArrayDouble::toVectorOfBool : the tuple #" << i << " has value " << pt[i] << " is invalid ! must be 0. or 1. !";
3424 throw INTERP_KERNEL::Exception(oss.str().c_str());
3431 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
3434 void DataArrayDouble::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
3439 tinyInfo[0]=getNumberOfTuples();
3440 tinyInfo[1]=getNumberOfComponents();
3450 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
3453 void DataArrayDouble::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
3457 int nbOfCompo=getNumberOfComponents();
3458 tinyInfo.resize(nbOfCompo+1);
3459 tinyInfo[0]=getName();
3460 for(int i=0;i<nbOfCompo;i++)
3461 tinyInfo[i+1]=getInfoOnComponent(i);
3466 tinyInfo[0]=getName();
3471 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
3472 * This method returns if a feeding is needed.
3474 bool DataArrayDouble::resizeForUnserialization(const std::vector<int>& tinyInfoI)
3476 int nbOfTuple=tinyInfoI[0];
3477 int nbOfComp=tinyInfoI[1];
3478 if(nbOfTuple!=-1 || nbOfComp!=-1)
3480 alloc(nbOfTuple,nbOfComp);
3487 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
3489 void DataArrayDouble::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
3491 setName(tinyInfoS[0]);
3494 int nbOfCompo=getNumberOfComponents();
3495 for(int i=0;i<nbOfCompo;i++)
3496 setInfoOnComponent(i,tinyInfoS[i+1]);
3501 * Low static method that operates 3D rotation of 'nbNodes' 3D nodes whose coordinates are arranged in \a coordsIn
3502 * around an axe ( \a center, \a vect) and with angle \a angle.
3504 void DataArrayDouble::Rotate3DAlg(const double *center, const double *vect, double angle, int nbNodes, const double *coordsIn, double *coordsOut)
3506 if(!center || !vect)
3507 throw INTERP_KERNEL::Exception("DataArrayDouble::Rotate3DAlg : null vector in input !");
3508 double sina(sin(angle));
3509 double cosa(cos(angle));
3510 double vectorNorm[3];
3512 double matrixTmp[9];
3513 double norm(sqrt(vect[0]*vect[0]+vect[1]*vect[1]+vect[2]*vect[2]));
3514 if(norm<std::numeric_limits<double>::min())
3515 throw INTERP_KERNEL::Exception("DataArrayDouble::Rotate3DAlg : magnitude of input vector is too close of 0. !");
3516 std::transform(vect,vect+3,vectorNorm,std::bind2nd(std::multiplies<double>(),1/norm));
3517 //rotation matrix computation
3518 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;
3519 matrixTmp[0]=vectorNorm[0]*vectorNorm[0]; matrixTmp[1]=vectorNorm[0]*vectorNorm[1]; matrixTmp[2]=vectorNorm[0]*vectorNorm[2];
3520 matrixTmp[3]=vectorNorm[1]*vectorNorm[0]; matrixTmp[4]=vectorNorm[1]*vectorNorm[1]; matrixTmp[5]=vectorNorm[1]*vectorNorm[2];
3521 matrixTmp[6]=vectorNorm[2]*vectorNorm[0]; matrixTmp[7]=vectorNorm[2]*vectorNorm[1]; matrixTmp[8]=vectorNorm[2]*vectorNorm[2];
3522 std::transform(matrixTmp,matrixTmp+9,matrixTmp,std::bind2nd(std::multiplies<double>(),1-cosa));
3523 std::transform(matrix,matrix+9,matrixTmp,matrix,std::plus<double>());
3524 matrixTmp[0]=0.; matrixTmp[1]=-vectorNorm[2]; matrixTmp[2]=vectorNorm[1];
3525 matrixTmp[3]=vectorNorm[2]; matrixTmp[4]=0.; matrixTmp[5]=-vectorNorm[0];
3526 matrixTmp[6]=-vectorNorm[1]; matrixTmp[7]=vectorNorm[0]; matrixTmp[8]=0.;
3527 std::transform(matrixTmp,matrixTmp+9,matrixTmp,std::bind2nd(std::multiplies<double>(),sina));
3528 std::transform(matrix,matrix+9,matrixTmp,matrix,std::plus<double>());
3529 //rotation matrix computed.
3531 for(int i=0; i<nbNodes; i++)
3533 std::transform(coordsIn+i*3,coordsIn+(i+1)*3,center,tmp,std::minus<double>());
3534 coordsOut[i*3]=matrix[0]*tmp[0]+matrix[1]*tmp[1]+matrix[2]*tmp[2]+center[0];
3535 coordsOut[i*3+1]=matrix[3]*tmp[0]+matrix[4]*tmp[1]+matrix[5]*tmp[2]+center[1];
3536 coordsOut[i*3+2]=matrix[6]*tmp[0]+matrix[7]*tmp[1]+matrix[8]*tmp[2]+center[2];
3540 void DataArrayDouble::Symmetry3DPlane(const double point[3], const double normalVector[3], int nbNodes, const double *coordsIn, double *coordsOut)
3542 double matrix[9],matrix2[9],matrix3[9];
3543 double vect[3],crossVect[3];
3544 INTERP_KERNEL::orthogonalVect3(normalVector,vect);
3545 crossVect[0]=normalVector[1]*vect[2]-normalVector[2]*vect[1];
3546 crossVect[1]=normalVector[2]*vect[0]-normalVector[0]*vect[2];
3547 crossVect[2]=normalVector[0]*vect[1]-normalVector[1]*vect[0];
3548 double nv(INTERP_KERNEL::norm<3>(vect)),ni(INTERP_KERNEL::norm<3>(normalVector)),nc(INTERP_KERNEL::norm<3>(crossVect));
3549 matrix[0]=vect[0]/nv; matrix[1]=crossVect[0]/nc; matrix[2]=-normalVector[0]/ni;
3550 matrix[3]=vect[1]/nv; matrix[4]=crossVect[1]/nc; matrix[5]=-normalVector[1]/ni;
3551 matrix[6]=vect[2]/nv; matrix[7]=crossVect[2]/nc; matrix[8]=-normalVector[2]/ni;
3552 matrix2[0]=vect[0]/nv; matrix2[1]=vect[1]/nv; matrix2[2]=vect[2]/nv;
3553 matrix2[3]=crossVect[0]/nc; matrix2[4]=crossVect[1]/nc; matrix2[5]=crossVect[2]/nc;
3554 matrix2[6]=normalVector[0]/ni; matrix2[7]=normalVector[1]/ni; matrix2[8]=normalVector[2]/ni;
3555 for(int i=0;i<3;i++)
3556 for(int j=0;j<3;j++)
3559 for(int k=0;k<3;k++)
3560 val+=matrix[3*i+k]*matrix2[3*k+j];
3563 //rotation matrix computed.
3565 for(int i=0; i<nbNodes; i++)
3567 std::transform(coordsIn+i*3,coordsIn+(i+1)*3,point,tmp,std::minus<double>());
3568 coordsOut[i*3]=matrix3[0]*tmp[0]+matrix3[1]*tmp[1]+matrix3[2]*tmp[2]+point[0];
3569 coordsOut[i*3+1]=matrix3[3]*tmp[0]+matrix3[4]*tmp[1]+matrix3[5]*tmp[2]+point[1];
3570 coordsOut[i*3+2]=matrix3[6]*tmp[0]+matrix3[7]*tmp[1]+matrix3[8]*tmp[2]+point[2];
3574 void DataArrayDouble::GiveBaseForPlane(const double normalVector[3], double baseOfPlane[9])
3576 double vect[3],crossVect[3];
3577 INTERP_KERNEL::orthogonalVect3(normalVector,vect);
3578 crossVect[0]=normalVector[1]*vect[2]-normalVector[2]*vect[1];
3579 crossVect[1]=normalVector[2]*vect[0]-normalVector[0]*vect[2];
3580 crossVect[2]=normalVector[0]*vect[1]-normalVector[1]*vect[0];
3581 double nv(INTERP_KERNEL::norm<3>(vect)),ni(INTERP_KERNEL::norm<3>(normalVector)),nc(INTERP_KERNEL::norm<3>(crossVect));
3582 baseOfPlane[0]=vect[0]/nv; baseOfPlane[1]=vect[1]/nv; baseOfPlane[2]=vect[2]/nv;
3583 baseOfPlane[3]=crossVect[0]/nc; baseOfPlane[4]=crossVect[1]/nc; baseOfPlane[5]=crossVect[2]/nc;
3584 baseOfPlane[6]=normalVector[0]/ni; baseOfPlane[7]=normalVector[1]/ni; baseOfPlane[8]=normalVector[2]/ni;
3588 * Low static method that operates 3D rotation of \a nbNodes 3D nodes whose coordinates are arranged in \a coords
3589 * around the center point \a center and with angle \a angle.
3591 void DataArrayDouble::Rotate2DAlg(const double *center, double angle, int nbNodes, const double *coordsIn, double *coordsOut)
3593 double cosa=cos(angle);
3594 double sina=sin(angle);
3596 matrix[0]=cosa; matrix[1]=-sina; matrix[2]=sina; matrix[3]=cosa;
3598 for(int i=0; i<nbNodes; i++)
3600 std::transform(coordsIn+i*2,coordsIn+(i+1)*2,center,tmp,std::minus<double>());
3601 coordsOut[i*2]=matrix[0]*tmp[0]+matrix[1]*tmp[1]+center[0];
3602 coordsOut[i*2+1]=matrix[2]*tmp[0]+matrix[3]*tmp[1]+center[1];
3606 DataArrayDoubleIterator::DataArrayDoubleIterator(DataArrayDouble *da):DataArrayIterator<double>(da)
3610 DataArrayDoubleTuple::DataArrayDoubleTuple(double *pt, int nbOfComp):DataArrayTuple<double>(pt,nbOfComp)
3615 std::string DataArrayDoubleTuple::repr() const
3617 std::ostringstream oss; oss.precision(17); oss << "(";
3618 for(int i=0;i<_nb_of_compo-1;i++)
3619 oss << _pt[i] << ", ";
3620 oss << _pt[_nb_of_compo-1] << ")";
3624 double DataArrayDoubleTuple::doubleValue() const
3626 return this->zeValue();
3630 * This method returns a newly allocated instance the caller should dealed with by a MEDCoupling::DataArrayDouble::decrRef.
3631 * This method performs \b no copy of data. The content is only referenced using MEDCoupling::DataArrayDouble::useArray with ownership set to \b false.
3632 * 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
3633 * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
3635 DataArrayDouble *DataArrayDoubleTuple::buildDADouble(int nbOfTuples, int nbOfCompo) const
3637 return this->buildDA(nbOfTuples,nbOfCompo);
3641 * Returns a new instance of DataArrayInt. The caller is to delete this array
3642 * using decrRef() as it is no more needed.
3644 DataArrayInt *DataArrayInt::New()
3646 return new DataArrayInt;
3650 * Returns the only one value in \a this, if and only if number of elements
3651 * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
3652 * \return double - the sole value stored in \a this array.
3653 * \throw If at least one of conditions stated above is not fulfilled.
3655 int DataArrayInt::intValue() const
3659 if(getNbOfElems()==1)
3661 return *getConstPointer();
3664 throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is allocated but number of elements is not equal to 1 !");
3667 throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is not allocated !");
3671 * Returns an integer value characterizing \a this array, which is useful for a quick
3672 * comparison of many instances of DataArrayInt.
3673 * \return int - the hash value.
3674 * \throw If \a this is not allocated.
3676 int DataArrayInt::getHashCode() const
3679 std::size_t nbOfElems=getNbOfElems();
3680 int ret=nbOfElems*65536;
3685 const int *pt=begin();
3686 for(std::size_t i=0;i<nbOfElems;i+=delta)
3687 ret0+=pt[i] & 0x1FFF;
3692 * Returns a full copy of \a this. For more info on copying data arrays see
3693 * \ref MEDCouplingArrayBasicsCopyDeep.
3694 * \return DataArrayInt * - a new instance of DataArrayInt.
3696 DataArrayInt32 *DataArrayInt32::deepCopy() const
3698 return new DataArrayInt32(*this);
3702 * Returns a textual and human readable representation of \a this instance of
3703 * DataArrayInt. This text is shown when a DataArrayInt is printed in Python.
3704 * \return std::string - text describing \a this DataArrayInt.
3706 * \sa reprNotTooLong, reprZip
3708 std::string DataArrayInt::repr() const
3710 std::ostringstream ret;
3715 std::string DataArrayInt::reprZip() const
3717 std::ostringstream ret;
3722 void DataArrayInt::writeVTK(std::ostream& ofs, int indent, const std::string& type, const std::string& nameInFile, DataArrayByte *byteArr) const
3724 static const char SPACE[4]={' ',' ',' ',' '};
3726 std::string idt(indent,' ');
3727 ofs << idt << "<DataArray type=\"" << type << "\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
3730 ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
3731 if(std::string(type)=="Int32")
3733 const char *data(reinterpret_cast<const char *>(begin()));
3734 std::size_t sz(getNbOfElems()*sizeof(int));
3735 byteArr->insertAtTheEnd(data,data+sz);
3736 byteArr->insertAtTheEnd(SPACE,SPACE+4);
3738 else if(std::string(type)=="Int8")
3740 INTERP_KERNEL::AutoPtr<char> tmp(new char[getNbOfElems()]);
3741 std::copy(begin(),end(),(char *)tmp);
3742 byteArr->insertAtTheEnd((char *)tmp,(char *)tmp+getNbOfElems());
3743 byteArr->insertAtTheEnd(SPACE,SPACE+4);
3745 else if(std::string(type)=="UInt8")
3747 INTERP_KERNEL::AutoPtr<unsigned char> tmp(new unsigned char[getNbOfElems()]);
3748 std::copy(begin(),end(),(unsigned char *)tmp);
3749 byteArr->insertAtTheEnd((unsigned char *)tmp,(unsigned char *)tmp+getNbOfElems());
3750 byteArr->insertAtTheEnd(SPACE,SPACE+4);
3753 throw INTERP_KERNEL::Exception("DataArrayInt::writeVTK : Only Int32, Int8 and UInt8 supported !");
3757 ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
3758 std::copy(begin(),end(),std::ostream_iterator<int>(ofs," "));
3760 ofs << std::endl << idt << "</DataArray>\n";
3763 void DataArrayInt::reprCppStream(const std::string& varName, std::ostream& stream) const
3765 int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
3766 const int *data=getConstPointer();
3767 stream << "DataArrayInt *" << varName << "=DataArrayInt::New();" << std::endl;
3768 if(nbTuples*nbComp>=1)
3770 stream << "const int " << varName << "Data[" << nbTuples*nbComp << "]={";
3771 std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<int>(stream,","));
3772 stream << data[nbTuples*nbComp-1] << "};" << std::endl;
3773 stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
3776 stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
3777 stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
3781 * Method that gives a quick overvien of \a this for python.
3783 void DataArrayInt::reprQuickOverview(std::ostream& stream) const
3785 static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
3786 stream << "DataArrayInt C++ instance at " << this << ". ";
3789 int nbOfCompo=(int)_info_on_compo.size();
3792 int nbOfTuples=getNumberOfTuples();
3793 stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
3794 reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
3797 stream << "Number of components : 0.";
3800 stream << "*** No data allocated ****";
3803 void DataArrayInt::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
3805 const int *data=begin();
3806 int nbOfTuples=getNumberOfTuples();
3807 int nbOfCompo=(int)_info_on_compo.size();
3808 std::ostringstream oss2; oss2 << "[";
3809 std::string oss2Str(oss2.str());
3810 bool isFinished=true;
3811 for(int i=0;i<nbOfTuples && isFinished;i++)
3816 for(int j=0;j<nbOfCompo;j++,data++)
3819 if(j!=nbOfCompo-1) oss2 << ", ";
3825 if(i!=nbOfTuples-1) oss2 << ", ";
3826 std::string oss3Str(oss2.str());
3827 if(oss3Str.length()<maxNbOfByteInRepr)
3839 * Computes distribution of values of \a this one-dimensional array between given value
3840 * ranges (casts). This method is typically useful for entity number spliting by types,
3842 * \warning The values contained in \a arrBg should be sorted ascendently. No
3843 * check of this is be done. If not, the result is not warranted.
3844 * \param [in] arrBg - the array of ascending values defining the value ranges. The i-th
3845 * value of \a arrBg (\a arrBg[ i ]) gives the lowest value of the i-th range,
3846 * and the greatest value of the i-th range equals to \a arrBg[ i+1 ] - 1. \a
3847 * arrBg containing \a n values defines \a n-1 ranges. The last value of \a arrBg
3848 * should be more than every value in \a this array.
3849 * \param [in] arrEnd - specifies the end of the array \a arrBg, so that
3850 * the last value of \a arrBg is \a arrEnd[ -1 ].
3851 * \param [out] castArr - a new instance of DataArrayInt, of same size as \a this array
3852 * (same number of tuples and components), the caller is to delete
3853 * using decrRef() as it is no more needed.
3854 * This array contains indices of ranges for every value of \a this array. I.e.
3855 * the i-th value of \a castArr gives the index of range the i-th value of \a this
3856 * belongs to. Or, in other words, this parameter contains for each tuple in \a
3857 * this in which cast it holds.
3858 * \param [out] rankInsideCast - a new instance of DataArrayInt, of same size as \a this
3859 * array, the caller is to delete using decrRef() as it is no more needed.
3860 * This array contains ranks of values of \a this array within ranges
3861 * they belongs to. I.e. the i-th value of \a rankInsideCast gives the rank of
3862 * the i-th value of \a this array within the \a castArr[ i ]-th range, to which
3863 * the i-th value of \a this belongs to. Or, in other words, this param contains
3864 * for each tuple its rank inside its cast. The rank is computed as difference
3865 * between the value and the lowest value of range.
3866 * \param [out] castsPresent - a new instance of DataArrayInt, containing indices of
3867 * ranges (casts) to which at least one value of \a this array belongs.
3868 * Or, in other words, this param contains the casts that \a this contains.
3869 * The caller is to delete this array using decrRef() as it is no more needed.
3871 * \b Example: If \a this contains [6,5,0,3,2,7,8,1,4] and \a arrBg contains [0,4,9] then
3872 * the output of this method will be :
3873 * - \a castArr : [1,1,0,0,0,1,1,0,1]
3874 * - \a rankInsideCast: [2,1,0,3,2,3,4,1,0]
3875 * - \a castsPresent : [0,1]
3877 * I.e. values of \a this array belong to 2 ranges: #0 and #1. Value 6 belongs to the
3878 * range #1 and its rank within this range is 2; etc.
3880 * \throw If \a this->getNumberOfComponents() != 1.
3881 * \throw If \a arrEnd - arrBg < 2.
3882 * \throw If any value of \a this is not less than \a arrEnd[-1].
3884 void DataArrayInt::splitByValueRange(const int *arrBg, const int *arrEnd,
3885 DataArrayInt *& castArr, DataArrayInt *& rankInsideCast, DataArrayInt *& castsPresent) const
3888 if(getNumberOfComponents()!=1)
3889 throw INTERP_KERNEL::Exception("Call splitByValueRange method on DataArrayInt with only one component, you can call 'rearrange' method before !");
3890 int nbOfTuples=getNumberOfTuples();
3891 std::size_t nbOfCast=std::distance(arrBg,arrEnd);
3893 throw INTERP_KERNEL::Exception("DataArrayInt::splitByValueRange : The input array giving the cast range values should be of size >=2 !");
3895 const int *work=getConstPointer();
3896 typedef std::reverse_iterator<const int *> rintstart;
3897 rintstart bg(arrEnd);//OK no problem because size of 'arr' is greater or equal 2
3898 rintstart end2(arrBg);
3899 MCAuto<DataArrayInt> ret1=DataArrayInt::New();
3900 MCAuto<DataArrayInt> ret2=DataArrayInt::New();
3901 MCAuto<DataArrayInt> ret3=DataArrayInt::New();
3902 ret1->alloc(nbOfTuples,1);
3903 ret2->alloc(nbOfTuples,1);
3904 int *ret1Ptr=ret1->getPointer();
3905 int *ret2Ptr=ret2->getPointer();
3906 std::set<std::size_t> castsDetected;
3907 for(int i=0;i<nbOfTuples;i++)
3909 rintstart res=std::find_if(bg,end2,std::bind2nd(std::less_equal<int>(), work[i]));
3910 std::size_t pos=std::distance(bg,res);
3911 std::size_t pos2=nbOfCast-pos;
3914 ret1Ptr[i]=(int)pos2;
3915 ret2Ptr[i]=work[i]-arrBg[pos2];
3916 castsDetected.insert(pos2);
3920 std::ostringstream oss; oss << "DataArrayInt::splitByValueRange : At rank #" << i << " the value is " << work[i] << " should be in [0," << *bg << ") !";
3921 throw INTERP_KERNEL::Exception(oss.str().c_str());
3924 ret3->alloc((int)castsDetected.size(),1);
3925 std::copy(castsDetected.begin(),castsDetected.end(),ret3->getPointer());
3926 castArr=ret1.retn();
3927 rankInsideCast=ret2.retn();
3928 castsPresent=ret3.retn();
3932 * 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 ).
3933 * 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 ).
3934 * This method works only if \a this is allocated and single component. If not an exception will be thrown.
3936 * \param [out] strt - the start of the range (included) if true is returned.
3937 * \param [out] sttoopp - the end of the range (not included) if true is returned.
3938 * \param [out] stteepp - the step of the range if true is returned.
3939 * \return the verdict of the check.
3941 * \sa DataArray::GetNumberOfItemGivenBES
3943 bool DataArrayInt::isRange(int& strt, int& sttoopp, int& stteepp) const
3946 if(getNumberOfComponents()!=1)
3947 throw INTERP_KERNEL::Exception("DataArrayInt::isRange : this must be single component array !");
3948 int nbTuples(getNumberOfTuples());
3950 { strt=0; sttoopp=0; stteepp=1; return true; }
3951 const int *pt(begin());
3954 { sttoopp=strt+1; stteepp=1; return true; }
3955 strt=*pt; sttoopp=pt[nbTuples-1];
3961 int a(sttoopp-1-strt),tmp(strt);
3962 if(a%(nbTuples-1)!=0)
3964 stteepp=a/(nbTuples-1);
3965 for(int i=0;i<nbTuples;i++,tmp+=stteepp)
3973 int a(strt-sttoopp-1),tmp(strt);
3974 if(a%(nbTuples-1)!=0)
3976 stteepp=-(a/(nbTuples-1));
3977 for(int i=0;i<nbTuples;i++,tmp+=stteepp)
3986 * Modifies in place \a this one-dimensional array so that each value \a v = \a indArrBg[ \a v ],
3987 * i.e. a current value is used as in index to get a new value from \a indArrBg.
3988 * \param [in] indArrBg - pointer to the first element of array of new values to assign
3990 * \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
3991 * the last value of \a indArrBg is \a indArrEnd[ -1 ].
3992 * \throw If \a this->getNumberOfComponents() != 1
3993 * \throw If any value of \a this can't be used as a valid index for
3994 * [\a indArrBg, \a indArrEnd).
3996 * \sa changeValue, findIdForEach
3998 void DataArrayInt::transformWithIndArr(const int *indArrBg, const int *indArrEnd)
4000 this->checkAllocated();
4001 if(this->getNumberOfComponents()!=1)
4002 throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
4003 int nbElemsIn((int)std::distance(indArrBg,indArrEnd)),nbOfTuples(getNumberOfTuples()),*pt(getPointer());
4004 for(int i=0;i<nbOfTuples;i++,pt++)
4006 if(*pt>=0 && *pt<nbElemsIn)
4010 std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " of this value is " << *pt << ", should be in [0," << nbElemsIn << ") !";
4011 throw INTERP_KERNEL::Exception(oss.str());
4014 this->declareAsNew();
4017 void DataArrayInt::transformWithIndArr(const MapKeyVal<int>& m)
4019 this->checkAllocated();
4020 if(this->getNumberOfComponents()!=1)
4021 throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
4022 const std::map<int,int>& dat(m.data());
4023 int nbOfTuples(getNumberOfTuples()),*pt(getPointer());
4024 for(int i=0;i<nbOfTuples;i++,pt++)
4026 std::map<int,int>::const_iterator it(dat.find(*pt));
4031 std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " of this value is " << *pt << " not in map !";
4032 throw INTERP_KERNEL::Exception(oss.str());
4035 this->declareAsNew();
4039 * Creates a one-dimensional DataArrayInt (\a res) whose contents are computed from
4040 * values of \a this (\a a) and the given (\a indArr) arrays as follows:
4041 * \a res[ \a indArr[ \a a[ i ]]] = i. I.e. for each value in place i \a v = \a a[ i ],
4042 * new value in place \a indArr[ \a v ] is i.
4043 * \param [in] indArrBg - the array holding indices within the result array to assign
4044 * indices of values of \a this array pointing to values of \a indArrBg.
4045 * \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
4046 * the last value of \a indArrBg is \a indArrEnd[ -1 ].
4047 * \return DataArrayInt * - the new instance of DataArrayInt.
4048 * The caller is to delete this result array using decrRef() as it is no more
4050 * \throw If \a this->getNumberOfComponents() != 1.
4051 * \throw If any value of \a this array is not a valid index for \a indArrBg array.
4052 * \throw If any value of \a indArrBg is not a valid index for \a this array.
4054 DataArrayInt *DataArrayInt::transformWithIndArrR(const int *indArrBg, const int *indArrEnd) const
4057 if(getNumberOfComponents()!=1)
4058 throw INTERP_KERNEL::Exception("Call transformWithIndArrR method on DataArrayInt with only one component, you can call 'rearrange' method before !");
4059 int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
4060 int nbOfTuples=getNumberOfTuples();
4061 const int *pt=getConstPointer();
4062 MCAuto<DataArrayInt> ret=DataArrayInt::New();
4063 ret->alloc(nbOfTuples,1);
4064 ret->fillWithValue(-1);
4065 int *tmp=ret->getPointer();
4066 for(int i=0;i<nbOfTuples;i++,pt++)
4068 if(*pt>=0 && *pt<nbElemsIn)
4070 int pos=indArrBg[*pt];
4071 if(pos>=0 && pos<nbOfTuples)
4075 std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value of new pos is " << pos << " ( indArrBg[" << *pt << "]) ! Should be in [0," << nbOfTuples << ") !";
4076 throw INTERP_KERNEL::Exception(oss.str().c_str());
4081 std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn << " !";
4082 throw INTERP_KERNEL::Exception(oss.str().c_str());
4089 * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
4090 * from values of \a this array, which is supposed to contain a renumbering map in
4091 * "Old to New" mode. The result array contains a renumbering map in "New to Old" mode.
4092 * To know how to use the renumbering maps see \ref numbering.
4093 * \param [in] newNbOfElem - the number of tuples in the result array.
4094 * \return DataArrayInt * - the new instance of DataArrayInt.
4095 * The caller is to delete this result array using decrRef() as it is no more
4098 * \if ENABLE_EXAMPLES
4099 * \ref cpp_mcdataarrayint_invertarrayo2n2n2o "Here is a C++ example".<br>
4100 * \ref py_mcdataarrayint_invertarrayo2n2n2o "Here is a Python example".
4103 DataArrayInt *DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const
4105 MCAuto<DataArrayInt> ret(DataArrayInt::New());
4106 ret->alloc(newNbOfElem,1);
4107 int nbOfOldNodes(this->getNumberOfTuples());
4108 const int *old2New(begin());
4109 int *pt(ret->getPointer());
4110 for(int i=0;i!=nbOfOldNodes;i++)
4112 int newp(old2New[i]);
4115 if(newp>=0 && newp<newNbOfElem)
4119 std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2O : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
4120 throw INTERP_KERNEL::Exception(oss.str().c_str());
4128 * This method is similar to DataArrayInt::invertArrayO2N2N2O except that
4129 * 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]
4131 DataArrayInt *DataArrayInt::invertArrayO2N2N2OBis(int newNbOfElem) const
4133 MCAuto<DataArrayInt> ret=DataArrayInt::New();
4134 ret->alloc(newNbOfElem,1);
4135 int nbOfOldNodes=getNumberOfTuples();
4136 const int *old2New=getConstPointer();
4137 int *pt=ret->getPointer();
4138 for(int i=nbOfOldNodes-1;i>=0;i--)
4140 int newp(old2New[i]);
4143 if(newp>=0 && newp<newNbOfElem)
4147 std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2OBis : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
4148 throw INTERP_KERNEL::Exception(oss.str().c_str());
4156 * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
4157 * from values of \a this array, which is supposed to contain a renumbering map in
4158 * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
4159 * To know how to use the renumbering maps see \ref numbering.
4160 * \param [in] newNbOfElem - the number of tuples in the result array.
4161 * \return DataArrayInt * - the new instance of DataArrayInt.
4162 * The caller is to delete this result array using decrRef() as it is no more
4165 * \if ENABLE_EXAMPLES
4166 * \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
4168 * \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
4169 * \sa invertArrayN2O2O2NOptimized
4172 DataArrayInt *DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const
4175 MCAuto<DataArrayInt> ret=DataArrayInt::New();
4176 ret->alloc(oldNbOfElem,1);
4177 const int *new2Old=getConstPointer();
4178 int *pt=ret->getPointer();
4179 std::fill(pt,pt+oldNbOfElem,-1);
4180 int nbOfNewElems=getNumberOfTuples();
4181 for(int i=0;i<nbOfNewElems;i++)
4184 if(v>=0 && v<oldNbOfElem)
4188 std::ostringstream oss; oss << "DataArrayInt::invertArrayN2O2O2N : in new id #" << i << " old value is " << v << " expected to be in [0," << oldNbOfElem << ") !";
4189 throw INTERP_KERNEL::Exception(oss.str().c_str());
4196 * Creates a map, whose contents are computed
4197 * from values of \a this array, which is supposed to contain a renumbering map in
4198 * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
4199 * To know how to use the renumbering maps see \ref numbering.
4200 * \param [in] newNbOfElem - the number of tuples in the result array.
4201 * \return MapII - the new instance of Map.
4203 * \if ENABLE_EXAMPLES
4204 * \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
4206 * \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
4207 * \sa invertArrayN2O2O2N
4210 MCAuto< MapKeyVal<int> > DataArrayInt32::invertArrayN2O2O2NOptimized() const
4213 if(getNumberOfComponents()!=1)
4214 throw INTERP_KERNEL::Exception("DataArrayInt32::invertArrayN2O2O2NOptimized : single component expected !");
4215 MCAuto< MapKeyVal<int> > ret(MapKeyVal<int>::New());
4216 std::map<int,int>& m(ret->data());
4217 const int *new2Old(begin());
4218 std::size_t nbOfNewElems(this->getNumberOfTuples());
4219 for(std::size_t i=0;i<nbOfNewElems;i++)
4228 * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode.
4229 * This map, if applied to \a this array, would make it sorted. For example, if
4230 * \a this array contents are [9,10,0,6,4,11,3,7] then the contents of the result array
4231 * are [5,6,0,3,2,7,1,4]; if this result array (\a res) is used as an argument in call
4232 * \a this->renumber(\a res) then the returned array contains [0,3,4,6,7,9,10,11].
4233 * This method is useful for renumbering (in MED file for example). For more info
4234 * on renumbering see \ref numbering.
4235 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4236 * array using decrRef() as it is no more needed.
4237 * \throw If \a this is not allocated.
4238 * \throw If \a this->getNumberOfComponents() != 1.
4239 * \throw If there are equal values in \a this array.
4241 DataArrayInt *DataArrayInt::checkAndPreparePermutation() const
4244 if(getNumberOfComponents()!=1)
4245 throw INTERP_KERNEL::Exception("DataArrayInt::checkAndPreparePermutation : number of components must == 1 !");
4246 int nbTuples=getNumberOfTuples();
4247 const int *pt=getConstPointer();
4248 int *pt2=CheckAndPreparePermutation(pt,pt+nbTuples);
4249 DataArrayInt *ret=DataArrayInt::New();
4250 ret->useArray(pt2,true,C_DEALLOC,nbTuples,1);
4255 * This method tries to find the permutation to apply to the first input \a ids1 to obtain the same array (without considering strings information) the second
4256 * input array \a ids2.
4257 * \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.
4258 * 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
4260 * In case of success both assertion will be true (no throw) :
4261 * \c ids1->renumber(ret)->isEqual(ids2) where \a ret is the return of this method.
4262 * \c ret->transformWithIndArr(ids2)->isEqual(ids1)
4265 * - \a ids1 : [3,1,103,4,6,10,-7,205]
4266 * - \a ids2 : [-7,1,205,10,6,3,103,4]
4267 * - \a return is : [5,1,6,7,4,3,0,2] because ids2[5]==ids1[0], ids2[1]==ids1[1], ids2[6]==ids1[2]...
4269 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4270 * array using decrRef() as it is no more needed.
4271 * \throw If either ids1 or ids2 is null not allocated or not with one components.
4273 * \sa DataArrayInt32::findIdForEach
4275 DataArrayInt *DataArrayInt::FindPermutationFromFirstToSecond(const DataArrayInt *ids1, const DataArrayInt *ids2)
4278 throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be not null !");
4279 if(!ids1->isAllocated() || !ids2->isAllocated())
4280 throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be allocated !");
4281 if(ids1->getNumberOfComponents()!=1 || ids2->getNumberOfComponents()!=1)
4282 throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays have exactly one component !");
4283 if(ids1->getNumberOfTuples()!=ids2->getNumberOfTuples())
4285 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 !";
4286 throw INTERP_KERNEL::Exception(oss.str().c_str());
4288 MCAuto<DataArrayInt> p1(ids1->deepCopy());
4289 MCAuto<DataArrayInt> p2(ids2->deepCopy());
4290 p1->sort(true); p2->sort(true);
4291 if(!p1->isEqualWithoutConsideringStr(*p2))
4292 throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two arrays are not lying on same ids ! Impossible to find a permutation between the 2 arrays !");
4293 p1=ids1->checkAndPreparePermutation();
4294 p2=ids2->checkAndPreparePermutation();
4295 p2=p2->invertArrayO2N2N2O(p2->getNumberOfTuples());
4296 p2=p2->selectByTupleIdSafe(p1->begin(),p1->end());
4301 * Returns two arrays describing a surjective mapping from \a this set of values (\a A)
4302 * onto a set of values of size \a targetNb (\a B). The surjective function is
4303 * \a B[ \a A[ i ]] = i. That is to say that for each \a id in [0,\a targetNb), where \a
4304 * targetNb < \a this->getNumberOfTuples(), there exists at least one tupleId (\a tid) so
4305 * that <em> this->getIJ( tid, 0 ) == id</em>. <br>
4306 * The first of out arrays returns indices of elements of \a this array, grouped by their
4307 * place in the set \a B. The second out array is the index of the first one; it shows how
4308 * many elements of \a A are mapped into each element of \a B. <br>
4310 * mapping and its usage in renumbering see \ref numbering. <br>
4312 * - \a this: [0,3,2,3,2,2,1,2]
4314 * - \a arr: [0, 6, 2,4,5,7, 1,3]
4315 * - \a arrI: [0,1,2,6,8]
4317 * This result means: <br>
4318 * the element of \a B 0 encounters within \a A once (\a arrI[ 0+1 ] - \a arrI[ 0 ]) and
4319 * its index within \a A is 0 ( \a arr[ 0:1 ] == \a arr[ \a arrI[ 0 ] : \a arrI[ 0+1 ]]);<br>
4320 * the element of \a B 2 encounters within \a A 4 times (\a arrI[ 2+1 ] - \a arrI[ 2 ]) and
4321 * its indices within \a A are [2,4,5,7] ( \a arr[ 2:6 ] == \a arr[ \a arrI[ 2 ] :
4322 * \a arrI[ 2+1 ]]); <br> etc.
4323 * \param [in] targetNb - the size of the set \a B. \a targetNb must be equal or more
4324 * than the maximal value of \a A.
4325 * \param [out] arr - a new instance of DataArrayInt returning indices of
4326 * elements of \a this, grouped by their place in the set \a B. The caller is to delete
4327 * this array using decrRef() as it is no more needed.
4328 * \param [out] arrI - a new instance of DataArrayInt returning size of groups of equal
4329 * elements of \a this. The caller is to delete this array using decrRef() as it
4330 * is no more needed.
4331 * \throw If \a this is not allocated.
4332 * \throw If \a this->getNumberOfComponents() != 1.
4333 * \throw If any value in \a this is more or equal to \a targetNb.
4335 void DataArrayInt::changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, DataArrayInt *&arrI) const
4338 if(getNumberOfComponents()!=1)
4339 throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : number of components must == 1 !");
4340 int nbOfTuples=getNumberOfTuples();
4341 MCAuto<DataArrayInt> ret(DataArrayInt::New());
4342 MCAuto<DataArrayInt> retI(DataArrayInt::New());
4343 retI->alloc(targetNb+1,1);
4344 const int *input=getConstPointer();
4345 std::vector< std::vector<int> > tmp(targetNb);
4346 for(int i=0;i<nbOfTuples;i++)
4349 if(tmp2>=0 && tmp2<targetNb)
4350 tmp[tmp2].push_back(i);
4353 std::ostringstream oss; oss << "DataArrayInt::changeSurjectiveFormat : At pos " << i << " presence of element " << tmp2 << " ! should be in [0," << targetNb << ") !";
4354 throw INTERP_KERNEL::Exception(oss.str().c_str());
4357 int *retIPtr=retI->getPointer();
4359 for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++,retIPtr++)
4360 retIPtr[1]=retIPtr[0]+(int)((*it1).size());
4361 if(nbOfTuples!=retI->getIJ(targetNb,0))
4362 throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : big problem should never happen !");
4363 ret->alloc(nbOfTuples,1);
4364 int *retPtr=ret->getPointer();
4365 for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++)
4366 retPtr=std::copy((*it1).begin(),(*it1).end(),retPtr);
4373 * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode computed
4374 * from a zip representation of a surjective format (returned e.g. by
4375 * \ref MEDCoupling::DataArrayDouble::findCommonTuples() "DataArrayDouble::findCommonTuples()"
4376 * for example). The result array minimizes the permutation. <br>
4377 * For more info on renumbering see \ref numbering. <br>
4379 * - \a nbOfOldTuples: 10
4380 * - \a arr : [0,3, 5,7,9]
4381 * - \a arrIBg : [0,2,5]
4382 * - \a newNbOfTuples: 7
4383 * - result array : [0,1,2,0,3,4,5,4,6,4]
4385 * \param [in] nbOfOldTuples - number of tuples in the initial array \a arr.
4386 * \param [in] arr - the array of tuple indices grouped by \a arrIBg array.
4387 * \param [in] arrIBg - the array dividing all indices stored in \a arr into groups of
4388 * (indices of) equal values. Its every element (except the last one) points to
4389 * the first element of a group of equal values.
4390 * \param [in] arrIEnd - specifies the end of \a arrIBg, so that the last element of \a
4391 * arrIBg is \a arrIEnd[ -1 ].
4392 * \param [out] newNbOfTuples - number of tuples after surjection application.
4393 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4394 * array using decrRef() as it is no more needed.
4395 * \throw If any value of \a arr breaks condition ( 0 <= \a arr[ i ] < \a nbOfOldTuples ).
4397 DataArrayInt *DataArrayInt::ConvertIndexArrayToO2N(int nbOfOldTuples, const int *arr, const int *arrIBg, const int *arrIEnd, int &newNbOfTuples)
4399 MCAuto<DataArrayInt> ret=DataArrayInt::New();
4400 ret->alloc(nbOfOldTuples,1);
4401 int *pt=ret->getPointer();
4402 std::fill(pt,pt+nbOfOldTuples,-1);
4403 int nbOfGrps=((int)std::distance(arrIBg,arrIEnd))-1;
4404 const int *cIPtr=arrIBg;
4405 for(int i=0;i<nbOfGrps;i++)
4406 pt[arr[cIPtr[i]]]=-(i+2);
4408 for(int iNode=0;iNode<nbOfOldTuples;iNode++)
4416 int grpId=-(pt[iNode]+2);
4417 for(int j=cIPtr[grpId];j<cIPtr[grpId+1];j++)
4419 if(arr[j]>=0 && arr[j]<nbOfOldTuples)
4423 std::ostringstream oss; oss << "DataArrayInt::ConvertIndexArrayToO2N : With element #" << j << " value is " << arr[j] << " should be in [0," << nbOfOldTuples << ") !";
4424 throw INTERP_KERNEL::Exception(oss.str().c_str());
4431 newNbOfTuples=newNb;
4436 * Returns a new DataArrayInt containing a renumbering map in "New to Old" mode,
4437 * which if applied to \a this array would make it sorted ascendingly.
4438 * For more info on renumbering see \ref numbering. <br>
4440 * - \a this: [2,0,1,1,0,1,2,0,1,1,0,0]
4441 * - result: [10,0,5,6,1,7,11,2,8,9,3,4]
4442 * - after applying result to \a this: [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2]
4444 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4445 * array using decrRef() as it is no more needed.
4446 * \throw If \a this is not allocated.
4447 * \throw If \a this->getNumberOfComponents() != 1.
4449 DataArrayInt *DataArrayInt::buildPermArrPerLevel() const
4452 if(getNumberOfComponents()!=1)
4453 throw INTERP_KERNEL::Exception("DataArrayInt::buildPermArrPerLevel : number of components must == 1 !");
4454 int nbOfTuples=getNumberOfTuples();
4455 const int *pt=getConstPointer();
4456 std::map<int,int> m;
4457 MCAuto<DataArrayInt> ret=DataArrayInt::New();
4458 ret->alloc(nbOfTuples,1);
4459 int *opt=ret->getPointer();
4460 for(int i=0;i<nbOfTuples;i++,pt++,opt++)
4463 std::map<int,int>::iterator it=m.find(val);
4472 m.insert(std::pair<int,int>(val,1));
4476 for(std::map<int,int>::iterator it=m.begin();it!=m.end();it++)
4478 int vt=(*it).second;
4482 pt=getConstPointer();
4483 opt=ret->getPointer();
4484 for(int i=0;i<nbOfTuples;i++,pt++,opt++)
4491 * Checks if \a this array has the given size, and if its contents is equal to an array filled with
4492 * iota(). This method is particularly useful for DataArrayInt instances that represent
4493 * a renumbering array, to check if there is a real need in renumbering.
4494 * This method checks than \a this can be considered as an identity mapping
4495 * of a set having \a sizeExpected elements into itself.
4497 * \param [in] sizeExpected - The number of elements expected.
4498 * \return bool - \a true if \a this array contents == \a range( \a this->getNumberOfTuples())
4499 * \throw If \a this is not allocated.
4500 * \throw If \a this->getNumberOfComponents() != 1.
4502 bool DataArrayInt::isIota(int sizeExpected) const
4505 if(getNumberOfComponents()!=1)
4507 int nbOfTuples(getNumberOfTuples());
4508 if(nbOfTuples!=sizeExpected)
4510 const int *pt=getConstPointer();
4511 for(int i=0;i<nbOfTuples;i++,pt++)
4518 * Checks if all values in \a this array are equal to \a val.
4519 * \param [in] val - value to check equality of array values to.
4520 * \return bool - \a true if all values are \a val.
4521 * \throw If \a this is not allocated.
4522 * \throw If \a this->getNumberOfComponents() != 1
4523 * \sa DataArrayInt::checkUniformAndGuess
4525 bool DataArrayInt::isUniform(int val) const
4528 if(getNumberOfComponents()!=1)
4529 throw INTERP_KERNEL::Exception("DataArrayInt::isUniform : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
4530 const int *w(begin()),*end2(end());
4538 * This method checks that \a this is uniform. If not and exception will be thrown.
4539 * In case of uniformity the corresponding value is returned.
4541 * \return int - the unique value contained in this
4542 * \throw If \a this is not allocated.
4543 * \throw If \a this->getNumberOfComponents() != 1
4544 * \throw If \a this is not uniform.
4545 * \sa DataArrayInt::isUniform
4547 int DataArrayInt::checkUniformAndGuess() const
4550 if(getNumberOfComponents()!=1)
4551 throw INTERP_KERNEL::Exception("DataArrayInt::checkUniformAndGuess : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
4553 throw INTERP_KERNEL::Exception("DataArrayInt::checkUniformAndGuess : this is empty !");
4554 const int *w(begin()),*end2(end());
4558 throw INTERP_KERNEL::Exception("DataArrayInt::checkUniformAndGuess : this is not uniform !");
4563 * Checks if all values in \a this array are unique.
4564 * \return bool - \a true if condition above is true
4565 * \throw If \a this is not allocated.
4566 * \throw If \a this->getNumberOfComponents() != 1
4568 bool DataArrayInt::hasUniqueValues() const
4571 if(getNumberOfComponents()!=1)
4572 throw INTERP_KERNEL::Exception("DataArrayInt::hasOnlyUniqueValues: must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
4573 std::size_t nbOfTuples(getNumberOfTuples());
4574 std::set<int> s(begin(),end()); // in C++11, should use unordered_set (O(1) complexity)
4575 if (s.size() != nbOfTuples)
4581 * Copy all components in a specified order from another DataArrayInt.
4582 * The specified components become the first ones in \a this array.
4583 * Both numerical and textual data is copied. The number of tuples in \a this and
4584 * the other array can be different.
4585 * \param [in] a - the array to copy data from.
4586 * \param [in] compoIds - sequence of zero based indices of components, data of which is
4588 * \throw If \a a is NULL.
4589 * \throw If \a compoIds.size() != \a a->getNumberOfComponents().
4590 * \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
4592 * \if ENABLE_EXAMPLES
4593 * \ref py_mcdataarrayint_setselectedcomponents "Here is a Python example".
4596 void DataArrayInt::setSelectedComponents(const DataArrayInt *a, const std::vector<int>& compoIds)
4599 throw INTERP_KERNEL::Exception("DataArrayInt::setSelectedComponents : input DataArrayInt is NULL !");
4601 a->checkAllocated();
4602 copyPartOfStringInfoFrom2(compoIds,*a);
4603 std::size_t partOfCompoSz=compoIds.size();
4604 int nbOfCompo=getNumberOfComponents();
4605 int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
4606 const int *ac=a->getConstPointer();
4607 int *nc=getPointer();
4608 for(int i=0;i<nbOfTuples;i++)
4609 for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
4610 nc[nbOfCompo*i+compoIds[j]]=*ac;
4613 DataArrayIntIterator *DataArrayInt::iterator()
4615 return new DataArrayIntIterator(this);
4619 * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to a
4620 * given one. The ids are sorted in the ascending order.
4621 * \param [in] val - the value to find within \a this.
4622 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4623 * array using decrRef() as it is no more needed.
4624 * \throw If \a this is not allocated.
4625 * \throw If \a this->getNumberOfComponents() != 1.
4626 * \sa DataArrayInt::findIdsEqualTuple
4628 DataArrayInt *DataArrayInt::findIdsEqual(int val) const
4631 if(getNumberOfComponents()!=1)
4632 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqual : the array must have only one component, you can call 'rearrange' method before !");
4633 const int *cptr(getConstPointer());
4634 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4635 int nbOfTuples=getNumberOfTuples();
4636 for(int i=0;i<nbOfTuples;i++,cptr++)
4638 ret->pushBackSilent(i);
4643 * Creates a new DataArrayInt containing IDs (indices) of tuples holding value \b not
4644 * equal to a given one.
4645 * \param [in] val - the value to ignore within \a this.
4646 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4647 * array using decrRef() as it is no more needed.
4648 * \throw If \a this is not allocated.
4649 * \throw If \a this->getNumberOfComponents() != 1.
4651 DataArrayInt *DataArrayInt::findIdsNotEqual(int val) const
4654 if(getNumberOfComponents()!=1)
4655 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotEqual : the array must have only one component, you can call 'rearrange' method before !");
4656 const int *cptr(getConstPointer());
4657 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4658 int nbOfTuples=getNumberOfTuples();
4659 for(int i=0;i<nbOfTuples;i++,cptr++)
4661 ret->pushBackSilent(i);
4666 * Creates a new DataArrayInt containing IDs (indices) of tuples holding tuple equal to those defined by [ \a tupleBg , \a tupleEnd )
4667 * This method is an extension of DataArrayInt::findIdsEqual method.
4669 * \param [in] tupleBg - the begin (included) of the input tuple to find within \a this.
4670 * \param [in] tupleEnd - the end (excluded) of the input tuple to find within \a this.
4671 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4672 * array using decrRef() as it is no more needed.
4673 * \throw If \a this is not allocated.
4674 * \throw If \a this->getNumberOfComponents() != std::distance(tupleBg,tupleEnd).
4675 * \throw If \a this->getNumberOfComponents() is equal to 0.
4676 * \sa DataArrayInt::findIdsEqual
4678 DataArrayInt *DataArrayInt::findIdsEqualTuple(const int *tupleBg, const int *tupleEnd) const
4680 std::size_t nbOfCompoExp(std::distance(tupleBg,tupleEnd));
4682 if(getNumberOfComponents()!=nbOfCompoExp)
4684 std::ostringstream oss; oss << "DataArrayInt::findIdsEqualTuple : mismatch of number of components. Input tuple has " << nbOfCompoExp << " whereas this array has " << getNumberOfComponents() << " components !";
4685 throw INTERP_KERNEL::Exception(oss.str().c_str());
4688 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqualTuple : number of components should be > 0 !");
4689 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4690 const int *bg(begin()),*end2(end()),*work(begin());
4693 work=std::search(work,end2,tupleBg,tupleEnd);
4696 std::size_t pos(std::distance(bg,work));
4697 if(pos%nbOfCompoExp==0)
4698 ret->pushBackSilent(pos/nbOfCompoExp);
4706 * This method finds for each element \a ELT in [valsBg,valsEnd) elements in \a this equal to it. Associated to ELT
4707 * this method will return the tuple id of last element found. If there is no element in \a this equal to ELT
4708 * an exception will be thrown.
4710 * In case of success this[ret]==vals. Samely ret->transformWithIndArr(this->begin(),this->end())==vals.
4711 * Where \a vals is the [valsBg,valsEnd) array and \a ret the array returned by this method.
4712 * This method can be seen as an extension of FindPermutationFromFirstToSecond.
4715 * - \a this: [17,27,2,10,-4,3,12,27,16]
4716 * - \a val : [3,16,-4,27,17]
4717 * - result: [5,8,4,7,0]
4719 * \return - An array of size std::distance(valsBg,valsEnd)
4721 * \sa DataArrayInt32::FindPermutationFromFirstToSecond
4723 MCAuto<DataArrayInt32> DataArrayInt32::findIdForEach(const int *valsBg, const int *valsEnd) const
4725 MCAuto<DataArrayInt32> ret(DataArrayInt32::New());
4726 std::size_t nbOfTuplesOut(std::distance(valsBg,valsEnd));
4727 ret->alloc(nbOfTuplesOut,1);
4728 MCAuto< MapKeyVal<int> > zeMap(invertArrayN2O2O2NOptimized());
4729 const std::map<int,int>& dat(zeMap->data());
4730 int *ptToFeed(ret->getPointer());
4731 for(const int *pt=valsBg;pt!=valsEnd;pt++)
4733 std::map<int,int>::const_iterator it(dat.find(*pt));
4735 *ptToFeed++=(*it).second;
4738 std::ostringstream oss; oss << "DataArrayInt32::findIdForEach : error for element at place " << std::distance(valsBg,pt);
4739 oss << " of input array value is " << *pt << " which is not in this !";
4740 throw INTERP_KERNEL::Exception(oss.str());
4747 * Assigns \a newValue to all elements holding \a oldValue within \a this
4748 * one-dimensional array.
4749 * \param [in] oldValue - the value to replace.
4750 * \param [in] newValue - the value to assign.
4751 * \return int - number of replacements performed.
4752 * \throw If \a this is not allocated.
4753 * \throw If \a this->getNumberOfComponents() != 1.
4755 int DataArrayInt::changeValue(int oldValue, int newValue)
4758 if(getNumberOfComponents()!=1)
4759 throw INTERP_KERNEL::Exception("DataArrayInt::changeValue : the array must have only one component, you can call 'rearrange' method before !");
4760 if(oldValue==newValue)
4762 int *start(getPointer()),*end2(start+getNbOfElems());
4764 for(int *val=start;val!=end2;val++)
4778 * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to
4779 * one of given values.
4780 * \param [in] valsBg - an array of values to find within \a this array.
4781 * \param [in] valsEnd - specifies the end of the array \a valsBg, so that
4782 * the last value of \a valsBg is \a valsEnd[ -1 ].
4783 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4784 * array using decrRef() as it is no more needed.
4785 * \throw If \a this->getNumberOfComponents() != 1.
4787 DataArrayInt *DataArrayInt::findIdsEqualList(const int *valsBg, const int *valsEnd) const
4789 if(getNumberOfComponents()!=1)
4790 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqualList : the array must have only one component, you can call 'rearrange' method before !");
4791 std::set<int> vals2(valsBg,valsEnd);
4792 const int *cptr(getConstPointer());
4793 std::vector<int> res;
4794 int nbOfTuples(getNumberOfTuples());
4795 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4796 for(int i=0;i<nbOfTuples;i++,cptr++)
4797 if(vals2.find(*cptr)!=vals2.end())
4798 ret->pushBackSilent(i);
4803 * Creates a new DataArrayInt containing IDs (indices) of tuples holding values \b not
4804 * equal to any of given values.
4805 * \param [in] valsBg - an array of values to ignore within \a this array.
4806 * \param [in] valsEnd - specifies the end of the array \a valsBg, so that
4807 * the last value of \a valsBg is \a valsEnd[ -1 ].
4808 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
4809 * array using decrRef() as it is no more needed.
4810 * \throw If \a this->getNumberOfComponents() != 1.
4812 DataArrayInt *DataArrayInt::findIdsNotEqualList(const int *valsBg, const int *valsEnd) const
4814 if(getNumberOfComponents()!=1)
4815 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotEqualList : the array must have only one component, you can call 'rearrange' method before !");
4816 std::set<int> vals2(valsBg,valsEnd);
4817 const int *cptr=getConstPointer();
4818 std::vector<int> res;
4819 int nbOfTuples=getNumberOfTuples();
4820 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
4821 for(int i=0;i<nbOfTuples;i++,cptr++)
4822 if(vals2.find(*cptr)==vals2.end())
4823 ret->pushBackSilent(i);
4828 * This method is an extension of DataArrayInt::findIdFirstEqual method because this method works for DataArrayInt with
4829 * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
4830 * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
4831 * If any the tuple id is returned. If not -1 is returned.
4833 * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
4834 * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
4836 * \return tuple id where \b tupl is. -1 if no such tuple exists in \b this.
4837 * \sa DataArrayInt::findIdSequence, DataArrayInt::presenceOfTuple.
4839 int DataArrayInt::findIdFirstEqualTuple(const std::vector<int>& tupl) const
4842 int nbOfCompo=getNumberOfComponents();
4844 throw INTERP_KERNEL::Exception("DataArrayInt::findIdFirstEqualTuple : 0 components in 'this' !");
4845 if(nbOfCompo!=(int)tupl.size())
4847 std::ostringstream oss; oss << "DataArrayInt::findIdFirstEqualTuple : 'this' contains " << nbOfCompo << " components and searching for a tuple of length " << tupl.size() << " !";
4848 throw INTERP_KERNEL::Exception(oss.str().c_str());
4850 const int *cptr=getConstPointer();
4851 std::size_t nbOfVals=getNbOfElems();
4852 for(const int *work=cptr;work!=cptr+nbOfVals;)
4854 work=std::search(work,cptr+nbOfVals,tupl.begin(),tupl.end());
4855 if(work!=cptr+nbOfVals)
4857 if(std::distance(cptr,work)%nbOfCompo!=0)
4860 return std::distance(cptr,work)/nbOfCompo;
4867 * This method searches the sequence specified in input parameter \b vals in \b this.
4868 * This works only for DataArrayInt having number of components equal to one (if not an INTERP_KERNEL::Exception will be thrown).
4869 * This method differs from DataArrayInt::findIdFirstEqualTuple in that the position is internal raw data is not considered here contrary to DataArrayInt::findIdFirstEqualTuple.
4870 * \sa DataArrayInt::findIdFirstEqualTuple
4872 int DataArrayInt::findIdSequence(const std::vector<int>& vals) const
4875 int nbOfCompo=getNumberOfComponents();
4877 throw INTERP_KERNEL::Exception("DataArrayInt::findIdSequence : works only for DataArrayInt instance with one component !");
4878 const int *cptr=getConstPointer();
4879 std::size_t nbOfVals=getNbOfElems();
4880 const int *loc=std::search(cptr,cptr+nbOfVals,vals.begin(),vals.end());
4881 if(loc!=cptr+nbOfVals)
4882 return std::distance(cptr,loc);
4887 * This method expects to be called when number of components of this is equal to one.
4888 * This method returns the tuple id, if it exists, of the first tuple equal to \b value.
4889 * If not any tuple contains \b value -1 is returned.
4890 * \sa DataArrayInt::presenceOfValue
4892 int DataArrayInt::findIdFirstEqual(int value) const
4895 if(getNumberOfComponents()!=1)
4896 throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
4897 const int *cptr=getConstPointer();
4898 int nbOfTuples=getNumberOfTuples();
4899 const int *ret=std::find(cptr,cptr+nbOfTuples,value);
4900 if(ret!=cptr+nbOfTuples)
4901 return std::distance(cptr,ret);
4906 * This method expects to be called when number of components of this is equal to one.
4907 * This method returns the tuple id, if it exists, of the first tuple so that the value is contained in \b vals.
4908 * If not any tuple contains one of the values contained in 'vals' -1 is returned.
4909 * \sa DataArrayInt::presenceOfValue
4911 int DataArrayInt::findIdFirstEqual(const std::vector<int>& vals) const
4914 if(getNumberOfComponents()!=1)
4915 throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
4916 std::set<int> vals2(vals.begin(),vals.end());
4917 const int *cptr=getConstPointer();
4918 int nbOfTuples=getNumberOfTuples();
4919 for(const int *w=cptr;w!=cptr+nbOfTuples;w++)
4920 if(vals2.find(*w)!=vals2.end())
4921 return std::distance(cptr,w);
4926 * This method returns the number of values in \a this that are equals to input parameter \a value.
4927 * This method only works for single component array.
4929 * \return a value in [ 0, \c this->getNumberOfTuples() )
4931 * \throw If \a this is not allocated
4934 int DataArrayInt::count(int value) const
4938 if(getNumberOfComponents()!=1)
4939 throw INTERP_KERNEL::Exception("DataArrayInt::count : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
4940 const int *vals=begin();
4941 int nbOfTuples=getNumberOfTuples();
4942 for(int i=0;i<nbOfTuples;i++,vals++)
4949 * This method is an extension of DataArrayInt::presenceOfValue method because this method works for DataArrayInt with
4950 * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
4951 * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
4952 * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
4953 * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
4954 * \sa DataArrayInt::findIdFirstEqualTuple
4956 bool DataArrayInt::presenceOfTuple(const std::vector<int>& tupl) const
4958 return findIdFirstEqualTuple(tupl)!=-1;
4963 * Returns \a true if a given value is present within \a this one-dimensional array.
4964 * \param [in] value - the value to find within \a this array.
4965 * \return bool - \a true in case if \a value is present within \a this array.
4966 * \throw If \a this is not allocated.
4967 * \throw If \a this->getNumberOfComponents() != 1.
4968 * \sa findIdFirstEqual()
4970 bool DataArrayInt::presenceOfValue(int value) const
4972 return findIdFirstEqual(value)!=-1;
4976 * This method expects to be called when number of components of this is equal to one.
4977 * This method returns true if it exists a tuple so that the value is contained in \b vals.
4978 * If not any tuple contains one of the values contained in 'vals' false is returned.
4979 * \sa DataArrayInt::findIdFirstEqual
4981 bool DataArrayInt::presenceOfValue(const std::vector<int>& vals) const
4983 return findIdFirstEqual(vals)!=-1;
4987 * Accumulates values of each component of \a this array.
4988 * \param [out] res - an array of length \a this->getNumberOfComponents(), allocated
4989 * by the caller, that is filled by this method with sum value for each
4991 * \throw If \a this is not allocated.
4993 void DataArrayInt::accumulate(int *res) const
4996 const int *ptr=getConstPointer();
4997 int nbTuple=getNumberOfTuples();
4998 int nbComps=getNumberOfComponents();
4999 std::fill(res,res+nbComps,0);
5000 for(int i=0;i<nbTuple;i++)
5001 std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<int>());
5004 int DataArrayInt::accumulate(int compId) const
5007 const int *ptr=getConstPointer();
5008 int nbTuple=getNumberOfTuples();
5009 int nbComps=getNumberOfComponents();
5010 if(compId<0 || compId>=nbComps)
5011 throw INTERP_KERNEL::Exception("DataArrayInt::accumulate : Invalid compId specified : No such nb of components !");
5013 for(int i=0;i<nbTuple;i++)
5014 ret+=ptr[i*nbComps+compId];
5019 * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
5020 * The returned array will have same number of components than \a this and number of tuples equal to
5021 * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
5023 * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
5025 * \param [in] bgOfIndex - begin (included) of the input index array.
5026 * \param [in] endOfIndex - end (excluded) of the input index array.
5027 * \return DataArrayInt * - the new instance having the same number of components than \a this.
5029 * \throw If bgOfIndex or end is NULL.
5030 * \throw If input index array is not ascendingly sorted.
5031 * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
5032 * \throw If std::distance(bgOfIndex,endOfIndex)==0.
5034 DataArrayInt *DataArrayInt::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
5036 if(!bgOfIndex || !endOfIndex)
5037 throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : input pointer NULL !");
5039 int nbCompo=getNumberOfComponents();
5040 int nbOfTuples=getNumberOfTuples();
5041 int sz=(int)std::distance(bgOfIndex,endOfIndex);
5043 throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : invalid size of input index array !");
5045 MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(sz,nbCompo);
5046 const int *w=bgOfIndex;
5047 if(*w<0 || *w>=nbOfTuples)
5048 throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
5049 const int *srcPt=begin()+(*w)*nbCompo;
5050 int *tmp=ret->getPointer();
5051 for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
5053 std::fill(tmp,tmp+nbCompo,0);
5056 for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
5058 if(j>=0 && j<nbOfTuples)
5059 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<int>());
5062 std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
5063 throw INTERP_KERNEL::Exception(oss.str().c_str());
5069 std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
5070 throw INTERP_KERNEL::Exception(oss.str().c_str());
5073 ret->copyStringInfoFrom(*this);
5078 * Returns a new DataArrayInt by concatenating two given arrays, so that (1) the number
5079 * of tuples in the result array is <em> a1->getNumberOfTuples() + a2->getNumberOfTuples() -
5080 * offsetA2</em> and (2)
5081 * the number of component in the result array is same as that of each of given arrays.
5082 * First \a offsetA2 tuples of \a a2 are skipped and thus are missing from the result array.
5083 * Info on components is copied from the first of the given arrays. Number of components
5084 * in the given arrays must be the same.
5085 * \param [in] a1 - an array to include in the result array.
5086 * \param [in] a2 - another array to include in the result array.
5087 * \param [in] offsetA2 - number of tuples of \a a2 to skip.
5088 * \return DataArrayInt * - the new instance of DataArrayInt.
5089 * The caller is to delete this result array using decrRef() as it is no more
5091 * \throw If either \a a1 or \a a2 is NULL.
5092 * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
5094 DataArrayInt *DataArrayInt::Aggregate(const DataArrayInt *a1, const DataArrayInt *a2, int offsetA2)
5097 throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input DataArrayInt instance is NULL !");
5098 std::size_t nbOfComp(a1->getNumberOfComponents());
5099 if(nbOfComp!=a2->getNumberOfComponents())
5100 throw INTERP_KERNEL::Exception("Nb of components mismatch for array Aggregation !");
5101 std::size_t nbOfTuple1(a1->getNumberOfTuples()),nbOfTuple2(a2->getNumberOfTuples());
5102 MCAuto<DataArrayInt> ret(DataArrayInt::New());
5103 ret->alloc(nbOfTuple1+nbOfTuple2-offsetA2,nbOfComp);
5104 int *pt=std::copy(a1->begin(),a1->end(),ret->getPointer());
5105 std::copy(a2->getConstPointer()+offsetA2*nbOfComp,a2->getConstPointer()+nbOfTuple2*nbOfComp,pt);
5106 ret->copyStringInfoFrom(*a1);
5111 * Returns a new DataArrayInt by concatenating all given arrays, so that (1) the number
5112 * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
5113 * the number of component in the result array is same as that of each of given arrays.
5114 * Info on components is copied from the first of the given arrays. Number of components
5115 * in the given arrays must be the same.
5116 * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it
5117 * not the object itself.
5118 * \param [in] arr - a sequence of arrays to include in the result array.
5119 * \return DataArrayInt * - the new instance of DataArrayInt.
5120 * The caller is to delete this result array using decrRef() as it is no more
5122 * \throw If all arrays within \a arr are NULL.
5123 * \throw If getNumberOfComponents() of arrays within \a arr.
5125 DataArrayInt *DataArrayInt::Aggregate(const std::vector<const DataArrayInt *>& arr)
5127 std::vector<const DataArrayInt *> a;
5128 for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
5132 throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input list must be NON EMPTY !");
5133 std::vector<const DataArrayInt *>::const_iterator it=a.begin();
5134 std::size_t nbOfComp((*it)->getNumberOfComponents()),nbt((*it++)->getNumberOfTuples());
5135 for(int i=1;it!=a.end();it++,i++)
5137 if((*it)->getNumberOfComponents()!=nbOfComp)
5138 throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : Nb of components mismatch for array aggregation !");
5139 nbt+=(*it)->getNumberOfTuples();
5141 MCAuto<DataArrayInt> ret=DataArrayInt::New();
5142 ret->alloc(nbt,nbOfComp);
5143 int *pt=ret->getPointer();
5144 for(it=a.begin();it!=a.end();it++)
5145 pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
5146 ret->copyStringInfoFrom(*(a[0]));
5151 * This method takes as input a list of DataArrayInt instances \a arrs that represent each a packed index arrays.
5152 * A packed index array is an allocated array with one component, and at least one tuple. The first element
5153 * of each array in \a arrs must be 0. Each array in \a arrs is expected to be increasingly monotonic.
5154 * 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.
5156 * \return DataArrayInt * - a new object to be managed by the caller.
5158 DataArrayInt *DataArrayInt::AggregateIndexes(const std::vector<const DataArrayInt *>& arrs)
5161 for(std::vector<const DataArrayInt *>::const_iterator it4=arrs.begin();it4!=arrs.end();it4++)
5165 (*it4)->checkAllocated();
5166 if((*it4)->getNumberOfComponents()!=1)
5168 std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of compo != 1 at pos " << std::distance(arrs.begin(),it4) << " !";
5169 throw INTERP_KERNEL::Exception(oss.str().c_str());
5171 int nbTupl=(*it4)->getNumberOfTuples();
5174 std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of tuples < 1 at pos " << std::distance(arrs.begin(),it4) << " !";
5175 throw INTERP_KERNEL::Exception(oss.str().c_str());
5177 if((*it4)->front()!=0)
5179 std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with front value != 0 at pos " << std::distance(arrs.begin(),it4) << " !";
5180 throw INTERP_KERNEL::Exception(oss.str().c_str());
5186 std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a null instance at pos " << std::distance(arrs.begin(),it4) << " !";
5187 throw INTERP_KERNEL::Exception(oss.str().c_str());
5191 throw INTERP_KERNEL::Exception("DataArrayInt::AggregateIndexes : input list must be NON EMPTY !");
5192 MCAuto<DataArrayInt> ret=DataArrayInt::New();
5193 ret->alloc(retSz,1);
5194 int *pt=ret->getPointer(); *pt++=0;
5195 for(std::vector<const DataArrayInt *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
5196 pt=std::transform((*it)->begin()+1,(*it)->end(),pt,std::bind2nd(std::plus<int>(),pt[-1]));
5197 ret->copyStringInfoFrom(*(arrs[0]));
5202 * Returns in a single walk in \a this the min value and the max value in \a this.
5203 * \a this is expected to be single component array.
5205 * \param [out] minValue - the min value in \a this.
5206 * \param [out] maxValue - the max value in \a this.
5208 * \sa getMinValueInArray, getMinValue, getMaxValueInArray, getMaxValue
5210 void DataArrayInt::getMinMaxValues(int& minValue, int& maxValue) const
5213 if(getNumberOfComponents()!=1)
5214 throw INTERP_KERNEL::Exception("DataArrayInt::getMinMaxValues : must be applied on DataArrayInt with only one component !");
5215 int nbTuples(getNumberOfTuples());
5216 const int *pt(begin());
5217 minValue=std::numeric_limits<int>::max(); maxValue=-std::numeric_limits<int>::max();
5218 for(int i=0;i<nbTuples;i++,pt++)
5228 * Modify all elements of \a this array, so that
5229 * an element _x_ becomes \f$ numerator / x \f$.
5230 * \warning If an exception is thrown because of presence of 0 element in \a this
5231 * array, all elements processed before detection of the zero element remain
5233 * \param [in] numerator - the numerator used to modify array elements.
5234 * \throw If \a this is not allocated.
5235 * \throw If there is an element equal to 0 in \a this array.
5237 void DataArrayInt::applyInv(int numerator)
5240 int *ptr=getPointer();
5241 std::size_t nbOfElems=getNbOfElems();
5242 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
5246 *ptr=numerator/(*ptr);
5250 std::ostringstream oss; oss << "DataArrayInt::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
5252 throw INTERP_KERNEL::Exception(oss.str().c_str());
5259 * Modify all elements of \a this array, so that
5260 * an element _x_ becomes \f$ x / val \f$.
5261 * \param [in] val - the denominator used to modify array elements.
5262 * \throw If \a this is not allocated.
5263 * \throw If \a val == 0.
5265 void DataArrayInt::applyDivideBy(int val)
5268 throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to divide by 0 !");
5270 int *ptr=getPointer();
5271 std::size_t nbOfElems=getNbOfElems();
5272 std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::divides<int>(),val));
5277 * Modify all elements of \a this array, so that
5278 * an element _x_ becomes <em> x % val </em>.
5279 * \param [in] val - the divisor used to modify array elements.
5280 * \throw If \a this is not allocated.
5281 * \throw If \a val <= 0.
5283 void DataArrayInt::applyModulus(int val)
5286 throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to operate modulus on value <= 0 !");
5288 int *ptr=getPointer();
5289 std::size_t nbOfElems=getNbOfElems();
5290 std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::modulus<int>(),val));
5295 * This method works only on data array with one component.
5296 * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
5297 * this[*id] in [\b vmin,\b vmax)
5299 * \param [in] vmin begin of range. This value is included in range (included).
5300 * \param [in] vmax end of range. This value is \b not included in range (excluded).
5301 * \return a newly allocated data array that the caller should deal with.
5303 * \sa DataArrayInt::findIdsNotInRange , DataArrayInt::findIdsStricltyNegative
5305 DataArrayInt *DataArrayInt::findIdsInRange(int vmin, int vmax) const
5307 InRange<int> ir(vmin,vmax);
5308 MCAuto<DataArrayInt> ret(findIdsAdv(ir));
5313 * This method works only on data array with one component.
5314 * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
5315 * this[*id] \b not in [\b vmin,\b vmax)
5317 * \param [in] vmin begin of range. This value is \b not included in range (excluded).
5318 * \param [in] vmax end of range. This value is included in range (included).
5319 * \return a newly allocated data array that the caller should deal with.
5321 * \sa DataArrayInt::findIdsInRange , DataArrayInt::findIdsStricltyNegative
5323 DataArrayInt *DataArrayInt::findIdsNotInRange(int vmin, int vmax) const
5325 NotInRange<int> nir(vmin,vmax);
5326 MCAuto<DataArrayInt> ret(findIdsAdv(nir));
5331 * This method works only on data array with one component.
5332 * 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.
5334 * \param [in] vmin begin of range. This value is included in range (included).
5335 * \param [in] vmax end of range. This value is \b not included in range (excluded).
5336 * \return if all ids in \a this are so that (*this)[i]==i for all i in [ 0, \c this->getNumberOfTuples() ). */
5337 bool DataArrayInt::checkAllIdsInRange(int vmin, int vmax) const
5340 if(getNumberOfComponents()!=1)
5341 throw INTERP_KERNEL::Exception("DataArrayInt::checkAllIdsInRange : this must have exactly one component !");
5342 int nbOfTuples=getNumberOfTuples();
5344 const int *cptr=getConstPointer();
5345 for(int i=0;i<nbOfTuples;i++,cptr++)
5347 if(*cptr>=vmin && *cptr<vmax)
5348 { ret=ret && *cptr==i; }
5351 std::ostringstream oss; oss << "DataArrayInt::checkAllIdsInRange : tuple #" << i << " has value " << *cptr << " should be in [" << vmin << "," << vmax << ") !";
5352 throw INTERP_KERNEL::Exception(oss.str().c_str());
5359 * Modify all elements of \a this array, so that
5360 * an element _x_ becomes <em> val % x </em>.
5361 * \warning If an exception is thrown because of presence of an element <= 0 in \a this
5362 * array, all elements processed before detection of the zero element remain
5364 * \param [in] val - the divident used to modify array elements.
5365 * \throw If \a this is not allocated.
5366 * \throw If there is an element equal to or less than 0 in \a this array.
5368 void DataArrayInt::applyRModulus(int val)
5371 int *ptr=getPointer();
5372 std::size_t nbOfElems=getNbOfElems();
5373 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
5381 std::ostringstream oss; oss << "DataArrayInt::applyRModulus : presence of value <=0 in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
5383 throw INTERP_KERNEL::Exception(oss.str().c_str());
5390 * Modify all elements of \a this array, so that
5391 * an element _x_ becomes <em> val ^ x </em>.
5392 * \param [in] val - the value used to apply pow on all array elements.
5393 * \throw If \a this is not allocated.
5394 * \throw If \a val < 0.
5396 void DataArrayInt::applyPow(int val)
5400 throw INTERP_KERNEL::Exception("DataArrayInt::applyPow : input pow in < 0 !");
5401 int *ptr=getPointer();
5402 std::size_t nbOfElems=getNbOfElems();
5405 std::fill(ptr,ptr+nbOfElems,1);
5408 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
5411 for(int j=0;j<val;j++)
5419 * Modify all elements of \a this array, so that
5420 * an element _x_ becomes \f$ val ^ x \f$.
5421 * \param [in] val - the value used to apply pow on all array elements.
5422 * \throw If \a this is not allocated.
5423 * \throw If there is an element < 0 in \a this array.
5424 * \warning If an exception is thrown because of presence of 0 element in \a this
5425 * array, all elements processed before detection of the zero element remain
5428 void DataArrayInt::applyRPow(int val)
5431 int *ptr=getPointer();
5432 std::size_t nbOfElems=getNbOfElems();
5433 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
5438 for(int j=0;j<*ptr;j++)
5444 std::ostringstream oss; oss << "DataArrayInt::applyRPow : presence of negative value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
5446 throw INTERP_KERNEL::Exception(oss.str().c_str());
5453 * Returns a new DataArrayInt which is a minimal partition of elements of \a groups.
5454 * The i-th item of the result array is an ID of a set of elements belonging to a
5455 * unique set of groups, which the i-th element is a part of. This set of elements
5456 * belonging to a unique set of groups is called \a family, so the result array contains
5457 * IDs of families each element belongs to.
5459 * \b Example: if we have two groups of elements: \a group1 [0,4] and \a group2 [ 0,1,2 ],
5460 * then there are 3 families:
5461 * - \a family1 (with ID 1) contains element [0] belonging to ( \a group1 + \a group2 ),
5462 * - \a family2 (with ID 2) contains elements [4] belonging to ( \a group1 ),
5463 * - \a family3 (with ID 3) contains element [1,2] belonging to ( \a group2 ), <br>
5464 * and the result array contains IDs of families [ 1,3,3,0,2 ]. <br> Note a family ID 0 which
5465 * stands for the element #3 which is in none of groups.
5467 * \param [in] groups - sequence of groups of element IDs.
5468 * \param [in] newNb - total number of elements; it must be more than max ID of element
5470 * \param [out] fidsOfGroups - IDs of families the elements of each group belong to.
5471 * \return DataArrayInt * - a new instance of DataArrayInt containing IDs of families
5472 * each element with ID from range [0, \a newNb ) belongs to. The caller is to
5473 * delete this array using decrRef() as it is no more needed.
5474 * \throw If any element ID in \a groups violates condition ( 0 <= ID < \a newNb ).
5476 DataArrayInt *DataArrayInt::MakePartition(const std::vector<const DataArrayInt *>& groups, int newNb, std::vector< std::vector<int> >& fidsOfGroups)
5478 std::vector<const DataArrayInt *> groups2;
5479 for(std::vector<const DataArrayInt *>::const_iterator it4=groups.begin();it4!=groups.end();it4++)
5481 groups2.push_back(*it4);
5482 MCAuto<DataArrayInt> ret=DataArrayInt::New();
5483 ret->alloc(newNb,1);
5484 int *retPtr=ret->getPointer();
5485 std::fill(retPtr,retPtr+newNb,0);
5487 for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++)
5489 const int *ptr=(*iter)->getConstPointer();
5490 std::size_t nbOfElem=(*iter)->getNbOfElems();
5492 for(int j=0;j<sfid;j++)
5495 for(std::size_t i=0;i<nbOfElem;i++)
5497 if(ptr[i]>=0 && ptr[i]<newNb)
5499 if(retPtr[ptr[i]]==j)
5507 std::ostringstream oss; oss << "DataArrayInt::MakePartition : In group \"" << (*iter)->getName() << "\" in tuple #" << i << " value = " << ptr[i] << " ! Should be in [0," << newNb;
5509 throw INTERP_KERNEL::Exception(oss.str().c_str());
5516 fidsOfGroups.clear();
5517 fidsOfGroups.resize(groups2.size());
5519 for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++,grId++)
5522 const int *ptr=(*iter)->getConstPointer();
5523 std::size_t nbOfElem=(*iter)->getNbOfElems();
5524 for(const int *p=ptr;p!=ptr+nbOfElem;p++)
5525 tmp.insert(retPtr[*p]);
5526 fidsOfGroups[grId].insert(fidsOfGroups[grId].end(),tmp.begin(),tmp.end());
5532 * Returns a new DataArrayInt which contains all elements of given one-dimensional
5533 * arrays. The result array does not contain any duplicates and its values
5534 * are sorted in ascending order.
5535 * \param [in] arr - sequence of DataArrayInt's to unite.
5536 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5537 * array using decrRef() as it is no more needed.
5538 * \throw If any \a arr[i] is not allocated.
5539 * \throw If \a arr[i]->getNumberOfComponents() != 1.
5541 DataArrayInt *DataArrayInt::BuildUnion(const std::vector<const DataArrayInt *>& arr)
5543 std::vector<const DataArrayInt *> a;
5544 for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
5547 for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
5549 (*it)->checkAllocated();
5550 if((*it)->getNumberOfComponents()!=1)
5551 throw INTERP_KERNEL::Exception("DataArrayInt::BuildUnion : only single component allowed !");
5555 for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
5557 const int *pt=(*it)->getConstPointer();
5558 int nbOfTuples=(*it)->getNumberOfTuples();
5559 r.insert(pt,pt+nbOfTuples);
5561 DataArrayInt *ret=DataArrayInt::New();
5562 ret->alloc((int)r.size(),1);
5563 std::copy(r.begin(),r.end(),ret->getPointer());
5568 * Returns a new DataArrayInt which contains elements present in each of given one-dimensional
5569 * arrays. The result array does not contain any duplicates and its values
5570 * are sorted in ascending order.
5571 * \param [in] arr - sequence of DataArrayInt's to intersect.
5572 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5573 * array using decrRef() as it is no more needed.
5574 * \throw If any \a arr[i] is not allocated.
5575 * \throw If \a arr[i]->getNumberOfComponents() != 1.
5577 DataArrayInt *DataArrayInt::BuildIntersection(const std::vector<const DataArrayInt *>& arr)
5579 std::vector<const DataArrayInt *> a;
5580 for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
5583 for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
5585 (*it)->checkAllocated();
5586 if((*it)->getNumberOfComponents()!=1)
5587 throw INTERP_KERNEL::Exception("DataArrayInt::BuildIntersection : only single component allowed !");
5591 for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
5593 const int *pt=(*it)->getConstPointer();
5594 int nbOfTuples=(*it)->getNumberOfTuples();
5595 std::set<int> s1(pt,pt+nbOfTuples);
5599 std::set_intersection(r.begin(),r.end(),s1.begin(),s1.end(),inserter(r2,r2.end()));
5605 DataArrayInt *ret(DataArrayInt::New());
5606 ret->alloc((int)r.size(),1);
5607 std::copy(r.begin(),r.end(),ret->getPointer());
5612 namespace MEDCouplingImpl
5617 OpSwitchedOn(int *pt):_pt(pt),_cnt(0) { }
5618 void operator()(const bool& b) { if(b) *_pt++=_cnt; _cnt++; }
5627 OpSwitchedOff(int *pt):_pt(pt),_cnt(0) { }
5628 void operator()(const bool& b) { if(!b) *_pt++=_cnt; _cnt++; }
5637 * This method returns the list of ids in ascending mode so that v[id]==true.
5639 DataArrayInt *DataArrayInt::BuildListOfSwitchedOn(const std::vector<bool>& v)
5641 int sz((int)std::count(v.begin(),v.end(),true));
5642 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
5643 std::for_each(v.begin(),v.end(),MEDCouplingImpl::OpSwitchedOn(ret->getPointer()));
5648 * This method returns the list of ids in ascending mode so that v[id]==false.
5650 DataArrayInt *DataArrayInt::BuildListOfSwitchedOff(const std::vector<bool>& v)
5652 int sz((int)std::count(v.begin(),v.end(),false));
5653 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
5654 std::for_each(v.begin(),v.end(),MEDCouplingImpl::OpSwitchedOff(ret->getPointer()));
5659 * This method allows to put a vector of vector of integer into a more compact data structure (skyline).
5660 * This method is not available into python because no available optimized data structure available to map std::vector< std::vector<int> >.
5662 * \param [in] v the input data structure to be translate into skyline format.
5663 * \param [out] data the first element of the skyline format. The user is expected to deal with newly allocated array.
5664 * \param [out] dataIndex the second element of the skyline format.
5666 void DataArrayInt::PutIntoToSkylineFrmt(const std::vector< std::vector<int> >& v, DataArrayInt *& data, DataArrayInt *& dataIndex)
5668 int sz((int)v.size());
5669 MCAuto<DataArrayInt> ret0(DataArrayInt::New()),ret1(DataArrayInt::New());
5670 ret1->alloc(sz+1,1);
5671 int *pt(ret1->getPointer()); *pt=0;
5672 for(int i=0;i<sz;i++,pt++)
5673 pt[1]=pt[0]+(int)v[i].size();
5674 ret0->alloc(ret1->back(),1);
5675 pt=ret0->getPointer();
5676 for(int i=0;i<sz;i++)
5677 pt=std::copy(v[i].begin(),v[i].end(),pt);
5678 data=ret0.retn(); dataIndex=ret1.retn();
5682 * Returns a new DataArrayInt which contains a complement of elements of \a this
5683 * one-dimensional array. I.e. the result array contains all elements from the range [0,
5684 * \a nbOfElement) not present in \a this array.
5685 * \param [in] nbOfElement - maximal size of the result array.
5686 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5687 * array using decrRef() as it is no more needed.
5688 * \throw If \a this is not allocated.
5689 * \throw If \a this->getNumberOfComponents() != 1.
5690 * \throw If any element \a x of \a this array violates condition ( 0 <= \a x < \a
5693 DataArrayInt *DataArrayInt::buildComplement(int nbOfElement) const
5696 if(getNumberOfComponents()!=1)
5697 throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : only single component allowed !");
5698 std::vector<bool> tmp(nbOfElement);
5699 const int *pt=getConstPointer();
5700 int nbOfTuples=getNumberOfTuples();
5701 for(const int *w=pt;w!=pt+nbOfTuples;w++)
5702 if(*w>=0 && *w<nbOfElement)
5705 throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : an element is not in valid range : [0,nbOfElement) !");
5706 int nbOfRetVal=(int)std::count(tmp.begin(),tmp.end(),false);
5707 DataArrayInt *ret=DataArrayInt::New();
5708 ret->alloc(nbOfRetVal,1);
5710 int *retPtr=ret->getPointer();
5711 for(int i=0;i<nbOfElement;i++)
5718 * Returns a new DataArrayInt containing elements of \a this one-dimensional missing
5719 * from an \a other one-dimensional array.
5720 * \param [in] other - a DataArrayInt containing elements not to include in the result array.
5721 * \return DataArrayInt * - a new instance of DataArrayInt with one component. The
5722 * caller is to delete this array using decrRef() as it is no more needed.
5723 * \throw If \a other is NULL.
5724 * \throw If \a other is not allocated.
5725 * \throw If \a other->getNumberOfComponents() != 1.
5726 * \throw If \a this is not allocated.
5727 * \throw If \a this->getNumberOfComponents() != 1.
5728 * \sa DataArrayInt::buildSubstractionOptimized()
5730 DataArrayInt *DataArrayInt::buildSubstraction(const DataArrayInt *other) const
5733 throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : DataArrayInt pointer in input is NULL !");
5735 other->checkAllocated();
5736 if(getNumberOfComponents()!=1)
5737 throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed !");
5738 if(other->getNumberOfComponents()!=1)
5739 throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed for other type !");
5740 const int *pt=getConstPointer();
5741 int nbOfTuples=getNumberOfTuples();
5742 std::set<int> s1(pt,pt+nbOfTuples);
5743 pt=other->getConstPointer();
5744 nbOfTuples=other->getNumberOfTuples();
5745 std::set<int> s2(pt,pt+nbOfTuples);
5747 std::set_difference(s1.begin(),s1.end(),s2.begin(),s2.end(),std::back_insert_iterator< std::vector<int> >(r));
5748 DataArrayInt *ret=DataArrayInt::New();
5749 ret->alloc((int)r.size(),1);
5750 std::copy(r.begin(),r.end(),ret->getPointer());
5755 * \a this is expected to have one component and to be sorted ascendingly (as for \a other).
5756 * \a other is expected to be a part of \a this. If not DataArrayInt::buildSubstraction should be called instead.
5758 * \param [in] other an array with one component and expected to be sorted ascendingly.
5759 * \ret list of ids in \a this but not in \a other.
5760 * \sa DataArrayInt::buildSubstraction
5762 DataArrayInt *DataArrayInt::buildSubstractionOptimized(const DataArrayInt *other) const
5764 static const char *MSG="DataArrayInt::buildSubstractionOptimized : only single component allowed !";
5765 if(!other) throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstractionOptimized : NULL input array !");
5766 checkAllocated(); other->checkAllocated();
5767 if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
5768 if(other->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
5769 const int *pt1Bg(begin()),*pt1End(end()),*pt2Bg(other->begin()),*pt2End(other->end());
5770 const int *work1(pt1Bg),*work2(pt2Bg);
5771 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
5772 for(;work1!=pt1End;work1++)
5774 if(work2!=pt2End && *work1==*work2)
5777 ret->pushBackSilent(*work1);
5784 * Returns a new DataArrayInt which contains all elements of \a this and a given
5785 * one-dimensional arrays. The result array does not contain any duplicates
5786 * and its values are sorted in ascending order.
5787 * \param [in] other - an array to unite with \a this one.
5788 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5789 * array using decrRef() as it is no more needed.
5790 * \throw If \a this or \a other is not allocated.
5791 * \throw If \a this->getNumberOfComponents() != 1.
5792 * \throw If \a other->getNumberOfComponents() != 1.
5794 DataArrayInt *DataArrayInt::buildUnion(const DataArrayInt *other) const
5796 std::vector<const DataArrayInt *>arrs(2);
5797 arrs[0]=this; arrs[1]=other;
5798 return BuildUnion(arrs);
5803 * Returns a new DataArrayInt which contains elements present in both \a this and a given
5804 * one-dimensional arrays. The result array does not contain any duplicates
5805 * and its values are sorted in ascending order.
5806 * \param [in] other - an array to intersect with \a this one.
5807 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5808 * array using decrRef() as it is no more needed.
5809 * \throw If \a this or \a other is not allocated.
5810 * \throw If \a this->getNumberOfComponents() != 1.
5811 * \throw If \a other->getNumberOfComponents() != 1.
5813 DataArrayInt *DataArrayInt::buildIntersection(const DataArrayInt *other) const
5815 std::vector<const DataArrayInt *>arrs(2);
5816 arrs[0]=this; arrs[1]=other;
5817 return BuildIntersection(arrs);
5821 * This method can be applied on allocated with one component DataArrayInt instance.
5822 * This method is typically relevant for sorted arrays. All consecutive duplicated items in \a this will appear only once in returned DataArrayInt instance.
5823 * 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]
5825 * \return a newly allocated array that contain the result of the unique operation applied on \a this.
5826 * \throw if \a this is not allocated or if \a this has not exactly one component.
5827 * \sa DataArrayInt::buildUniqueNotSorted
5829 DataArrayInt *DataArrayInt::buildUnique() const
5832 if(getNumberOfComponents()!=1)
5833 throw INTERP_KERNEL::Exception("DataArrayInt::buildUnique : only single component allowed !");
5834 int nbOfTuples=getNumberOfTuples();
5835 MCAuto<DataArrayInt> tmp=deepCopy();
5836 int *data=tmp->getPointer();
5837 int *last=std::unique(data,data+nbOfTuples);
5838 MCAuto<DataArrayInt> ret=DataArrayInt::New();
5839 ret->alloc(std::distance(data,last),1);
5840 std::copy(data,last,ret->getPointer());
5845 * This method can be applied on allocated with one component DataArrayInt instance.
5846 * This method keep elements only once by keeping the same order in \a this that is not expected to be sorted.
5848 * \return a newly allocated array that contain the result of the unique operation applied on \a this.
5850 * \throw if \a this is not allocated or if \a this has not exactly one component.
5852 * \sa DataArrayInt::buildUnique
5854 DataArrayInt *DataArrayInt::buildUniqueNotSorted() const
5857 if(getNumberOfComponents()!=1)
5858 throw INTERP_KERNEL::Exception("DataArrayInt::buildUniqueNotSorted : only single component allowed !");
5860 getMinMaxValues(minVal,maxVal);
5861 std::vector<bool> b(maxVal-minVal+1,false);
5862 const int *ptBg(begin()),*endBg(end());
5863 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
5864 for(const int *pt=ptBg;pt!=endBg;pt++)
5868 ret->pushBackSilent(*pt);
5872 ret->copyStringInfoFrom(*this);
5877 * Returns a new DataArrayInt which contains size of every of groups described by \a this
5878 * "index" array. Such "index" array is returned for example by
5879 * \ref MEDCoupling::MEDCouplingUMesh::buildDescendingConnectivity
5880 * "MEDCouplingUMesh::buildDescendingConnectivity" and
5881 * \ref MEDCoupling::MEDCouplingUMesh::getNodalConnectivityIndex
5882 * "MEDCouplingUMesh::getNodalConnectivityIndex" etc.
5883 * This method performs the reverse operation of DataArrayInt::computeOffsetsFull.
5884 * \return DataArrayInt * - a new instance of DataArrayInt, whose number of tuples
5885 * equals to \a this->getNumberOfComponents() - 1, and number of components is 1.
5886 * The caller is to delete this array using decrRef() as it is no more needed.
5887 * \throw If \a this is not allocated.
5888 * \throw If \a this->getNumberOfComponents() != 1.
5889 * \throw If \a this->getNumberOfTuples() < 2.
5892 * - this contains [1,3,6,7,7,9,15]
5893 * - result array contains [2,3,1,0,2,6],
5894 * where 2 = 3 - 1, 3 = 6 - 3, 1 = 7 - 6 etc.
5896 * \sa DataArrayInt::computeOffsetsFull
5898 DataArrayInt *DataArrayInt::deltaShiftIndex() const
5901 if(getNumberOfComponents()!=1)
5902 throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : only single component allowed !");
5903 int nbOfTuples=getNumberOfTuples();
5905 throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : 1 tuple at least must be present in 'this' !");
5906 const int *ptr=getConstPointer();
5907 DataArrayInt *ret=DataArrayInt::New();
5908 ret->alloc(nbOfTuples-1,1);
5909 int *out=ret->getPointer();
5910 std::transform(ptr+1,ptr+nbOfTuples,ptr,out,std::minus<int>());
5915 * Modifies \a this one-dimensional array so that value of each element \a x
5916 * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
5917 * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number of tuples
5918 * and components remains the same.<br>
5919 * This method is useful for allToAllV in MPI with contiguous policy. This method
5920 * differs from computeOffsetsFull() in that the number of tuples is \b not changed by
5922 * \throw If \a this is not allocated.
5923 * \throw If \a this->getNumberOfComponents() != 1.
5926 * - Before \a this contains [3,5,1,2,0,8]
5927 * - After \a this contains [0,3,8,9,11,11]<br>
5928 * Note that the last element 19 = 11 + 8 is missing because size of \a this
5929 * array is retained and thus there is no space to store the last element.
5931 void DataArrayInt::computeOffsets()
5934 if(getNumberOfComponents()!=1)
5935 throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets : only single component allowed !");
5936 int nbOfTuples=getNumberOfTuples();
5939 int *work=getPointer();
5942 for(int i=1;i<nbOfTuples;i++)
5945 work[i]=work[i-1]+tmp;
5953 * Modifies \a this one-dimensional array so that value of each element \a x
5954 * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
5955 * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number
5956 * components remains the same and number of tuples is inceamented by one.<br>
5957 * This method is useful for allToAllV in MPI with contiguous policy. This method
5958 * differs from computeOffsets() in that the number of tuples is changed by this one.
5959 * This method performs the reverse operation of DataArrayInt::deltaShiftIndex.
5960 * \throw If \a this is not allocated.
5961 * \throw If \a this->getNumberOfComponents() != 1.
5964 * - Before \a this contains [3,5,1,2,0,8]
5965 * - After \a this contains [0,3,8,9,11,11,19]<br>
5966 * \sa DataArrayInt::deltaShiftIndex
5968 void DataArrayInt::computeOffsetsFull()
5971 if(getNumberOfComponents()!=1)
5972 throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsetsFull : only single component allowed !");
5973 int nbOfTuples=getNumberOfTuples();
5974 int *ret=(int *)malloc((nbOfTuples+1)*sizeof(int));
5975 const int *work=getConstPointer();
5977 for(int i=0;i<nbOfTuples;i++)
5978 ret[i+1]=work[i]+ret[i];
5979 useArray(ret,true,C_DEALLOC,nbOfTuples+1,1);
5984 * Returns two new DataArrayInt instances whose contents is computed from that of \a this and \a listOfIds arrays as follows.
5985 * \a this is expected to be an offset format ( as returned by DataArrayInt::computeOffsetsFull ) that is to say with one component
5986 * and ** sorted strictly increasingly **. \a listOfIds is expected to be sorted ascendingly (not strictly needed for \a listOfIds).
5987 * This methods searches in \a this, considered as a set of contiguous \c this->getNumberOfComponents() ranges, all ids in \a listOfIds
5988 * filling completely one of the ranges in \a this.
5990 * \param [in] listOfIds a list of ids that has to be sorted ascendingly.
5991 * \param [out] rangeIdsFetched the range ids fetched
5992 * \param [out] idsInInputListThatFetch contains the list of ids in \a listOfIds that are \b fully included in a range in \a this. So
5993 * \a idsInInputListThatFetch is a part of input \a listOfIds.
5995 * \sa DataArrayInt::computeOffsetsFull
5998 * - \a this : [0,3,7,9,15,18]
5999 * - \a listOfIds contains [0,1,2,3,7,8,15,16,17]
6000 * - \a rangeIdsFetched result array: [0,2,4]
6001 * - \a idsInInputListThatFetch result array: [0,1,2,7,8,15,16,17]
6002 * In this example id 3 in input \a listOfIds is alone so it do not appear in output \a idsInInputListThatFetch.
6005 void DataArrayInt::findIdsRangesInListOfIds(const DataArrayInt *listOfIds, DataArrayInt *& rangeIdsFetched, DataArrayInt *& idsInInputListThatFetch) const
6008 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : input list of ids is null !");
6009 listOfIds->checkAllocated(); checkAllocated();
6010 if(listOfIds->getNumberOfComponents()!=1)
6011 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : input list of ids must have exactly one component !");
6012 if(getNumberOfComponents()!=1)
6013 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : this must have exactly one component !");
6014 MCAuto<DataArrayInt> ret0=DataArrayInt::New(); ret0->alloc(0,1);
6015 MCAuto<DataArrayInt> ret1=DataArrayInt::New(); ret1->alloc(0,1);
6016 const int *tupEnd(listOfIds->end()),*offBg(begin()),*offEnd(end()-1);
6017 const int *tupPtr(listOfIds->begin()),*offPtr(offBg);
6018 while(tupPtr!=tupEnd && offPtr!=offEnd)
6020 if(*tupPtr==*offPtr)
6023 while(i<offPtr[1] && *tupPtr==i && tupPtr!=tupEnd) { i++; tupPtr++; }
6026 ret0->pushBackSilent((int)std::distance(offBg,offPtr));
6027 ret1->pushBackValsSilent(tupPtr-(offPtr[1]-offPtr[0]),tupPtr);
6032 { if(*tupPtr<*offPtr) tupPtr++; else offPtr++; }
6034 rangeIdsFetched=ret0.retn();
6035 idsInInputListThatFetch=ret1.retn();
6039 * Returns a new DataArrayInt whose contents is computed from that of \a this and \a
6040 * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
6041 * "index" array of a "iota" array, thus, whose each element gives an index of a group
6042 * beginning within the "iota" array. And \a this is a one-dimensional array
6043 * considered as a selector of groups described by \a offsets to include into the result array.
6044 * \throw If \a offsets is NULL.
6045 * \throw If \a offsets is not allocated.
6046 * \throw If \a offsets->getNumberOfComponents() != 1.
6047 * \throw If \a offsets is not monotonically increasing.
6048 * \throw If \a this is not allocated.
6049 * \throw If \a this->getNumberOfComponents() != 1.
6050 * \throw If any element of \a this is not a valid index for \a offsets array.
6053 * - \a this: [0,2,3]
6054 * - \a offsets: [0,3,6,10,14,20]
6055 * - result array: [0,1,2,6,7,8,9,10,11,12,13] == <br>
6056 * \c range(0,3) + \c range(6,10) + \c range(10,14) ==<br>
6057 * \c range( \a offsets[ \a this[0] ], offsets[ \a this[0]+1 ]) +
6058 * \c range( \a offsets[ \a this[1] ], offsets[ \a this[1]+1 ]) +
6059 * \c range( \a offsets[ \a this[2] ], offsets[ \a this[2]+1 ])
6061 DataArrayInt *DataArrayInt::buildExplicitArrByRanges(const DataArrayInt *offsets) const
6064 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : DataArrayInt pointer in input is NULL !");
6066 if(getNumberOfComponents()!=1)
6067 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : only single component allowed !");
6068 offsets->checkAllocated();
6069 if(offsets->getNumberOfComponents()!=1)
6070 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : input array should have only single component !");
6071 int othNbTuples=offsets->getNumberOfTuples()-1;
6072 int nbOfTuples=getNumberOfTuples();
6073 int retNbOftuples=0;
6074 const int *work=getConstPointer();
6075 const int *offPtr=offsets->getConstPointer();
6076 for(int i=0;i<nbOfTuples;i++)
6079 if(val>=0 && val<othNbTuples)
6081 int delta=offPtr[val+1]-offPtr[val];
6083 retNbOftuples+=delta;
6086 std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << val << " of offset array has a delta < 0 !";
6087 throw INTERP_KERNEL::Exception(oss.str().c_str());
6092 std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << i << " in this contains " << val;
6093 oss << " whereas offsets array is of size " << othNbTuples+1 << " !";
6094 throw INTERP_KERNEL::Exception(oss.str().c_str());
6097 MCAuto<DataArrayInt> ret=DataArrayInt::New();
6098 ret->alloc(retNbOftuples,1);
6099 int *retPtr=ret->getPointer();
6100 for(int i=0;i<nbOfTuples;i++)
6103 int start=offPtr[val];
6104 int off=offPtr[val+1]-start;
6105 for(int j=0;j<off;j++,retPtr++)
6112 * Returns a new DataArrayInt whose contents is computed using \a this that must be a
6113 * scaled array (monotonically increasing).
6114 from that of \a this and \a
6115 * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
6116 * "index" array of a "iota" array, thus, whose each element gives an index of a group
6117 * beginning within the "iota" array. And \a this is a one-dimensional array
6118 * considered as a selector of groups described by \a offsets to include into the result array.
6119 * \throw If \a is NULL.
6120 * \throw If \a this is not allocated.
6121 * \throw If \a this->getNumberOfComponents() != 1.
6122 * \throw If \a this->getNumberOfTuples() == 0.
6123 * \throw If \a this is not monotonically increasing.
6124 * \throw If any element of ids in ( \a bg \a stop \a step ) points outside the scale in \a this.
6127 * - \a bg , \a stop and \a step : (0,5,2)
6128 * - \a this: [0,3,6,10,14,20]
6129 * - result array: [0,0,0, 2,2,2,2, 4,4,4,4,4,4] == <br>
6131 DataArrayInt *DataArrayInt::buildExplicitArrOfSliceOnScaledArr(int bg, int stop, int step) const
6134 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : not allocated array !");
6135 if(getNumberOfComponents()!=1)
6136 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of components is expected to be equal to one !");
6137 int nbOfTuples(getNumberOfTuples());
6139 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of tuples must be != 0 !");
6140 const int *ids(begin());
6141 int nbOfEltsInSlc(GetNumberOfItemGivenBESRelative(bg,stop,step,"DataArrayInt::buildExplicitArrOfSliceOnScaledArr")),sz(0),pos(bg);
6142 for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
6144 if(pos>=0 && pos<nbOfTuples-1)
6146 int delta(ids[pos+1]-ids[pos]);
6150 std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " and at this pos this is not monotonically increasing !";
6151 throw INTERP_KERNEL::Exception(oss.str().c_str());
6156 std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " should be in [0," << nbOfTuples-1 << ") !";
6157 throw INTERP_KERNEL::Exception(oss.str().c_str());
6160 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
6161 int *retPtr(ret->getPointer());
6163 for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
6165 int delta(ids[pos+1]-ids[pos]);
6166 for(int j=0;j<delta;j++,retPtr++)
6173 * 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.
6174 * 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
6175 * in tuple **i** of returned DataArrayInt.
6176 * If ranges overlapped (in theory it should not) this method do not detect it and always returns the first range.
6178 * 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)]
6179 * The return DataArrayInt will contain : **[0,4,1,2,2,3]**
6181 * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
6182 * for lower value included and 2nd component is the upper value of corresponding range **excluded**.
6183 * \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
6184 * is thrown if no ranges in \a ranges contains value in \a this.
6186 * \sa DataArrayInt::findIdInRangeForEachTuple
6188 DataArrayInt *DataArrayInt::findRangeIdForEachTuple(const DataArrayInt *ranges) const
6191 throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : null input pointer !");
6192 if(ranges->getNumberOfComponents()!=2)
6193 throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : input DataArrayInt instance should have 2 components !");
6195 if(getNumberOfComponents()!=1)
6196 throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : this should have only one component !");
6197 int nbTuples=getNumberOfTuples();
6198 MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
6199 int nbOfRanges=ranges->getNumberOfTuples();
6200 const int *rangesPtr=ranges->getConstPointer();
6201 int *retPtr=ret->getPointer();
6202 const int *inPtr=getConstPointer();
6203 for(int i=0;i<nbTuples;i++,retPtr++)
6207 for(int j=0;j<nbOfRanges && !found;j++)
6208 if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
6209 { *retPtr=j; found=true; }
6214 std::ostringstream oss; oss << "DataArrayInt::findRangeIdForEachTuple : tuple #" << i << " not found by any ranges !";
6215 throw INTERP_KERNEL::Exception(oss.str().c_str());
6222 * 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.
6223 * 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
6224 * in tuple **i** of returned DataArrayInt.
6225 * If ranges overlapped (in theory it should not) this method do not detect it and always returns the sub position of the first range.
6227 * 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)]
6228 * The return DataArrayInt will contain : **[1,2,4,0,2,2]**
6229 * This method is often called in pair with DataArrayInt::findRangeIdForEachTuple method.
6231 * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
6232 * for lower value included and 2nd component is the upper value of corresponding range **excluded**.
6233 * \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
6234 * is thrown if no ranges in \a ranges contains value in \a this.
6235 * \sa DataArrayInt::findRangeIdForEachTuple
6237 DataArrayInt *DataArrayInt::findIdInRangeForEachTuple(const DataArrayInt *ranges) const
6240 throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : null input pointer !");
6241 if(ranges->getNumberOfComponents()!=2)
6242 throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : input DataArrayInt instance should have 2 components !");
6244 if(getNumberOfComponents()!=1)
6245 throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : this should have only one component !");
6246 int nbTuples=getNumberOfTuples();
6247 MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
6248 int nbOfRanges=ranges->getNumberOfTuples();
6249 const int *rangesPtr=ranges->getConstPointer();
6250 int *retPtr=ret->getPointer();
6251 const int *inPtr=getConstPointer();
6252 for(int i=0;i<nbTuples;i++,retPtr++)
6256 for(int j=0;j<nbOfRanges && !found;j++)
6257 if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
6258 { *retPtr=val-rangesPtr[2*j]; found=true; }
6263 std::ostringstream oss; oss << "DataArrayInt::findIdInRangeForEachTuple : tuple #" << i << " not found by any ranges !";
6264 throw INTERP_KERNEL::Exception(oss.str().c_str());
6271 * \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).
6272 * 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).
6273 * 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 !
6274 * If this method has correctly worked, \a this will be able to be considered as a linked list.
6275 * This method does nothing if number of tuples is lower of equal to 1.
6277 * This method is useful for users having an unstructured mesh having only SEG2 to rearrange internaly the connectibity without any coordinates consideration.
6279 * \sa MEDCouplingUMesh::orderConsecutiveCells1D, DataArrayInt::fromLinkedListOfPairToList
6281 void DataArrayInt::sortEachPairToMakeALinkedList()
6284 if(getNumberOfComponents()!=2)
6285 throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : Only works on DataArrayInt instance with nb of components equal to 2 !");
6286 int nbOfTuples(getNumberOfTuples());
6289 int *conn(getPointer());
6290 for(int i=1;i<nbOfTuples;i++,conn+=2)
6294 if(conn[2]==conn[3])
6296 std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " presence of a pair filled with same ids !";
6297 throw INTERP_KERNEL::Exception(oss.str().c_str());
6299 if(conn[2]!=conn[1] && conn[3]==conn[1] && conn[2]!=conn[0])
6300 std::swap(conn[2],conn[3]);
6301 //not(conn[2]==conn[1] && conn[3]!=conn[1] && conn[3]!=conn[0])
6302 if(conn[2]!=conn[1] || conn[3]==conn[1] || conn[3]==conn[0])
6304 std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " something is invalid !";
6305 throw INTERP_KERNEL::Exception(oss.str().c_str());
6310 if(conn[0]==conn[1] || conn[2]==conn[3])
6311 throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : In the 2 first tuples presence of a pair filled with same ids !");
6314 s.insert(conn,conn+4);
6316 throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : This can't be considered as a linked list regarding 2 first tuples !");
6317 if(std::count(conn,conn+4,conn[0])==2)
6322 if(conn[2]==conn[0])
6326 std::copy(tmp,tmp+4,conn);
6329 {//here we are sure to have (std::count(conn,conn+4,conn[1])==2)
6330 if(conn[1]==conn[3])
6331 std::swap(conn[2],conn[3]);
6338 * \a this is expected to be a correctly linked list of pairs.
6340 * \sa DataArrayInt::sortEachPairToMakeALinkedList
6342 MCAuto<DataArrayInt> DataArrayInt::fromLinkedListOfPairToList() const
6345 checkNbOfComps(2,"DataArrayInt::fromLinkedListOfPairToList : this is expected to have 2 components");
6346 int nbTuples(getNumberOfTuples());
6348 throw INTERP_KERNEL::Exception("DataArrayInt::fromLinkedListOfPairToList : no tuples in this ! Not a linked list !");
6349 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbTuples+1,1);
6350 const int *thisPtr(begin());
6351 int *retPtr(ret->getPointer());
6352 retPtr[0]=thisPtr[0];
6353 for(int i=0;i<nbTuples;i++)
6355 retPtr[i+1]=thisPtr[2*i+1];
6357 if(thisPtr[2*i+1]!=thisPtr[2*(i+1)+0])
6359 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 ?";
6360 throw INTERP_KERNEL::Exception(oss.str());
6367 * This method returns all different values found in \a this. This method throws if \a this has not been allocated.
6368 * But the number of components can be different from one.
6369 * \return a newly allocated array (that should be dealt by the caller) containing different values in \a this.
6371 DataArrayInt *DataArrayInt::getDifferentValues() const
6375 ret.insert(begin(),end());
6376 MCAuto<DataArrayInt> ret2=DataArrayInt::New(); ret2->alloc((int)ret.size(),1);
6377 std::copy(ret.begin(),ret.end(),ret2->getPointer());
6382 * This method is a refinement of DataArrayInt::getDifferentValues because it returns not only different values in \a this but also, for each of
6383 * them it tells which tuple id have this id.
6384 * This method works only on arrays with one component (if it is not the case call DataArrayInt::rearrange(1) ).
6385 * This method returns two arrays having same size.
6386 * 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.
6387 * 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]]
6389 std::vector<DataArrayInt *> DataArrayInt::partitionByDifferentValues(std::vector<int>& differentIds) const
6392 if(getNumberOfComponents()!=1)
6393 throw INTERP_KERNEL::Exception("DataArrayInt::partitionByDifferentValues : this should have only one component !");
6395 std::map<int,int> m,m2,m3;
6396 for(const int *w=begin();w!=end();w++)
6398 differentIds.resize(m.size());
6399 std::vector<DataArrayInt *> ret(m.size());
6400 std::vector<int *> retPtr(m.size());
6401 for(std::map<int,int>::const_iterator it=m.begin();it!=m.end();it++,id++)
6404 ret[id]=DataArrayInt::New();
6405 ret[id]->alloc((*it).second,1);
6406 retPtr[id]=ret[id]->getPointer();
6407 differentIds[id]=(*it).first;
6410 for(const int *w=begin();w!=end();w++,id++)
6412 retPtr[m2[*w]][m3[*w]++]=id;
6418 * This method split ids in [0, \c this->getNumberOfTuples() ) using \a this array as a field of weight (>=0 each).
6419 * The aim of this method is to return a set of \a nbOfSlices chunk of contiguous ids as balanced as possible.
6421 * \param [in] nbOfSlices - number of slices expected.
6422 * \return - a vector having a size equal to \a nbOfSlices giving the start (included) and the stop (excluded) of each chunks.
6424 * \sa DataArray::GetSlice
6425 * \throw If \a this is not allocated or not with exactly one component.
6426 * \throw If an element in \a this if < 0.
6428 std::vector< std::pair<int,int> > DataArrayInt::splitInBalancedSlices(int nbOfSlices) const
6430 if(!isAllocated() || getNumberOfComponents()!=1)
6431 throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : this array should have number of components equal to one and must be allocated !");
6433 throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : number of slices must be >= 1 !");
6434 int sum(accumulate(0)),nbOfTuples(getNumberOfTuples());
6435 int sumPerSlc(sum/nbOfSlices),pos(0);
6436 const int *w(begin());
6437 std::vector< std::pair<int,int> > ret(nbOfSlices);
6438 for(int i=0;i<nbOfSlices;i++)
6440 std::pair<int,int> p(pos,-1);
6442 while(locSum<sumPerSlc && pos<nbOfTuples) { pos++; locSum+=*w++; }
6446 p.second=nbOfTuples;
6453 * Returns a new DataArrayInt that is a modulus of two given arrays. There are 3
6455 * 1. The arrays have same number of tuples and components. Then each value of
6456 * the result array (_a_) is a division of the corresponding values of \a a1 and
6457 * \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, j ].
6458 * 2. The arrays have same number of tuples and one array, say _a2_, has one
6460 * _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, 0 ].
6461 * 3. The arrays have same number of components and one array, say _a2_, has one
6463 * _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ 0, j ].
6465 * Info on components is copied either from the first array (in the first case) or from
6466 * the array with maximal number of elements (getNbOfElems()).
6467 * \warning No check of division by zero is performed!
6468 * \param [in] a1 - a dividend array.
6469 * \param [in] a2 - a divisor array.
6470 * \return DataArrayInt * - the new instance of DataArrayInt.
6471 * The caller is to delete this result array using decrRef() as it is no more
6473 * \throw If either \a a1 or \a a2 is NULL.
6474 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
6475 * \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
6476 * none of them has number of tuples or components equal to 1.
6478 DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt *a2)
6481 throw INTERP_KERNEL::Exception("DataArrayInt::Modulus : input DataArrayInt instance is NULL !");
6482 int nbOfTuple1=a1->getNumberOfTuples();
6483 int nbOfTuple2=a2->getNumberOfTuples();
6484 int nbOfComp1=a1->getNumberOfComponents();
6485 int nbOfComp2=a2->getNumberOfComponents();
6486 if(nbOfTuple2==nbOfTuple1)
6488 if(nbOfComp1==nbOfComp2)
6490 MCAuto<DataArrayInt> ret=DataArrayInt::New();
6491 ret->alloc(nbOfTuple2,nbOfComp1);
6492 std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::modulus<int>());
6493 ret->copyStringInfoFrom(*a1);
6496 else if(nbOfComp2==1)
6498 MCAuto<DataArrayInt> ret=DataArrayInt::New();
6499 ret->alloc(nbOfTuple1,nbOfComp1);
6500 const int *a2Ptr=a2->getConstPointer();
6501 const int *a1Ptr=a1->getConstPointer();
6502 int *res=ret->getPointer();
6503 for(int i=0;i<nbOfTuple1;i++)
6504 res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::modulus<int>(),a2Ptr[i]));
6505 ret->copyStringInfoFrom(*a1);
6510 a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
6514 else if(nbOfTuple2==1)
6516 a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
6517 MCAuto<DataArrayInt> ret=DataArrayInt::New();
6518 ret->alloc(nbOfTuple1,nbOfComp1);
6519 const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
6520 int *pt=ret->getPointer();
6521 for(int i=0;i<nbOfTuple1;i++)
6522 pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::modulus<int>());
6523 ret->copyStringInfoFrom(*a1);
6528 a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Modulus !");//will always throw an exception
6534 * Modify \a this array so that each value becomes a modulus of division of this value by
6535 * a value of another DataArrayInt. There are 3 valid cases.
6536 * 1. The arrays have same number of tuples and components. Then each value of
6537 * \a this array is divided by the corresponding value of \a other one, i.e.:
6538 * _a_ [ i, j ] %= _other_ [ i, j ].
6539 * 2. The arrays have same number of tuples and \a other array has one component. Then
6540 * _a_ [ i, j ] %= _other_ [ i, 0 ].
6541 * 3. The arrays have same number of components and \a other array has one tuple. Then
6542 * _a_ [ i, j ] %= _a2_ [ 0, j ].
6544 * \warning No check of division by zero is performed!
6545 * \param [in] other - a divisor array.
6546 * \throw If \a other is NULL.
6547 * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
6548 * \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
6549 * \a other has number of both tuples and components not equal to 1.
6551 void DataArrayInt::modulusEqual(const DataArrayInt *other)
6554 throw INTERP_KERNEL::Exception("DataArrayInt::modulusEqual : input DataArrayInt instance is NULL !");
6555 const char *msg="Nb of tuples mismatch for DataArrayInt::modulusEqual !";
6556 checkAllocated(); other->checkAllocated();
6557 int nbOfTuple=getNumberOfTuples();
6558 int nbOfTuple2=other->getNumberOfTuples();
6559 int nbOfComp=getNumberOfComponents();
6560 int nbOfComp2=other->getNumberOfComponents();
6561 if(nbOfTuple==nbOfTuple2)
6563 if(nbOfComp==nbOfComp2)
6565 std::transform(begin(),end(),other->begin(),getPointer(),std::modulus<int>());
6567 else if(nbOfComp2==1)
6569 if(nbOfComp2==nbOfComp)
6571 int *ptr=getPointer();
6572 const int *ptrc=other->getConstPointer();
6573 for(int i=0;i<nbOfTuple;i++)
6574 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::modulus<int>(),*ptrc++));
6577 throw INTERP_KERNEL::Exception(msg);
6580 throw INTERP_KERNEL::Exception(msg);
6582 else if(nbOfTuple2==1)
6584 int *ptr=getPointer();
6585 const int *ptrc=other->getConstPointer();
6586 for(int i=0;i<nbOfTuple;i++)
6587 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::modulus<int>());
6590 throw INTERP_KERNEL::Exception(msg);
6595 * Returns a new DataArrayInt that is the result of pow of two given arrays. There are 3
6598 * \param [in] a1 - an array to pow up.
6599 * \param [in] a2 - another array to sum up.
6600 * \return DataArrayInt * - the new instance of DataArrayInt.
6601 * The caller is to delete this result array using decrRef() as it is no more
6603 * \throw If either \a a1 or \a a2 is NULL.
6604 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
6605 * \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
6606 * \throw If there is a negative value in \a a2.
6608 DataArrayInt *DataArrayInt::Pow(const DataArrayInt *a1, const DataArrayInt *a2)
6611 throw INTERP_KERNEL::Exception("DataArrayInt::Pow : at least one of input instances is null !");
6612 int nbOfTuple=a1->getNumberOfTuples();
6613 int nbOfTuple2=a2->getNumberOfTuples();
6614 int nbOfComp=a1->getNumberOfComponents();
6615 int nbOfComp2=a2->getNumberOfComponents();
6616 if(nbOfTuple!=nbOfTuple2)
6617 throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of tuples mismatches !");
6618 if(nbOfComp!=1 || nbOfComp2!=1)
6619 throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of components of both arrays must be equal to 1 !");
6620 MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuple,1);
6621 const int *ptr1(a1->begin()),*ptr2(a2->begin());
6622 int *ptr=ret->getPointer();
6623 for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
6628 for(int j=0;j<*ptr2;j++)
6634 std::ostringstream oss; oss << "DataArrayInt::Pow : on tuple #" << i << " of a2 value is < 0 (" << *ptr2 << ") !";
6635 throw INTERP_KERNEL::Exception(oss.str().c_str());
6642 * Apply pow on values of another DataArrayInt to values of \a this one.
6644 * \param [in] other - an array to pow to \a this one.
6645 * \throw If \a other is NULL.
6646 * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
6647 * \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
6648 * \throw If there is a negative value in \a other.
6650 void DataArrayInt::powEqual(const DataArrayInt *other)
6653 throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : input instance is null !");
6654 int nbOfTuple=getNumberOfTuples();
6655 int nbOfTuple2=other->getNumberOfTuples();
6656 int nbOfComp=getNumberOfComponents();
6657 int nbOfComp2=other->getNumberOfComponents();
6658 if(nbOfTuple!=nbOfTuple2)
6659 throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of tuples mismatches !");
6660 if(nbOfComp!=1 || nbOfComp2!=1)
6661 throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of components of both arrays must be equal to 1 !");
6662 int *ptr=getPointer();
6663 const int *ptrc=other->begin();
6664 for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
6669 for(int j=0;j<*ptrc;j++)
6675 std::ostringstream oss; oss << "DataArrayInt::powEqual : on tuple #" << i << " of other value is < 0 (" << *ptrc << ") !";
6676 throw INTERP_KERNEL::Exception(oss.str().c_str());
6683 * Returns a C array which is a renumbering map in "Old to New" mode for the input array.
6684 * This map, if applied to \a start array, would make it sorted. For example, if
6685 * \a start array contents are [9,10,0,6,4,11,3,7] then the contents of the result array is
6686 * [5,6,0,3,2,7,1,4].
6687 * \param [in] start - pointer to the first element of the array for which the
6688 * permutation map is computed.
6689 * \param [in] end - pointer specifying the end of the array \a start, so that
6690 * the last value of \a start is \a end[ -1 ].
6691 * \return int * - the result permutation array that the caller is to delete as it is no
6693 * \throw If there are equal values in the input array.
6695 int *DataArrayInt::CheckAndPreparePermutation(const int *start, const int *end)
6697 std::size_t sz=std::distance(start,end);
6698 int *ret=(int *)malloc(sz*sizeof(int));
6699 int *work=new int[sz];
6700 std::copy(start,end,work);
6701 std::sort(work,work+sz);
6702 if(std::unique(work,work+sz)!=work+sz)
6706 throw INTERP_KERNEL::Exception("Some elements are equals in the specified array !");
6708 std::map<int,int> m;
6709 for(int *workPt=work;workPt!=work+sz;workPt++)
6710 m[*workPt]=(int)std::distance(work,workPt);
6712 for(const int *iter=start;iter!=end;iter++,iter2++)
6719 * Returns a new DataArrayInt containing an arithmetic progression
6720 * that is equal to the sequence returned by Python \c range(\a begin,\a end,\a step )
6722 * \param [in] begin - the start value of the result sequence.
6723 * \param [in] end - limiting value, so that every value of the result array is less than
6725 * \param [in] step - specifies the increment or decrement.
6726 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6727 * array using decrRef() as it is no more needed.
6728 * \throw If \a step == 0.
6729 * \throw If \a end < \a begin && \a step > 0.
6730 * \throw If \a end > \a begin && \a step < 0.
6732 DataArrayInt *DataArrayInt::Range(int begin, int end, int step)
6734 int nbOfTuples=GetNumberOfItemGivenBESRelative(begin,end,step,"DataArrayInt::Range");
6735 MCAuto<DataArrayInt> ret=DataArrayInt::New();
6736 ret->alloc(nbOfTuples,1);
6737 int *ptr=ret->getPointer();
6740 for(int i=begin;i<end;i+=step,ptr++)
6745 for(int i=begin;i>end;i+=step,ptr++)
6752 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
6755 void DataArrayInt::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
6760 tinyInfo[0]=getNumberOfTuples();
6761 tinyInfo[1]=getNumberOfComponents();
6771 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
6774 void DataArrayInt::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
6778 int nbOfCompo=getNumberOfComponents();
6779 tinyInfo.resize(nbOfCompo+1);
6780 tinyInfo[0]=getName();
6781 for(int i=0;i<nbOfCompo;i++)
6782 tinyInfo[i+1]=getInfoOnComponent(i);
6787 tinyInfo[0]=getName();
6792 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
6793 * This method returns if a feeding is needed.
6795 bool DataArrayInt::resizeForUnserialization(const std::vector<int>& tinyInfoI)
6797 int nbOfTuple=tinyInfoI[0];
6798 int nbOfComp=tinyInfoI[1];
6799 if(nbOfTuple!=-1 || nbOfComp!=-1)
6801 alloc(nbOfTuple,nbOfComp);
6808 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
6809 * This method returns if a feeding is needed.
6811 void DataArrayInt::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
6813 setName(tinyInfoS[0]);
6816 int nbOfCompo=tinyInfoI[1];
6817 for(int i=0;i<nbOfCompo;i++)
6818 setInfoOnComponent(i,tinyInfoS[i+1]);
6822 DataArrayIntIterator::DataArrayIntIterator(DataArrayInt *da):DataArrayIterator<int>(da)
6826 DataArrayInt32Tuple::DataArrayInt32Tuple(int *pt, int nbOfComp):DataArrayTuple<int>(pt,nbOfComp)
6830 std::string DataArrayIntTuple::repr() const
6832 std::ostringstream oss; oss << "(";
6833 for(int i=0;i<_nb_of_compo-1;i++)
6834 oss << _pt[i] << ", ";
6835 oss << _pt[_nb_of_compo-1] << ")";
6839 int DataArrayIntTuple::intValue() const
6841 return this->zeValue();
6845 * This method returns a newly allocated instance the caller should dealed with by a MEDCoupling::DataArrayInt::decrRef.
6846 * This method performs \b no copy of data. The content is only referenced using MEDCoupling::DataArrayInt::useArray with ownership set to \b false.
6847 * 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
6848 * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
6850 DataArrayInt *DataArrayIntTuple::buildDAInt(int nbOfTuples, int nbOfCompo) const
6852 return this->buildDA(nbOfTuples,nbOfCompo);