1 // Copyright (C) 2007-2016 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 // Author : Anthony Geay (CEA/DEN)
21 #include "MEDCouplingMemArray.txx"
24 #include "GenMathFormulae.hxx"
25 #include "InterpKernelAutoPtr.hxx"
26 #include "InterpKernelExprParser.hxx"
35 typedef double (*MYFUNCPTR)(double);
37 using namespace MEDCoupling;
39 template class MEDCoupling::MemArray<int>;
40 template class MEDCoupling::MemArray<double>;
41 template class MEDCoupling::DataArrayTemplate<int>;
42 template class MEDCoupling::DataArrayTemplate<double>;
43 template class MEDCoupling::DataArrayTemplateClassic<int>;
44 template class MEDCoupling::DataArrayTemplateClassic<double>;
45 template class MEDCoupling::DataArrayTemplateFP<double>;
47 template<int SPACEDIM>
48 void DataArrayDouble::findCommonTuplesAlg(const double *bbox, int nbNodes, int limitNodeId, double prec, DataArrayInt *c, DataArrayInt *cI) const
50 const double *coordsPtr=getConstPointer();
51 BBTreePts<SPACEDIM,int> myTree(bbox,0,0,nbNodes,prec);
52 std::vector<bool> isDone(nbNodes);
53 for(int i=0;i<nbNodes;i++)
57 std::vector<int> intersectingElems;
58 myTree.getElementsAroundPoint(coordsPtr+i*SPACEDIM,intersectingElems);
59 if(intersectingElems.size()>1)
61 std::vector<int> commonNodes;
62 for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
66 commonNodes.push_back(*it);
69 if(!commonNodes.empty())
71 cI->pushBackSilent(cI->back()+(int)commonNodes.size()+1);
73 c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
80 template<int SPACEDIM>
81 void DataArrayDouble::FindTupleIdsNearTuplesAlg(const BBTreePts<SPACEDIM,int>& myTree, const double *pos, int nbOfTuples, double eps,
82 DataArrayInt *c, DataArrayInt *cI)
84 for(int i=0;i<nbOfTuples;i++)
86 std::vector<int> intersectingElems;
87 myTree.getElementsAroundPoint(pos+i*SPACEDIM,intersectingElems);
88 std::vector<int> commonNodes;
89 for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
90 commonNodes.push_back(*it);
91 cI->pushBackSilent(cI->back()+(int)commonNodes.size());
92 c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
96 template<int SPACEDIM>
97 void DataArrayDouble::FindClosestTupleIdAlg(const BBTreePts<SPACEDIM,int>& myTree, double dist, const double *pos, int nbOfTuples, const double *thisPt, int thisNbOfTuples, int *res)
100 const double *p(pos);
102 for(int i=0;i<nbOfTuples;i++,p+=SPACEDIM,r++)
107 double ret=myTree.getElementsAroundPoint2(p,distOpt,elem);
108 if(ret!=std::numeric_limits<double>::max())
110 distOpt=std::max(ret,1e-4);
115 { distOpt=2*distOpt; continue; }
120 int DataArray::EffectiveCircPerm(int nbOfShift, int nbOfTuples)
123 throw INTERP_KERNEL::Exception("DataArray::EffectiveCircPerm : number of tuples is expected to be > 0 !");
126 return nbOfShift%nbOfTuples;
132 return nbOfTuples-tmp;
136 std::size_t DataArray::getHeapMemorySizeWithoutChildren() const
138 std::size_t sz1=_name.capacity();
139 std::size_t sz2=_info_on_compo.capacity();
141 for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
142 sz3+=(*it).capacity();
146 std::vector<const BigMemoryObject *> DataArray::getDirectChildrenWithNull() const
148 return std::vector<const BigMemoryObject *>();
152 * Sets the attribute \a _name of \a this array.
153 * See \ref MEDCouplingArrayBasicsName "DataArrays infos" for more information.
154 * \param [in] name - new array name
156 void DataArray::setName(const std::string& name)
162 * Copies textual data from an \a other DataArray. The copied data are
163 * - the name attribute,
164 * - the information of components.
166 * For more information on these data see \ref MEDCouplingArrayBasicsName "DataArrays infos".
168 * \param [in] other - another instance of DataArray to copy the textual data from.
169 * \throw If number of components of \a this array differs from that of the \a other.
171 void DataArray::copyStringInfoFrom(const DataArray& other)
173 if(_info_on_compo.size()!=other._info_on_compo.size())
174 throw INTERP_KERNEL::Exception("Size of arrays mismatches on copyStringInfoFrom !");
176 _info_on_compo=other._info_on_compo;
179 void DataArray::copyPartOfStringInfoFrom(const DataArray& other, const std::vector<int>& compoIds)
181 int nbOfCompoOth=other.getNumberOfComponents();
182 std::size_t newNbOfCompo=compoIds.size();
183 for(std::size_t i=0;i<newNbOfCompo;i++)
184 if(compoIds[i]>=nbOfCompoOth || compoIds[i]<0)
186 std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompoOth << ")";
187 throw INTERP_KERNEL::Exception(oss.str().c_str());
189 for(std::size_t i=0;i<newNbOfCompo;i++)
190 setInfoOnComponent((int)i,other.getInfoOnComponent(compoIds[i]));
193 void DataArray::copyPartOfStringInfoFrom2(const std::vector<int>& compoIds, const DataArray& other)
195 int nbOfCompo=getNumberOfComponents();
196 std::size_t partOfCompoToSet=compoIds.size();
197 if((int)partOfCompoToSet!=other.getNumberOfComponents())
198 throw INTERP_KERNEL::Exception("Given compoIds has not the same size as number of components of given array !");
199 for(std::size_t i=0;i<partOfCompoToSet;i++)
200 if(compoIds[i]>=nbOfCompo || compoIds[i]<0)
202 std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompo << ")";
203 throw INTERP_KERNEL::Exception(oss.str().c_str());
205 for(std::size_t i=0;i<partOfCompoToSet;i++)
206 setInfoOnComponent(compoIds[i],other.getInfoOnComponent((int)i));
209 bool DataArray::areInfoEqualsIfNotWhy(const DataArray& other, std::string& reason) const
211 std::ostringstream oss;
212 if(_name!=other._name)
214 oss << "Names DataArray mismatch : this name=\"" << _name << " other name=\"" << other._name << "\" !";
218 if(_info_on_compo!=other._info_on_compo)
220 oss << "Components DataArray mismatch : \nThis components=";
221 for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
222 oss << "\"" << *it << "\",";
223 oss << "\nOther components=";
224 for(std::vector<std::string>::const_iterator it=other._info_on_compo.begin();it!=other._info_on_compo.end();it++)
225 oss << "\"" << *it << "\",";
233 * Compares textual information of \a this DataArray with that of an \a other one.
234 * The compared data are
235 * - the name attribute,
236 * - the information of components.
238 * For more information on these data see \ref MEDCouplingArrayBasicsName "DataArrays infos".
239 * \param [in] other - another instance of DataArray to compare the textual data of.
240 * \return bool - \a true if the textual information is same, \a false else.
242 bool DataArray::areInfoEquals(const DataArray& other) const
245 return areInfoEqualsIfNotWhy(other,tmp);
248 void DataArray::reprWithoutNameStream(std::ostream& stream) const
250 stream << "Number of components : "<< getNumberOfComponents() << "\n";
251 stream << "Info of these components : ";
252 for(std::vector<std::string>::const_iterator iter=_info_on_compo.begin();iter!=_info_on_compo.end();iter++)
253 stream << "\"" << *iter << "\" ";
257 std::string DataArray::cppRepr(const std::string& varName) const
259 std::ostringstream ret;
260 reprCppStream(varName,ret);
265 * Sets information on all components. To know more on format of this information
266 * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
267 * \param [in] info - a vector of strings.
268 * \throw If size of \a info differs from the number of components of \a this.
270 void DataArray::setInfoOnComponents(const std::vector<std::string>& info)
272 if(getNumberOfComponents()!=(int)info.size())
274 std::ostringstream oss; oss << "DataArray::setInfoOnComponents : input is of size " << info.size() << " whereas number of components is equal to " << getNumberOfComponents() << " !";
275 throw INTERP_KERNEL::Exception(oss.str().c_str());
281 * This method is only a dispatcher towards DataArrayDouble::setPartOfValues3, DataArrayInt::setPartOfValues3, DataArrayChar::setPartOfValues3 depending on the true
282 * type of \a this and \a aBase.
284 * \throw If \a aBase and \a this do not have the same type.
286 * \sa DataArrayDouble::setPartOfValues3, DataArrayInt::setPartOfValues3, DataArrayChar::setPartOfValues3.
288 void DataArray::setPartOfValuesBase3(const DataArray *aBase, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
291 throw INTERP_KERNEL::Exception("DataArray::setPartOfValuesBase3 : input aBase object is NULL !");
292 DataArrayDouble *this1(dynamic_cast<DataArrayDouble *>(this));
293 DataArrayInt *this2(dynamic_cast<DataArrayInt *>(this));
294 DataArrayChar *this3(dynamic_cast<DataArrayChar *>(this));
295 const DataArrayDouble *a1(dynamic_cast<const DataArrayDouble *>(aBase));
296 const DataArrayInt *a2(dynamic_cast<const DataArrayInt *>(aBase));
297 const DataArrayChar *a3(dynamic_cast<const DataArrayChar *>(aBase));
300 this1->setPartOfValues3(a1,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
305 this2->setPartOfValues3(a2,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
310 this3->setPartOfValues3(a3,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
313 throw INTERP_KERNEL::Exception("DataArray::setPartOfValuesBase3 : input aBase object and this do not have the same type !");
316 std::vector<std::string> DataArray::getVarsOnComponent() const
318 int nbOfCompo=(int)_info_on_compo.size();
319 std::vector<std::string> ret(nbOfCompo);
320 for(int i=0;i<nbOfCompo;i++)
321 ret[i]=getVarOnComponent(i);
325 std::vector<std::string> DataArray::getUnitsOnComponent() const
327 int nbOfCompo=(int)_info_on_compo.size();
328 std::vector<std::string> ret(nbOfCompo);
329 for(int i=0;i<nbOfCompo;i++)
330 ret[i]=getUnitOnComponent(i);
335 * Returns information on a component specified by an index.
336 * To know more on format of this information
337 * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
338 * \param [in] i - the index (zero based) of the component of interest.
339 * \return std::string - a string containing the information on \a i-th component.
340 * \throw If \a i is not a valid component index.
342 std::string DataArray::getInfoOnComponent(int i) const
344 if(i<(int)_info_on_compo.size() && i>=0)
345 return _info_on_compo[i];
348 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();
349 throw INTERP_KERNEL::Exception(oss.str().c_str());
354 * Returns the var part of the full information of the \a i-th component.
355 * For example, if \c getInfoOnComponent(0) returns "SIGXY [N/m^2]", then
356 * \c getVarOnComponent(0) returns "SIGXY".
357 * If a unit part of information is not detected by presence of
358 * two square brackets, then the full information is returned.
359 * To read more about the component information format, see
360 * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
361 * \param [in] i - the index (zero based) of the component of interest.
362 * \return std::string - a string containing the var information, or the full info.
363 * \throw If \a i is not a valid component index.
365 std::string DataArray::getVarOnComponent(int i) const
367 if(i<(int)_info_on_compo.size() && i>=0)
369 return GetVarNameFromInfo(_info_on_compo[i]);
373 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();
374 throw INTERP_KERNEL::Exception(oss.str().c_str());
379 * Returns the unit part of the full information of the \a i-th component.
380 * For example, if \c getInfoOnComponent(0) returns "SIGXY [ N/m^2]", then
381 * \c getUnitOnComponent(0) returns " N/m^2".
382 * If a unit part of information is not detected by presence of
383 * two square brackets, then an empty string is returned.
384 * To read more about the component information format, see
385 * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
386 * \param [in] i - the index (zero based) of the component of interest.
387 * \return std::string - a string containing the unit information, if any, or "".
388 * \throw If \a i is not a valid component index.
390 std::string DataArray::getUnitOnComponent(int i) const
392 if(i<(int)_info_on_compo.size() && i>=0)
394 return GetUnitFromInfo(_info_on_compo[i]);
398 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();
399 throw INTERP_KERNEL::Exception(oss.str().c_str());
404 * Returns the var part of the full component information.
405 * For example, if \a info == "SIGXY [N/m^2]", then this method returns "SIGXY".
406 * If a unit part of information is not detected by presence of
407 * two square brackets, then the whole \a info is returned.
408 * To read more about the component information format, see
409 * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
410 * \param [in] info - the full component information.
411 * \return std::string - a string containing only var information, or the \a info.
413 std::string DataArray::GetVarNameFromInfo(const std::string& info)
415 std::size_t p1=info.find_last_of('[');
416 std::size_t p2=info.find_last_of(']');
417 if(p1==std::string::npos || p2==std::string::npos)
422 return std::string();
423 std::size_t p3=info.find_last_not_of(' ',p1-1);
424 return info.substr(0,p3+1);
428 * Returns the unit part of the full component information.
429 * For example, if \a info == "SIGXY [ N/m^2]", then this method returns " N/m^2".
430 * If a unit part of information is not detected by presence of
431 * two square brackets, then an empty string is returned.
432 * To read more about the component information format, see
433 * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
434 * \param [in] info - the full component information.
435 * \return std::string - a string containing only unit information, if any, or "".
437 std::string DataArray::GetUnitFromInfo(const std::string& info)
439 std::size_t p1=info.find_last_of('[');
440 std::size_t p2=info.find_last_of(']');
441 if(p1==std::string::npos || p2==std::string::npos)
442 return std::string();
444 return std::string();
445 return info.substr(p1+1,p2-p1-1);
449 * This method put in info format the result of the merge of \a var and \a unit.
450 * The standard format for that is "var [unit]".
451 * Inversely you can retrieve the var part or the unit part of info string using resp. GetVarNameFromInfo and GetUnitFromInfo.
453 std::string DataArray::BuildInfoFromVarAndUnit(const std::string& var, const std::string& unit)
455 std::ostringstream oss;
456 oss << var << " [" << unit << "]";
460 std::string DataArray::GetAxisTypeRepr(MEDCouplingAxisType at)
465 return std::string("AX_CART");
467 return std::string("AX_CYL");
469 return std::string("AX_SPHER");
471 throw INTERP_KERNEL::Exception("DataArray::GetAxisTypeRepr : unrecognized axis type enum !");
476 * Returns a new DataArray by concatenating all given arrays, so that (1) the number
477 * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
478 * the number of component in the result array is same as that of each of given arrays.
479 * Info on components is copied from the first of the given arrays. Number of components
480 * in the given arrays must be the same.
481 * \param [in] arrs - a sequence of arrays to include in the result array. All arrays must have the same type.
482 * \return DataArray * - the new instance of DataArray (that can be either DataArrayInt, DataArrayDouble, DataArrayChar).
483 * The caller is to delete this result array using decrRef() as it is no more
485 * \throw If all arrays within \a arrs are NULL.
486 * \throw If all not null arrays in \a arrs have not the same type.
487 * \throw If getNumberOfComponents() of arrays within \a arrs.
489 DataArray *DataArray::Aggregate(const std::vector<const DataArray *>& arrs)
491 std::vector<const DataArray *> arr2;
492 for(std::vector<const DataArray *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
496 throw INTERP_KERNEL::Exception("DataArray::Aggregate : only null instance in input vector !");
497 std::vector<const DataArrayDouble *> arrd;
498 std::vector<const DataArrayInt *> arri;
499 std::vector<const DataArrayChar *> arrc;
500 for(std::vector<const DataArray *>::const_iterator it=arr2.begin();it!=arr2.end();it++)
502 const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(*it);
504 { arrd.push_back(a); continue; }
505 const DataArrayInt *b=dynamic_cast<const DataArrayInt *>(*it);
507 { arri.push_back(b); continue; }
508 const DataArrayChar *c=dynamic_cast<const DataArrayChar *>(*it);
510 { arrc.push_back(c); continue; }
511 throw INTERP_KERNEL::Exception("DataArray::Aggregate : presence of not null instance in inuput that is not in [DataArrayDouble, DataArrayInt, DataArrayChar] !");
513 if(arr2.size()==arrd.size())
514 return DataArrayDouble::Aggregate(arrd);
515 if(arr2.size()==arri.size())
516 return DataArrayInt::Aggregate(arri);
517 if(arr2.size()==arrc.size())
518 return DataArrayChar::Aggregate(arrc);
519 throw INTERP_KERNEL::Exception("DataArray::Aggregate : all input arrays must have the same type !");
523 * Sets information on a component specified by an index.
524 * To know more on format of this information
525 * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
526 * \warning Don't pass NULL as \a info!
527 * \param [in] i - the index (zero based) of the component of interest.
528 * \param [in] info - the string containing the information.
529 * \throw If \a i is not a valid component index.
531 void DataArray::setInfoOnComponent(int i, const std::string& info)
533 if(i<(int)_info_on_compo.size() && i>=0)
534 _info_on_compo[i]=info;
537 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();
538 throw INTERP_KERNEL::Exception(oss.str().c_str());
543 * Sets information on all components. This method can change number of components
544 * at certain conditions; if the conditions are not respected, an exception is thrown.
545 * The number of components can be changed in \a this only if \a this is not allocated.
546 * The condition of number of components must not be changed.
548 * To know more on format of the component information see
549 * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
550 * \param [in] info - a vector of component infos.
551 * \throw If \a this->getNumberOfComponents() != \a info.size() && \a this->isAllocated()
553 void DataArray::setInfoAndChangeNbOfCompo(const std::vector<std::string>& info)
555 if(getNumberOfComponents()!=(int)info.size())
561 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 !";
562 throw INTERP_KERNEL::Exception(oss.str().c_str());
569 void DataArray::checkNbOfTuples(int nbOfTuples, const std::string& msg) const
571 if(getNumberOfTuples()!=nbOfTuples)
573 std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " << nbOfTuples << " having " << getNumberOfTuples() << " !";
574 throw INTERP_KERNEL::Exception(oss.str().c_str());
578 void DataArray::checkNbOfComps(int nbOfCompo, const std::string& msg) const
580 if(getNumberOfComponents()!=nbOfCompo)
582 std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << nbOfCompo << " having " << getNumberOfComponents() << " !";
583 throw INTERP_KERNEL::Exception(oss.str().c_str());
587 void DataArray::checkNbOfElems(std::size_t nbOfElems, const std::string& msg) const
589 if(getNbOfElems()!=nbOfElems)
591 std::ostringstream oss; oss << msg << " : mismatch number of elems : Expected " << nbOfElems << " having " << getNbOfElems() << " !";
592 throw INTERP_KERNEL::Exception(oss.str().c_str());
596 void DataArray::checkNbOfTuplesAndComp(const DataArray& other, const std::string& msg) const
598 if(getNumberOfTuples()!=other.getNumberOfTuples())
600 std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " << other.getNumberOfTuples() << " having " << getNumberOfTuples() << " !";
601 throw INTERP_KERNEL::Exception(oss.str().c_str());
603 if(getNumberOfComponents()!=other.getNumberOfComponents())
605 std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << other.getNumberOfComponents() << " having " << getNumberOfComponents() << " !";
606 throw INTERP_KERNEL::Exception(oss.str().c_str());
610 void DataArray::checkNbOfTuplesAndComp(int nbOfTuples, int nbOfCompo, const std::string& msg) const
612 checkNbOfTuples(nbOfTuples,msg);
613 checkNbOfComps(nbOfCompo,msg);
617 * Simply this method checks that \b value is in [0,\b ref).
619 void DataArray::CheckValueInRange(int ref, int value, const std::string& msg)
621 if(value<0 || value>=ref)
623 std::ostringstream oss; oss << "DataArray::CheckValueInRange : " << msg << " ! Expected in range [0," << ref << "[ having " << value << " !";
624 throw INTERP_KERNEL::Exception(oss.str().c_str());
629 * This method checks that [\b start, \b end) is compliant with ref length \b value.
630 * typicaly start in [0,\b value) and end in [0,\b value). If value==start and start==end, it is supported.
632 void DataArray::CheckValueInRangeEx(int value, int start, int end, const std::string& msg)
634 if(start<0 || start>=value)
636 if(value!=start || end!=start)
638 std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg << " ! Expected start " << start << " of input range, in [0," << value << "[ !";
639 throw INTERP_KERNEL::Exception(oss.str().c_str());
642 if(end<0 || end>value)
644 std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg << " ! Expected end " << end << " of input range, in [0," << value << "] !";
645 throw INTERP_KERNEL::Exception(oss.str().c_str());
649 void DataArray::CheckClosingParInRange(int ref, int value, const std::string& msg)
651 if(value<0 || value>ref)
653 std::ostringstream oss; oss << "DataArray::CheckClosingParInRange : " << msg << " ! Expected input range in [0," << ref << "] having closing open parenthesis " << value << " !";
654 throw INTERP_KERNEL::Exception(oss.str().c_str());
659 * 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,
660 * typically it is a whole slice of tuples of DataArray or cells, nodes of a mesh...
662 * The input \a sliceId should be an id in [0, \a nbOfSlices) that specifies the slice of work.
664 * \param [in] start - the start of the input slice of the whole work to perform splitted into slices.
665 * \param [in] stop - the stop of the input slice of the whole work to perform splitted into slices.
666 * \param [in] step - the step (that can be <0) of the input slice of the whole work to perform splitted into slices.
667 * \param [in] sliceId - the slice id considered
668 * \param [in] nbOfSlices - the number of slices (typically the number of cores on which the work is expected to be sliced)
669 * \param [out] startSlice - the start of the slice considered
670 * \param [out] stopSlice - the stop of the slice consided
672 * \throw If \a step == 0
673 * \throw If \a nbOfSlices not > 0
674 * \throw If \a sliceId not in [0,nbOfSlices)
676 void DataArray::GetSlice(int start, int stop, int step, int sliceId, int nbOfSlices, int& startSlice, int& stopSlice)
680 std::ostringstream oss; oss << "DataArray::GetSlice : nbOfSlices (" << nbOfSlices << ") must be > 0 !";
681 throw INTERP_KERNEL::Exception(oss.str().c_str());
683 if(sliceId<0 || sliceId>=nbOfSlices)
685 std::ostringstream oss; oss << "DataArray::GetSlice : sliceId (" << nbOfSlices << ") must be in [0 , nbOfSlices (" << nbOfSlices << ") ) !";
686 throw INTERP_KERNEL::Exception(oss.str().c_str());
688 int nbElems=GetNumberOfItemGivenBESRelative(start,stop,step,"DataArray::GetSlice");
689 int minNbOfElemsPerSlice=nbElems/nbOfSlices;
690 startSlice=start+minNbOfElemsPerSlice*step*sliceId;
691 if(sliceId<nbOfSlices-1)
692 stopSlice=start+minNbOfElemsPerSlice*step*(sliceId+1);
697 int DataArray::GetNumberOfItemGivenBES(int begin, int end, int step, const std::string& msg)
701 std::ostringstream oss; oss << msg << " : end before begin !";
702 throw INTERP_KERNEL::Exception(oss.str().c_str());
708 std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
709 throw INTERP_KERNEL::Exception(oss.str().c_str());
711 return (end-1-begin)/step+1;
714 int DataArray::GetNumberOfItemGivenBESRelative(int begin, int end, int step, const std::string& msg)
717 throw INTERP_KERNEL::Exception("DataArray::GetNumberOfItemGivenBES : step=0 is not allowed !");
718 if(end<begin && step>0)
720 std::ostringstream oss; oss << msg << " : end before begin whereas step is positive !";
721 throw INTERP_KERNEL::Exception(oss.str().c_str());
723 if(begin<end && step<0)
725 std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
726 throw INTERP_KERNEL::Exception(oss.str().c_str());
729 return (std::max(begin,end)-1-std::min(begin,end))/std::abs(step)+1;
734 int DataArray::GetPosOfItemGivenBESRelativeNoThrow(int value, int begin, int end, int step)
740 if(begin<=value && value<end)
742 if((value-begin)%step==0)
743 return (value-begin)/step;
752 if(begin>=value && value>end)
754 if((begin-value)%(-step)==0)
755 return (begin-value)/(-step);
768 * Returns a new instance of DataArrayDouble. The caller is to delete this array
769 * using decrRef() as it is no more needed.
771 DataArrayDouble *DataArrayDouble::New()
773 return new DataArrayDouble;
777 * Returns the only one value in \a this, if and only if number of elements
778 * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
779 * \return double - the sole value stored in \a this array.
780 * \throw If at least one of conditions stated above is not fulfilled.
782 double DataArrayDouble::doubleValue() const
786 if(getNbOfElems()==1)
788 return *getConstPointer();
791 throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is allocated but number of elements is not equal to 1 !");
794 throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is not allocated !");
798 * Returns a full copy of \a this. For more info on copying data arrays see
799 * \ref MEDCouplingArrayBasicsCopyDeep.
800 * \return DataArrayDouble * - a new instance of DataArrayDouble. The caller is to
801 * delete this array using decrRef() as it is no more needed.
803 DataArrayDouble *DataArrayDouble::deepCopy() const
805 return new DataArrayDouble(*this);
809 * Returns either a \a deep or \a shallow copy of this array. For more info see
810 * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
811 * \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
812 * \return DataArrayDouble * - either a new instance of DataArrayDouble (if \a dCpy
813 * == \a true) or \a this instance (if \a dCpy == \a false).
815 DataArrayDouble *DataArrayDouble::performCopyOrIncrRef(bool dCpy) const
817 return DataArrayTemplateClassic<double>::PerformCopyOrIncrRef(dCpy,*this);
821 * Assign zero to all values in \a this array. To know more on filling arrays see
822 * \ref MEDCouplingArrayFill.
823 * \throw If \a this is not allocated.
825 void DataArrayDouble::fillWithZero()
831 * Checks that \a this array is consistently **increasing** or **decreasing** in value,
832 * with at least absolute difference value of |\a eps| at each step.
833 * If not an exception is thrown.
834 * \param [in] increasing - if \a true, the array values should be increasing.
835 * \param [in] eps - minimal absolute difference between the neighbor values at which
836 * the values are considered different.
837 * \throw If sequence of values is not strictly monotonic in agreement with \a
839 * \throw If \a this->getNumberOfComponents() != 1.
840 * \throw If \a this is not allocated.
842 void DataArrayDouble::checkMonotonic(bool increasing, double eps) const
844 if(!isMonotonic(increasing,eps))
847 throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not INCREASING monotonic !");
849 throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not DECREASING monotonic !");
854 * Checks that \a this array is consistently **increasing** or **decreasing** in value,
855 * with at least absolute difference value of |\a eps| at each step.
856 * \param [in] increasing - if \a true, array values should be increasing.
857 * \param [in] eps - minimal absolute difference between the neighbor values at which
858 * the values are considered different.
859 * \return bool - \a true if values change in accordance with \a increasing arg.
860 * \throw If \a this->getNumberOfComponents() != 1.
861 * \throw If \a this is not allocated.
863 bool DataArrayDouble::isMonotonic(bool increasing, double eps) const
866 if(getNumberOfComponents()!=1)
867 throw INTERP_KERNEL::Exception("DataArrayDouble::isMonotonic : only supported with 'this' array with ONE component !");
868 int nbOfElements=getNumberOfTuples();
869 const double *ptr=getConstPointer();
873 double absEps=fabs(eps);
876 for(int i=1;i<nbOfElements;i++)
878 if(ptr[i]<(ref+absEps))
886 for(int i=1;i<nbOfElements;i++)
888 if(ptr[i]>(ref-absEps))
897 * Returns a textual and human readable representation of \a this instance of
898 * DataArrayDouble. This text is shown when a DataArrayDouble is printed in Python.
899 * \return std::string - text describing \a this DataArrayDouble.
901 * \sa reprNotTooLong, reprZip
903 std::string DataArrayDouble::repr() const
905 std::ostringstream ret;
910 std::string DataArrayDouble::reprZip() const
912 std::ostringstream ret;
918 * This method is close to repr method except that when \a this has more than 1000 tuples, all tuples are not
919 * printed out to avoid to consume too much space in interpretor.
922 std::string DataArrayDouble::reprNotTooLong() const
924 std::ostringstream ret;
925 reprNotTooLongStream(ret);
929 void DataArrayDouble::writeVTK(std::ostream& ofs, int indent, const std::string& nameInFile, DataArrayByte *byteArr) const
931 static const char SPACE[4]={' ',' ',' ',' '};
933 std::string idt(indent,' ');
935 ofs << idt << "<DataArray type=\"Float32\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
937 bool areAllEmpty(true);
938 for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
942 for(std::size_t i=0;i<_info_on_compo.size();i++)
943 ofs << " ComponentName" << i << "=\"" << _info_on_compo[i] << "\"";
947 ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
948 INTERP_KERNEL::AutoPtr<float> tmp(new float[getNbOfElems()]);
950 // to make Visual C++ happy : instead of std::copy(begin(),end(),(float *)tmp);
951 for(const double *src=begin();src!=end();src++,pt++)
953 const char *data(reinterpret_cast<const char *>((float *)tmp));
954 std::size_t sz(getNbOfElems()*sizeof(float));
955 byteArr->insertAtTheEnd(data,data+sz);
956 byteArr->insertAtTheEnd(SPACE,SPACE+4);
960 ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
961 std::copy(begin(),end(),std::ostream_iterator<double>(ofs," "));
963 ofs << std::endl << idt << "</DataArray>\n";
966 void DataArrayDouble::reprStream(std::ostream& stream) const
968 stream << "Name of double array : \"" << _name << "\"\n";
969 reprWithoutNameStream(stream);
972 void DataArrayDouble::reprZipStream(std::ostream& stream) const
974 stream << "Name of double array : \"" << _name << "\"\n";
975 reprZipWithoutNameStream(stream);
978 void DataArrayDouble::reprNotTooLongStream(std::ostream& stream) const
980 stream << "Name of double array : \"" << _name << "\"\n";
981 reprNotTooLongWithoutNameStream(stream);
984 void DataArrayDouble::reprWithoutNameStream(std::ostream& stream) const
986 DataArray::reprWithoutNameStream(stream);
987 stream.precision(17);
988 _mem.repr(getNumberOfComponents(),stream);
991 void DataArrayDouble::reprZipWithoutNameStream(std::ostream& stream) const
993 DataArray::reprWithoutNameStream(stream);
994 stream.precision(17);
995 _mem.reprZip(getNumberOfComponents(),stream);
998 void DataArrayDouble::reprNotTooLongWithoutNameStream(std::ostream& stream) const
1000 DataArray::reprWithoutNameStream(stream);
1001 stream.precision(17);
1002 _mem.reprNotTooLong(getNumberOfComponents(),stream);
1005 void DataArrayDouble::reprCppStream(const std::string& varName, std::ostream& stream) const
1007 int nbTuples(getNumberOfTuples()),nbComp(getNumberOfComponents());
1008 const double *data(getConstPointer());
1009 stream.precision(17);
1010 stream << "DataArrayDouble *" << varName << "=DataArrayDouble::New();" << std::endl;
1011 if(nbTuples*nbComp>=1)
1013 stream << "const double " << varName << "Data[" << nbTuples*nbComp << "]={";
1014 std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<double>(stream,","));
1015 stream << data[nbTuples*nbComp-1] << "};" << std::endl;
1016 stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
1019 stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
1020 stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
1024 * Method that gives a quick overvien of \a this for python.
1026 void DataArrayDouble::reprQuickOverview(std::ostream& stream) const
1028 static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
1029 stream << "DataArrayDouble C++ instance at " << this << ". ";
1032 int nbOfCompo=(int)_info_on_compo.size();
1035 int nbOfTuples=getNumberOfTuples();
1036 stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
1037 reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
1040 stream << "Number of components : 0.";
1043 stream << "*** No data allocated ****";
1046 void DataArrayDouble::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
1048 const double *data=begin();
1049 int nbOfTuples=getNumberOfTuples();
1050 int nbOfCompo=(int)_info_on_compo.size();
1051 std::ostringstream oss2; oss2 << "[";
1053 std::string oss2Str(oss2.str());
1054 bool isFinished=true;
1055 for(int i=0;i<nbOfTuples && isFinished;i++)
1060 for(int j=0;j<nbOfCompo;j++,data++)
1063 if(j!=nbOfCompo-1) oss2 << ", ";
1069 if(i!=nbOfTuples-1) oss2 << ", ";
1070 std::string oss3Str(oss2.str());
1071 if(oss3Str.length()<maxNbOfByteInRepr)
1083 * Equivalent to DataArrayDouble::isEqual except that if false the reason of
1084 * mismatch is given.
1086 * \param [in] other the instance to be compared with \a this
1087 * \param [in] prec the precision to compare numeric data of the arrays.
1088 * \param [out] reason In case of inequality returns the reason.
1089 * \sa DataArrayDouble::isEqual
1091 bool DataArrayDouble::isEqualIfNotWhy(const DataArrayDouble& other, double prec, std::string& reason) const
1093 if(!areInfoEqualsIfNotWhy(other,reason))
1095 return _mem.isEqual(other._mem,prec,reason);
1099 * Checks if \a this and another DataArrayDouble are fully equal. For more info see
1100 * \ref MEDCouplingArrayBasicsCompare.
1101 * \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1102 * \param [in] prec - precision value to compare numeric data of the arrays.
1103 * \return bool - \a true if the two arrays are equal, \a false else.
1105 bool DataArrayDouble::isEqual(const DataArrayDouble& other, double prec) const
1108 return isEqualIfNotWhy(other,prec,tmp);
1112 * Checks if values of \a this and another DataArrayDouble are equal. For more info see
1113 * \ref MEDCouplingArrayBasicsCompare.
1114 * \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1115 * \param [in] prec - precision value to compare numeric data of the arrays.
1116 * \return bool - \a true if the values of two arrays are equal, \a false else.
1118 bool DataArrayDouble::isEqualWithoutConsideringStr(const DataArrayDouble& other, double prec) const
1121 return _mem.isEqual(other._mem,prec,tmp);
1125 * Returns a new DataArrayDouble holding the same values as \a this array but differently
1126 * arranged in memory. If \a this array holds 2 components of 3 values:
1127 * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
1128 * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
1129 * \warning Do not confuse this method with transpose()!
1130 * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1131 * is to delete using decrRef() as it is no more needed.
1132 * \throw If \a this is not allocated.
1134 DataArrayDouble *DataArrayDouble::fromNoInterlace() const
1137 throw INTERP_KERNEL::Exception("DataArrayDouble::fromNoInterlace : Not defined array !");
1138 double *tab=_mem.fromNoInterlace(getNumberOfComponents());
1139 DataArrayDouble *ret=DataArrayDouble::New();
1140 ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
1145 * Returns a new DataArrayDouble holding the same values as \a this array but differently
1146 * arranged in memory. If \a this array holds 2 components of 3 values:
1147 * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
1148 * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
1149 * \warning Do not confuse this method with transpose()!
1150 * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1151 * is to delete using decrRef() as it is no more needed.
1152 * \throw If \a this is not allocated.
1154 DataArrayDouble *DataArrayDouble::toNoInterlace() const
1157 throw INTERP_KERNEL::Exception("DataArrayDouble::toNoInterlace : Not defined array !");
1158 double *tab=_mem.toNoInterlace(getNumberOfComponents());
1159 DataArrayDouble *ret=DataArrayDouble::New();
1160 ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
1165 * Appends components of another array to components of \a this one, tuple by tuple.
1166 * So that the number of tuples of \a this array remains the same and the number of
1167 * components increases.
1168 * \param [in] other - the DataArrayDouble to append to \a this one.
1169 * \throw If \a this is not allocated.
1170 * \throw If \a this and \a other arrays have different number of tuples.
1172 * \if ENABLE_EXAMPLES
1173 * \ref cpp_mcdataarraydouble_meldwith "Here is a C++ example".
1175 * \ref py_mcdataarraydouble_meldwith "Here is a Python example".
1178 void DataArrayDouble::meldWith(const DataArrayDouble *other)
1181 other->checkAllocated();
1182 int nbOfTuples=getNumberOfTuples();
1183 if(nbOfTuples!=other->getNumberOfTuples())
1184 throw INTERP_KERNEL::Exception("DataArrayDouble::meldWith : mismatch of number of tuples !");
1185 int nbOfComp1=getNumberOfComponents();
1186 int nbOfComp2=other->getNumberOfComponents();
1187 double *newArr=(double *)malloc((nbOfTuples*(nbOfComp1+nbOfComp2))*sizeof(double));
1189 const double *inp1=getConstPointer();
1190 const double *inp2=other->getConstPointer();
1191 for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
1193 w=std::copy(inp1,inp1+nbOfComp1,w);
1194 w=std::copy(inp2,inp2+nbOfComp2,w);
1196 useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
1197 std::vector<int> compIds(nbOfComp2);
1198 for(int i=0;i<nbOfComp2;i++)
1199 compIds[i]=nbOfComp1+i;
1200 copyPartOfStringInfoFrom2(compIds,*other);
1204 * This method checks that all tuples in \a other are in \a this.
1205 * If true, the output param \a tupleIds contains the tuples ids of \a this that correspond to tupes in \a this.
1206 * 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.
1208 * \param [in] other - the array having the same number of components than \a this.
1209 * \param [out] tupleIds - the tuple ids containing the same number of tuples than \a other has.
1210 * \sa DataArrayDouble::findCommonTuples
1212 bool DataArrayDouble::areIncludedInMe(const DataArrayDouble *other, double prec, DataArrayInt *&tupleIds) const
1215 throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : input array is NULL !");
1216 checkAllocated(); other->checkAllocated();
1217 if(getNumberOfComponents()!=other->getNumberOfComponents())
1218 throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : the number of components does not match !");
1219 MCAuto<DataArrayDouble> a=DataArrayDouble::Aggregate(this,other);
1220 DataArrayInt *c=0,*ci=0;
1221 a->findCommonTuples(prec,getNumberOfTuples(),c,ci);
1222 MCAuto<DataArrayInt> cSafe(c),ciSafe(ci);
1223 int newNbOfTuples=-1;
1224 MCAuto<DataArrayInt> ids=DataArrayInt::ConvertIndexArrayToO2N(a->getNumberOfTuples(),c->begin(),ci->begin(),ci->end(),newNbOfTuples);
1225 MCAuto<DataArrayInt> ret1=ids->selectByTupleIdSafeSlice(getNumberOfTuples(),a->getNumberOfTuples(),1);
1226 tupleIds=ret1.retn();
1227 return newNbOfTuples==getNumberOfTuples();
1231 * Searches for tuples coincident within \a prec tolerance. Each tuple is considered
1232 * as coordinates of a point in getNumberOfComponents()-dimensional space. The
1233 * distance separating two points is computed with the infinite norm.
1235 * Indices of coincident tuples are stored in output arrays.
1236 * A pair of arrays (\a comm, \a commIndex) is called "Surjective Format 2".
1238 * This method is typically used by MEDCouplingPointSet::findCommonNodes() and
1239 * MEDCouplingUMesh::mergeNodes().
1240 * \param [in] prec - minimal absolute distance between two tuples (infinite norm) at which they are
1241 * considered not coincident.
1242 * \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
1243 * tuples have id strictly lower than \a limitTupleId then they are not returned.
1244 * \param [out] comm - the array holding ids (== indices) of coincident tuples.
1245 * \a comm->getNumberOfComponents() == 1.
1246 * \a comm->getNumberOfTuples() == \a commIndex->back().
1247 * \param [out] commIndex - the array dividing all indices stored in \a comm into
1248 * groups of (indices of) coincident tuples. Its every value is a tuple
1249 * index where a next group of tuples begins. For example the second
1250 * group of tuples in \a comm is described by following range of indices:
1251 * [ \a commIndex[1], \a commIndex[2] ). \a commIndex->getNumberOfTuples()-1
1252 * gives the number of groups of coincident tuples.
1253 * \throw If \a this is not allocated.
1254 * \throw If the number of components is not in [1,2,3,4].
1256 * \if ENABLE_EXAMPLES
1257 * \ref cpp_mcdataarraydouble_findcommontuples "Here is a C++ example".
1259 * \ref py_mcdataarraydouble_findcommontuples "Here is a Python example".
1261 * \sa DataArrayInt::ConvertIndexArrayToO2N(), DataArrayDouble::areIncludedInMe
1263 void DataArrayDouble::findCommonTuples(double prec, int limitTupleId, DataArrayInt *&comm, DataArrayInt *&commIndex) const
1266 int nbOfCompo=getNumberOfComponents();
1267 if ((nbOfCompo<1) || (nbOfCompo>4)) //test before work
1268 throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : Unexpected spacedim of coords. Must be 1, 2, 3 or 4.");
1270 int nbOfTuples=getNumberOfTuples();
1272 MCAuto<DataArrayInt> c(DataArrayInt::New()),cI(DataArrayInt::New()); c->alloc(0,1); cI->pushBackSilent(0);
1276 findCommonTuplesAlg<4>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1279 findCommonTuplesAlg<3>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1282 findCommonTuplesAlg<2>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1285 findCommonTuplesAlg<1>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1288 throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : nb of components managed are 1,2,3 and 4 ! not implemented for other number of components !");
1291 commIndex=cI.retn();
1296 * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayDouble instance.
1297 * \a nbTimes should be at least equal to 1.
1298 * \return a newly allocated DataArrayDouble having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
1299 * \throw if \a this is not allocated or if \a this has not number of components set to one or if \a nbTimes is lower than 1.
1301 DataArrayDouble *DataArrayDouble::duplicateEachTupleNTimes(int nbTimes) const
1304 if(getNumberOfComponents()!=1)
1305 throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : this should have only one component !");
1307 throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : nb times should be >= 1 !");
1308 int nbTuples=getNumberOfTuples();
1309 const double *inPtr=getConstPointer();
1310 MCAuto<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbTimes*nbTuples,1);
1311 double *retPtr=ret->getPointer();
1312 for(int i=0;i<nbTuples;i++,inPtr++)
1315 for(int j=0;j<nbTimes;j++,retPtr++)
1318 ret->copyStringInfoFrom(*this);
1323 * This methods returns the minimal distance between the two set of points \a this and \a other.
1324 * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
1325 * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
1327 * \param [out] thisTupleId the tuple id in \a this corresponding to the returned minimal distance
1328 * \param [out] otherTupleId the tuple id in \a other corresponding to the returned minimal distance
1329 * \return the minimal distance between the two set of points \a this and \a other.
1330 * \sa DataArrayDouble::findClosestTupleId
1332 double DataArrayDouble::minimalDistanceTo(const DataArrayDouble *other, int& thisTupleId, int& otherTupleId) const
1334 MCAuto<DataArrayInt> part1=findClosestTupleId(other);
1335 int nbOfCompo(getNumberOfComponents());
1336 int otherNbTuples(other->getNumberOfTuples());
1337 const double *thisPt(begin()),*otherPt(other->begin());
1338 const int *part1Pt(part1->begin());
1339 double ret=std::numeric_limits<double>::max();
1340 for(int i=0;i<otherNbTuples;i++,part1Pt++,otherPt+=nbOfCompo)
1343 for(int j=0;j<nbOfCompo;j++)
1344 tmp+=(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j])*(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j]);
1346 { ret=tmp; thisTupleId=*part1Pt; otherTupleId=i; }
1352 * This methods returns for each tuple in \a other which tuple in \a this is the closest.
1353 * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
1354 * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
1356 * \return a newly allocated (new object to be dealt by the caller) DataArrayInt having \c other->getNumberOfTuples() tuples and one components.
1357 * \sa DataArrayDouble::minimalDistanceTo
1359 DataArrayInt *DataArrayDouble::findClosestTupleId(const DataArrayDouble *other) const
1362 throw INTERP_KERNEL::Exception("DataArrayDouble::findClosestTupleId : other instance is NULL !");
1363 checkAllocated(); other->checkAllocated();
1364 int nbOfCompo=getNumberOfComponents();
1365 if(nbOfCompo!=other->getNumberOfComponents())
1367 std::ostringstream oss; oss << "DataArrayDouble::findClosestTupleId : number of components in this is " << nbOfCompo;
1368 oss << ", whereas number of components in other is " << other->getNumberOfComponents() << "! Should be equal !";
1369 throw INTERP_KERNEL::Exception(oss.str().c_str());
1371 int nbOfTuples=other->getNumberOfTuples();
1372 int thisNbOfTuples=getNumberOfTuples();
1373 MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuples,1);
1375 getMinMaxPerComponent(bounds);
1380 double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2])),zDelta(fabs(bounds[5]-bounds[4]));
1381 double delta=std::max(xDelta,yDelta); delta=std::max(delta,zDelta);
1382 double characSize=pow((delta*delta*delta)/((double)thisNbOfTuples),1./3.);
1383 BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1384 FindClosestTupleIdAlg<3>(myTree,3.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1389 double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2]));
1390 double delta=std::max(xDelta,yDelta);
1391 double characSize=sqrt(delta/(double)thisNbOfTuples);
1392 BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1393 FindClosestTupleIdAlg<2>(myTree,2.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1398 double characSize=fabs(bounds[1]-bounds[0])/thisNbOfTuples;
1399 BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1400 FindClosestTupleIdAlg<1>(myTree,1.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1404 throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for findClosestTupleId. Must be 1, 2 or 3.");
1410 * This method expects that \a this and \a otherBBoxFrmt arrays are bounding box arrays ( as the output of MEDCouplingPointSet::getBoundingBoxForBBTree method ).
1411 * 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
1412 * how many bounding boxes in \a otherBBoxFrmt.
1413 * So, this method expects that \a this and \a otherBBoxFrmt have the same number of components.
1415 * \param [in] otherBBoxFrmt - It is an array .
1416 * \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.
1417 * \sa MEDCouplingPointSet::getBoundingBoxForBBTree
1418 * \throw If \a this and \a otherBBoxFrmt have not the same number of components.
1419 * \throw If \a this and \a otherBBoxFrmt number of components is not even (BBox format).
1421 DataArrayInt *DataArrayDouble::computeNbOfInteractionsWith(const DataArrayDouble *otherBBoxFrmt, double eps) const
1424 throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : input array is NULL !");
1425 if(!isAllocated() || !otherBBoxFrmt->isAllocated())
1426 throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : this and input array must be allocated !");
1427 int nbOfComp(getNumberOfComponents()),nbOfTuples(getNumberOfTuples());
1428 if(nbOfComp!=otherBBoxFrmt->getNumberOfComponents())
1430 std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : this number of components (" << nbOfComp << ") must be equal to the number of components of input array (" << otherBBoxFrmt->getNumberOfComponents() << ") !";
1431 throw INTERP_KERNEL::Exception(oss.str().c_str());
1435 std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : Number of components (" << nbOfComp << ") is not even ! It should be to be compatible with bbox format !";
1436 throw INTERP_KERNEL::Exception(oss.str().c_str());
1438 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbOfTuples,1);
1439 const double *thisBBPtr(begin());
1440 int *retPtr(ret->getPointer());
1445 BBTree<3,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
1446 for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
1447 *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
1452 BBTree<2,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
1453 for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
1454 *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
1459 BBTree<1,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
1460 for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
1461 *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
1465 throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : space dimension supported are [1,2,3] !");
1472 * Returns a copy of \a this array by excluding coincident tuples. Each tuple is
1473 * considered as coordinates of a point in getNumberOfComponents()-dimensional
1474 * space. The distance between tuples is computed using norm2. If several tuples are
1475 * not far each from other than \a prec, only one of them remains in the result
1476 * array. The order of tuples in the result array is same as in \a this one except
1477 * that coincident tuples are excluded.
1478 * \param [in] prec - minimal absolute distance between two tuples at which they are
1479 * considered not coincident.
1480 * \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
1481 * tuples have id strictly lower than \a limitTupleId then they are not excluded.
1482 * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1483 * is to delete using decrRef() as it is no more needed.
1484 * \throw If \a this is not allocated.
1485 * \throw If the number of components is not in [1,2,3,4].
1487 * \if ENABLE_EXAMPLES
1488 * \ref py_mcdataarraydouble_getdifferentvalues "Here is a Python example".
1491 DataArrayDouble *DataArrayDouble::getDifferentValues(double prec, int limitTupleId) const
1494 DataArrayInt *c0=0,*cI0=0;
1495 findCommonTuples(prec,limitTupleId,c0,cI0);
1496 MCAuto<DataArrayInt> c(c0),cI(cI0);
1497 int newNbOfTuples=-1;
1498 MCAuto<DataArrayInt> o2n=DataArrayInt::ConvertIndexArrayToO2N(getNumberOfTuples(),c0->begin(),cI0->begin(),cI0->end(),newNbOfTuples);
1499 return renumberAndReduce(o2n->getConstPointer(),newNbOfTuples);
1503 * Copy all components in a specified order from another DataArrayDouble.
1504 * Both numerical and textual data is copied. The number of tuples in \a this and
1505 * the other array can be different.
1506 * \param [in] a - the array to copy data from.
1507 * \param [in] compoIds - sequence of zero based indices of components, data of which is
1509 * \throw If \a a is NULL.
1510 * \throw If \a compoIds.size() != \a a->getNumberOfComponents().
1511 * \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
1513 * \if ENABLE_EXAMPLES
1514 * \ref py_mcdataarraydouble_setselectedcomponents "Here is a Python example".
1517 void DataArrayDouble::setSelectedComponents(const DataArrayDouble *a, const std::vector<int>& compoIds)
1520 throw INTERP_KERNEL::Exception("DataArrayDouble::setSelectedComponents : input DataArrayDouble is NULL !");
1522 copyPartOfStringInfoFrom2(compoIds,*a);
1523 std::size_t partOfCompoSz=compoIds.size();
1524 int nbOfCompo=getNumberOfComponents();
1525 int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
1526 const double *ac=a->getConstPointer();
1527 double *nc=getPointer();
1528 for(int i=0;i<nbOfTuples;i++)
1529 for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
1530 nc[nbOfCompo*i+compoIds[j]]=*ac;
1533 void DataArrayDouble::SetArrayIn(DataArrayDouble *newArray, DataArrayDouble* &arrayToSet)
1535 if(newArray!=arrayToSet)
1538 arrayToSet->decrRef();
1539 arrayToSet=newArray;
1541 arrayToSet->incrRef();
1545 void DataArrayDouble::aggregate(const DataArrayDouble *other)
1548 throw INTERP_KERNEL::Exception("DataArrayDouble::aggregate : null pointer !");
1549 if(getNumberOfComponents()!=other->getNumberOfComponents())
1550 throw INTERP_KERNEL::Exception("DataArrayDouble::aggregate : mismatch number of components !");
1551 _mem.insertAtTheEnd(other->begin(),other->end());
1555 * Checks if 0.0 value is present in \a this array. If it is the case, an exception
1557 * \throw If zero is found in \a this array.
1559 void DataArrayDouble::checkNoNullValues() const
1561 const double *tmp=getConstPointer();
1562 std::size_t nbOfElems=getNbOfElems();
1563 const double *where=std::find(tmp,tmp+nbOfElems,0.);
1564 if(where!=tmp+nbOfElems)
1565 throw INTERP_KERNEL::Exception("A value 0.0 have been detected !");
1569 * Computes minimal and maximal value in each component. An output array is filled
1570 * with \c 2 * \a this->getNumberOfComponents() values, so the caller is to allocate
1571 * enough memory before calling this method.
1572 * \param [out] bounds - array of size at least 2 *\a this->getNumberOfComponents().
1573 * It is filled as follows:<br>
1574 * \a bounds[0] = \c min_of_component_0 <br>
1575 * \a bounds[1] = \c max_of_component_0 <br>
1576 * \a bounds[2] = \c min_of_component_1 <br>
1577 * \a bounds[3] = \c max_of_component_1 <br>
1580 void DataArrayDouble::getMinMaxPerComponent(double *bounds) const
1583 int dim=getNumberOfComponents();
1584 for (int idim=0; idim<dim; idim++)
1586 bounds[idim*2]=std::numeric_limits<double>::max();
1587 bounds[idim*2+1]=-std::numeric_limits<double>::max();
1589 const double *ptr=getConstPointer();
1590 int nbOfTuples=getNumberOfTuples();
1591 for(int i=0;i<nbOfTuples;i++)
1593 for(int idim=0;idim<dim;idim++)
1595 if(bounds[idim*2]>ptr[i*dim+idim])
1597 bounds[idim*2]=ptr[i*dim+idim];
1599 if(bounds[idim*2+1]<ptr[i*dim+idim])
1601 bounds[idim*2+1]=ptr[i*dim+idim];
1608 * This method retrieves a newly allocated DataArrayDouble instance having same number of tuples than \a this and twice number of components than \a this
1609 * to store both the min and max per component of each tuples.
1610 * \param [in] epsilon the width of the bbox (identical in each direction) - 0.0 by default
1612 * \return a newly created DataArrayDouble instance having \c this->getNumberOfTuples() tuples and 2 * \c this->getNumberOfComponent() components
1614 * \throw If \a this is not allocated yet.
1616 DataArrayDouble *DataArrayDouble::computeBBoxPerTuple(double epsilon) const
1619 const double *dataPtr=getConstPointer();
1620 int nbOfCompo=getNumberOfComponents();
1621 int nbTuples=getNumberOfTuples();
1622 MCAuto<DataArrayDouble> bbox=DataArrayDouble::New();
1623 bbox->alloc(nbTuples,2*nbOfCompo);
1624 double *bboxPtr=bbox->getPointer();
1625 for(int i=0;i<nbTuples;i++)
1627 for(int j=0;j<nbOfCompo;j++)
1629 bboxPtr[2*nbOfCompo*i+2*j]=dataPtr[nbOfCompo*i+j]-epsilon;
1630 bboxPtr[2*nbOfCompo*i+2*j+1]=dataPtr[nbOfCompo*i+j]+epsilon;
1637 * For each tuples **t** in \a other, this method retrieves tuples in \a this that are equal to **t**.
1638 * Two tuples are considered equal if the euclidian distance between the two tuples is lower than \a eps.
1640 * \param [in] other a DataArrayDouble having same number of components than \a this.
1641 * \param [in] eps absolute precision representing distance (using infinite norm) between 2 tuples behind which 2 tuples are considered equal.
1642 * \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.
1643 * \a cI allows to extract information in \a c.
1644 * \param [out] cI is an indirection array that allows to extract the data contained in \a c.
1646 * \throw In case of:
1647 * - \a this is not allocated
1648 * - \a other is not allocated or null
1649 * - \a this and \a other do not have the same number of components
1650 * - if number of components of \a this is not in [1,2,3]
1652 * \sa MEDCouplingPointSet::getNodeIdsNearPoints, DataArrayDouble::getDifferentValues
1654 void DataArrayDouble::computeTupleIdsNearTuples(const DataArrayDouble *other, double eps, DataArrayInt *& c, DataArrayInt *& cI) const
1657 throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : input pointer other is null !");
1659 other->checkAllocated();
1660 int nbOfCompo=getNumberOfComponents();
1661 int otherNbOfCompo=other->getNumberOfComponents();
1662 if(nbOfCompo!=otherNbOfCompo)
1663 throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : number of components should be equal between this and other !");
1664 int nbOfTuplesOther=other->getNumberOfTuples();
1665 MCAuto<DataArrayInt> cArr(DataArrayInt::New()),cIArr(DataArrayInt::New()); cArr->alloc(0,1); cIArr->pushBackSilent(0);
1670 BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
1671 FindTupleIdsNearTuplesAlg<3>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
1676 BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
1677 FindTupleIdsNearTuplesAlg<2>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
1682 BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
1683 FindTupleIdsNearTuplesAlg<1>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
1687 throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for computeTupleIdsNearTuples. Must be 1, 2 or 3.");
1689 c=cArr.retn(); cI=cIArr.retn();
1693 * 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
1694 * around origin of 'radius' 1.
1696 * \param [in] eps absolute epsilon. under that value of delta between max and min no scale is performed.
1698 void DataArrayDouble::recenterForMaxPrecision(double eps)
1701 int dim=getNumberOfComponents();
1702 std::vector<double> bounds(2*dim);
1703 getMinMaxPerComponent(&bounds[0]);
1704 for(int i=0;i<dim;i++)
1706 double delta=bounds[2*i+1]-bounds[2*i];
1707 double offset=(bounds[2*i]+bounds[2*i+1])/2.;
1709 applyLin(1./delta,-offset/delta,i);
1711 applyLin(1.,-offset,i);
1716 * Returns the maximal value and all its locations within \a this one-dimensional array.
1717 * \param [out] tupleIds - a new instance of DataArrayInt containg indices of
1718 * tuples holding the maximal value. The caller is to delete it using
1719 * decrRef() as it is no more needed.
1720 * \return double - the maximal value among all values of \a this array.
1721 * \throw If \a this->getNumberOfComponents() != 1
1722 * \throw If \a this->getNumberOfTuples() < 1
1724 double DataArrayDouble::getMaxValue2(DataArrayInt*& tupleIds) const
1728 double ret=getMaxValue(tmp);
1729 tupleIds=findIdsInRange(ret,ret);
1734 * Returns the minimal value and all its locations within \a this one-dimensional array.
1735 * \param [out] tupleIds - a new instance of DataArrayInt containg indices of
1736 * tuples holding the minimal value. The caller is to delete it using
1737 * decrRef() as it is no more needed.
1738 * \return double - the minimal value among all values of \a this array.
1739 * \throw If \a this->getNumberOfComponents() != 1
1740 * \throw If \a this->getNumberOfTuples() < 1
1742 double DataArrayDouble::getMinValue2(DataArrayInt*& tupleIds) const
1746 double ret=getMinValue(tmp);
1747 tupleIds=findIdsInRange(ret,ret);
1752 * 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.
1753 * This method only works for single component array.
1755 * \return a value in [ 0, \c this->getNumberOfTuples() )
1757 * \throw If \a this is not allocated
1760 int DataArrayDouble::count(double value, double eps) const
1764 if(getNumberOfComponents()!=1)
1765 throw INTERP_KERNEL::Exception("DataArrayDouble::count : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
1766 const double *vals=begin();
1767 int nbOfTuples=getNumberOfTuples();
1768 for(int i=0;i<nbOfTuples;i++,vals++)
1769 if(fabs(*vals-value)<=eps)
1775 * Returns the average value of \a this one-dimensional array.
1776 * \return double - the average value over all values of \a this array.
1777 * \throw If \a this->getNumberOfComponents() != 1
1778 * \throw If \a this->getNumberOfTuples() < 1
1780 double DataArrayDouble::getAverageValue() const
1782 if(getNumberOfComponents()!=1)
1783 throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
1784 int nbOfTuples=getNumberOfTuples();
1786 throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : array exists but number of tuples must be > 0 !");
1787 const double *vals=getConstPointer();
1788 double ret=std::accumulate(vals,vals+nbOfTuples,0.);
1789 return ret/nbOfTuples;
1793 * Returns the Euclidean norm of the vector defined by \a this array.
1794 * \return double - the value of the Euclidean norm, i.e.
1795 * the square root of the inner product of vector.
1796 * \throw If \a this is not allocated.
1798 double DataArrayDouble::norm2() const
1802 std::size_t nbOfElems=getNbOfElems();
1803 const double *pt=getConstPointer();
1804 for(std::size_t i=0;i<nbOfElems;i++,pt++)
1810 * Returns the maximum norm of the vector defined by \a this array.
1811 * This method works even if the number of components is diferent from one.
1812 * If the number of elements in \a this is 0, -1. is returned.
1813 * \return double - the value of the maximum norm, i.e.
1814 * the maximal absolute value among values of \a this array (whatever its number of components).
1815 * \throw If \a this is not allocated.
1817 double DataArrayDouble::normMax() const
1821 std::size_t nbOfElems(getNbOfElems());
1822 const double *pt(getConstPointer());
1823 for(std::size_t i=0;i<nbOfElems;i++,pt++)
1825 double val(std::abs(*pt));
1833 * Returns the minimum norm (absolute value) of the vector defined by \a this array.
1834 * This method works even if the number of components is diferent from one.
1835 * If the number of elements in \a this is 0, std::numeric_limits<double>::max() is returned.
1836 * \return double - the value of the minimum norm, i.e.
1837 * the minimal absolute value among values of \a this array (whatever its number of components).
1838 * \throw If \a this is not allocated.
1840 double DataArrayDouble::normMin() const
1843 double ret(std::numeric_limits<double>::max());
1844 std::size_t nbOfElems(getNbOfElems());
1845 const double *pt(getConstPointer());
1846 for(std::size_t i=0;i<nbOfElems;i++,pt++)
1848 double val(std::abs(*pt));
1856 * Accumulates values of each component of \a this array.
1857 * \param [out] res - an array of length \a this->getNumberOfComponents(), allocated
1858 * by the caller, that is filled by this method with sum value for each
1860 * \throw If \a this is not allocated.
1862 void DataArrayDouble::accumulate(double *res) const
1865 const double *ptr=getConstPointer();
1866 int nbTuple=getNumberOfTuples();
1867 int nbComps=getNumberOfComponents();
1868 std::fill(res,res+nbComps,0.);
1869 for(int i=0;i<nbTuple;i++)
1870 std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<double>());
1874 * This method returns the min distance from an external tuple defined by [ \a tupleBg , \a tupleEnd ) to \a this and
1875 * the first tuple in \a this that matches the returned distance. If there is no tuples in \a this an exception will be thrown.
1878 * \a this is expected to be allocated and expected to have a number of components equal to the distance from \a tupleBg to
1879 * \a tupleEnd. If not an exception will be thrown.
1881 * \param [in] tupleBg start pointer (included) of input external tuple
1882 * \param [in] tupleEnd end pointer (not included) of input external tuple
1883 * \param [out] tupleId the tuple id in \a this that matches the min of distance between \a this and input external tuple
1884 * \return the min distance.
1885 * \sa MEDCouplingUMesh::distanceToPoint
1887 double DataArrayDouble::distanceToTuple(const double *tupleBg, const double *tupleEnd, int& tupleId) const
1890 int nbTuple=getNumberOfTuples();
1891 int nbComps=getNumberOfComponents();
1892 if(nbComps!=(int)std::distance(tupleBg,tupleEnd))
1893 { 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()); }
1895 throw INTERP_KERNEL::Exception("DataArrayDouble::distanceToTuple : no tuple in this ! No distance to compute !");
1896 double ret0=std::numeric_limits<double>::max();
1898 const double *work=getConstPointer();
1899 for(int i=0;i<nbTuple;i++)
1902 for(int j=0;j<nbComps;j++,work++)
1903 val+=(*work-tupleBg[j])*((*work-tupleBg[j]));
1907 { ret0=val; tupleId=i; }
1913 * Accumulate values of the given component of \a this array.
1914 * \param [in] compId - the index of the component of interest.
1915 * \return double - a sum value of \a compId-th component.
1916 * \throw If \a this is not allocated.
1917 * \throw If \a the condition ( 0 <= \a compId < \a this->getNumberOfComponents() ) is
1920 double DataArrayDouble::accumulate(int compId) const
1923 const double *ptr=getConstPointer();
1924 int nbTuple=getNumberOfTuples();
1925 int nbComps=getNumberOfComponents();
1926 if(compId<0 || compId>=nbComps)
1927 throw INTERP_KERNEL::Exception("DataArrayDouble::accumulate : Invalid compId specified : No such nb of components !");
1929 for(int i=0;i<nbTuple;i++)
1930 ret+=ptr[i*nbComps+compId];
1935 * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
1936 * The returned array will have same number of components than \a this and number of tuples equal to
1937 * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
1939 * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
1940 * 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.
1942 * \param [in] bgOfIndex - begin (included) of the input index array.
1943 * \param [in] endOfIndex - end (excluded) of the input index array.
1944 * \return DataArrayDouble * - the new instance having the same number of components than \a this.
1946 * \throw If bgOfIndex or end is NULL.
1947 * \throw If input index array is not ascendingly sorted.
1948 * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
1949 * \throw If std::distance(bgOfIndex,endOfIndex)==0.
1951 DataArrayDouble *DataArrayDouble::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
1953 if(!bgOfIndex || !endOfIndex)
1954 throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : input pointer NULL !");
1956 int nbCompo=getNumberOfComponents();
1957 int nbOfTuples=getNumberOfTuples();
1958 int sz=(int)std::distance(bgOfIndex,endOfIndex);
1960 throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : invalid size of input index array !");
1962 MCAuto<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(sz,nbCompo);
1963 const int *w=bgOfIndex;
1964 if(*w<0 || *w>=nbOfTuples)
1965 throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
1966 const double *srcPt=begin()+(*w)*nbCompo;
1967 double *tmp=ret->getPointer();
1968 for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
1970 std::fill(tmp,tmp+nbCompo,0.);
1973 for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
1975 if(j>=0 && j<nbOfTuples)
1976 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<double>());
1979 std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
1980 throw INTERP_KERNEL::Exception(oss.str().c_str());
1986 std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
1987 throw INTERP_KERNEL::Exception(oss.str().c_str());
1990 ret->copyStringInfoFrom(*this);
1995 * 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.
1996 * This method expects that \a this as only one component. The returned array will have \a this->getNumberOfTuples()+1 tuple with also one component.
1997 * The ith element of returned array is equal to the sum of elements in \a this with rank strictly lower than i.
1999 * \return DataArrayDouble - A newly built array containing cum sum of \a this.
2001 MCAuto<DataArrayDouble> DataArrayDouble::cumSum() const
2004 checkNbOfComps(1,"DataArrayDouble::cumSum : this is expected to be single component");
2005 int nbOfTuple(getNumberOfTuples());
2006 MCAuto<DataArrayDouble> ret(DataArrayDouble::New()); ret->alloc(nbOfTuple+1,1);
2007 double *ptr(ret->getPointer());
2009 const double *thisPtr(begin());
2010 for(int i=0;i<nbOfTuple;i++)
2011 ptr[i+1]=ptr[i]+thisPtr[i];
2016 * Converts each 2D point defined by the tuple of \a this array from the Polar to the
2017 * Cartesian coordinate system. The two components of the tuple of \a this array are
2018 * considered to contain (1) radius and (2) angle of the point in the Polar CS.
2019 * \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
2020 * contains X and Y coordinates of the point in the Cartesian CS. The caller
2021 * is to delete this array using decrRef() as it is no more needed. The array
2022 * does not contain any textual info on components.
2023 * \throw If \a this->getNumberOfComponents() != 2.
2024 * \sa fromCartToPolar
2026 DataArrayDouble *DataArrayDouble::fromPolarToCart() const
2029 int nbOfComp(getNumberOfComponents());
2031 throw INTERP_KERNEL::Exception("DataArrayDouble::fromPolarToCart : must be an array with exactly 2 components !");
2032 int nbOfTuple(getNumberOfTuples());
2033 DataArrayDouble *ret(DataArrayDouble::New());
2034 ret->alloc(nbOfTuple,2);
2035 double *w(ret->getPointer());
2036 const double *wIn(getConstPointer());
2037 for(int i=0;i<nbOfTuple;i++,w+=2,wIn+=2)
2039 w[0]=wIn[0]*cos(wIn[1]);
2040 w[1]=wIn[0]*sin(wIn[1]);
2046 * Converts each 3D point defined by the tuple of \a this array from the Cylindrical to
2047 * the Cartesian coordinate system. The three components of the tuple of \a this array
2048 * are considered to contain (1) radius, (2) azimuth and (3) altitude of the point in
2049 * the Cylindrical CS.
2050 * \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
2051 * contains X, Y and Z coordinates of the point in the Cartesian CS. The info
2052 * on the third component is copied from \a this array. The caller
2053 * is to delete this array using decrRef() as it is no more needed.
2054 * \throw If \a this->getNumberOfComponents() != 3.
2057 DataArrayDouble *DataArrayDouble::fromCylToCart() const
2060 int nbOfComp(getNumberOfComponents());
2062 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCylToCart : must be an array with exactly 3 components !");
2063 int nbOfTuple(getNumberOfTuples());
2064 DataArrayDouble *ret(DataArrayDouble::New());
2065 ret->alloc(getNumberOfTuples(),3);
2066 double *w(ret->getPointer());
2067 const double *wIn(getConstPointer());
2068 for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
2070 w[0]=wIn[0]*cos(wIn[1]);
2071 w[1]=wIn[0]*sin(wIn[1]);
2074 ret->setInfoOnComponent(2,getInfoOnComponent(2));
2079 * Converts each 3D point defined by the tuple of \a this array from the Spherical to
2080 * the Cartesian coordinate system. The three components of the tuple of \a this array
2081 * are considered to contain (1) radius, (2) polar angle and (3) azimuthal angle of the
2082 * point in the Cylindrical CS.
2083 * \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
2084 * contains X, Y and Z coordinates of the point in the Cartesian CS. The info
2085 * on the third component is copied from \a this array. The caller
2086 * is to delete this array using decrRef() as it is no more needed.
2087 * \throw If \a this->getNumberOfComponents() != 3.
2088 * \sa fromCartToSpher
2090 DataArrayDouble *DataArrayDouble::fromSpherToCart() const
2093 int nbOfComp(getNumberOfComponents());
2095 throw INTERP_KERNEL::Exception("DataArrayDouble::fromSpherToCart : must be an array with exactly 3 components !");
2096 int nbOfTuple(getNumberOfTuples());
2097 DataArrayDouble *ret(DataArrayDouble::New());
2098 ret->alloc(getNumberOfTuples(),3);
2099 double *w(ret->getPointer());
2100 const double *wIn(getConstPointer());
2101 for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
2103 w[0]=wIn[0]*cos(wIn[2])*sin(wIn[1]);
2104 w[1]=wIn[0]*sin(wIn[2])*sin(wIn[1]);
2105 w[2]=wIn[0]*cos(wIn[1]);
2111 * 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.
2112 * 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.
2113 * If \a at equals to AX_CYL the returned array will be the result of operation cylindric to cartesian of \a this...
2115 * \param [in] atOfThis - The axis type of \a this.
2116 * \return DataArrayDouble * - the new instance of DataArrayDouble (that must be dealed by caller) containing the result of the cartesianizification of \a this.
2118 DataArrayDouble *DataArrayDouble::cartesianize(MEDCouplingAxisType atOfThis) const
2121 int nbOfComp(getNumberOfComponents());
2122 MCAuto<DataArrayDouble> ret;
2130 ret=fromCylToCart();
2135 ret=fromPolarToCart();
2139 throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : For AX_CYL, number of components must be in [2,3] !");
2143 ret=fromSpherToCart();
2148 ret=fromPolarToCart();
2152 throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : For AX_CYL, number of components must be in [2,3] !");
2154 throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : not recognized axis type ! Only AX_CART, AX_CYL and AX_SPHER supported !");
2156 ret->copyStringInfoFrom(*this);
2161 * This method returns a newly created array to be deallocated that contains the result of conversion from cartesian to polar.
2162 * This method expects that \a this has exactly 2 components.
2163 * \sa fromPolarToCart
2165 DataArrayDouble *DataArrayDouble::fromCartToPolar() const
2167 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2169 int nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2171 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToPolar : must be an array with exactly 2 components !");
2172 ret->alloc(nbTuples,2);
2173 double *retPtr(ret->getPointer());
2174 const double *ptr(begin());
2175 for(int i=0;i<nbTuples;i++,ptr+=2,retPtr+=2)
2177 retPtr[0]=sqrt(ptr[0]*ptr[0]+ptr[1]*ptr[1]);
2178 retPtr[1]=atan2(ptr[1],ptr[0]);
2184 * This method returns a newly created array to be deallocated that contains the result of conversion from cartesian to cylindrical.
2185 * This method expects that \a this has exactly 3 components.
2188 DataArrayDouble *DataArrayDouble::fromCartToCyl() const
2190 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2192 int nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2194 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCyl : must be an array with exactly 3 components !");
2195 ret->alloc(nbTuples,3);
2196 double *retPtr(ret->getPointer());
2197 const double *ptr(begin());
2198 for(int i=0;i<nbTuples;i++,ptr+=3,retPtr+=3)
2200 retPtr[0]=sqrt(ptr[0]*ptr[0]+ptr[1]*ptr[1]);
2201 retPtr[1]=atan2(ptr[1],ptr[0]);
2208 * This method returns a newly created array to be deallocated that contains the result of conversion from cartesian to spherical coordinates.
2209 * \sa fromSpherToCart
2211 DataArrayDouble *DataArrayDouble::fromCartToSpher() const
2213 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2215 int nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2217 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToSpher : must be an array with exactly 3 components !");
2218 ret->alloc(nbTuples,3);
2219 double *retPtr(ret->getPointer());
2220 const double *ptr(begin());
2221 for(int i=0;i<nbTuples;i++,ptr+=3,retPtr+=3)
2223 retPtr[0]=sqrt(ptr[0]*ptr[0]+ptr[1]*ptr[1]+ptr[2]*ptr[2]);
2224 retPtr[1]=acos(ptr[2]/retPtr[0]);
2225 retPtr[2]=atan2(ptr[1],ptr[0]);
2231 * 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.
2232 * This method expects that \a this has exactly 3 components.
2233 * \sa MEDCouplingFieldDouble::computeVectorFieldCyl
2235 DataArrayDouble *DataArrayDouble::fromCartToCylGiven(const DataArrayDouble *coords, const double center[3], const double vect[3]) const
2238 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : input coords are NULL !");
2239 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2240 checkAllocated(); coords->checkAllocated();
2241 int nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2243 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : must be an array with exactly 3 components !");
2244 if(coords->getNumberOfComponents()!=3)
2245 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : coords array must have exactly 3 components !");
2246 if(coords->getNumberOfTuples()!=nbTuples)
2247 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : coords array must have the same number of tuples !");
2248 ret->alloc(nbTuples,nbOfComp);
2249 double magOfVect(sqrt(vect[0]*vect[0]+vect[1]*vect[1]+vect[2]*vect[2]));
2251 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : magnitude of vect is too low !");
2252 double Ur[3],Uteta[3],Uz[3],*retPtr(ret->getPointer());
2253 const double *coo(coords->begin()),*vectField(begin());
2254 std::transform(vect,vect+3,Uz,std::bind2nd(std::multiplies<double>(),1./magOfVect));
2255 for(int i=0;i<nbTuples;i++,vectField+=3,retPtr+=3,coo+=3)
2257 std::transform(coo,coo+3,center,Ur,std::minus<double>());
2258 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];
2259 double magOfTeta(sqrt(Uteta[0]*Uteta[0]+Uteta[1]*Uteta[1]+Uteta[2]*Uteta[2]));
2260 std::transform(Uteta,Uteta+3,Uteta,std::bind2nd(std::multiplies<double>(),1./magOfTeta));
2261 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];
2262 retPtr[0]=Ur[0]*vectField[0]+Ur[1]*vectField[1]+Ur[2]*vectField[2];
2263 retPtr[1]=Uteta[0]*vectField[0]+Uteta[1]*vectField[1]+Uteta[2]*vectField[2];
2264 retPtr[2]=Uz[0]*vectField[0]+Uz[1]*vectField[1]+Uz[2]*vectField[2];
2266 ret->copyStringInfoFrom(*this);
2271 * Computes the doubly contracted product of every tensor defined by the tuple of \a this
2272 * array contating 6 components.
2273 * \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
2274 * is calculated from the tuple <em>(t)</em> of \a this array as follows:
2275 * \f$ t[0]^2+t[1]^2+t[2]^2+2*t[3]^2+2*t[4]^2+2*t[5]^2\f$.
2276 * The caller is to delete this result array using decrRef() as it is no more needed.
2277 * \throw If \a this->getNumberOfComponents() != 6.
2279 DataArrayDouble *DataArrayDouble::doublyContractedProduct() const
2282 int nbOfComp(getNumberOfComponents());
2284 throw INTERP_KERNEL::Exception("DataArrayDouble::doublyContractedProduct : must be an array with exactly 6 components !");
2285 DataArrayDouble *ret=DataArrayDouble::New();
2286 int nbOfTuple=getNumberOfTuples();
2287 ret->alloc(nbOfTuple,1);
2288 const double *src=getConstPointer();
2289 double *dest=ret->getPointer();
2290 for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
2291 *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];
2296 * Computes the determinant of every square matrix defined by the tuple of \a this
2297 * array, which contains either 4, 6 or 9 components. The case of 6 components
2298 * corresponds to that of the upper triangular matrix.
2299 * \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
2300 * is the determinant of matrix of the corresponding tuple of \a this array.
2301 * The caller is to delete this result array using decrRef() as it is no more
2303 * \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2305 DataArrayDouble *DataArrayDouble::determinant() const
2308 DataArrayDouble *ret=DataArrayDouble::New();
2309 int nbOfTuple=getNumberOfTuples();
2310 ret->alloc(nbOfTuple,1);
2311 const double *src=getConstPointer();
2312 double *dest=ret->getPointer();
2313 switch(getNumberOfComponents())
2316 for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
2317 *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];
2320 for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
2321 *dest=src[0]*src[3]-src[1]*src[2];
2324 for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
2325 *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];
2329 throw INTERP_KERNEL::Exception("DataArrayDouble::determinant : Invalid number of components ! must be in 4,6,9 !");
2334 * Computes 3 eigenvalues of every upper triangular matrix defined by the tuple of
2335 * \a this array, which contains 6 components.
2336 * \return DataArrayDouble * - the new instance of DataArrayDouble containing 3
2337 * components, whose each tuple contains the eigenvalues of the matrix of
2338 * corresponding tuple of \a this array.
2339 * The caller is to delete this result array using decrRef() as it is no more
2341 * \throw If \a this->getNumberOfComponents() != 6.
2343 DataArrayDouble *DataArrayDouble::eigenValues() const
2346 int nbOfComp=getNumberOfComponents();
2348 throw INTERP_KERNEL::Exception("DataArrayDouble::eigenValues : must be an array with exactly 6 components !");
2349 DataArrayDouble *ret=DataArrayDouble::New();
2350 int nbOfTuple=getNumberOfTuples();
2351 ret->alloc(nbOfTuple,3);
2352 const double *src=getConstPointer();
2353 double *dest=ret->getPointer();
2354 for(int i=0;i<nbOfTuple;i++,dest+=3,src+=6)
2355 INTERP_KERNEL::computeEigenValues6(src,dest);
2360 * Computes 3 eigenvectors of every upper triangular matrix defined by the tuple of
2361 * \a this array, which contains 6 components.
2362 * \return DataArrayDouble * - the new instance of DataArrayDouble containing 9
2363 * components, whose each tuple contains 3 eigenvectors of the matrix of
2364 * corresponding tuple of \a this array.
2365 * The caller is to delete this result array using decrRef() as it is no more
2367 * \throw If \a this->getNumberOfComponents() != 6.
2369 DataArrayDouble *DataArrayDouble::eigenVectors() const
2372 int nbOfComp=getNumberOfComponents();
2374 throw INTERP_KERNEL::Exception("DataArrayDouble::eigenVectors : must be an array with exactly 6 components !");
2375 DataArrayDouble *ret=DataArrayDouble::New();
2376 int nbOfTuple=getNumberOfTuples();
2377 ret->alloc(nbOfTuple,9);
2378 const double *src=getConstPointer();
2379 double *dest=ret->getPointer();
2380 for(int i=0;i<nbOfTuple;i++,src+=6)
2383 INTERP_KERNEL::computeEigenValues6(src,tmp);
2384 for(int j=0;j<3;j++,dest+=3)
2385 INTERP_KERNEL::computeEigenVectorForEigenValue6(src,tmp[j],1e-12,dest);
2391 * Computes the inverse matrix of every matrix defined by the tuple of \a this
2392 * array, which contains either 4, 6 or 9 components. The case of 6 components
2393 * corresponds to that of the upper triangular matrix.
2394 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2395 * same number of components as \a this one, whose each tuple is the inverse
2396 * matrix of the matrix of corresponding tuple of \a this array.
2397 * The caller is to delete this result array using decrRef() as it is no more
2399 * \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2401 DataArrayDouble *DataArrayDouble::inverse() const
2404 int nbOfComp=getNumberOfComponents();
2405 if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
2406 throw INTERP_KERNEL::Exception("DataArrayDouble::inversion : must be an array with 4,6 or 9 components !");
2407 DataArrayDouble *ret=DataArrayDouble::New();
2408 int nbOfTuple=getNumberOfTuples();
2409 ret->alloc(nbOfTuple,nbOfComp);
2410 const double *src=getConstPointer();
2411 double *dest=ret->getPointer();
2413 for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
2415 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];
2416 dest[0]=(src[1]*src[2]-src[4]*src[4])/det;
2417 dest[1]=(src[0]*src[2]-src[5]*src[5])/det;
2418 dest[2]=(src[0]*src[1]-src[3]*src[3])/det;
2419 dest[3]=(src[5]*src[4]-src[3]*src[2])/det;
2420 dest[4]=(src[5]*src[3]-src[0]*src[4])/det;
2421 dest[5]=(src[3]*src[4]-src[1]*src[5])/det;
2423 else if(nbOfComp==4)
2424 for(int i=0;i<nbOfTuple;i++,dest+=4,src+=4)
2426 double det=src[0]*src[3]-src[1]*src[2];
2428 dest[1]=-src[1]/det;
2429 dest[2]=-src[2]/det;
2433 for(int i=0;i<nbOfTuple;i++,dest+=9,src+=9)
2435 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];
2436 dest[0]=(src[4]*src[8]-src[7]*src[5])/det;
2437 dest[1]=(src[7]*src[2]-src[1]*src[8])/det;
2438 dest[2]=(src[1]*src[5]-src[4]*src[2])/det;
2439 dest[3]=(src[6]*src[5]-src[3]*src[8])/det;
2440 dest[4]=(src[0]*src[8]-src[6]*src[2])/det;
2441 dest[5]=(src[2]*src[3]-src[0]*src[5])/det;
2442 dest[6]=(src[3]*src[7]-src[6]*src[4])/det;
2443 dest[7]=(src[6]*src[1]-src[0]*src[7])/det;
2444 dest[8]=(src[0]*src[4]-src[1]*src[3])/det;
2450 * Computes the trace of every matrix defined by the tuple of \a this
2451 * array, which contains either 4, 6 or 9 components. The case of 6 components
2452 * corresponds to that of the upper triangular matrix.
2453 * \return DataArrayDouble * - the new instance of DataArrayDouble containing
2454 * 1 component, whose each tuple is the trace of
2455 * the matrix of corresponding tuple of \a this array.
2456 * The caller is to delete this result array using decrRef() as it is no more
2458 * \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2460 DataArrayDouble *DataArrayDouble::trace() const
2463 int nbOfComp=getNumberOfComponents();
2464 if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
2465 throw INTERP_KERNEL::Exception("DataArrayDouble::trace : must be an array with 4,6 or 9 components !");
2466 DataArrayDouble *ret=DataArrayDouble::New();
2467 int nbOfTuple=getNumberOfTuples();
2468 ret->alloc(nbOfTuple,1);
2469 const double *src=getConstPointer();
2470 double *dest=ret->getPointer();
2472 for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
2473 *dest=src[0]+src[1]+src[2];
2474 else if(nbOfComp==4)
2475 for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
2476 *dest=src[0]+src[3];
2478 for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
2479 *dest=src[0]+src[4]+src[8];
2484 * Computes the stress deviator tensor of every stress tensor defined by the tuple of
2485 * \a this array, which contains 6 components.
2486 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2487 * same number of components and tuples as \a this array.
2488 * The caller is to delete this result array using decrRef() as it is no more
2490 * \throw If \a this->getNumberOfComponents() != 6.
2492 DataArrayDouble *DataArrayDouble::deviator() const
2495 int nbOfComp=getNumberOfComponents();
2497 throw INTERP_KERNEL::Exception("DataArrayDouble::deviator : must be an array with exactly 6 components !");
2498 DataArrayDouble *ret=DataArrayDouble::New();
2499 int nbOfTuple=getNumberOfTuples();
2500 ret->alloc(nbOfTuple,6);
2501 const double *src=getConstPointer();
2502 double *dest=ret->getPointer();
2503 for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
2505 double tr=(src[0]+src[1]+src[2])/3.;
2517 * Computes the magnitude of every vector defined by the tuple of
2519 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2520 * same number of tuples as \a this array and one component.
2521 * The caller is to delete this result array using decrRef() as it is no more
2523 * \throw If \a this is not allocated.
2525 DataArrayDouble *DataArrayDouble::magnitude() const
2528 int nbOfComp=getNumberOfComponents();
2529 DataArrayDouble *ret=DataArrayDouble::New();
2530 int nbOfTuple=getNumberOfTuples();
2531 ret->alloc(nbOfTuple,1);
2532 const double *src=getConstPointer();
2533 double *dest=ret->getPointer();
2534 for(int i=0;i<nbOfTuple;i++,dest++)
2537 for(int j=0;j<nbOfComp;j++,src++)
2545 * Computes for each tuple the sum of number of components values in the tuple and return it.
2547 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2548 * same number of tuples as \a this array and one component.
2549 * The caller is to delete this result array using decrRef() as it is no more
2551 * \throw If \a this is not allocated.
2553 DataArrayDouble *DataArrayDouble::sumPerTuple() const
2556 int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
2557 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2558 ret->alloc(nbOfTuple,1);
2559 const double *src(getConstPointer());
2560 double *dest(ret->getPointer());
2561 for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
2562 *dest=std::accumulate(src,src+nbOfComp,0.);
2567 * Computes the maximal value within every tuple of \a this array.
2568 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2569 * same number of tuples as \a this array and one component.
2570 * The caller is to delete this result array using decrRef() as it is no more
2572 * \throw If \a this is not allocated.
2573 * \sa DataArrayDouble::maxPerTupleWithCompoId
2575 DataArrayDouble *DataArrayDouble::maxPerTuple() const
2578 int nbOfComp=getNumberOfComponents();
2579 MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
2580 int nbOfTuple=getNumberOfTuples();
2581 ret->alloc(nbOfTuple,1);
2582 const double *src=getConstPointer();
2583 double *dest=ret->getPointer();
2584 for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
2585 *dest=*std::max_element(src,src+nbOfComp);
2590 * Computes the maximal value within every tuple of \a this array and it returns the first component
2591 * id for each tuple that corresponds to the maximal value within the tuple.
2593 * \param [out] compoIdOfMaxPerTuple - the new new instance of DataArrayInt containing the
2594 * same number of tuples and only one component.
2595 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2596 * same number of tuples as \a this array and one component.
2597 * The caller is to delete this result array using decrRef() as it is no more
2599 * \throw If \a this is not allocated.
2600 * \sa DataArrayDouble::maxPerTuple
2602 DataArrayDouble *DataArrayDouble::maxPerTupleWithCompoId(DataArrayInt* &compoIdOfMaxPerTuple) const
2605 int nbOfComp=getNumberOfComponents();
2606 MCAuto<DataArrayDouble> ret0=DataArrayDouble::New();
2607 MCAuto<DataArrayInt> ret1=DataArrayInt::New();
2608 int nbOfTuple=getNumberOfTuples();
2609 ret0->alloc(nbOfTuple,1); ret1->alloc(nbOfTuple,1);
2610 const double *src=getConstPointer();
2611 double *dest=ret0->getPointer(); int *dest1=ret1->getPointer();
2612 for(int i=0;i<nbOfTuple;i++,dest++,dest1++,src+=nbOfComp)
2614 const double *loc=std::max_element(src,src+nbOfComp);
2616 *dest1=(int)std::distance(src,loc);
2618 compoIdOfMaxPerTuple=ret1.retn();
2623 * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c this->getNumberOfTuples() tuples.
2624 * \n This returned array contains the euclidian distance for each tuple in \a this.
2625 * \n So the returned array can be seen as a dense symmetrical matrix whose diagonal elements are equal to 0.
2626 * \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)
2628 * \warning use this method with care because it can leads to big amount of consumed memory !
2630 * \return A newly allocated (huge) MEDCoupling::DataArrayDouble instance that the caller should deal with.
2632 * \throw If \a this is not allocated.
2634 * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrixWith
2636 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrix() const
2639 int nbOfComp=getNumberOfComponents();
2640 int nbOfTuples=getNumberOfTuples();
2641 const double *inData=getConstPointer();
2642 MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
2643 ret->alloc(nbOfTuples*nbOfTuples,1);
2644 double *outData=ret->getPointer();
2645 for(int i=0;i<nbOfTuples;i++)
2647 outData[i*nbOfTuples+i]=0.;
2648 for(int j=i+1;j<nbOfTuples;j++)
2651 for(int k=0;k<nbOfComp;k++)
2652 { double delta=inData[i*nbOfComp+k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
2654 outData[i*nbOfTuples+j]=dist;
2655 outData[j*nbOfTuples+i]=dist;
2662 * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c other->getNumberOfTuples() tuples.
2663 * \n This returned array contains the euclidian distance for each tuple in \a other with each tuple in \a this.
2664 * \n So the returned array can be seen as a dense rectangular matrix with \c other->getNumberOfTuples() rows and \c this->getNumberOfTuples() columns.
2665 * \n Output rectangular matrix is sorted along rows.
2666 * \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)
2668 * \warning use this method with care because it can leads to big amount of consumed memory !
2670 * \param [in] other DataArrayDouble instance having same number of components than \a this.
2671 * \return A newly allocated (huge) MEDCoupling::DataArrayDouble instance that the caller should deal with.
2673 * \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.
2675 * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrix
2677 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrixWith(const DataArrayDouble *other) const
2680 throw INTERP_KERNEL::Exception("DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : input parameter is null !");
2682 other->checkAllocated();
2683 int nbOfComp=getNumberOfComponents();
2684 int otherNbOfComp=other->getNumberOfComponents();
2685 if(nbOfComp!=otherNbOfComp)
2687 std::ostringstream oss; oss << "DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : this nb of compo=" << nbOfComp << " and other nb of compo=" << otherNbOfComp << ". It should match !";
2688 throw INTERP_KERNEL::Exception(oss.str().c_str());
2690 int nbOfTuples=getNumberOfTuples();
2691 int otherNbOfTuples=other->getNumberOfTuples();
2692 const double *inData=getConstPointer();
2693 const double *inDataOther=other->getConstPointer();
2694 MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
2695 ret->alloc(otherNbOfTuples*nbOfTuples,1);
2696 double *outData=ret->getPointer();
2697 for(int i=0;i<otherNbOfTuples;i++,inDataOther+=nbOfComp)
2699 for(int j=0;j<nbOfTuples;j++)
2702 for(int k=0;k<nbOfComp;k++)
2703 { double delta=inDataOther[k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
2705 outData[i*nbOfTuples+j]=dist;
2712 * Sorts value within every tuple of \a this array.
2713 * \param [in] asc - if \a true, the values are sorted in ascending order, else,
2714 * in descending order.
2715 * \throw If \a this is not allocated.
2717 void DataArrayDouble::sortPerTuple(bool asc)
2720 double *pt=getPointer();
2721 int nbOfTuple=getNumberOfTuples();
2722 int nbOfComp=getNumberOfComponents();
2724 for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
2725 std::sort(pt,pt+nbOfComp);
2727 for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
2728 std::sort(pt,pt+nbOfComp,std::greater<double>());
2733 * Converts every value of \a this array to its absolute value.
2734 * \b WARNING this method is non const. If a new DataArrayDouble instance should be built containing the result of abs DataArrayDouble::computeAbs
2735 * should be called instead.
2737 * \throw If \a this is not allocated.
2738 * \sa DataArrayDouble::computeAbs
2740 void DataArrayDouble::abs()
2743 double *ptr(getPointer());
2744 std::size_t nbOfElems(getNbOfElems());
2745 std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<double,double>(fabs));
2750 * This method builds a new instance of \a this object containing the result of std::abs applied of all elements in \a this.
2751 * This method is a const method (that do not change any values in \a this) contrary to DataArrayDouble::abs method.
2753 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2754 * same number of tuples and component as \a this array.
2755 * The caller is to delete this result array using decrRef() as it is no more
2757 * \throw If \a this is not allocated.
2758 * \sa DataArrayDouble::abs
2760 DataArrayDouble *DataArrayDouble::computeAbs() const
2763 DataArrayDouble *newArr(DataArrayDouble::New());
2764 int nbOfTuples(getNumberOfTuples());
2765 int nbOfComp(getNumberOfComponents());
2766 newArr->alloc(nbOfTuples,nbOfComp);
2767 std::transform(begin(),end(),newArr->getPointer(),std::ptr_fun<double,double>(fabs));
2768 newArr->copyStringInfoFrom(*this);
2773 * Apply a linear function to a given component of \a this array, so that
2774 * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
2775 * \param [in] a - the first coefficient of the function.
2776 * \param [in] b - the second coefficient of the function.
2777 * \param [in] compoId - the index of component to modify.
2778 * \throw If \a this is not allocated, or \a compoId is not in [0,\c this->getNumberOfComponents() ).
2780 void DataArrayDouble::applyLin(double a, double b, int compoId)
2783 double *ptr(getPointer()+compoId);
2784 int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
2785 if(compoId<0 || compoId>=nbOfComp)
2787 std::ostringstream oss; oss << "DataArrayDouble::applyLin : The compoId requested (" << compoId << ") is not valid ! Must be in [0," << nbOfComp << ") !";
2788 throw INTERP_KERNEL::Exception(oss.str().c_str());
2790 for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
2796 * Apply a linear function to all elements of \a this array, so that
2797 * an element _x_ becomes \f$ a * x + b \f$.
2798 * \param [in] a - the first coefficient of the function.
2799 * \param [in] b - the second coefficient of the function.
2800 * \throw If \a this is not allocated.
2802 void DataArrayDouble::applyLin(double a, double b)
2805 double *ptr=getPointer();
2806 std::size_t nbOfElems=getNbOfElems();
2807 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2813 * Modify all elements of \a this array, so that
2814 * an element _x_ becomes \f$ numerator / x \f$.
2815 * \warning If an exception is thrown because of presence of 0.0 element in \a this
2816 * array, all elements processed before detection of the zero element remain
2818 * \param [in] numerator - the numerator used to modify array elements.
2819 * \throw If \a this is not allocated.
2820 * \throw If there is an element equal to 0.0 in \a this array.
2822 void DataArrayDouble::applyInv(double numerator)
2825 double *ptr=getPointer();
2826 std::size_t nbOfElems=getNbOfElems();
2827 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2829 if(std::abs(*ptr)>std::numeric_limits<double>::min())
2831 *ptr=numerator/(*ptr);
2835 std::ostringstream oss; oss << "DataArrayDouble::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
2837 throw INTERP_KERNEL::Exception(oss.str().c_str());
2844 * Returns a full copy of \a this array except that sign of all elements is reversed.
2845 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2846 * same number of tuples and component as \a this array.
2847 * The caller is to delete this result array using decrRef() as it is no more
2849 * \throw If \a this is not allocated.
2851 DataArrayDouble *DataArrayDouble::negate() const
2854 DataArrayDouble *newArr=DataArrayDouble::New();
2855 int nbOfTuples=getNumberOfTuples();
2856 int nbOfComp=getNumberOfComponents();
2857 newArr->alloc(nbOfTuples,nbOfComp);
2858 const double *cptr=getConstPointer();
2859 std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<double>());
2860 newArr->copyStringInfoFrom(*this);
2865 * Modify all elements of \a this array, so that
2866 * an element _x_ becomes <em> val ^ x </em>. Contrary to DataArrayInt::applyPow
2867 * all values in \a this have to be >= 0 if val is \b not integer.
2868 * \param [in] val - the value used to apply pow on all array elements.
2869 * \throw If \a this is not allocated.
2870 * \warning If an exception is thrown because of presence of 0 element in \a this
2871 * array and \a val is \b not integer, all elements processed before detection of the zero element remain
2874 void DataArrayDouble::applyPow(double val)
2877 double *ptr=getPointer();
2878 std::size_t nbOfElems=getNbOfElems();
2880 bool isInt=((double)val2)==val;
2883 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2889 std::ostringstream oss; oss << "DataArrayDouble::applyPow (double) : At elem # " << i << " value is " << *ptr << " ! must be >=0. !";
2890 throw INTERP_KERNEL::Exception(oss.str().c_str());
2896 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2897 *ptr=pow(*ptr,val2);
2903 * Modify all elements of \a this array, so that
2904 * an element _x_ becomes \f$ val ^ x \f$.
2905 * \param [in] val - the value used to apply pow on all array elements.
2906 * \throw If \a this is not allocated.
2907 * \throw If \a val < 0.
2908 * \warning If an exception is thrown because of presence of 0 element in \a this
2909 * array, all elements processed before detection of the zero element remain
2912 void DataArrayDouble::applyRPow(double val)
2916 throw INTERP_KERNEL::Exception("DataArrayDouble::applyRPow : the input value has to be >= 0 !");
2917 double *ptr=getPointer();
2918 std::size_t nbOfElems=getNbOfElems();
2919 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2925 * Returns a new DataArrayDouble created from \a this one by applying \a
2926 * FunctionToEvaluate to every tuple of \a this array. Textual data is not copied.
2927 * For more info see \ref MEDCouplingArrayApplyFunc
2928 * \param [in] nbOfComp - number of components in the result array.
2929 * \param [in] func - the \a FunctionToEvaluate declared as
2930 * \c bool (*\a func)(\c const \c double *\a pos, \c double *\a res),
2931 * where \a pos points to the first component of a tuple of \a this array
2932 * and \a res points to the first component of a tuple of the result array.
2933 * Note that length (number of components) of \a pos can differ from
2935 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2936 * same number of tuples as \a this array.
2937 * The caller is to delete this result array using decrRef() as it is no more
2939 * \throw If \a this is not allocated.
2940 * \throw If \a func returns \a false.
2942 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, FunctionToEvaluate func) const
2945 DataArrayDouble *newArr=DataArrayDouble::New();
2946 int nbOfTuples=getNumberOfTuples();
2947 int oldNbOfComp=getNumberOfComponents();
2948 newArr->alloc(nbOfTuples,nbOfComp);
2949 const double *ptr=getConstPointer();
2950 double *ptrToFill=newArr->getPointer();
2951 for(int i=0;i<nbOfTuples;i++)
2953 if(!func(ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp))
2955 std::ostringstream oss; oss << "For tuple # " << i << " with value (";
2956 std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
2957 oss << ") : Evaluation of function failed !";
2959 throw INTERP_KERNEL::Exception(oss.str().c_str());
2966 * Returns a new DataArrayDouble created from \a this one by applying a function to every
2967 * tuple of \a this array. Textual data is not copied.
2968 * For more info see \ref MEDCouplingArrayApplyFunc1.
2969 * \param [in] nbOfComp - number of components in the result array.
2970 * \param [in] func - the expression defining how to transform a tuple of \a this array.
2971 * Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
2972 * \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
2973 * If false the computation is carried on without any notification. When false the evaluation is a little faster.
2974 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2975 * same number of tuples as \a this array and \a nbOfComp components.
2976 * The caller is to delete this result array using decrRef() as it is no more
2978 * \throw If \a this is not allocated.
2979 * \throw If computing \a func fails.
2981 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, const std::string& func, bool isSafe) const
2983 INTERP_KERNEL::ExprParser expr(func);
2985 std::set<std::string> vars;
2986 expr.getTrueSetOfVars(vars);
2987 std::vector<std::string> varsV(vars.begin(),vars.end());
2988 return applyFuncNamedCompo(nbOfComp,varsV,func,isSafe);
2992 * Returns a new DataArrayDouble created from \a this one by applying a function to every
2993 * tuple of \a this array. Textual data is not copied. This method works by tuples (whatever its size).
2994 * If \a this is a one component array, call applyFuncOnThis instead that performs the same work faster.
2996 * For more info see \ref MEDCouplingArrayApplyFunc0.
2997 * \param [in] func - the expression defining how to transform a tuple of \a this array.
2998 * Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
2999 * \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
3000 * If false the computation is carried on without any notification. When false the evaluation is a little faster.
3001 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3002 * same number of tuples and components as \a this array.
3003 * The caller is to delete this result array using decrRef() as it is no more
3005 * \sa applyFuncOnThis
3006 * \throw If \a this is not allocated.
3007 * \throw If computing \a func fails.
3009 DataArrayDouble *DataArrayDouble::applyFunc(const std::string& func, bool isSafe) const
3011 int nbOfComp(getNumberOfComponents());
3013 throw INTERP_KERNEL::Exception("DataArrayDouble::applyFunc : output number of component must be > 0 !");
3015 int nbOfTuples(getNumberOfTuples());
3016 MCAuto<DataArrayDouble> newArr(DataArrayDouble::New());
3017 newArr->alloc(nbOfTuples,nbOfComp);
3018 INTERP_KERNEL::ExprParser expr(func);
3020 std::set<std::string> vars;
3021 expr.getTrueSetOfVars(vars);
3022 if((int)vars.size()>1)
3024 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 : ";
3025 std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
3026 throw INTERP_KERNEL::Exception(oss.str().c_str());
3030 expr.prepareFastEvaluator();
3031 newArr->rearrange(1);
3032 newArr->fillWithValue(expr.evaluateDouble());
3033 newArr->rearrange(nbOfComp);
3034 return newArr.retn();
3036 std::vector<std::string> vars2(vars.begin(),vars.end());
3037 double buff,*ptrToFill(newArr->getPointer());
3038 const double *ptr(begin());
3039 std::vector<double> stck;
3040 expr.prepareExprEvaluationDouble(vars2,1,1,0,&buff,&buff+1);
3041 expr.prepareFastEvaluator();
3044 for(int i=0;i<nbOfTuples;i++)
3046 for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
3049 expr.evaluateDoubleInternal(stck);
3050 *ptrToFill=stck.back();
3057 for(int i=0;i<nbOfTuples;i++)
3059 for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
3064 expr.evaluateDoubleInternalSafe(stck);
3066 catch(INTERP_KERNEL::Exception& e)
3068 std::ostringstream oss; oss << "For tuple # " << i << " component # " << iComp << " with value (";
3070 oss << ") : Evaluation of function failed !" << e.what();
3071 throw INTERP_KERNEL::Exception(oss.str().c_str());
3073 *ptrToFill=stck.back();
3078 return newArr.retn();
3082 * This method is a non const method that modify the array in \a this.
3083 * This method only works on one component array. It means that function \a func must
3084 * contain at most one variable.
3085 * This method is a specialization of applyFunc method with one parameter on one component array.
3087 * \param [in] func - the expression defining how to transform a tuple of \a this array.
3088 * Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
3089 * \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
3090 * If false the computation is carried on without any notification. When false the evaluation is a little faster.
3094 void DataArrayDouble::applyFuncOnThis(const std::string& func, bool isSafe)
3096 int nbOfComp(getNumberOfComponents());
3098 throw INTERP_KERNEL::Exception("DataArrayDouble::applyFuncOnThis : output number of component must be > 0 !");
3100 int nbOfTuples(getNumberOfTuples());
3101 INTERP_KERNEL::ExprParser expr(func);
3103 std::set<std::string> vars;
3104 expr.getTrueSetOfVars(vars);
3105 if((int)vars.size()>1)
3107 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 : ";
3108 std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
3109 throw INTERP_KERNEL::Exception(oss.str().c_str());
3113 expr.prepareFastEvaluator();
3114 std::vector<std::string> compInfo(getInfoOnComponents());
3116 fillWithValue(expr.evaluateDouble());
3117 rearrange(nbOfComp);
3118 setInfoOnComponents(compInfo);
3121 std::vector<std::string> vars2(vars.begin(),vars.end());
3122 double buff,*ptrToFill(getPointer());
3123 const double *ptr(begin());
3124 std::vector<double> stck;
3125 expr.prepareExprEvaluationDouble(vars2,1,1,0,&buff,&buff+1);
3126 expr.prepareFastEvaluator();
3129 for(int i=0;i<nbOfTuples;i++)
3131 for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
3134 expr.evaluateDoubleInternal(stck);
3135 *ptrToFill=stck.back();
3142 for(int i=0;i<nbOfTuples;i++)
3144 for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
3149 expr.evaluateDoubleInternalSafe(stck);
3151 catch(INTERP_KERNEL::Exception& e)
3153 std::ostringstream oss; oss << "For tuple # " << i << " component # " << iComp << " with value (";
3155 oss << ") : Evaluation of function failed !" << e.what();
3156 throw INTERP_KERNEL::Exception(oss.str().c_str());
3158 *ptrToFill=stck.back();
3166 * Returns a new DataArrayDouble created from \a this one by applying a function to every
3167 * tuple of \a this array. Textual data is not copied.
3168 * For more info see \ref MEDCouplingArrayApplyFunc2.
3169 * \param [in] nbOfComp - number of components in the result array.
3170 * \param [in] func - the expression defining how to transform a tuple of \a this array.
3171 * Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
3172 * \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
3173 * If false the computation is carried on without any notification. When false the evaluation is a little faster.
3174 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3175 * same number of tuples as \a this array.
3176 * The caller is to delete this result array using decrRef() as it is no more
3178 * \throw If \a this is not allocated.
3179 * \throw If \a func contains vars that are not in \a this->getInfoOnComponent().
3180 * \throw If computing \a func fails.
3182 DataArrayDouble *DataArrayDouble::applyFuncCompo(int nbOfComp, const std::string& func, bool isSafe) const
3184 return applyFuncNamedCompo(nbOfComp,getVarsOnComponent(),func,isSafe);
3188 * Returns a new DataArrayDouble created from \a this one by applying a function to every
3189 * tuple of \a this array. Textual data is not copied.
3190 * For more info see \ref MEDCouplingArrayApplyFunc3.
3191 * \param [in] nbOfComp - number of components in the result array.
3192 * \param [in] varsOrder - sequence of vars defining their order.
3193 * \param [in] func - the expression defining how to transform a tuple of \a this array.
3194 * Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
3195 * \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
3196 * If false the computation is carried on without any notification. When false the evaluation is a little faster.
3197 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3198 * same number of tuples as \a this array.
3199 * The caller is to delete this result array using decrRef() as it is no more
3201 * \throw If \a this is not allocated.
3202 * \throw If \a func contains vars not in \a varsOrder.
3203 * \throw If computing \a func fails.
3205 DataArrayDouble *DataArrayDouble::applyFuncNamedCompo(int nbOfComp, const std::vector<std::string>& varsOrder, const std::string& func, bool isSafe) const
3208 throw INTERP_KERNEL::Exception("DataArrayDouble::applyFuncNamedCompo : output number of component must be > 0 !");
3209 std::vector<std::string> varsOrder2(varsOrder);
3210 int oldNbOfComp(getNumberOfComponents());
3211 for(int i=(int)varsOrder.size();i<oldNbOfComp;i++)
3212 varsOrder2.push_back(std::string());
3214 int nbOfTuples(getNumberOfTuples());
3215 INTERP_KERNEL::ExprParser expr(func);
3217 std::set<std::string> vars;
3218 expr.getTrueSetOfVars(vars);
3219 if((int)vars.size()>oldNbOfComp)
3221 std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
3222 oss << vars.size() << " variables : ";
3223 std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
3224 throw INTERP_KERNEL::Exception(oss.str().c_str());
3226 MCAuto<DataArrayDouble> newArr(DataArrayDouble::New());
3227 newArr->alloc(nbOfTuples,nbOfComp);
3228 INTERP_KERNEL::AutoPtr<double> buff(new double[oldNbOfComp]);
3229 double *buffPtr(buff),*ptrToFill;
3230 std::vector<double> stck;
3231 for(int iComp=0;iComp<nbOfComp;iComp++)
3233 expr.prepareExprEvaluationDouble(varsOrder2,oldNbOfComp,nbOfComp,iComp,buffPtr,buffPtr+oldNbOfComp);
3234 expr.prepareFastEvaluator();
3235 const double *ptr(getConstPointer());
3236 ptrToFill=newArr->getPointer()+iComp;
3239 for(int i=0;i<nbOfTuples;i++,ptrToFill+=nbOfComp,ptr+=oldNbOfComp)
3241 std::copy(ptr,ptr+oldNbOfComp,buffPtr);
3242 expr.evaluateDoubleInternal(stck);
3243 *ptrToFill=stck.back();
3249 for(int i=0;i<nbOfTuples;i++,ptrToFill+=nbOfComp,ptr+=oldNbOfComp)
3251 std::copy(ptr,ptr+oldNbOfComp,buffPtr);
3254 expr.evaluateDoubleInternalSafe(stck);
3255 *ptrToFill=stck.back();
3258 catch(INTERP_KERNEL::Exception& e)
3260 std::ostringstream oss; oss << "For tuple # " << i << " with value (";
3261 std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
3262 oss << ") : Evaluation of function failed !" << e.what();
3263 throw INTERP_KERNEL::Exception(oss.str().c_str());
3268 return newArr.retn();
3271 void DataArrayDouble::applyFuncFast32(const std::string& func)
3274 INTERP_KERNEL::ExprParser expr(func);
3276 char *funcStr=expr.compileX86();
3278 *((void **)&funcPtr)=funcStr;//he he...
3280 double *ptr=getPointer();
3281 int nbOfComp=getNumberOfComponents();
3282 int nbOfTuples=getNumberOfTuples();
3283 int nbOfElems=nbOfTuples*nbOfComp;
3284 for(int i=0;i<nbOfElems;i++,ptr++)
3289 void DataArrayDouble::applyFuncFast64(const std::string& func)
3292 INTERP_KERNEL::ExprParser expr(func);
3294 char *funcStr=expr.compileX86_64();
3296 *((void **)&funcPtr)=funcStr;//he he...
3298 double *ptr=getPointer();
3299 int nbOfComp=getNumberOfComponents();
3300 int nbOfTuples=getNumberOfTuples();
3301 int nbOfElems=nbOfTuples*nbOfComp;
3302 for(int i=0;i<nbOfElems;i++,ptr++)
3308 * \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.
3310 MCAuto<DataArrayDouble> DataArrayDouble::symmetry3DPlane(const double point[3], const double normalVector[3]) const
3313 if(getNumberOfComponents()!=3)
3314 throw INTERP_KERNEL::Exception("DataArrayDouble::symmetry3DPlane : this is excepted to have 3 components !");
3315 int nbTuples(getNumberOfTuples());
3316 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
3317 ret->alloc(nbTuples,3);
3318 Symmetry3DPlane(point,normalVector,nbTuples,begin(),ret->getPointer());
3322 DataArrayDoubleIterator *DataArrayDouble::iterator()
3324 return new DataArrayDoubleIterator(this);
3328 * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional
3329 * array whose values are within a given range. Textual data is not copied.
3330 * \param [in] vmin - a lowest acceptable value (included).
3331 * \param [in] vmax - a greatest acceptable value (included).
3332 * \return DataArrayInt * - the new instance of DataArrayInt.
3333 * The caller is to delete this result array using decrRef() as it is no more
3335 * \throw If \a this->getNumberOfComponents() != 1.
3337 * \sa DataArrayDouble::findIdsNotInRange
3339 * \if ENABLE_EXAMPLES
3340 * \ref cpp_mcdataarraydouble_getidsinrange "Here is a C++ example".<br>
3341 * \ref py_mcdataarraydouble_getidsinrange "Here is a Python example".
3344 DataArrayInt *DataArrayDouble::findIdsInRange(double vmin, double vmax) const
3347 if(getNumberOfComponents()!=1)
3348 throw INTERP_KERNEL::Exception("DataArrayDouble::findIdsInRange : this must have exactly one component !");
3349 const double *cptr(begin());
3350 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
3351 int nbOfTuples(getNumberOfTuples());
3352 for(int i=0;i<nbOfTuples;i++,cptr++)
3353 if(*cptr>=vmin && *cptr<=vmax)
3354 ret->pushBackSilent(i);
3359 * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional
3360 * array whose values are not within a given range. Textual data is not copied.
3361 * \param [in] vmin - a lowest not acceptable value (excluded).
3362 * \param [in] vmax - a greatest not acceptable value (excluded).
3363 * \return DataArrayInt * - the new instance of DataArrayInt.
3364 * The caller is to delete this result array using decrRef() as it is no more
3366 * \throw If \a this->getNumberOfComponents() != 1.
3368 * \sa DataArrayDouble::findIdsInRange
3370 DataArrayInt *DataArrayDouble::findIdsNotInRange(double vmin, double vmax) const
3373 if(getNumberOfComponents()!=1)
3374 throw INTERP_KERNEL::Exception("DataArrayDouble::findIdsNotInRange : this must have exactly one component !");
3375 const double *cptr(begin());
3376 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
3377 int nbOfTuples(getNumberOfTuples());
3378 for(int i=0;i<nbOfTuples;i++,cptr++)
3379 if(*cptr<vmin || *cptr>vmax)
3380 ret->pushBackSilent(i);
3385 * Returns a new DataArrayDouble by concatenating two given arrays, so that (1) the number
3386 * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
3387 * the number of component in the result array is same as that of each of given arrays.
3388 * Info on components is copied from the first of the given arrays. Number of components
3389 * in the given arrays must be the same.
3390 * \param [in] a1 - an array to include in the result array.
3391 * \param [in] a2 - another array to include in the result array.
3392 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3393 * The caller is to delete this result array using decrRef() as it is no more
3395 * \throw If both \a a1 and \a a2 are NULL.
3396 * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
3398 DataArrayDouble *DataArrayDouble::Aggregate(const DataArrayDouble *a1, const DataArrayDouble *a2)
3400 std::vector<const DataArrayDouble *> tmp(2);
3401 tmp[0]=a1; tmp[1]=a2;
3402 return Aggregate(tmp);
3406 * Returns a new DataArrayDouble by concatenating all given arrays, so that (1) the number
3407 * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
3408 * the number of component in the result array is same as that of each of given arrays.
3409 * Info on components is copied from the first of the given arrays. Number of components
3410 * in the given arrays must be the same.
3411 * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it
3412 * not the object itself.
3413 * \param [in] arr - a sequence of arrays to include in the result array.
3414 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3415 * The caller is to delete this result array using decrRef() as it is no more
3417 * \throw If all arrays within \a arr are NULL.
3418 * \throw If getNumberOfComponents() of arrays within \a arr.
3420 DataArrayDouble *DataArrayDouble::Aggregate(const std::vector<const DataArrayDouble *>& arr)
3422 std::vector<const DataArrayDouble *> a;
3423 for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
3427 throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : input list must contain at least one NON EMPTY DataArrayDouble !");
3428 std::vector<const DataArrayDouble *>::const_iterator it=a.begin();
3429 int nbOfComp=(*it)->getNumberOfComponents();
3430 int nbt=(*it++)->getNumberOfTuples();
3431 for(int i=1;it!=a.end();it++,i++)
3433 if((*it)->getNumberOfComponents()!=nbOfComp)
3434 throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : Nb of components mismatch for array aggregation !");
3435 nbt+=(*it)->getNumberOfTuples();
3437 MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
3438 ret->alloc(nbt,nbOfComp);
3439 double *pt=ret->getPointer();
3440 for(it=a.begin();it!=a.end();it++)
3441 pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
3442 ret->copyStringInfoFrom(*(a[0]));
3447 * Returns a new DataArrayDouble by aggregating two given arrays, so that (1) the number
3448 * of components in the result array is a sum of the number of components of given arrays
3449 * and (2) the number of tuples in the result array is same as that of each of given
3450 * arrays. In other words the i-th tuple of result array includes all components of
3451 * i-th tuples of all given arrays.
3452 * Number of tuples in the given arrays must be the same.
3453 * \param [in] a1 - an array to include in the result array.
3454 * \param [in] a2 - another array to include in the result array.
3455 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3456 * The caller is to delete this result array using decrRef() as it is no more
3458 * \throw If both \a a1 and \a a2 are NULL.
3459 * \throw If any given array is not allocated.
3460 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3462 DataArrayDouble *DataArrayDouble::Meld(const DataArrayDouble *a1, const DataArrayDouble *a2)
3464 std::vector<const DataArrayDouble *> arr(2);
3465 arr[0]=a1; arr[1]=a2;
3470 * Returns a new DataArrayDouble by aggregating all given arrays, so that (1) the number
3471 * of components in the result array is a sum of the number of components of given arrays
3472 * and (2) the number of tuples in the result array is same as that of each of given
3473 * arrays. In other words the i-th tuple of result array includes all components of
3474 * i-th tuples of all given arrays.
3475 * Number of tuples in the given arrays must be the same.
3476 * \param [in] arr - a sequence of arrays to include in the result array.
3477 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3478 * The caller is to delete this result array using decrRef() as it is no more
3480 * \throw If all arrays within \a arr are NULL.
3481 * \throw If any given array is not allocated.
3482 * \throw If getNumberOfTuples() of arrays within \a arr is different.
3484 DataArrayDouble *DataArrayDouble::Meld(const std::vector<const DataArrayDouble *>& arr)
3486 std::vector<const DataArrayDouble *> a;
3487 for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
3491 throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : input list must contain at least one NON EMPTY DataArrayDouble !");
3492 std::vector<const DataArrayDouble *>::const_iterator it;
3493 for(it=a.begin();it!=a.end();it++)
3494 (*it)->checkAllocated();
3496 int nbOfTuples=(*it)->getNumberOfTuples();
3497 std::vector<int> nbc(a.size());
3498 std::vector<const double *> pts(a.size());
3499 nbc[0]=(*it)->getNumberOfComponents();
3500 pts[0]=(*it++)->getConstPointer();
3501 for(int i=1;it!=a.end();it++,i++)
3503 if(nbOfTuples!=(*it)->getNumberOfTuples())
3504 throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : mismatch of number of tuples !");
3505 nbc[i]=(*it)->getNumberOfComponents();
3506 pts[i]=(*it)->getConstPointer();
3508 int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
3509 DataArrayDouble *ret=DataArrayDouble::New();
3510 ret->alloc(nbOfTuples,totalNbOfComp);
3511 double *retPtr=ret->getPointer();
3512 for(int i=0;i<nbOfTuples;i++)
3513 for(int j=0;j<(int)a.size();j++)
3515 retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
3519 for(int i=0;i<(int)a.size();i++)
3520 for(int j=0;j<nbc[i];j++,k++)
3521 ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j));
3526 * Returns a new DataArrayDouble containing a dot product of two given arrays, so that
3527 * the i-th tuple of the result array is a sum of products of j-th components of i-th
3528 * tuples of given arrays (\f$ a_i = \sum_{j=1}^n a1_j * a2_j \f$).
3529 * Info on components and name is copied from the first of the given arrays.
3530 * Number of tuples and components in the given arrays must be the same.
3531 * \param [in] a1 - a given array.
3532 * \param [in] a2 - another given array.
3533 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3534 * The caller is to delete this result array using decrRef() as it is no more
3536 * \throw If either \a a1 or \a a2 is NULL.
3537 * \throw If any given array is not allocated.
3538 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3539 * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
3541 DataArrayDouble *DataArrayDouble::Dot(const DataArrayDouble *a1, const DataArrayDouble *a2)
3544 throw INTERP_KERNEL::Exception("DataArrayDouble::Dot : input DataArrayDouble instance is NULL !");
3545 a1->checkAllocated();
3546 a2->checkAllocated();
3547 int nbOfComp=a1->getNumberOfComponents();
3548 if(nbOfComp!=a2->getNumberOfComponents())
3549 throw INTERP_KERNEL::Exception("Nb of components mismatch for array Dot !");
3550 int nbOfTuple=a1->getNumberOfTuples();
3551 if(nbOfTuple!=a2->getNumberOfTuples())
3552 throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Dot !");
3553 DataArrayDouble *ret=DataArrayDouble::New();
3554 ret->alloc(nbOfTuple,1);
3555 double *retPtr=ret->getPointer();
3556 const double *a1Ptr=a1->getConstPointer();
3557 const double *a2Ptr=a2->getConstPointer();
3558 for(int i=0;i<nbOfTuple;i++)
3561 for(int j=0;j<nbOfComp;j++)
3562 sum+=a1Ptr[i*nbOfComp+j]*a2Ptr[i*nbOfComp+j];
3565 ret->setInfoOnComponent(0,a1->getInfoOnComponent(0));
3566 ret->setName(a1->getName());
3571 * Returns a new DataArrayDouble containing a cross product of two given arrays, so that
3572 * the i-th tuple of the result array contains 3 components of a vector which is a cross
3573 * product of two vectors defined by the i-th tuples of given arrays.
3574 * Info on components is copied from the first of the given arrays.
3575 * Number of tuples in the given arrays must be the same.
3576 * Number of components in the given arrays must be 3.
3577 * \param [in] a1 - a given array.
3578 * \param [in] a2 - another given array.
3579 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3580 * The caller is to delete this result array using decrRef() as it is no more
3582 * \throw If either \a a1 or \a a2 is NULL.
3583 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3584 * \throw If \a a1->getNumberOfComponents() != 3
3585 * \throw If \a a2->getNumberOfComponents() != 3
3587 DataArrayDouble *DataArrayDouble::CrossProduct(const DataArrayDouble *a1, const DataArrayDouble *a2)
3590 throw INTERP_KERNEL::Exception("DataArrayDouble::CrossProduct : input DataArrayDouble instance is NULL !");
3591 int nbOfComp=a1->getNumberOfComponents();
3592 if(nbOfComp!=a2->getNumberOfComponents())
3593 throw INTERP_KERNEL::Exception("Nb of components mismatch for array crossProduct !");
3595 throw INTERP_KERNEL::Exception("Nb of components must be equal to 3 for array crossProduct !");
3596 int nbOfTuple=a1->getNumberOfTuples();
3597 if(nbOfTuple!=a2->getNumberOfTuples())
3598 throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array crossProduct !");
3599 DataArrayDouble *ret=DataArrayDouble::New();
3600 ret->alloc(nbOfTuple,3);
3601 double *retPtr=ret->getPointer();
3602 const double *a1Ptr=a1->getConstPointer();
3603 const double *a2Ptr=a2->getConstPointer();
3604 for(int i=0;i<nbOfTuple;i++)
3606 retPtr[3*i]=a1Ptr[3*i+1]*a2Ptr[3*i+2]-a1Ptr[3*i+2]*a2Ptr[3*i+1];
3607 retPtr[3*i+1]=a1Ptr[3*i+2]*a2Ptr[3*i]-a1Ptr[3*i]*a2Ptr[3*i+2];
3608 retPtr[3*i+2]=a1Ptr[3*i]*a2Ptr[3*i+1]-a1Ptr[3*i+1]*a2Ptr[3*i];
3610 ret->copyStringInfoFrom(*a1);
3615 * Returns a new DataArrayDouble containing maximal values of two given arrays.
3616 * Info on components is copied from the first of the given arrays.
3617 * Number of tuples and components in the given arrays must be the same.
3618 * \param [in] a1 - an array to compare values with another one.
3619 * \param [in] a2 - another array to compare values with the first one.
3620 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3621 * The caller is to delete this result array using decrRef() as it is no more
3623 * \throw If either \a a1 or \a a2 is NULL.
3624 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3625 * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
3627 DataArrayDouble *DataArrayDouble::Max(const DataArrayDouble *a1, const DataArrayDouble *a2)
3630 throw INTERP_KERNEL::Exception("DataArrayDouble::Max : input DataArrayDouble instance is NULL !");
3631 int nbOfComp=a1->getNumberOfComponents();
3632 if(nbOfComp!=a2->getNumberOfComponents())
3633 throw INTERP_KERNEL::Exception("Nb of components mismatch for array Max !");
3634 int nbOfTuple=a1->getNumberOfTuples();
3635 if(nbOfTuple!=a2->getNumberOfTuples())
3636 throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Max !");
3637 DataArrayDouble *ret=DataArrayDouble::New();
3638 ret->alloc(nbOfTuple,nbOfComp);
3639 double *retPtr=ret->getPointer();
3640 const double *a1Ptr=a1->getConstPointer();
3641 const double *a2Ptr=a2->getConstPointer();
3642 int nbElem=nbOfTuple*nbOfComp;
3643 for(int i=0;i<nbElem;i++)
3644 retPtr[i]=std::max(a1Ptr[i],a2Ptr[i]);
3645 ret->copyStringInfoFrom(*a1);
3650 * Returns a new DataArrayDouble containing minimal values of two given arrays.
3651 * Info on components is copied from the first of the given arrays.
3652 * Number of tuples and components in the given arrays must be the same.
3653 * \param [in] a1 - an array to compare values with another one.
3654 * \param [in] a2 - another array to compare values with the first one.
3655 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3656 * The caller is to delete this result array using decrRef() as it is no more
3658 * \throw If either \a a1 or \a a2 is NULL.
3659 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3660 * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
3662 DataArrayDouble *DataArrayDouble::Min(const DataArrayDouble *a1, const DataArrayDouble *a2)
3665 throw INTERP_KERNEL::Exception("DataArrayDouble::Min : input DataArrayDouble instance is NULL !");
3666 int nbOfComp=a1->getNumberOfComponents();
3667 if(nbOfComp!=a2->getNumberOfComponents())
3668 throw INTERP_KERNEL::Exception("Nb of components mismatch for array min !");
3669 int nbOfTuple=a1->getNumberOfTuples();
3670 if(nbOfTuple!=a2->getNumberOfTuples())
3671 throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array min !");
3672 DataArrayDouble *ret=DataArrayDouble::New();
3673 ret->alloc(nbOfTuple,nbOfComp);
3674 double *retPtr=ret->getPointer();
3675 const double *a1Ptr=a1->getConstPointer();
3676 const double *a2Ptr=a2->getConstPointer();
3677 int nbElem=nbOfTuple*nbOfComp;
3678 for(int i=0;i<nbElem;i++)
3679 retPtr[i]=std::min(a1Ptr[i],a2Ptr[i]);
3680 ret->copyStringInfoFrom(*a1);
3685 * Returns a new DataArrayDouble that is a sum of two given arrays. There are 3
3687 * 1. The arrays have same number of tuples and components. Then each value of
3688 * the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
3689 * i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
3690 * 2. The arrays have same number of tuples and one array, say _a2_, has one
3692 * _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
3693 * 3. The arrays have same number of components and one array, say _a2_, has one
3695 * _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
3697 * Info on components is copied either from the first array (in the first case) or from
3698 * the array with maximal number of elements (getNbOfElems()).
3699 * \param [in] a1 - an array to sum up.
3700 * \param [in] a2 - another array to sum up.
3701 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3702 * The caller is to delete this result array using decrRef() as it is no more
3704 * \throw If either \a a1 or \a a2 is NULL.
3705 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
3706 * \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
3707 * none of them has number of tuples or components equal to 1.
3709 DataArrayDouble *DataArrayDouble::Add(const DataArrayDouble *a1, const DataArrayDouble *a2)
3712 throw INTERP_KERNEL::Exception("DataArrayDouble::Add : input DataArrayDouble instance is NULL !");
3713 int nbOfTuple=a1->getNumberOfTuples();
3714 int nbOfTuple2=a2->getNumberOfTuples();
3715 int nbOfComp=a1->getNumberOfComponents();
3716 int nbOfComp2=a2->getNumberOfComponents();
3717 MCAuto<DataArrayDouble> ret=0;
3718 if(nbOfTuple==nbOfTuple2)
3720 if(nbOfComp==nbOfComp2)
3722 ret=DataArrayDouble::New();
3723 ret->alloc(nbOfTuple,nbOfComp);
3724 std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<double>());
3725 ret->copyStringInfoFrom(*a1);
3729 int nbOfCompMin,nbOfCompMax;
3730 const DataArrayDouble *aMin, *aMax;
3731 if(nbOfComp>nbOfComp2)
3733 nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
3738 nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
3743 ret=DataArrayDouble::New();
3744 ret->alloc(nbOfTuple,nbOfCompMax);
3745 const double *aMinPtr=aMin->getConstPointer();
3746 const double *aMaxPtr=aMax->getConstPointer();
3747 double *res=ret->getPointer();
3748 for(int i=0;i<nbOfTuple;i++)
3749 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<double>(),aMinPtr[i]));
3750 ret->copyStringInfoFrom(*aMax);
3753 throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
3756 else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
3758 if(nbOfComp==nbOfComp2)
3760 int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
3761 const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
3762 const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
3763 const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
3764 ret=DataArrayDouble::New();
3765 ret->alloc(nbOfTupleMax,nbOfComp);
3766 double *res=ret->getPointer();
3767 for(int i=0;i<nbOfTupleMax;i++)
3768 res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<double>());
3769 ret->copyStringInfoFrom(*aMax);
3772 throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
3775 throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
3780 * Adds values of another DataArrayDouble to values of \a this one. There are 3
3782 * 1. The arrays have same number of tuples and components. Then each value of
3783 * \a other array is added to the corresponding value of \a this array, i.e.:
3784 * _a_ [ i, j ] += _other_ [ i, j ].
3785 * 2. The arrays have same number of tuples and \a other array has one component. Then
3786 * _a_ [ i, j ] += _other_ [ i, 0 ].
3787 * 3. The arrays have same number of components and \a other array has one tuple. Then
3788 * _a_ [ i, j ] += _a2_ [ 0, j ].
3790 * \param [in] other - an array to add to \a this one.
3791 * \throw If \a other is NULL.
3792 * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
3793 * \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
3794 * \a other has number of both tuples and components not equal to 1.
3796 void DataArrayDouble::addEqual(const DataArrayDouble *other)
3799 throw INTERP_KERNEL::Exception("DataArrayDouble::addEqual : input DataArrayDouble instance is NULL !");
3800 const char *msg="Nb of tuples mismatch for DataArrayDouble::addEqual !";
3802 other->checkAllocated();
3803 int nbOfTuple=getNumberOfTuples();
3804 int nbOfTuple2=other->getNumberOfTuples();
3805 int nbOfComp=getNumberOfComponents();
3806 int nbOfComp2=other->getNumberOfComponents();
3807 if(nbOfTuple==nbOfTuple2)
3809 if(nbOfComp==nbOfComp2)
3811 std::transform(begin(),end(),other->begin(),getPointer(),std::plus<double>());
3813 else if(nbOfComp2==1)
3815 double *ptr=getPointer();
3816 const double *ptrc=other->getConstPointer();
3817 for(int i=0;i<nbOfTuple;i++)
3818 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<double>(),*ptrc++));
3821 throw INTERP_KERNEL::Exception(msg);
3823 else if(nbOfTuple2==1)
3825 if(nbOfComp2==nbOfComp)
3827 double *ptr=getPointer();
3828 const double *ptrc=other->getConstPointer();
3829 for(int i=0;i<nbOfTuple;i++)
3830 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<double>());
3833 throw INTERP_KERNEL::Exception(msg);
3836 throw INTERP_KERNEL::Exception(msg);
3841 * Returns a new DataArrayDouble that is a subtraction of two given arrays. There are 3
3843 * 1. The arrays have same number of tuples and components. Then each value of
3844 * the result array (_a_) is a subtraction of the corresponding values of \a a1 and
3845 * \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
3846 * 2. The arrays have same number of tuples and one array, say _a2_, has one
3848 * _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
3849 * 3. The arrays have same number of components and one array, say _a2_, has one
3851 * _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
3853 * Info on components is copied either from the first array (in the first case) or from
3854 * the array with maximal number of elements (getNbOfElems()).
3855 * \param [in] a1 - an array to subtract from.
3856 * \param [in] a2 - an array to subtract.
3857 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3858 * The caller is to delete this result array using decrRef() as it is no more
3860 * \throw If either \a a1 or \a a2 is NULL.
3861 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
3862 * \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
3863 * none of them has number of tuples or components equal to 1.
3865 DataArrayDouble *DataArrayDouble::Substract(const DataArrayDouble *a1, const DataArrayDouble *a2)
3868 throw INTERP_KERNEL::Exception("DataArrayDouble::Substract : input DataArrayDouble instance is NULL !");
3869 int nbOfTuple1=a1->getNumberOfTuples();
3870 int nbOfTuple2=a2->getNumberOfTuples();
3871 int nbOfComp1=a1->getNumberOfComponents();
3872 int nbOfComp2=a2->getNumberOfComponents();
3873 if(nbOfTuple2==nbOfTuple1)
3875 if(nbOfComp1==nbOfComp2)
3877 MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
3878 ret->alloc(nbOfTuple2,nbOfComp1);
3879 std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<double>());
3880 ret->copyStringInfoFrom(*a1);
3883 else if(nbOfComp2==1)
3885 MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
3886 ret->alloc(nbOfTuple1,nbOfComp1);
3887 const double *a2Ptr=a2->getConstPointer();
3888 const double *a1Ptr=a1->getConstPointer();
3889 double *res=ret->getPointer();
3890 for(int i=0;i<nbOfTuple1;i++)
3891 res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<double>(),a2Ptr[i]));
3892 ret->copyStringInfoFrom(*a1);
3897 a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
3901 else if(nbOfTuple2==1)
3903 a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
3904 MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
3905 ret->alloc(nbOfTuple1,nbOfComp1);
3906 const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
3907 double *pt=ret->getPointer();
3908 for(int i=0;i<nbOfTuple1;i++)
3909 pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<double>());
3910 ret->copyStringInfoFrom(*a1);
3915 a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
3921 * Subtract values of another DataArrayDouble from values of \a this one. There are 3
3923 * 1. The arrays have same number of tuples and components. Then each value of
3924 * \a other array is subtracted from the corresponding value of \a this array, i.e.:
3925 * _a_ [ i, j ] -= _other_ [ i, j ].
3926 * 2. The arrays have same number of tuples and \a other array has one component. Then
3927 * _a_ [ i, j ] -= _other_ [ i, 0 ].
3928 * 3. The arrays have same number of components and \a other array has one tuple. Then
3929 * _a_ [ i, j ] -= _a2_ [ 0, j ].
3931 * \param [in] other - an array to subtract from \a this one.
3932 * \throw If \a other is NULL.
3933 * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
3934 * \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
3935 * \a other has number of both tuples and components not equal to 1.
3937 void DataArrayDouble::substractEqual(const DataArrayDouble *other)
3940 throw INTERP_KERNEL::Exception("DataArrayDouble::substractEqual : input DataArrayDouble instance is NULL !");
3941 const char *msg="Nb of tuples mismatch for DataArrayDouble::substractEqual !";
3943 other->checkAllocated();
3944 int nbOfTuple=getNumberOfTuples();
3945 int nbOfTuple2=other->getNumberOfTuples();
3946 int nbOfComp=getNumberOfComponents();
3947 int nbOfComp2=other->getNumberOfComponents();
3948 if(nbOfTuple==nbOfTuple2)
3950 if(nbOfComp==nbOfComp2)
3952 std::transform(begin(),end(),other->begin(),getPointer(),std::minus<double>());
3954 else if(nbOfComp2==1)
3956 double *ptr=getPointer();
3957 const double *ptrc=other->getConstPointer();
3958 for(int i=0;i<nbOfTuple;i++)
3959 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<double>(),*ptrc++));
3962 throw INTERP_KERNEL::Exception(msg);
3964 else if(nbOfTuple2==1)
3966 if(nbOfComp2==nbOfComp)
3968 double *ptr=getPointer();
3969 const double *ptrc=other->getConstPointer();
3970 for(int i=0;i<nbOfTuple;i++)
3971 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<double>());
3974 throw INTERP_KERNEL::Exception(msg);
3977 throw INTERP_KERNEL::Exception(msg);
3982 * Returns a new DataArrayDouble that is a product of two given arrays. There are 3
3984 * 1. The arrays have same number of tuples and components. Then each value of
3985 * the result array (_a_) is a product of the corresponding values of \a a1 and
3986 * \a a2, i.e. _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
3987 * 2. The arrays have same number of tuples and one array, say _a2_, has one
3989 * _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
3990 * 3. The arrays have same number of components and one array, say _a2_, has one
3992 * _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
3994 * Info on components is copied either from the first array (in the first case) or from
3995 * the array with maximal number of elements (getNbOfElems()).
3996 * \param [in] a1 - a factor array.
3997 * \param [in] a2 - another factor array.
3998 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3999 * The caller is to delete this result array using decrRef() as it is no more
4001 * \throw If either \a a1 or \a a2 is NULL.
4002 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
4003 * \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
4004 * none of them has number of tuples or components equal to 1.
4006 DataArrayDouble *DataArrayDouble::Multiply(const DataArrayDouble *a1, const DataArrayDouble *a2)
4009 throw INTERP_KERNEL::Exception("DataArrayDouble::Multiply : input DataArrayDouble instance is NULL !");
4010 int nbOfTuple=a1->getNumberOfTuples();
4011 int nbOfTuple2=a2->getNumberOfTuples();
4012 int nbOfComp=a1->getNumberOfComponents();
4013 int nbOfComp2=a2->getNumberOfComponents();
4014 MCAuto<DataArrayDouble> ret=0;
4015 if(nbOfTuple==nbOfTuple2)
4017 if(nbOfComp==nbOfComp2)
4019 ret=DataArrayDouble::New();
4020 ret->alloc(nbOfTuple,nbOfComp);
4021 std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<double>());
4022 ret->copyStringInfoFrom(*a1);
4026 int nbOfCompMin,nbOfCompMax;
4027 const DataArrayDouble *aMin, *aMax;
4028 if(nbOfComp>nbOfComp2)
4030 nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
4035 nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
4040 ret=DataArrayDouble::New();
4041 ret->alloc(nbOfTuple,nbOfCompMax);
4042 const double *aMinPtr=aMin->getConstPointer();
4043 const double *aMaxPtr=aMax->getConstPointer();
4044 double *res=ret->getPointer();
4045 for(int i=0;i<nbOfTuple;i++)
4046 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<double>(),aMinPtr[i]));
4047 ret->copyStringInfoFrom(*aMax);
4050 throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
4053 else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
4055 if(nbOfComp==nbOfComp2)
4057 int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
4058 const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
4059 const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
4060 const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
4061 ret=DataArrayDouble::New();
4062 ret->alloc(nbOfTupleMax,nbOfComp);
4063 double *res=ret->getPointer();
4064 for(int i=0;i<nbOfTupleMax;i++)
4065 res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<double>());
4066 ret->copyStringInfoFrom(*aMax);
4069 throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
4072 throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
4077 * Multiply values of another DataArrayDouble to values of \a this one. There are 3
4079 * 1. The arrays have same number of tuples and components. Then each value of
4080 * \a other array is multiplied to the corresponding value of \a this array, i.e.
4081 * _this_ [ i, j ] *= _other_ [ i, j ].
4082 * 2. The arrays have same number of tuples and \a other array has one component. Then
4083 * _this_ [ i, j ] *= _other_ [ i, 0 ].
4084 * 3. The arrays have same number of components and \a other array has one tuple. Then
4085 * _this_ [ i, j ] *= _a2_ [ 0, j ].
4087 * \param [in] other - an array to multiply to \a this one.
4088 * \throw If \a other is NULL.
4089 * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
4090 * \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
4091 * \a other has number of both tuples and components not equal to 1.
4093 void DataArrayDouble::multiplyEqual(const DataArrayDouble *other)
4096 throw INTERP_KERNEL::Exception("DataArrayDouble::multiplyEqual : input DataArrayDouble instance is NULL !");
4097 const char *msg="Nb of tuples mismatch for DataArrayDouble::multiplyEqual !";
4099 other->checkAllocated();
4100 int nbOfTuple=getNumberOfTuples();
4101 int nbOfTuple2=other->getNumberOfTuples();
4102 int nbOfComp=getNumberOfComponents();
4103 int nbOfComp2=other->getNumberOfComponents();
4104 if(nbOfTuple==nbOfTuple2)
4106 if(nbOfComp==nbOfComp2)
4108 std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<double>());
4110 else if(nbOfComp2==1)
4112 double *ptr=getPointer();
4113 const double *ptrc=other->getConstPointer();
4114 for(int i=0;i<nbOfTuple;i++)
4115 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<double>(),*ptrc++));
4118 throw INTERP_KERNEL::Exception(msg);
4120 else if(nbOfTuple2==1)
4122 if(nbOfComp2==nbOfComp)
4124 double *ptr=getPointer();
4125 const double *ptrc=other->getConstPointer();
4126 for(int i=0;i<nbOfTuple;i++)
4127 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<double>());
4130 throw INTERP_KERNEL::Exception(msg);
4133 throw INTERP_KERNEL::Exception(msg);
4138 * Returns a new DataArrayDouble that is a division of two given arrays. There are 3
4140 * 1. The arrays have same number of tuples and components. Then each value of
4141 * the result array (_a_) is a division of the corresponding values of \a a1 and
4142 * \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
4143 * 2. The arrays have same number of tuples and one array, say _a2_, has one
4145 * _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
4146 * 3. The arrays have same number of components and one array, say _a2_, has one
4148 * _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
4150 * Info on components is copied either from the first array (in the first case) or from
4151 * the array with maximal number of elements (getNbOfElems()).
4152 * \warning No check of division by zero is performed!
4153 * \param [in] a1 - a numerator array.
4154 * \param [in] a2 - a denominator array.
4155 * \return DataArrayDouble * - the new instance of DataArrayDouble.
4156 * The caller is to delete this result array using decrRef() as it is no more
4158 * \throw If either \a a1 or \a a2 is NULL.
4159 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
4160 * \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
4161 * none of them has number of tuples or components equal to 1.
4163 DataArrayDouble *DataArrayDouble::Divide(const DataArrayDouble *a1, const DataArrayDouble *a2)
4166 throw INTERP_KERNEL::Exception("DataArrayDouble::Divide : input DataArrayDouble instance is NULL !");
4167 int nbOfTuple1=a1->getNumberOfTuples();
4168 int nbOfTuple2=a2->getNumberOfTuples();
4169 int nbOfComp1=a1->getNumberOfComponents();
4170 int nbOfComp2=a2->getNumberOfComponents();
4171 if(nbOfTuple2==nbOfTuple1)
4173 if(nbOfComp1==nbOfComp2)
4175 MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
4176 ret->alloc(nbOfTuple2,nbOfComp1);
4177 std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<double>());
4178 ret->copyStringInfoFrom(*a1);
4181 else if(nbOfComp2==1)
4183 MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
4184 ret->alloc(nbOfTuple1,nbOfComp1);
4185 const double *a2Ptr=a2->getConstPointer();
4186 const double *a1Ptr=a1->getConstPointer();
4187 double *res=ret->getPointer();
4188 for(int i=0;i<nbOfTuple1;i++)
4189 res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<double>(),a2Ptr[i]));
4190 ret->copyStringInfoFrom(*a1);
4195 a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
4199 else if(nbOfTuple2==1)
4201 a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
4202 MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
4203 ret->alloc(nbOfTuple1,nbOfComp1);
4204 const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
4205 double *pt=ret->getPointer();
4206 for(int i=0;i<nbOfTuple1;i++)
4207 pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<double>());
4208 ret->copyStringInfoFrom(*a1);
4213 a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
4219 * Divide values of \a this array by values of another DataArrayDouble. There are 3
4221 * 1. The arrays have same number of tuples and components. Then each value of
4222 * \a this array is divided by the corresponding value of \a other one, i.e.:
4223 * _a_ [ i, j ] /= _other_ [ i, j ].
4224 * 2. The arrays have same number of tuples and \a other array has one component. Then
4225 * _a_ [ i, j ] /= _other_ [ i, 0 ].
4226 * 3. The arrays have same number of components and \a other array has one tuple. Then
4227 * _a_ [ i, j ] /= _a2_ [ 0, j ].
4229 * \warning No check of division by zero is performed!
4230 * \param [in] other - an array to divide \a this one by.
4231 * \throw If \a other is NULL.
4232 * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
4233 * \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
4234 * \a other has number of both tuples and components not equal to 1.
4236 void DataArrayDouble::divideEqual(const DataArrayDouble *other)
4239 throw INTERP_KERNEL::Exception("DataArrayDouble::divideEqual : input DataArrayDouble instance is NULL !");
4240 const char *msg="Nb of tuples mismatch for DataArrayDouble::divideEqual !";
4242 other->checkAllocated();
4243 int nbOfTuple=getNumberOfTuples();
4244 int nbOfTuple2=other->getNumberOfTuples();
4245 int nbOfComp=getNumberOfComponents();
4246 int nbOfComp2=other->getNumberOfComponents();
4247 if(nbOfTuple==nbOfTuple2)
4249 if(nbOfComp==nbOfComp2)
4251 std::transform(begin(),end(),other->begin(),getPointer(),std::divides<double>());
4253 else if(nbOfComp2==1)
4255 double *ptr=getPointer();
4256 const double *ptrc=other->getConstPointer();
4257 for(int i=0;i<nbOfTuple;i++)
4258 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<double>(),*ptrc++));
4261 throw INTERP_KERNEL::Exception(msg);
4263 else if(nbOfTuple2==1)
4265 if(nbOfComp2==nbOfComp)
4267 double *ptr=getPointer();
4268 const double *ptrc=other->getConstPointer();
4269 for(int i=0;i<nbOfTuple;i++)
4270 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<double>());
4273 throw INTERP_KERNEL::Exception(msg);
4276 throw INTERP_KERNEL::Exception(msg);
4281 * Returns a new DataArrayDouble that is the result of pow of two given arrays. There are 3
4284 * \param [in] a1 - an array to pow up.
4285 * \param [in] a2 - another array to sum up.
4286 * \return DataArrayDouble * - the new instance of DataArrayDouble.
4287 * The caller is to delete this result array using decrRef() as it is no more
4289 * \throw If either \a a1 or \a a2 is NULL.
4290 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4291 * \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
4292 * \throw If there is a negative value in \a a1.
4294 DataArrayDouble *DataArrayDouble::Pow(const DataArrayDouble *a1, const DataArrayDouble *a2)
4297 throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : at least one of input instances is null !");
4298 int nbOfTuple=a1->getNumberOfTuples();
4299 int nbOfTuple2=a2->getNumberOfTuples();
4300 int nbOfComp=a1->getNumberOfComponents();
4301 int nbOfComp2=a2->getNumberOfComponents();
4302 if(nbOfTuple!=nbOfTuple2)
4303 throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of tuples mismatches !");
4304 if(nbOfComp!=1 || nbOfComp2!=1)
4305 throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of components of both arrays must be equal to 1 !");
4306 MCAuto<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbOfTuple,1);
4307 const double *ptr1(a1->begin()),*ptr2(a2->begin());
4308 double *ptr=ret->getPointer();
4309 for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
4313 *ptr=pow(*ptr1,*ptr2);
4317 std::ostringstream oss; oss << "DataArrayDouble::Pow : on tuple #" << i << " of a1 value is < 0 (" << *ptr1 << ") !";
4318 throw INTERP_KERNEL::Exception(oss.str().c_str());
4325 * Apply pow on values of another DataArrayDouble to values of \a this one.
4327 * \param [in] other - an array to pow to \a this one.
4328 * \throw If \a other is NULL.
4329 * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
4330 * \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
4331 * \throw If there is a negative value in \a this.
4333 void DataArrayDouble::powEqual(const DataArrayDouble *other)
4336 throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : input instance is null !");
4337 int nbOfTuple=getNumberOfTuples();
4338 int nbOfTuple2=other->getNumberOfTuples();
4339 int nbOfComp=getNumberOfComponents();
4340 int nbOfComp2=other->getNumberOfComponents();
4341 if(nbOfTuple!=nbOfTuple2)
4342 throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of tuples mismatches !");
4343 if(nbOfComp!=1 || nbOfComp2!=1)
4344 throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of components of both arrays must be equal to 1 !");
4345 double *ptr=getPointer();
4346 const double *ptrc=other->begin();
4347 for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
4350 *ptr=pow(*ptr,*ptrc);
4353 std::ostringstream oss; oss << "DataArrayDouble::powEqual : on tuple #" << i << " of this value is < 0 (" << *ptr << ") !";
4354 throw INTERP_KERNEL::Exception(oss.str().c_str());
4361 * This method is \b NOT wrapped into python because it can be useful only for performance reasons in C++ context.
4362 * All values in \a this must be 0. or 1. within eps error. 0 means false, 1 means true.
4363 * If an another value than 0 or 1 appear (within eps precision) an INTERP_KERNEL::Exception will be thrown.
4365 * \throw if \a this is not allocated.
4366 * \throw if \a this has not exactly one component.
4368 std::vector<bool> DataArrayDouble::toVectorOfBool(double eps) const
4371 if(getNumberOfComponents()!=1)
4372 throw INTERP_KERNEL::Exception("DataArrayDouble::toVectorOfBool : must be applied on single component array !");
4373 int nbt(getNumberOfTuples());
4374 std::vector<bool> ret(nbt);
4375 const double *pt(begin());
4376 for(int i=0;i<nbt;i++)
4380 else if(fabs(pt[i]-1.)<eps)
4384 std::ostringstream oss; oss << "DataArrayDouble::toVectorOfBool : the tuple #" << i << " has value " << pt[i] << " is invalid ! must be 0. or 1. !";
4385 throw INTERP_KERNEL::Exception(oss.str().c_str());
4392 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
4395 void DataArrayDouble::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
4400 tinyInfo[0]=getNumberOfTuples();
4401 tinyInfo[1]=getNumberOfComponents();
4411 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
4414 void DataArrayDouble::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
4418 int nbOfCompo=getNumberOfComponents();
4419 tinyInfo.resize(nbOfCompo+1);
4420 tinyInfo[0]=getName();
4421 for(int i=0;i<nbOfCompo;i++)
4422 tinyInfo[i+1]=getInfoOnComponent(i);
4427 tinyInfo[0]=getName();
4432 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
4433 * This method returns if a feeding is needed.
4435 bool DataArrayDouble::resizeForUnserialization(const std::vector<int>& tinyInfoI)
4437 int nbOfTuple=tinyInfoI[0];
4438 int nbOfComp=tinyInfoI[1];
4439 if(nbOfTuple!=-1 || nbOfComp!=-1)
4441 alloc(nbOfTuple,nbOfComp);
4448 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
4450 void DataArrayDouble::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
4452 setName(tinyInfoS[0]);
4455 int nbOfCompo=getNumberOfComponents();
4456 for(int i=0;i<nbOfCompo;i++)
4457 setInfoOnComponent(i,tinyInfoS[i+1]);
4462 * Low static method that operates 3D rotation of 'nbNodes' 3D nodes whose coordinates are arranged in \a coordsIn
4463 * around an axe ( \a center, \a vect) and with angle \a angle.
4465 void DataArrayDouble::Rotate3DAlg(const double *center, const double *vect, double angle, int nbNodes, const double *coordsIn, double *coordsOut)
4467 if(!center || !vect)
4468 throw INTERP_KERNEL::Exception("DataArrayDouble::Rotate3DAlg : null vector in input !");
4469 double sina(sin(angle));
4470 double cosa(cos(angle));
4471 double vectorNorm[3];
4473 double matrixTmp[9];
4474 double norm(sqrt(vect[0]*vect[0]+vect[1]*vect[1]+vect[2]*vect[2]));
4475 if(norm<std::numeric_limits<double>::min())
4476 throw INTERP_KERNEL::Exception("DataArrayDouble::Rotate3DAlg : magnitude of input vector is too close of 0. !");
4477 std::transform(vect,vect+3,vectorNorm,std::bind2nd(std::multiplies<double>(),1/norm));
4478 //rotation matrix computation
4479 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;
4480 matrixTmp[0]=vectorNorm[0]*vectorNorm[0]; matrixTmp[1]=vectorNorm[0]*vectorNorm[1]; matrixTmp[2]=vectorNorm[0]*vectorNorm[2];
4481 matrixTmp[3]=vectorNorm[1]*vectorNorm[0]; matrixTmp[4]=vectorNorm[1]*vectorNorm[1]; matrixTmp[5]=vectorNorm[1]*vectorNorm[2];
4482 matrixTmp[6]=vectorNorm[2]*vectorNorm[0]; matrixTmp[7]=vectorNorm[2]*vectorNorm[1]; matrixTmp[8]=vectorNorm[2]*vectorNorm[2];
4483 std::transform(matrixTmp,matrixTmp+9,matrixTmp,std::bind2nd(std::multiplies<double>(),1-cosa));
4484 std::transform(matrix,matrix+9,matrixTmp,matrix,std::plus<double>());
4485 matrixTmp[0]=0.; matrixTmp[1]=-vectorNorm[2]; matrixTmp[2]=vectorNorm[1];
4486 matrixTmp[3]=vectorNorm[2]; matrixTmp[4]=0.; matrixTmp[5]=-vectorNorm[0];
4487 matrixTmp[6]=-vectorNorm[1]; matrixTmp[7]=vectorNorm[0]; matrixTmp[8]=0.;
4488 std::transform(matrixTmp,matrixTmp+9,matrixTmp,std::bind2nd(std::multiplies<double>(),sina));
4489 std::transform(matrix,matrix+9,matrixTmp,matrix,std::plus<double>());
4490 //rotation matrix computed.
4492 for(int i=0; i<nbNodes; i++)
4494 std::transform(coordsIn+i*3,coordsIn+(i+1)*3,center,tmp,std::minus<double>());
4495 coordsOut[i*3]=matrix[0]*tmp[0]+matrix[1]*tmp[1]+matrix[2]*tmp[2]+center[0];
4496 coordsOut[i*3+1]=matrix[3]*tmp[0]+matrix[4]*tmp[1]+matrix[5]*tmp[2]+center[1];
4497 coordsOut[i*3+2]=matrix[6]*tmp[0]+matrix[7]*tmp[1]+matrix[8]*tmp[2]+center[2];
4501 void DataArrayDouble::Symmetry3DPlane(const double point[3], const double normalVector[3], int nbNodes, const double *coordsIn, double *coordsOut)
4503 double matrix[9],matrix2[9],matrix3[9];
4504 double vect[3],crossVect[3];
4505 INTERP_KERNEL::orthogonalVect3(normalVector,vect);
4506 crossVect[0]=normalVector[1]*vect[2]-normalVector[2]*vect[1];
4507 crossVect[1]=normalVector[2]*vect[0]-normalVector[0]*vect[2];
4508 crossVect[2]=normalVector[0]*vect[1]-normalVector[1]*vect[0];
4509 double nv(INTERP_KERNEL::norm<3>(vect)),ni(INTERP_KERNEL::norm<3>(normalVector)),nc(INTERP_KERNEL::norm<3>(crossVect));
4510 matrix[0]=vect[0]/nv; matrix[1]=crossVect[0]/nc; matrix[2]=-normalVector[0]/ni;
4511 matrix[3]=vect[1]/nv; matrix[4]=crossVect[1]/nc; matrix[5]=-normalVector[1]/ni;
4512 matrix[6]=vect[2]/nv; matrix[7]=crossVect[2]/nc; matrix[8]=-normalVector[2]/ni;
4513 matrix2[0]=vect[0]/nv; matrix2[1]=vect[1]/nv; matrix2[2]=vect[2]/nv;
4514 matrix2[3]=crossVect[0]/nc; matrix2[4]=crossVect[1]/nc; matrix2[5]=crossVect[2]/nc;
4515 matrix2[6]=normalVector[0]/ni; matrix2[7]=normalVector[1]/ni; matrix2[8]=normalVector[2]/ni;
4516 for(int i=0;i<3;i++)
4517 for(int j=0;j<3;j++)
4520 for(int k=0;k<3;k++)
4521 val+=matrix[3*i+k]*matrix2[3*k+j];
4524 //rotation matrix computed.
4526 for(int i=0; i<nbNodes; i++)
4528 std::transform(coordsIn+i*3,coordsIn+(i+1)*3,point,tmp,std::minus<double>());
4529 coordsOut[i*3]=matrix3[0]*tmp[0]+matrix3[1]*tmp[1]+matrix3[2]*tmp[2]+point[0];
4530 coordsOut[i*3+1]=matrix3[3]*tmp[0]+matrix3[4]*tmp[1]+matrix3[5]*tmp[2]+point[1];
4531 coordsOut[i*3+2]=matrix3[6]*tmp[0]+matrix3[7]*tmp[1]+matrix3[8]*tmp[2]+point[2];
4535 void DataArrayDouble::GiveBaseForPlane(const double normalVector[3], double baseOfPlane[9])
4537 double vect[3],crossVect[3];
4538 INTERP_KERNEL::orthogonalVect3(normalVector,vect);
4539 crossVect[0]=normalVector[1]*vect[2]-normalVector[2]*vect[1];
4540 crossVect[1]=normalVector[2]*vect[0]-normalVector[0]*vect[2];
4541 crossVect[2]=normalVector[0]*vect[1]-normalVector[1]*vect[0];
4542 double nv(INTERP_KERNEL::norm<3>(vect)),ni(INTERP_KERNEL::norm<3>(normalVector)),nc(INTERP_KERNEL::norm<3>(crossVect));
4543 baseOfPlane[0]=vect[0]/nv; baseOfPlane[1]=vect[1]/nv; baseOfPlane[2]=vect[2]/nv;
4544 baseOfPlane[3]=crossVect[0]/nc; baseOfPlane[4]=crossVect[1]/nc; baseOfPlane[5]=crossVect[2]/nc;
4545 baseOfPlane[6]=normalVector[0]/ni; baseOfPlane[7]=normalVector[1]/ni; baseOfPlane[8]=normalVector[2]/ni;
4549 * Low static method that operates 3D rotation of \a nbNodes 3D nodes whose coordinates are arranged in \a coords
4550 * around the center point \a center and with angle \a angle.
4552 void DataArrayDouble::Rotate2DAlg(const double *center, double angle, int nbNodes, const double *coordsIn, double *coordsOut)
4554 double cosa=cos(angle);
4555 double sina=sin(angle);
4557 matrix[0]=cosa; matrix[1]=-sina; matrix[2]=sina; matrix[3]=cosa;
4559 for(int i=0; i<nbNodes; i++)
4561 std::transform(coordsIn+i*2,coordsIn+(i+1)*2,center,tmp,std::minus<double>());
4562 coordsOut[i*2]=matrix[0]*tmp[0]+matrix[1]*tmp[1]+center[0];
4563 coordsOut[i*2+1]=matrix[2]*tmp[0]+matrix[3]*tmp[1]+center[1];
4567 DataArrayDoubleIterator::DataArrayDoubleIterator(DataArrayDouble *da):_da(da),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
4572 if(_da->isAllocated())
4574 _nb_comp=da->getNumberOfComponents();
4575 _nb_tuple=da->getNumberOfTuples();
4576 _pt=da->getPointer();
4581 DataArrayDoubleIterator::~DataArrayDoubleIterator()
4587 DataArrayDoubleTuple *DataArrayDoubleIterator::nextt()
4589 if(_tuple_id<_nb_tuple)
4592 DataArrayDoubleTuple *ret=new DataArrayDoubleTuple(_pt,_nb_comp);
4600 DataArrayDoubleTuple::DataArrayDoubleTuple(double *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
4605 std::string DataArrayDoubleTuple::repr() const
4607 std::ostringstream oss; oss.precision(17); oss << "(";
4608 for(int i=0;i<_nb_of_compo-1;i++)
4609 oss << _pt[i] << ", ";
4610 oss << _pt[_nb_of_compo-1] << ")";
4614 double DataArrayDoubleTuple::doubleValue() const
4618 throw INTERP_KERNEL::Exception("DataArrayDoubleTuple::doubleValue : DataArrayDoubleTuple instance has not exactly 1 component -> Not possible to convert it into a double precision float !");
4622 * This method returns a newly allocated instance the caller should dealed with by a MEDCoupling::DataArrayDouble::decrRef.
4623 * This method performs \b no copy of data. The content is only referenced using MEDCoupling::DataArrayDouble::useArray with ownership set to \b false.
4624 * 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
4625 * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
4627 DataArrayDouble *DataArrayDoubleTuple::buildDADouble(int nbOfTuples, int nbOfCompo) const
4629 if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
4631 DataArrayDouble *ret=DataArrayDouble::New();
4632 ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
4637 std::ostringstream oss; oss << "DataArrayDoubleTuple::buildDADouble : unable to build a requested DataArrayDouble instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
4638 oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
4639 throw INTERP_KERNEL::Exception(oss.str().c_str());
4644 * Returns a new instance of DataArrayInt. The caller is to delete this array
4645 * using decrRef() as it is no more needed.
4647 DataArrayInt *DataArrayInt::New()
4649 return new DataArrayInt;
4653 * Returns the only one value in \a this, if and only if number of elements
4654 * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
4655 * \return double - the sole value stored in \a this array.
4656 * \throw If at least one of conditions stated above is not fulfilled.
4658 int DataArrayInt::intValue() const
4662 if(getNbOfElems()==1)
4664 return *getConstPointer();
4667 throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is allocated but number of elements is not equal to 1 !");
4670 throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is not allocated !");
4674 * Returns an integer value characterizing \a this array, which is useful for a quick
4675 * comparison of many instances of DataArrayInt.
4676 * \return int - the hash value.
4677 * \throw If \a this is not allocated.
4679 int DataArrayInt::getHashCode() const
4682 std::size_t nbOfElems=getNbOfElems();
4683 int ret=nbOfElems*65536;
4688 const int *pt=begin();
4689 for(std::size_t i=0;i<nbOfElems;i+=delta)
4690 ret0+=pt[i] & 0x1FFF;
4695 * Returns a full copy of \a this. For more info on copying data arrays see
4696 * \ref MEDCouplingArrayBasicsCopyDeep.
4697 * \return DataArrayInt * - a new instance of DataArrayInt.
4699 DataArrayInt *DataArrayInt::deepCopy() const
4701 return new DataArrayInt(*this);
4705 * Returns either a \a deep or \a shallow copy of this array. For more info see
4706 * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
4707 * \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
4708 * \return DataArrayInt * - either a new instance of DataArrayInt (if \a dCpy
4709 * == \a true) or \a this instance (if \a dCpy == \a false).
4711 DataArrayInt *DataArrayInt::performCopyOrIncrRef(bool dCpy) const
4713 return DataArrayTemplateClassic<int>::PerformCopyOrIncrRef(dCpy,*this);
4717 * Assign zero to all values in \a this array. To know more on filling arrays see
4718 * \ref MEDCouplingArrayFill.
4719 * \throw If \a this is not allocated.
4721 void DataArrayInt::fillWithZero()
4727 * Set all values in \a this array so that the i-th element equals to \a init + i
4728 * (i starts from zero). To know more on filling arrays see \ref MEDCouplingArrayFill.
4729 * \param [in] init - value to assign to the first element of array.
4730 * \throw If \a this->getNumberOfComponents() != 1
4731 * \throw If \a this is not allocated.
4733 void DataArrayInt::iota(int init)
4736 if(getNumberOfComponents()!=1)
4737 throw INTERP_KERNEL::Exception("DataArrayInt::iota : works only for arrays with only one component, you can call 'rearrange' method before !");
4738 int *ptr=getPointer();
4739 int ntuples=getNumberOfTuples();
4740 for(int i=0;i<ntuples;i++)
4746 * Returns a textual and human readable representation of \a this instance of
4747 * DataArrayInt. This text is shown when a DataArrayInt is printed in Python.
4748 * \return std::string - text describing \a this DataArrayInt.
4750 * \sa reprNotTooLong, reprZip
4752 std::string DataArrayInt::repr() const
4754 std::ostringstream ret;
4759 std::string DataArrayInt::reprZip() const
4761 std::ostringstream ret;
4767 * This method is close to repr method except that when \a this has more than 1000 tuples, all tuples are not
4768 * printed out to avoid to consume too much space in interpretor.
4771 std::string DataArrayInt::reprNotTooLong() const
4773 std::ostringstream ret;
4774 reprNotTooLongStream(ret);
4778 void DataArrayInt::writeVTK(std::ostream& ofs, int indent, const std::string& type, const std::string& nameInFile, DataArrayByte *byteArr) const
4780 static const char SPACE[4]={' ',' ',' ',' '};
4782 std::string idt(indent,' ');
4783 ofs << idt << "<DataArray type=\"" << type << "\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
4786 ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
4787 if(std::string(type)=="Int32")
4789 const char *data(reinterpret_cast<const char *>(begin()));
4790 std::size_t sz(getNbOfElems()*sizeof(int));
4791 byteArr->insertAtTheEnd(data,data+sz);
4792 byteArr->insertAtTheEnd(SPACE,SPACE+4);
4794 else if(std::string(type)=="Int8")
4796 INTERP_KERNEL::AutoPtr<char> tmp(new char[getNbOfElems()]);
4797 std::copy(begin(),end(),(char *)tmp);
4798 byteArr->insertAtTheEnd((char *)tmp,(char *)tmp+getNbOfElems());
4799 byteArr->insertAtTheEnd(SPACE,SPACE+4);
4801 else if(std::string(type)=="UInt8")
4803 INTERP_KERNEL::AutoPtr<unsigned char> tmp(new unsigned char[getNbOfElems()]);
4804 std::copy(begin(),end(),(unsigned char *)tmp);
4805 byteArr->insertAtTheEnd((unsigned char *)tmp,(unsigned char *)tmp+getNbOfElems());
4806 byteArr->insertAtTheEnd(SPACE,SPACE+4);
4809 throw INTERP_KERNEL::Exception("DataArrayInt::writeVTK : Only Int32, Int8 and UInt8 supported !");
4813 ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
4814 std::copy(begin(),end(),std::ostream_iterator<int>(ofs," "));
4816 ofs << std::endl << idt << "</DataArray>\n";
4819 void DataArrayInt::reprStream(std::ostream& stream) const
4821 stream << "Name of int array : \"" << _name << "\"\n";
4822 reprWithoutNameStream(stream);
4825 void DataArrayInt::reprZipStream(std::ostream& stream) const
4827 stream << "Name of int array : \"" << _name << "\"\n";
4828 reprZipWithoutNameStream(stream);
4831 void DataArrayInt::reprNotTooLongStream(std::ostream& stream) const
4833 stream << "Name of int array : \"" << _name << "\"\n";
4834 reprNotTooLongWithoutNameStream(stream);
4837 void DataArrayInt::reprWithoutNameStream(std::ostream& stream) const
4839 DataArray::reprWithoutNameStream(stream);
4840 _mem.repr(getNumberOfComponents(),stream);
4843 void DataArrayInt::reprZipWithoutNameStream(std::ostream& stream) const
4845 DataArray::reprWithoutNameStream(stream);
4846 _mem.reprZip(getNumberOfComponents(),stream);
4849 void DataArrayInt::reprNotTooLongWithoutNameStream(std::ostream& stream) const
4851 DataArray::reprWithoutNameStream(stream);
4852 stream.precision(17);
4853 _mem.reprNotTooLong(getNumberOfComponents(),stream);
4856 void DataArrayInt::reprCppStream(const std::string& varName, std::ostream& stream) const
4858 int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
4859 const int *data=getConstPointer();
4860 stream << "DataArrayInt *" << varName << "=DataArrayInt::New();" << std::endl;
4861 if(nbTuples*nbComp>=1)
4863 stream << "const int " << varName << "Data[" << nbTuples*nbComp << "]={";
4864 std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<int>(stream,","));
4865 stream << data[nbTuples*nbComp-1] << "};" << std::endl;
4866 stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
4869 stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
4870 stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
4874 * Method that gives a quick overvien of \a this for python.
4876 void DataArrayInt::reprQuickOverview(std::ostream& stream) const
4878 static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
4879 stream << "DataArrayInt C++ instance at " << this << ". ";
4882 int nbOfCompo=(int)_info_on_compo.size();
4885 int nbOfTuples=getNumberOfTuples();
4886 stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
4887 reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
4890 stream << "Number of components : 0.";
4893 stream << "*** No data allocated ****";
4896 void DataArrayInt::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
4898 const int *data=begin();
4899 int nbOfTuples=getNumberOfTuples();
4900 int nbOfCompo=(int)_info_on_compo.size();
4901 std::ostringstream oss2; oss2 << "[";
4902 std::string oss2Str(oss2.str());
4903 bool isFinished=true;
4904 for(int i=0;i<nbOfTuples && isFinished;i++)
4909 for(int j=0;j<nbOfCompo;j++,data++)
4912 if(j!=nbOfCompo-1) oss2 << ", ";
4918 if(i!=nbOfTuples-1) oss2 << ", ";
4919 std::string oss3Str(oss2.str());
4920 if(oss3Str.length()<maxNbOfByteInRepr)
4932 * Modifies in place \a this one-dimensional array so that each value \a v = \a indArrBg[ \a v ],
4933 * i.e. a current value is used as in index to get a new value from \a indArrBg.
4934 * \param [in] indArrBg - pointer to the first element of array of new values to assign
4936 * \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
4937 * the last value of \a indArrBg is \a indArrEnd[ -1 ].
4938 * \throw If \a this->getNumberOfComponents() != 1
4939 * \throw If any value of \a this can't be used as a valid index for
4940 * [\a indArrBg, \a indArrEnd).
4944 void DataArrayInt::transformWithIndArr(const int *indArrBg, const int *indArrEnd)
4947 if(getNumberOfComponents()!=1)
4948 throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
4949 int nbElemsIn((int)std::distance(indArrBg,indArrEnd)),nbOfTuples(getNumberOfTuples()),*pt(getPointer());
4950 for(int i=0;i<nbOfTuples;i++,pt++)
4952 if(*pt>=0 && *pt<nbElemsIn)
4956 std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " of this value is " << *pt << ", should be in [0," << nbElemsIn << ") !";
4957 throw INTERP_KERNEL::Exception(oss.str().c_str());
4964 * Computes distribution of values of \a this one-dimensional array between given value
4965 * ranges (casts). This method is typically useful for entity number spliting by types,
4967 * \warning The values contained in \a arrBg should be sorted ascendently. No
4968 * check of this is be done. If not, the result is not warranted.
4969 * \param [in] arrBg - the array of ascending values defining the value ranges. The i-th
4970 * value of \a arrBg (\a arrBg[ i ]) gives the lowest value of the i-th range,
4971 * and the greatest value of the i-th range equals to \a arrBg[ i+1 ] - 1. \a
4972 * arrBg containing \a n values defines \a n-1 ranges. The last value of \a arrBg
4973 * should be more than every value in \a this array.
4974 * \param [in] arrEnd - specifies the end of the array \a arrBg, so that
4975 * the last value of \a arrBg is \a arrEnd[ -1 ].
4976 * \param [out] castArr - a new instance of DataArrayInt, of same size as \a this array
4977 * (same number of tuples and components), the caller is to delete
4978 * using decrRef() as it is no more needed.
4979 * This array contains indices of ranges for every value of \a this array. I.e.
4980 * the i-th value of \a castArr gives the index of range the i-th value of \a this
4981 * belongs to. Or, in other words, this parameter contains for each tuple in \a
4982 * this in which cast it holds.
4983 * \param [out] rankInsideCast - a new instance of DataArrayInt, of same size as \a this
4984 * array, the caller is to delete using decrRef() as it is no more needed.
4985 * This array contains ranks of values of \a this array within ranges
4986 * they belongs to. I.e. the i-th value of \a rankInsideCast gives the rank of
4987 * the i-th value of \a this array within the \a castArr[ i ]-th range, to which
4988 * the i-th value of \a this belongs to. Or, in other words, this param contains
4989 * for each tuple its rank inside its cast. The rank is computed as difference
4990 * between the value and the lowest value of range.
4991 * \param [out] castsPresent - a new instance of DataArrayInt, containing indices of
4992 * ranges (casts) to which at least one value of \a this array belongs.
4993 * Or, in other words, this param contains the casts that \a this contains.
4994 * The caller is to delete this array using decrRef() as it is no more needed.
4996 * \b Example: If \a this contains [6,5,0,3,2,7,8,1,4] and \a arrBg contains [0,4,9] then
4997 * the output of this method will be :
4998 * - \a castArr : [1,1,0,0,0,1,1,0,1]
4999 * - \a rankInsideCast: [2,1,0,3,2,3,4,1,0]
5000 * - \a castsPresent : [0,1]
5002 * I.e. values of \a this array belong to 2 ranges: #0 and #1. Value 6 belongs to the
5003 * range #1 and its rank within this range is 2; etc.
5005 * \throw If \a this->getNumberOfComponents() != 1.
5006 * \throw If \a arrEnd - arrBg < 2.
5007 * \throw If any value of \a this is not less than \a arrEnd[-1].
5009 void DataArrayInt::splitByValueRange(const int *arrBg, const int *arrEnd,
5010 DataArrayInt *& castArr, DataArrayInt *& rankInsideCast, DataArrayInt *& castsPresent) const
5013 if(getNumberOfComponents()!=1)
5014 throw INTERP_KERNEL::Exception("Call splitByValueRange method on DataArrayInt with only one component, you can call 'rearrange' method before !");
5015 int nbOfTuples=getNumberOfTuples();
5016 std::size_t nbOfCast=std::distance(arrBg,arrEnd);
5018 throw INTERP_KERNEL::Exception("DataArrayInt::splitByValueRange : The input array giving the cast range values should be of size >=2 !");
5020 const int *work=getConstPointer();
5021 typedef std::reverse_iterator<const int *> rintstart;
5022 rintstart bg(arrEnd);//OK no problem because size of 'arr' is greater or equal 2
5023 rintstart end2(arrBg);
5024 MCAuto<DataArrayInt> ret1=DataArrayInt::New();
5025 MCAuto<DataArrayInt> ret2=DataArrayInt::New();
5026 MCAuto<DataArrayInt> ret3=DataArrayInt::New();
5027 ret1->alloc(nbOfTuples,1);
5028 ret2->alloc(nbOfTuples,1);
5029 int *ret1Ptr=ret1->getPointer();
5030 int *ret2Ptr=ret2->getPointer();
5031 std::set<std::size_t> castsDetected;
5032 for(int i=0;i<nbOfTuples;i++)
5034 rintstart res=std::find_if(bg,end2,std::bind2nd(std::less_equal<int>(), work[i]));
5035 std::size_t pos=std::distance(bg,res);
5036 std::size_t pos2=nbOfCast-pos;
5039 ret1Ptr[i]=(int)pos2;
5040 ret2Ptr[i]=work[i]-arrBg[pos2];
5041 castsDetected.insert(pos2);
5045 std::ostringstream oss; oss << "DataArrayInt::splitByValueRange : At rank #" << i << " the value is " << work[i] << " should be in [0," << *bg << ") !";
5046 throw INTERP_KERNEL::Exception(oss.str().c_str());
5049 ret3->alloc((int)castsDetected.size(),1);
5050 std::copy(castsDetected.begin(),castsDetected.end(),ret3->getPointer());
5051 castArr=ret1.retn();
5052 rankInsideCast=ret2.retn();
5053 castsPresent=ret3.retn();
5057 * 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 ).
5058 * 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 ).
5059 * This method works only if \a this is allocated and single component. If not an exception will be thrown.
5061 * \param [out] strt - the start of the range (included) if true is returned.
5062 * \param [out] sttoopp - the end of the range (not included) if true is returned.
5063 * \param [out] stteepp - the step of the range if true is returned.
5064 * \return the verdict of the check.
5066 * \sa DataArray::GetNumberOfItemGivenBES
5068 bool DataArrayInt::isRange(int& strt, int& sttoopp, int& stteepp) const
5071 if(getNumberOfComponents()!=1)
5072 throw INTERP_KERNEL::Exception("DataArrayInt::isRange : this must be single component array !");
5073 int nbTuples(getNumberOfTuples());
5075 { strt=0; sttoopp=0; stteepp=1; return true; }
5076 const int *pt(begin());
5079 { sttoopp=strt+1; stteepp=1; return true; }
5080 strt=*pt; sttoopp=pt[nbTuples-1];
5086 int a(sttoopp-1-strt),tmp(strt);
5087 if(a%(nbTuples-1)!=0)
5089 stteepp=a/(nbTuples-1);
5090 for(int i=0;i<nbTuples;i++,tmp+=stteepp)
5098 int a(strt-sttoopp-1),tmp(strt);
5099 if(a%(nbTuples-1)!=0)
5101 stteepp=-(a/(nbTuples-1));
5102 for(int i=0;i<nbTuples;i++,tmp+=stteepp)
5110 * Creates a one-dimensional DataArrayInt (\a res) whose contents are computed from
5111 * values of \a this (\a a) and the given (\a indArr) arrays as follows:
5112 * \a res[ \a indArr[ \a a[ i ]]] = i. I.e. for each value in place i \a v = \a a[ i ],
5113 * new value in place \a indArr[ \a v ] is i.
5114 * \param [in] indArrBg - the array holding indices within the result array to assign
5115 * indices of values of \a this array pointing to values of \a indArrBg.
5116 * \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
5117 * the last value of \a indArrBg is \a indArrEnd[ -1 ].
5118 * \return DataArrayInt * - the new instance of DataArrayInt.
5119 * The caller is to delete this result array using decrRef() as it is no more
5121 * \throw If \a this->getNumberOfComponents() != 1.
5122 * \throw If any value of \a this array is not a valid index for \a indArrBg array.
5123 * \throw If any value of \a indArrBg is not a valid index for \a this array.
5125 DataArrayInt *DataArrayInt::transformWithIndArrR(const int *indArrBg, const int *indArrEnd) const
5128 if(getNumberOfComponents()!=1)
5129 throw INTERP_KERNEL::Exception("Call transformWithIndArrR method on DataArrayInt with only one component, you can call 'rearrange' method before !");
5130 int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
5131 int nbOfTuples=getNumberOfTuples();
5132 const int *pt=getConstPointer();
5133 MCAuto<DataArrayInt> ret=DataArrayInt::New();
5134 ret->alloc(nbOfTuples,1);
5135 ret->fillWithValue(-1);
5136 int *tmp=ret->getPointer();
5137 for(int i=0;i<nbOfTuples;i++,pt++)
5139 if(*pt>=0 && *pt<nbElemsIn)
5141 int pos=indArrBg[*pt];
5142 if(pos>=0 && pos<nbOfTuples)
5146 std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value of new pos is " << pos << " ( indArrBg[" << *pt << "]) ! Should be in [0," << nbOfTuples << ") !";
5147 throw INTERP_KERNEL::Exception(oss.str().c_str());
5152 std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn << " !";
5153 throw INTERP_KERNEL::Exception(oss.str().c_str());
5160 * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
5161 * from values of \a this array, which is supposed to contain a renumbering map in
5162 * "Old to New" mode. The result array contains a renumbering map in "New to Old" mode.
5163 * To know how to use the renumbering maps see \ref numbering.
5164 * \param [in] newNbOfElem - the number of tuples in the result array.
5165 * \return DataArrayInt * - the new instance of DataArrayInt.
5166 * The caller is to delete this result array using decrRef() as it is no more
5169 * \if ENABLE_EXAMPLES
5170 * \ref cpp_mcdataarrayint_invertarrayo2n2n2o "Here is a C++ example".<br>
5171 * \ref py_mcdataarrayint_invertarrayo2n2n2o "Here is a Python example".
5174 DataArrayInt *DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const
5176 MCAuto<DataArrayInt> ret=DataArrayInt::New();
5177 ret->alloc(newNbOfElem,1);
5178 int nbOfOldNodes=getNumberOfTuples();
5179 const int *old2New=getConstPointer();
5180 int *pt=ret->getPointer();
5181 for(int i=0;i!=nbOfOldNodes;i++)
5183 int newp(old2New[i]);
5186 if(newp>=0 && newp<newNbOfElem)
5190 std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2O : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
5191 throw INTERP_KERNEL::Exception(oss.str().c_str());
5199 * This method is similar to DataArrayInt::invertArrayO2N2N2O except that
5200 * 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]
5202 DataArrayInt *DataArrayInt::invertArrayO2N2N2OBis(int newNbOfElem) const
5204 MCAuto<DataArrayInt> ret=DataArrayInt::New();
5205 ret->alloc(newNbOfElem,1);
5206 int nbOfOldNodes=getNumberOfTuples();
5207 const int *old2New=getConstPointer();
5208 int *pt=ret->getPointer();
5209 for(int i=nbOfOldNodes-1;i>=0;i--)
5211 int newp(old2New[i]);
5214 if(newp>=0 && newp<newNbOfElem)
5218 std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2OBis : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
5219 throw INTERP_KERNEL::Exception(oss.str().c_str());
5227 * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
5228 * from values of \a this array, which is supposed to contain a renumbering map in
5229 * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
5230 * To know how to use the renumbering maps see \ref numbering.
5231 * \param [in] newNbOfElem - the number of tuples in the result array.
5232 * \return DataArrayInt * - the new instance of DataArrayInt.
5233 * The caller is to delete this result array using decrRef() as it is no more
5236 * \if ENABLE_EXAMPLES
5237 * \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
5239 * \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
5242 DataArrayInt *DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const
5245 MCAuto<DataArrayInt> ret=DataArrayInt::New();
5246 ret->alloc(oldNbOfElem,1);
5247 const int *new2Old=getConstPointer();
5248 int *pt=ret->getPointer();
5249 std::fill(pt,pt+oldNbOfElem,-1);
5250 int nbOfNewElems=getNumberOfTuples();
5251 for(int i=0;i<nbOfNewElems;i++)
5254 if(v>=0 && v<oldNbOfElem)
5258 std::ostringstream oss; oss << "DataArrayInt::invertArrayN2O2O2N : in new id #" << i << " old value is " << v << " expected to be in [0," << oldNbOfElem << ") !";
5259 throw INTERP_KERNEL::Exception(oss.str().c_str());
5266 * Equivalent to DataArrayInt::isEqual except that if false the reason of
5267 * mismatch is given.
5269 * \param [in] other the instance to be compared with \a this
5270 * \param [out] reason In case of inequality returns the reason.
5271 * \sa DataArrayInt::isEqual
5273 bool DataArrayInt::isEqualIfNotWhy(const DataArrayInt& other, std::string& reason) const
5275 if(!areInfoEqualsIfNotWhy(other,reason))
5277 return _mem.isEqual(other._mem,0,reason);
5281 * Checks if \a this and another DataArrayInt are fully equal. For more info see
5282 * \ref MEDCouplingArrayBasicsCompare.
5283 * \param [in] other - an instance of DataArrayInt to compare with \a this one.
5284 * \return bool - \a true if the two arrays are equal, \a false else.
5286 bool DataArrayInt::isEqual(const DataArrayInt& other) const
5289 return isEqualIfNotWhy(other,tmp);
5293 * Checks if values of \a this and another DataArrayInt are equal. For more info see
5294 * \ref MEDCouplingArrayBasicsCompare.
5295 * \param [in] other - an instance of DataArrayInt to compare with \a this one.
5296 * \return bool - \a true if the values of two arrays are equal, \a false else.
5298 bool DataArrayInt::isEqualWithoutConsideringStr(const DataArrayInt& other) const
5301 return _mem.isEqual(other._mem,0,tmp);
5305 * Checks if values of \a this and another DataArrayInt are equal. Comparison is
5306 * performed on sorted value sequences.
5307 * For more info see\ref MEDCouplingArrayBasicsCompare.
5308 * \param [in] other - an instance of DataArrayInt to compare with \a this one.
5309 * \return bool - \a true if the sorted values of two arrays are equal, \a false else.
5311 bool DataArrayInt::isEqualWithoutConsideringStrAndOrder(const DataArrayInt& other) const
5313 MCAuto<DataArrayInt> a=deepCopy();
5314 MCAuto<DataArrayInt> b=other.deepCopy();
5317 return a->isEqualWithoutConsideringStr(*b);
5321 * This method compares content of input vector \a v and \a this.
5322 * If for each id in \a this v[id]==True and for all other ids id2 not in \a this v[id2]==False, true is returned.
5323 * For performance reasons \a this is expected to be sorted ascendingly. If not an exception will be thrown.
5325 * \param [in] v - the vector of 'flags' to be compared with \a this.
5327 * \throw If \a this is not sorted ascendingly.
5328 * \throw If \a this has not exactly one component.
5329 * \throw If \a this is not allocated.
5331 bool DataArrayInt::isFittingWith(const std::vector<bool>& v) const
5334 if(getNumberOfComponents()!=1)
5335 throw INTERP_KERNEL::Exception("DataArrayInt::isFittingWith : number of components of this should be equal to one !");
5336 const int *w(begin()),*end2(end());
5337 int refVal=-std::numeric_limits<int>::max();
5339 std::vector<bool>::const_iterator it(v.begin());
5340 for(;it!=v.end();it++,i++)
5352 std::ostringstream oss; oss << "DataArrayInt::isFittingWith : At pos #" << std::distance(begin(),w-1) << " this is not sorted ascendingly !";
5353 throw INTERP_KERNEL::Exception(oss.str().c_str());
5367 * This method assumes that \a this has one component and is allocated. This method scans all tuples in \a this and for all tuple equal to \a val
5368 * put True to the corresponding entry in \a vec.
5369 * \a vec is expected to be with the same size than the number of tuples of \a this.
5371 * \sa DataArrayInt::switchOnTupleNotEqualTo.
5373 void DataArrayInt::switchOnTupleEqualTo(int val, std::vector<bool>& vec) const
5376 if(getNumberOfComponents()!=1)
5377 throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleEqualTo : number of components of this should be equal to one !");
5378 int nbOfTuples(getNumberOfTuples());
5379 if(nbOfTuples!=(int)vec.size())
5380 throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleEqualTo : number of tuples of this should be equal to size of input vector of bool !");
5381 const int *pt(begin());
5382 for(int i=0;i<nbOfTuples;i++)
5388 * This method assumes that \a this has one component and is allocated. This method scans all tuples in \a this and for all tuple different from \a val
5389 * put True to the corresponding entry in \a vec.
5390 * \a vec is expected to be with the same size than the number of tuples of \a this.
5392 * \sa DataArrayInt::switchOnTupleEqualTo.
5394 void DataArrayInt::switchOnTupleNotEqualTo(int val, std::vector<bool>& vec) const
5397 if(getNumberOfComponents()!=1)
5398 throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleNotEqualTo : number of components of this should be equal to one !");
5399 int nbOfTuples(getNumberOfTuples());
5400 if(nbOfTuples!=(int)vec.size())
5401 throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleNotEqualTo : number of tuples of this should be equal to size of input vector of bool !");
5402 const int *pt(begin());
5403 for(int i=0;i<nbOfTuples;i++)
5409 * Computes for each tuple the sum of number of components values in the tuple and return it.
5411 * \return DataArrayInt * - the new instance of DataArrayInt containing the
5412 * same number of tuples as \a this array and one component.
5413 * The caller is to delete this result array using decrRef() as it is no more
5415 * \throw If \a this is not allocated.
5417 DataArrayInt *DataArrayInt::sumPerTuple() const
5420 int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
5421 MCAuto<DataArrayInt> ret(DataArrayInt::New());
5422 ret->alloc(nbOfTuple,1);
5423 const int *src(getConstPointer());
5424 int *dest(ret->getPointer());
5425 for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
5426 *dest=std::accumulate(src,src+nbOfComp,0);
5431 * Checks that \a this array is consistently **increasing** or **decreasing** in value.
5432 * If not an exception is thrown.
5433 * \param [in] increasing - if \a true, the array values should be increasing.
5434 * \throw If sequence of values is not strictly monotonic in agreement with \a
5436 * \throw If \a this->getNumberOfComponents() != 1.
5437 * \throw If \a this is not allocated.
5439 void DataArrayInt::checkMonotonic(bool increasing) const
5441 if(!isMonotonic(increasing))
5444 throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not INCREASING monotonic !");
5446 throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not DECREASING monotonic !");
5451 * Checks that \a this array is consistently **increasing** or **decreasing** in value.
5452 * \param [in] increasing - if \a true, array values should be increasing.
5453 * \return bool - \a true if values change in accordance with \a increasing arg.
5454 * \throw If \a this->getNumberOfComponents() != 1.
5455 * \throw If \a this is not allocated.
5457 bool DataArrayInt::isMonotonic(bool increasing) const
5460 if(getNumberOfComponents()!=1)
5461 throw INTERP_KERNEL::Exception("DataArrayInt::isMonotonic : only supported with 'this' array with ONE component !");
5462 int nbOfElements=getNumberOfTuples();
5463 const int *ptr=getConstPointer();
5469 for(int i=1;i<nbOfElements;i++)
5479 for(int i=1;i<nbOfElements;i++)
5491 * This method check that array consistently INCREASING or DECREASING in value.
5493 bool DataArrayInt::isStrictlyMonotonic(bool increasing) const
5496 if(getNumberOfComponents()!=1)
5497 throw INTERP_KERNEL::Exception("DataArrayInt::isStrictlyMonotonic : only supported with 'this' array with ONE component !");
5498 int nbOfElements=getNumberOfTuples();
5499 const int *ptr=getConstPointer();
5505 for(int i=1;i<nbOfElements;i++)
5515 for(int i=1;i<nbOfElements;i++)
5527 * This method check that array consistently INCREASING or DECREASING in value.
5529 void DataArrayInt::checkStrictlyMonotonic(bool increasing) const
5531 if(!isStrictlyMonotonic(increasing))
5534 throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly INCREASING monotonic !");
5536 throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly DECREASING monotonic !");
5541 * Creates a new one-dimensional DataArrayInt of the same size as \a this and a given
5542 * one-dimensional arrays that must be of the same length. The result array describes
5543 * correspondence between \a this and \a other arrays, so that
5544 * <em> other.getIJ(i,0) == this->getIJ(ret->getIJ(i),0)</em>. If such a permutation is
5545 * not possible because some element in \a other is not in \a this, an exception is thrown.
5546 * \param [in] other - an array to compute permutation to.
5547 * \return DataArrayInt * - a new instance of DataArrayInt, which is a permutation array
5548 * from \a this to \a other. The caller is to delete this array using decrRef() as it is
5550 * \throw If \a this->getNumberOfComponents() != 1.
5551 * \throw If \a other->getNumberOfComponents() != 1.
5552 * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples().
5553 * \throw If \a other includes a value which is not in \a this array.
5555 * \if ENABLE_EXAMPLES
5556 * \ref cpp_mcdataarrayint_buildpermutationarr "Here is a C++ example".
5558 * \ref py_mcdataarrayint_buildpermutationarr "Here is a Python example".
5561 DataArrayInt *DataArrayInt::buildPermutationArr(const DataArrayInt& other) const
5564 if(getNumberOfComponents()!=1 || other.getNumberOfComponents()!=1)
5565 throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' have to have exactly ONE component !");
5566 int nbTuple=getNumberOfTuples();
5567 other.checkAllocated();
5568 if(nbTuple!=other.getNumberOfTuples())
5569 throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' must have the same number of tuple !");
5570 MCAuto<DataArrayInt> ret=DataArrayInt::New();
5571 ret->alloc(nbTuple,1);
5572 ret->fillWithValue(-1);
5573 const int *pt=getConstPointer();
5574 std::map<int,int> mm;
5575 for(int i=0;i<nbTuple;i++)
5577 pt=other.getConstPointer();
5578 int *retToFill=ret->getPointer();
5579 for(int i=0;i<nbTuple;i++)
5581 std::map<int,int>::const_iterator it=mm.find(pt[i]);
5584 std::ostringstream oss; oss << "DataArrayInt::buildPermutationArr : Arrays mismatch : element (" << pt[i] << ") in 'other' not findable in 'this' !";
5585 throw INTERP_KERNEL::Exception(oss.str().c_str());
5587 retToFill[i]=(*it).second;
5593 * Elements of \a partOfThis are expected to be included in \a this.
5594 * The returned array \a ret is so that this[ret]==partOfThis
5596 * For example, if \a this array contents are [9,10,0,6,4,11,3,8] and if \a partOfThis contains [6,0,11,8]
5597 * the return array will contain [3,2,5,7].
5599 * \a this is expected to be a 1 compo allocated array.
5600 * \param [in] partOfThis - A 1 compo allocated array
5601 * \return - A newly allocated array to be dealed by caller having the same number of tuples than \a partOfThis.
5602 * \throw if two same element is present twice in \a this
5603 * \throw if an element in \a partOfThis is \b NOT in \a this.
5605 DataArrayInt *DataArrayInt::indicesOfSubPart(const DataArrayInt& partOfThis) const
5607 if(getNumberOfComponents()!=1 || partOfThis.getNumberOfComponents()!=1)
5608 throw INTERP_KERNEL::Exception("DataArrayInt::indicesOfSubPart : this and input array must be one component array !");
5609 checkAllocated(); partOfThis.checkAllocated();
5610 int thisNbTuples(getNumberOfTuples()),nbTuples(partOfThis.getNumberOfTuples());
5611 const int *thisPt(begin()),*pt(partOfThis.begin());
5612 MCAuto<DataArrayInt> ret(DataArrayInt::New());
5613 ret->alloc(nbTuples,1);
5614 int *retPt(ret->getPointer());
5615 std::map<int,int> m;
5616 for(int i=0;i<thisNbTuples;i++,thisPt++)
5618 if(m.size()!=thisNbTuples)
5619 throw INTERP_KERNEL::Exception("DataArrayInt::indicesOfSubPart : some elements appears more than once !");
5620 for(int i=0;i<nbTuples;i++,retPt++,pt++)
5622 std::map<int,int>::const_iterator it(m.find(*pt));
5624 *retPt=(*it).second;
5627 std::ostringstream oss; oss << "DataArrayInt::indicesOfSubPart : At pos #" << i << " of input array value is " << *pt << " not in this !";
5628 throw INTERP_KERNEL::Exception(oss.str());
5634 void DataArrayInt::aggregate(const DataArrayInt *other)
5637 throw INTERP_KERNEL::Exception("DataArrayInt::aggregate : null pointer !");
5638 if(getNumberOfComponents()!=other->getNumberOfComponents())
5639 throw INTERP_KERNEL::Exception("DataArrayInt::aggregate : mismatch number of components !");
5640 _mem.insertAtTheEnd(other->begin(),other->end());
5644 * Returns a new DataArrayInt holding the same values as \a this array but differently
5645 * arranged in memory. If \a this array holds 2 components of 3 values:
5646 * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
5647 * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
5648 * \warning Do not confuse this method with transpose()!
5649 * \return DataArrayInt * - the new instance of DataArrayInt that the caller
5650 * is to delete using decrRef() as it is no more needed.
5651 * \throw If \a this is not allocated.
5653 DataArrayInt *DataArrayInt::fromNoInterlace() const
5657 throw INTERP_KERNEL::Exception("DataArrayInt::fromNoInterlace : Not defined array !");
5658 int *tab=_mem.fromNoInterlace(getNumberOfComponents());
5659 DataArrayInt *ret=DataArrayInt::New();
5660 ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
5665 * Returns a new DataArrayInt holding the same values as \a this array but differently
5666 * arranged in memory. If \a this array holds 2 components of 3 values:
5667 * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
5668 * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
5669 * \warning Do not confuse this method with transpose()!
5670 * \return DataArrayInt * - the new instance of DataArrayInt that the caller
5671 * is to delete using decrRef() as it is no more needed.
5672 * \throw If \a this is not allocated.
5674 DataArrayInt *DataArrayInt::toNoInterlace() const
5678 throw INTERP_KERNEL::Exception("DataArrayInt::toNoInterlace : Not defined array !");
5679 int *tab=_mem.toNoInterlace(getNumberOfComponents());
5680 DataArrayInt *ret=DataArrayInt::New();
5681 ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
5686 * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode.
5687 * This map, if applied to \a this array, would make it sorted. For example, if
5688 * \a this array contents are [9,10,0,6,4,11,3,7] then the contents of the result array
5689 * are [5,6,0,3,2,7,1,4]; if this result array (\a res) is used as an argument in call
5690 * \a this->renumber(\a res) then the returned array contains [0,3,4,6,7,9,10,11].
5691 * This method is useful for renumbering (in MED file for example). For more info
5692 * on renumbering see \ref numbering.
5693 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5694 * array using decrRef() as it is no more needed.
5695 * \throw If \a this is not allocated.
5696 * \throw If \a this->getNumberOfComponents() != 1.
5697 * \throw If there are equal values in \a this array.
5699 DataArrayInt *DataArrayInt::checkAndPreparePermutation() const
5702 if(getNumberOfComponents()!=1)
5703 throw INTERP_KERNEL::Exception("DataArrayInt::checkAndPreparePermutation : number of components must == 1 !");
5704 int nbTuples=getNumberOfTuples();
5705 const int *pt=getConstPointer();
5706 int *pt2=CheckAndPreparePermutation(pt,pt+nbTuples);
5707 DataArrayInt *ret=DataArrayInt::New();
5708 ret->useArray(pt2,true,C_DEALLOC,nbTuples,1);
5713 * This method tries to find the permutation to apply to the first input \a ids1 to obtain the same array (without considering strings informations) the second
5714 * input array \a ids2.
5715 * \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.
5716 * 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
5718 * In case of success (no throw) : \c ids1->renumber(ret)->isEqual(ids2) where \a ret is the return of this method.
5720 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5721 * array using decrRef() as it is no more needed.
5722 * \throw If either ids1 or ids2 is null not allocated or not with one components.
5725 DataArrayInt *DataArrayInt::FindPermutationFromFirstToSecond(const DataArrayInt *ids1, const DataArrayInt *ids2)
5728 throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be not null !");
5729 if(!ids1->isAllocated() || !ids2->isAllocated())
5730 throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be allocated !");
5731 if(ids1->getNumberOfComponents()!=1 || ids2->getNumberOfComponents()!=1)
5732 throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays have exactly one component !");
5733 if(ids1->getNumberOfTuples()!=ids2->getNumberOfTuples())
5735 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 !";
5736 throw INTERP_KERNEL::Exception(oss.str().c_str());
5738 MCAuto<DataArrayInt> p1(ids1->deepCopy());
5739 MCAuto<DataArrayInt> p2(ids2->deepCopy());
5740 p1->sort(true); p2->sort(true);
5741 if(!p1->isEqualWithoutConsideringStr(*p2))
5742 throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two arrays are not lying on same ids ! Impossible to find a permutation between the 2 arrays !");
5743 p1=ids1->checkAndPreparePermutation();
5744 p2=ids2->checkAndPreparePermutation();
5745 p2=p2->invertArrayO2N2N2O(p2->getNumberOfTuples());
5746 p2=p2->selectByTupleIdSafe(p1->begin(),p1->end());
5751 * Returns two arrays describing a surjective mapping from \a this set of values (\a A)
5752 * onto a set of values of size \a targetNb (\a B). The surjective function is
5753 * \a B[ \a A[ i ]] = i. That is to say that for each \a id in [0,\a targetNb), where \a
5754 * targetNb < \a this->getNumberOfTuples(), there exists at least one tupleId (\a tid) so
5755 * that <em> this->getIJ( tid, 0 ) == id</em>. <br>
5756 * The first of out arrays returns indices of elements of \a this array, grouped by their
5757 * place in the set \a B. The second out array is the index of the first one; it shows how
5758 * many elements of \a A are mapped into each element of \a B. <br>
5760 * mapping and its usage in renumbering see \ref numbering. <br>
5762 * - \a this: [0,3,2,3,2,2,1,2]
5764 * - \a arr: [0, 6, 2,4,5,7, 1,3]
5765 * - \a arrI: [0,1,2,6,8]
5767 * This result means: <br>
5768 * the element of \a B 0 encounters within \a A once (\a arrI[ 0+1 ] - \a arrI[ 0 ]) and
5769 * its index within \a A is 0 ( \a arr[ 0:1 ] == \a arr[ \a arrI[ 0 ] : \a arrI[ 0+1 ]]);<br>
5770 * the element of \a B 2 encounters within \a A 4 times (\a arrI[ 2+1 ] - \a arrI[ 2 ]) and
5771 * its indices within \a A are [2,4,5,7] ( \a arr[ 2:6 ] == \a arr[ \a arrI[ 2 ] :
5772 * \a arrI[ 2+1 ]]); <br> etc.
5773 * \param [in] targetNb - the size of the set \a B. \a targetNb must be equal or more
5774 * than the maximal value of \a A.
5775 * \param [out] arr - a new instance of DataArrayInt returning indices of
5776 * elements of \a this, grouped by their place in the set \a B. The caller is to delete
5777 * this array using decrRef() as it is no more needed.
5778 * \param [out] arrI - a new instance of DataArrayInt returning size of groups of equal
5779 * elements of \a this. The caller is to delete this array using decrRef() as it
5780 * is no more needed.
5781 * \throw If \a this is not allocated.
5782 * \throw If \a this->getNumberOfComponents() != 1.
5783 * \throw If any value in \a this is more or equal to \a targetNb.
5785 void DataArrayInt::changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, DataArrayInt *&arrI) const
5788 if(getNumberOfComponents()!=1)
5789 throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : number of components must == 1 !");
5790 int nbOfTuples=getNumberOfTuples();
5791 MCAuto<DataArrayInt> ret(DataArrayInt::New());
5792 MCAuto<DataArrayInt> retI(DataArrayInt::New());
5793 retI->alloc(targetNb+1,1);
5794 const int *input=getConstPointer();
5795 std::vector< std::vector<int> > tmp(targetNb);
5796 for(int i=0;i<nbOfTuples;i++)
5799 if(tmp2>=0 && tmp2<targetNb)
5800 tmp[tmp2].push_back(i);
5803 std::ostringstream oss; oss << "DataArrayInt::changeSurjectiveFormat : At pos " << i << " presence of element " << tmp2 << " ! should be in [0," << targetNb << ") !";
5804 throw INTERP_KERNEL::Exception(oss.str().c_str());
5807 int *retIPtr=retI->getPointer();
5809 for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++,retIPtr++)
5810 retIPtr[1]=retIPtr[0]+(int)((*it1).size());
5811 if(nbOfTuples!=retI->getIJ(targetNb,0))
5812 throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : big problem should never happen !");
5813 ret->alloc(nbOfTuples,1);
5814 int *retPtr=ret->getPointer();
5815 for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++)
5816 retPtr=std::copy((*it1).begin(),(*it1).end(),retPtr);
5823 * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode computed
5824 * from a zip representation of a surjective format (returned e.g. by
5825 * \ref MEDCoupling::DataArrayDouble::findCommonTuples() "DataArrayDouble::findCommonTuples()"
5826 * for example). The result array minimizes the permutation. <br>
5827 * For more info on renumbering see \ref numbering. <br>
5829 * - \a nbOfOldTuples: 10
5830 * - \a arr : [0,3, 5,7,9]
5831 * - \a arrIBg : [0,2,5]
5832 * - \a newNbOfTuples: 7
5833 * - result array : [0,1,2,0,3,4,5,4,6,4]
5835 * \param [in] nbOfOldTuples - number of tuples in the initial array \a arr.
5836 * \param [in] arr - the array of tuple indices grouped by \a arrIBg array.
5837 * \param [in] arrIBg - the array dividing all indices stored in \a arr into groups of
5838 * (indices of) equal values. Its every element (except the last one) points to
5839 * the first element of a group of equal values.
5840 * \param [in] arrIEnd - specifies the end of \a arrIBg, so that the last element of \a
5841 * arrIBg is \a arrIEnd[ -1 ].
5842 * \param [out] newNbOfTuples - number of tuples after surjection application.
5843 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5844 * array using decrRef() as it is no more needed.
5845 * \throw If any value of \a arr breaks condition ( 0 <= \a arr[ i ] < \a nbOfOldTuples ).
5847 DataArrayInt *DataArrayInt::ConvertIndexArrayToO2N(int nbOfOldTuples, const int *arr, const int *arrIBg, const int *arrIEnd, int &newNbOfTuples)
5849 MCAuto<DataArrayInt> ret=DataArrayInt::New();
5850 ret->alloc(nbOfOldTuples,1);
5851 int *pt=ret->getPointer();
5852 std::fill(pt,pt+nbOfOldTuples,-1);
5853 int nbOfGrps=((int)std::distance(arrIBg,arrIEnd))-1;
5854 const int *cIPtr=arrIBg;
5855 for(int i=0;i<nbOfGrps;i++)
5856 pt[arr[cIPtr[i]]]=-(i+2);
5858 for(int iNode=0;iNode<nbOfOldTuples;iNode++)
5866 int grpId=-(pt[iNode]+2);
5867 for(int j=cIPtr[grpId];j<cIPtr[grpId+1];j++)
5869 if(arr[j]>=0 && arr[j]<nbOfOldTuples)
5873 std::ostringstream oss; oss << "DataArrayInt::ConvertIndexArrayToO2N : With element #" << j << " value is " << arr[j] << " should be in [0," << nbOfOldTuples << ") !";
5874 throw INTERP_KERNEL::Exception(oss.str().c_str());
5881 newNbOfTuples=newNb;
5886 * Returns a new DataArrayInt containing a renumbering map in "New to Old" mode,
5887 * which if applied to \a this array would make it sorted ascendingly.
5888 * For more info on renumbering see \ref numbering. <br>
5890 * - \a this: [2,0,1,1,0,1,2,0,1,1,0,0]
5891 * - result: [10,0,5,6,1,7,11,2,8,9,3,4]
5892 * - after applying result to \a this: [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2]
5894 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5895 * array using decrRef() as it is no more needed.
5896 * \throw If \a this is not allocated.
5897 * \throw If \a this->getNumberOfComponents() != 1.
5899 DataArrayInt *DataArrayInt::buildPermArrPerLevel() const
5902 if(getNumberOfComponents()!=1)
5903 throw INTERP_KERNEL::Exception("DataArrayInt::buildPermArrPerLevel : number of components must == 1 !");
5904 int nbOfTuples=getNumberOfTuples();
5905 const int *pt=getConstPointer();
5906 std::map<int,int> m;
5907 MCAuto<DataArrayInt> ret=DataArrayInt::New();
5908 ret->alloc(nbOfTuples,1);
5909 int *opt=ret->getPointer();
5910 for(int i=0;i<nbOfTuples;i++,pt++,opt++)
5913 std::map<int,int>::iterator it=m.find(val);
5922 m.insert(std::pair<int,int>(val,1));
5926 for(std::map<int,int>::iterator it=m.begin();it!=m.end();it++)
5928 int vt=(*it).second;
5932 pt=getConstPointer();
5933 opt=ret->getPointer();
5934 for(int i=0;i<nbOfTuples;i++,pt++,opt++)
5941 * Checks if \a this array has the given size, and if its contents is equal to an array filled with
5942 * iota(). This method is particularly useful for DataArrayInt instances that represent
5943 * a renumbering array, to check if there is a real need in renumbering.
5944 * This method checks than \a this can be considered as an identity mapping
5945 * of a set having \a sizeExpected elements into itself.
5947 * \param [in] sizeExpected - The number of elements expected.
5948 * \return bool - \a true if \a this array contents == \a range( \a this->getNumberOfTuples())
5949 * \throw If \a this is not allocated.
5950 * \throw If \a this->getNumberOfComponents() != 1.
5952 bool DataArrayInt::isIota(int sizeExpected) const
5955 if(getNumberOfComponents()!=1)
5957 int nbOfTuples(getNumberOfTuples());
5958 if(nbOfTuples!=sizeExpected)
5960 const int *pt=getConstPointer();
5961 for(int i=0;i<nbOfTuples;i++,pt++)
5968 * Checks if all values in \a this array are equal to \a val.
5969 * \param [in] val - value to check equality of array values to.
5970 * \return bool - \a true if all values are \a val.
5971 * \throw If \a this is not allocated.
5972 * \throw If \a this->getNumberOfComponents() != 1
5974 bool DataArrayInt::isUniform(int val) const
5977 if(getNumberOfComponents()!=1)
5978 throw INTERP_KERNEL::Exception("DataArrayInt::isUniform : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
5979 int nbOfTuples=getNumberOfTuples();
5980 const int *w=getConstPointer();
5981 const int *end2=w+nbOfTuples;
5989 * Checks if all values in \a this array are unique.
5990 * \return bool - \a true if condition above is true
5991 * \throw If \a this is not allocated.
5992 * \throw If \a this->getNumberOfComponents() != 1
5994 bool DataArrayInt::hasUniqueValues() const
5997 if(getNumberOfComponents()!=1)
5998 throw INTERP_KERNEL::Exception("DataArrayInt::hasOnlyUniqueValues: must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
5999 int nbOfTuples(getNumberOfTuples());
6000 std::set<int> s(begin(),end()); // in C++11, should use unordered_set (O(1) complexity)
6001 if (s.size() != nbOfTuples)
6007 * Appends components of another array to components of \a this one, tuple by tuple.
6008 * So that the number of tuples of \a this array remains the same and the number of
6009 * components increases.
6010 * \param [in] other - the DataArrayInt to append to \a this one.
6011 * \throw If \a this is not allocated.
6012 * \throw If \a this and \a other arrays have different number of tuples.
6014 * \if ENABLE_EXAMPLES
6015 * \ref cpp_mcdataarrayint_meldwith "Here is a C++ example".
6017 * \ref py_mcdataarrayint_meldwith "Here is a Python example".
6020 void DataArrayInt::meldWith(const DataArrayInt *other)
6023 throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : DataArrayInt pointer in input is NULL !");
6025 other->checkAllocated();
6026 int nbOfTuples=getNumberOfTuples();
6027 if(nbOfTuples!=other->getNumberOfTuples())
6028 throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : mismatch of number of tuples !");
6029 int nbOfComp1=getNumberOfComponents();
6030 int nbOfComp2=other->getNumberOfComponents();
6031 int *newArr=(int *)malloc(nbOfTuples*(nbOfComp1+nbOfComp2)*sizeof(int));
6033 const int *inp1=getConstPointer();
6034 const int *inp2=other->getConstPointer();
6035 for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
6037 w=std::copy(inp1,inp1+nbOfComp1,w);
6038 w=std::copy(inp2,inp2+nbOfComp2,w);
6040 useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
6041 std::vector<int> compIds(nbOfComp2);
6042 for(int i=0;i<nbOfComp2;i++)
6043 compIds[i]=nbOfComp1+i;
6044 copyPartOfStringInfoFrom2(compIds,*other);
6048 * Copy all components in a specified order from another DataArrayInt.
6049 * The specified components become the first ones in \a this array.
6050 * Both numerical and textual data is copied. The number of tuples in \a this and
6051 * the other array can be different.
6052 * \param [in] a - the array to copy data from.
6053 * \param [in] compoIds - sequence of zero based indices of components, data of which is
6055 * \throw If \a a is NULL.
6056 * \throw If \a compoIds.size() != \a a->getNumberOfComponents().
6057 * \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
6059 * \if ENABLE_EXAMPLES
6060 * \ref py_mcdataarrayint_setselectedcomponents "Here is a Python example".
6063 void DataArrayInt::setSelectedComponents(const DataArrayInt *a, const std::vector<int>& compoIds)
6066 throw INTERP_KERNEL::Exception("DataArrayInt::setSelectedComponents : input DataArrayInt is NULL !");
6068 a->checkAllocated();
6069 copyPartOfStringInfoFrom2(compoIds,*a);
6070 std::size_t partOfCompoSz=compoIds.size();
6071 int nbOfCompo=getNumberOfComponents();
6072 int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
6073 const int *ac=a->getConstPointer();
6074 int *nc=getPointer();
6075 for(int i=0;i<nbOfTuples;i++)
6076 for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
6077 nc[nbOfCompo*i+compoIds[j]]=*ac;
6081 * Assign pointer to one array to a pointer to another appay. Reference counter of
6082 * \a arrayToSet is incremented / decremented.
6083 * \param [in] newArray - the pointer to array to assign to \a arrayToSet.
6084 * \param [in,out] arrayToSet - the pointer to array to assign to.
6086 void DataArrayInt::SetArrayIn(DataArrayInt *newArray, DataArrayInt* &arrayToSet)
6088 if(newArray!=arrayToSet)
6091 arrayToSet->decrRef();
6092 arrayToSet=newArray;
6094 arrayToSet->incrRef();
6098 DataArrayIntIterator *DataArrayInt::iterator()
6100 return new DataArrayIntIterator(this);
6104 * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to a
6105 * given one. The ids are sorted in the ascending order.
6106 * \param [in] val - the value to find within \a this.
6107 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6108 * array using decrRef() as it is no more needed.
6109 * \throw If \a this is not allocated.
6110 * \throw If \a this->getNumberOfComponents() != 1.
6111 * \sa DataArrayInt::findIdsEqualTuple
6113 DataArrayInt *DataArrayInt::findIdsEqual(int val) const
6116 if(getNumberOfComponents()!=1)
6117 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqual : the array must have only one component, you can call 'rearrange' method before !");
6118 const int *cptr(getConstPointer());
6119 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6120 int nbOfTuples=getNumberOfTuples();
6121 for(int i=0;i<nbOfTuples;i++,cptr++)
6123 ret->pushBackSilent(i);
6128 * Creates a new DataArrayInt containing IDs (indices) of tuples holding value \b not
6129 * equal to a given one.
6130 * \param [in] val - the value to ignore within \a this.
6131 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6132 * array using decrRef() as it is no more needed.
6133 * \throw If \a this is not allocated.
6134 * \throw If \a this->getNumberOfComponents() != 1.
6136 DataArrayInt *DataArrayInt::findIdsNotEqual(int val) const
6139 if(getNumberOfComponents()!=1)
6140 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotEqual : the array must have only one component, you can call 'rearrange' method before !");
6141 const int *cptr(getConstPointer());
6142 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6143 int nbOfTuples=getNumberOfTuples();
6144 for(int i=0;i<nbOfTuples;i++,cptr++)
6146 ret->pushBackSilent(i);
6151 * Creates a new DataArrayInt containing IDs (indices) of tuples holding tuple equal to those defined by [ \a tupleBg , \a tupleEnd )
6152 * This method is an extension of DataArrayInt::findIdsEqual method.
6154 * \param [in] tupleBg - the begin (included) of the input tuple to find within \a this.
6155 * \param [in] tupleEnd - the end (excluded) of the input tuple to find within \a this.
6156 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6157 * array using decrRef() as it is no more needed.
6158 * \throw If \a this is not allocated.
6159 * \throw If \a this->getNumberOfComponents() != std::distance(tupleBg,tupleEnd).
6160 * \throw If \a this->getNumberOfComponents() is equal to 0.
6161 * \sa DataArrayInt::findIdsEqual
6163 DataArrayInt *DataArrayInt::findIdsEqualTuple(const int *tupleBg, const int *tupleEnd) const
6165 std::size_t nbOfCompoExp(std::distance(tupleBg,tupleEnd));
6167 if(getNumberOfComponents()!=(int)nbOfCompoExp)
6169 std::ostringstream oss; oss << "DataArrayInt::findIdsEqualTuple : mismatch of number of components. Input tuple has " << nbOfCompoExp << " whereas this array has " << getNumberOfComponents() << " components !";
6170 throw INTERP_KERNEL::Exception(oss.str().c_str());
6173 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqualTuple : number of components should be > 0 !");
6174 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6175 const int *bg(begin()),*end2(end()),*work(begin());
6178 work=std::search(work,end2,tupleBg,tupleEnd);
6181 std::size_t pos(std::distance(bg,work));
6182 if(pos%nbOfCompoExp==0)
6183 ret->pushBackSilent(pos/nbOfCompoExp);
6191 * Assigns \a newValue to all elements holding \a oldValue within \a this
6192 * one-dimensional array.
6193 * \param [in] oldValue - the value to replace.
6194 * \param [in] newValue - the value to assign.
6195 * \return int - number of replacements performed.
6196 * \throw If \a this is not allocated.
6197 * \throw If \a this->getNumberOfComponents() != 1.
6199 int DataArrayInt::changeValue(int oldValue, int newValue)
6202 if(getNumberOfComponents()!=1)
6203 throw INTERP_KERNEL::Exception("DataArrayInt::changeValue : the array must have only one component, you can call 'rearrange' method before !");
6204 if(oldValue==newValue)
6206 int *start(getPointer()),*end2(start+getNbOfElems());
6208 for(int *val=start;val!=end2;val++)
6222 * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to
6223 * one of given values.
6224 * \param [in] valsBg - an array of values to find within \a this array.
6225 * \param [in] valsEnd - specifies the end of the array \a valsBg, so that
6226 * the last value of \a valsBg is \a valsEnd[ -1 ].
6227 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6228 * array using decrRef() as it is no more needed.
6229 * \throw If \a this->getNumberOfComponents() != 1.
6231 DataArrayInt *DataArrayInt::findIdsEqualList(const int *valsBg, const int *valsEnd) const
6233 if(getNumberOfComponents()!=1)
6234 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqualList : the array must have only one component, you can call 'rearrange' method before !");
6235 std::set<int> vals2(valsBg,valsEnd);
6236 const int *cptr(getConstPointer());
6237 std::vector<int> res;
6238 int nbOfTuples(getNumberOfTuples());
6239 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6240 for(int i=0;i<nbOfTuples;i++,cptr++)
6241 if(vals2.find(*cptr)!=vals2.end())
6242 ret->pushBackSilent(i);
6247 * Creates a new DataArrayInt containing IDs (indices) of tuples holding values \b not
6248 * equal to any of given values.
6249 * \param [in] valsBg - an array of values to ignore within \a this array.
6250 * \param [in] valsEnd - specifies the end of the array \a valsBg, so that
6251 * the last value of \a valsBg is \a valsEnd[ -1 ].
6252 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6253 * array using decrRef() as it is no more needed.
6254 * \throw If \a this->getNumberOfComponents() != 1.
6256 DataArrayInt *DataArrayInt::findIdsNotEqualList(const int *valsBg, const int *valsEnd) const
6258 if(getNumberOfComponents()!=1)
6259 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotEqualList : the array must have only one component, you can call 'rearrange' method before !");
6260 std::set<int> vals2(valsBg,valsEnd);
6261 const int *cptr=getConstPointer();
6262 std::vector<int> res;
6263 int nbOfTuples=getNumberOfTuples();
6264 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6265 for(int i=0;i<nbOfTuples;i++,cptr++)
6266 if(vals2.find(*cptr)==vals2.end())
6267 ret->pushBackSilent(i);
6272 * This method is an extension of DataArrayInt::findIdFirstEqual method because this method works for DataArrayInt with
6273 * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
6274 * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
6275 * If any the tuple id is returned. If not -1 is returned.
6277 * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
6278 * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
6280 * \return tuple id where \b tupl is. -1 if no such tuple exists in \b this.
6281 * \sa DataArrayInt::findIdSequence, DataArrayInt::presenceOfTuple.
6283 int DataArrayInt::findIdFirstEqualTuple(const std::vector<int>& tupl) const
6286 int nbOfCompo=getNumberOfComponents();
6288 throw INTERP_KERNEL::Exception("DataArrayInt::findIdFirstEqualTuple : 0 components in 'this' !");
6289 if(nbOfCompo!=(int)tupl.size())
6291 std::ostringstream oss; oss << "DataArrayInt::findIdFirstEqualTuple : 'this' contains " << nbOfCompo << " components and searching for a tuple of length " << tupl.size() << " !";
6292 throw INTERP_KERNEL::Exception(oss.str().c_str());
6294 const int *cptr=getConstPointer();
6295 std::size_t nbOfVals=getNbOfElems();
6296 for(const int *work=cptr;work!=cptr+nbOfVals;)
6298 work=std::search(work,cptr+nbOfVals,tupl.begin(),tupl.end());
6299 if(work!=cptr+nbOfVals)
6301 if(std::distance(cptr,work)%nbOfCompo!=0)
6304 return std::distance(cptr,work)/nbOfCompo;
6311 * This method searches the sequence specified in input parameter \b vals in \b this.
6312 * This works only for DataArrayInt having number of components equal to one (if not an INTERP_KERNEL::Exception will be thrown).
6313 * This method differs from DataArrayInt::findIdFirstEqualTuple in that the position is internal raw data is not considered here contrary to DataArrayInt::findIdFirstEqualTuple.
6314 * \sa DataArrayInt::findIdFirstEqualTuple
6316 int DataArrayInt::findIdSequence(const std::vector<int>& vals) const
6319 int nbOfCompo=getNumberOfComponents();
6321 throw INTERP_KERNEL::Exception("DataArrayInt::findIdSequence : works only for DataArrayInt instance with one component !");
6322 const int *cptr=getConstPointer();
6323 std::size_t nbOfVals=getNbOfElems();
6324 const int *loc=std::search(cptr,cptr+nbOfVals,vals.begin(),vals.end());
6325 if(loc!=cptr+nbOfVals)
6326 return std::distance(cptr,loc);
6331 * This method expects to be called when number of components of this is equal to one.
6332 * This method returns the tuple id, if it exists, of the first tuple equal to \b value.
6333 * If not any tuple contains \b value -1 is returned.
6334 * \sa DataArrayInt::presenceOfValue
6336 int DataArrayInt::findIdFirstEqual(int value) const
6339 if(getNumberOfComponents()!=1)
6340 throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
6341 const int *cptr=getConstPointer();
6342 int nbOfTuples=getNumberOfTuples();
6343 const int *ret=std::find(cptr,cptr+nbOfTuples,value);
6344 if(ret!=cptr+nbOfTuples)
6345 return std::distance(cptr,ret);
6350 * This method expects to be called when number of components of this is equal to one.
6351 * This method returns the tuple id, if it exists, of the first tuple so that the value is contained in \b vals.
6352 * If not any tuple contains one of the values contained in 'vals' -1 is returned.
6353 * \sa DataArrayInt::presenceOfValue
6355 int DataArrayInt::findIdFirstEqual(const std::vector<int>& vals) const
6358 if(getNumberOfComponents()!=1)
6359 throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
6360 std::set<int> vals2(vals.begin(),vals.end());
6361 const int *cptr=getConstPointer();
6362 int nbOfTuples=getNumberOfTuples();
6363 for(const int *w=cptr;w!=cptr+nbOfTuples;w++)
6364 if(vals2.find(*w)!=vals2.end())
6365 return std::distance(cptr,w);
6370 * This method returns the number of values in \a this that are equals to input parameter \a value.
6371 * This method only works for single component array.
6373 * \return a value in [ 0, \c this->getNumberOfTuples() )
6375 * \throw If \a this is not allocated
6378 int DataArrayInt::count(int value) const
6382 if(getNumberOfComponents()!=1)
6383 throw INTERP_KERNEL::Exception("DataArrayInt::count : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
6384 const int *vals=begin();
6385 int nbOfTuples=getNumberOfTuples();
6386 for(int i=0;i<nbOfTuples;i++,vals++)
6393 * This method is an extension of DataArrayInt::presenceOfValue method because this method works for DataArrayInt with
6394 * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
6395 * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
6396 * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
6397 * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
6398 * \sa DataArrayInt::findIdFirstEqualTuple
6400 bool DataArrayInt::presenceOfTuple(const std::vector<int>& tupl) const
6402 return findIdFirstEqualTuple(tupl)!=-1;
6407 * Returns \a true if a given value is present within \a this one-dimensional array.
6408 * \param [in] value - the value to find within \a this array.
6409 * \return bool - \a true in case if \a value is present within \a this array.
6410 * \throw If \a this is not allocated.
6411 * \throw If \a this->getNumberOfComponents() != 1.
6412 * \sa findIdFirstEqual()
6414 bool DataArrayInt::presenceOfValue(int value) const
6416 return findIdFirstEqual(value)!=-1;
6420 * This method expects to be called when number of components of this is equal to one.
6421 * This method returns true if it exists a tuple so that the value is contained in \b vals.
6422 * If not any tuple contains one of the values contained in 'vals' false is returned.
6423 * \sa DataArrayInt::findIdFirstEqual
6425 bool DataArrayInt::presenceOfValue(const std::vector<int>& vals) const
6427 return findIdFirstEqual(vals)!=-1;
6431 * Accumulates values of each component of \a this array.
6432 * \param [out] res - an array of length \a this->getNumberOfComponents(), allocated
6433 * by the caller, that is filled by this method with sum value for each
6435 * \throw If \a this is not allocated.
6437 void DataArrayInt::accumulate(int *res) const
6440 const int *ptr=getConstPointer();
6441 int nbTuple=getNumberOfTuples();
6442 int nbComps=getNumberOfComponents();
6443 std::fill(res,res+nbComps,0);
6444 for(int i=0;i<nbTuple;i++)
6445 std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<int>());
6448 int DataArrayInt::accumulate(int compId) const
6451 const int *ptr=getConstPointer();
6452 int nbTuple=getNumberOfTuples();
6453 int nbComps=getNumberOfComponents();
6454 if(compId<0 || compId>=nbComps)
6455 throw INTERP_KERNEL::Exception("DataArrayInt::accumulate : Invalid compId specified : No such nb of components !");
6457 for(int i=0;i<nbTuple;i++)
6458 ret+=ptr[i*nbComps+compId];
6463 * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
6464 * The returned array will have same number of components than \a this and number of tuples equal to
6465 * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
6467 * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
6469 * \param [in] bgOfIndex - begin (included) of the input index array.
6470 * \param [in] endOfIndex - end (excluded) of the input index array.
6471 * \return DataArrayInt * - the new instance having the same number of components than \a this.
6473 * \throw If bgOfIndex or end is NULL.
6474 * \throw If input index array is not ascendingly sorted.
6475 * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
6476 * \throw If std::distance(bgOfIndex,endOfIndex)==0.
6478 DataArrayInt *DataArrayInt::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
6480 if(!bgOfIndex || !endOfIndex)
6481 throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : input pointer NULL !");
6483 int nbCompo=getNumberOfComponents();
6484 int nbOfTuples=getNumberOfTuples();
6485 int sz=(int)std::distance(bgOfIndex,endOfIndex);
6487 throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : invalid size of input index array !");
6489 MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(sz,nbCompo);
6490 const int *w=bgOfIndex;
6491 if(*w<0 || *w>=nbOfTuples)
6492 throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
6493 const int *srcPt=begin()+(*w)*nbCompo;
6494 int *tmp=ret->getPointer();
6495 for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
6497 std::fill(tmp,tmp+nbCompo,0);
6500 for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
6502 if(j>=0 && j<nbOfTuples)
6503 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<int>());
6506 std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
6507 throw INTERP_KERNEL::Exception(oss.str().c_str());
6513 std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
6514 throw INTERP_KERNEL::Exception(oss.str().c_str());
6517 ret->copyStringInfoFrom(*this);
6522 * Returns a new DataArrayInt by concatenating two given arrays, so that (1) the number
6523 * of tuples in the result array is <em> a1->getNumberOfTuples() + a2->getNumberOfTuples() -
6524 * offsetA2</em> and (2)
6525 * the number of component in the result array is same as that of each of given arrays.
6526 * First \a offsetA2 tuples of \a a2 are skipped and thus are missing from the result array.
6527 * Info on components is copied from the first of the given arrays. Number of components
6528 * in the given arrays must be the same.
6529 * \param [in] a1 - an array to include in the result array.
6530 * \param [in] a2 - another array to include in the result array.
6531 * \param [in] offsetA2 - number of tuples of \a a2 to skip.
6532 * \return DataArrayInt * - the new instance of DataArrayInt.
6533 * The caller is to delete this result array using decrRef() as it is no more
6535 * \throw If either \a a1 or \a a2 is NULL.
6536 * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
6538 DataArrayInt *DataArrayInt::Aggregate(const DataArrayInt *a1, const DataArrayInt *a2, int offsetA2)
6541 throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input DataArrayInt instance is NULL !");
6542 int nbOfComp=a1->getNumberOfComponents();
6543 if(nbOfComp!=a2->getNumberOfComponents())
6544 throw INTERP_KERNEL::Exception("Nb of components mismatch for array Aggregation !");
6545 int nbOfTuple1=a1->getNumberOfTuples();
6546 int nbOfTuple2=a2->getNumberOfTuples();
6547 DataArrayInt *ret=DataArrayInt::New();
6548 ret->alloc(nbOfTuple1+nbOfTuple2-offsetA2,nbOfComp);
6549 int *pt=std::copy(a1->getConstPointer(),a1->getConstPointer()+nbOfTuple1*nbOfComp,ret->getPointer());
6550 std::copy(a2->getConstPointer()+offsetA2*nbOfComp,a2->getConstPointer()+nbOfTuple2*nbOfComp,pt);
6551 ret->copyStringInfoFrom(*a1);
6556 * Returns a new DataArrayInt by concatenating all given arrays, so that (1) the number
6557 * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
6558 * the number of component in the result array is same as that of each of given arrays.
6559 * Info on components is copied from the first of the given arrays. Number of components
6560 * in the given arrays must be the same.
6561 * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it
6562 * not the object itself.
6563 * \param [in] arr - a sequence of arrays to include in the result array.
6564 * \return DataArrayInt * - the new instance of DataArrayInt.
6565 * The caller is to delete this result array using decrRef() as it is no more
6567 * \throw If all arrays within \a arr are NULL.
6568 * \throw If getNumberOfComponents() of arrays within \a arr.
6570 DataArrayInt *DataArrayInt::Aggregate(const std::vector<const DataArrayInt *>& arr)
6572 std::vector<const DataArrayInt *> a;
6573 for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
6577 throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input list must be NON EMPTY !");
6578 std::vector<const DataArrayInt *>::const_iterator it=a.begin();
6579 int nbOfComp=(*it)->getNumberOfComponents();
6580 int nbt=(*it++)->getNumberOfTuples();
6581 for(int i=1;it!=a.end();it++,i++)
6583 if((*it)->getNumberOfComponents()!=nbOfComp)
6584 throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : Nb of components mismatch for array aggregation !");
6585 nbt+=(*it)->getNumberOfTuples();
6587 MCAuto<DataArrayInt> ret=DataArrayInt::New();
6588 ret->alloc(nbt,nbOfComp);
6589 int *pt=ret->getPointer();
6590 for(it=a.begin();it!=a.end();it++)
6591 pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
6592 ret->copyStringInfoFrom(*(a[0]));
6597 * This method takes as input a list of DataArrayInt instances \a arrs that represent each a packed index arrays.
6598 * A packed index array is an allocated array with one component, and at least one tuple. The first element
6599 * of each array in \a arrs must be 0. Each array in \a arrs is expected to be increasingly monotonic.
6600 * 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.
6602 * \return DataArrayInt * - a new object to be managed by the caller.
6604 DataArrayInt *DataArrayInt::AggregateIndexes(const std::vector<const DataArrayInt *>& arrs)
6607 for(std::vector<const DataArrayInt *>::const_iterator it4=arrs.begin();it4!=arrs.end();it4++)
6611 (*it4)->checkAllocated();
6612 if((*it4)->getNumberOfComponents()!=1)
6614 std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of compo != 1 at pos " << std::distance(arrs.begin(),it4) << " !";
6615 throw INTERP_KERNEL::Exception(oss.str().c_str());
6617 int nbTupl=(*it4)->getNumberOfTuples();
6620 std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of tuples < 1 at pos " << std::distance(arrs.begin(),it4) << " !";
6621 throw INTERP_KERNEL::Exception(oss.str().c_str());
6623 if((*it4)->front()!=0)
6625 std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with front value != 0 at pos " << std::distance(arrs.begin(),it4) << " !";
6626 throw INTERP_KERNEL::Exception(oss.str().c_str());
6632 std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a null instance at pos " << std::distance(arrs.begin(),it4) << " !";
6633 throw INTERP_KERNEL::Exception(oss.str().c_str());
6637 throw INTERP_KERNEL::Exception("DataArrayInt::AggregateIndexes : input list must be NON EMPTY !");
6638 MCAuto<DataArrayInt> ret=DataArrayInt::New();
6639 ret->alloc(retSz,1);
6640 int *pt=ret->getPointer(); *pt++=0;
6641 for(std::vector<const DataArrayInt *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
6642 pt=std::transform((*it)->begin()+1,(*it)->end(),pt,std::bind2nd(std::plus<int>(),pt[-1]));
6643 ret->copyStringInfoFrom(*(arrs[0]));
6648 * Returns in a single walk in \a this the min value and the max value in \a this.
6649 * \a this is expected to be single component array.
6651 * \param [out] minValue - the min value in \a this.
6652 * \param [out] maxValue - the max value in \a this.
6654 * \sa getMinValueInArray, getMinValue, getMaxValueInArray, getMaxValue
6656 void DataArrayInt::getMinMaxValues(int& minValue, int& maxValue) const
6659 if(getNumberOfComponents()!=1)
6660 throw INTERP_KERNEL::Exception("DataArrayInt::getMinMaxValues : must be applied on DataArrayInt with only one component !");
6661 int nbTuples(getNumberOfTuples());
6662 const int *pt(begin());
6663 minValue=std::numeric_limits<int>::max(); maxValue=-std::numeric_limits<int>::max();
6664 for(int i=0;i<nbTuples;i++,pt++)
6674 * Converts every value of \a this array to its absolute value.
6675 * \b WARNING this method is non const. If a new DataArrayInt instance should be built containing the result of abs DataArrayInt::computeAbs
6676 * should be called instead.
6678 * \throw If \a this is not allocated.
6679 * \sa DataArrayInt::computeAbs
6681 void DataArrayInt::abs()
6684 int *ptr(getPointer());
6685 std::size_t nbOfElems(getNbOfElems());
6686 std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<int,int>(std::abs));
6691 * This method builds a new instance of \a this object containing the result of std::abs applied of all elements in \a this.
6692 * This method is a const method (that do not change any values in \a this) contrary to DataArrayInt::abs method.
6694 * \return DataArrayInt * - the new instance of DataArrayInt containing the
6695 * same number of tuples and component as \a this array.
6696 * The caller is to delete this result array using decrRef() as it is no more
6698 * \throw If \a this is not allocated.
6699 * \sa DataArrayInt::abs
6701 DataArrayInt *DataArrayInt::computeAbs() const
6704 DataArrayInt *newArr(DataArrayInt::New());
6705 int nbOfTuples(getNumberOfTuples());
6706 int nbOfComp(getNumberOfComponents());
6707 newArr->alloc(nbOfTuples,nbOfComp);
6708 std::transform(begin(),end(),newArr->getPointer(),std::ptr_fun<int,int>(std::abs));
6709 newArr->copyStringInfoFrom(*this);
6714 * Apply a liner function to a given component of \a this array, so that
6715 * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
6716 * \param [in] a - the first coefficient of the function.
6717 * \param [in] b - the second coefficient of the function.
6718 * \param [in] compoId - the index of component to modify.
6719 * \throw If \a this is not allocated.
6721 void DataArrayInt::applyLin(int a, int b, int compoId)
6724 int *ptr=getPointer()+compoId;
6725 int nbOfComp=getNumberOfComponents();
6726 int nbOfTuple=getNumberOfTuples();
6727 for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
6733 * Apply a liner function to all elements of \a this array, so that
6734 * an element _x_ becomes \f$ a * x + b \f$.
6735 * \param [in] a - the first coefficient of the function.
6736 * \param [in] b - the second coefficient of the function.
6737 * \throw If \a this is not allocated.
6739 void DataArrayInt::applyLin(int a, int b)
6742 int *ptr=getPointer();
6743 std::size_t nbOfElems=getNbOfElems();
6744 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
6750 * Returns a full copy of \a this array except that sign of all elements is reversed.
6751 * \return DataArrayInt * - the new instance of DataArrayInt containing the
6752 * same number of tuples and component as \a this array.
6753 * The caller is to delete this result array using decrRef() as it is no more
6755 * \throw If \a this is not allocated.
6757 DataArrayInt *DataArrayInt::negate() const
6760 DataArrayInt *newArr=DataArrayInt::New();
6761 int nbOfTuples=getNumberOfTuples();
6762 int nbOfComp=getNumberOfComponents();
6763 newArr->alloc(nbOfTuples,nbOfComp);
6764 const int *cptr=getConstPointer();
6765 std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<int>());
6766 newArr->copyStringInfoFrom(*this);
6771 * Modify all elements of \a this array, so that
6772 * an element _x_ becomes \f$ numerator / x \f$.
6773 * \warning If an exception is thrown because of presence of 0 element in \a this
6774 * array, all elements processed before detection of the zero element remain
6776 * \param [in] numerator - the numerator used to modify array elements.
6777 * \throw If \a this is not allocated.
6778 * \throw If there is an element equal to 0 in \a this array.
6780 void DataArrayInt::applyInv(int numerator)
6783 int *ptr=getPointer();
6784 std::size_t nbOfElems=getNbOfElems();
6785 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
6789 *ptr=numerator/(*ptr);
6793 std::ostringstream oss; oss << "DataArrayInt::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
6795 throw INTERP_KERNEL::Exception(oss.str().c_str());
6802 * Modify all elements of \a this array, so that
6803 * an element _x_ becomes \f$ x / val \f$.
6804 * \param [in] val - the denominator used to modify array elements.
6805 * \throw If \a this is not allocated.
6806 * \throw If \a val == 0.
6808 void DataArrayInt::applyDivideBy(int val)
6811 throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to divide by 0 !");
6813 int *ptr=getPointer();
6814 std::size_t nbOfElems=getNbOfElems();
6815 std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::divides<int>(),val));
6820 * Modify all elements of \a this array, so that
6821 * an element _x_ becomes <em> x % val </em>.
6822 * \param [in] val - the divisor used to modify array elements.
6823 * \throw If \a this is not allocated.
6824 * \throw If \a val <= 0.
6826 void DataArrayInt::applyModulus(int val)
6829 throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to operate modulus on value <= 0 !");
6831 int *ptr=getPointer();
6832 std::size_t nbOfElems=getNbOfElems();
6833 std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::modulus<int>(),val));
6839 GreatEqual(int v):_v(v) { }
6840 bool operator()(int v) const { return v>=_v; }
6846 GreaterThan(int v):_v(v) { }
6847 bool operator()(int v) const { return v>_v; }
6853 LowerEqual(int v):_v(v) { }
6854 bool operator()(int v) const { return v<=_v; }
6860 LowerThan(int v):_v(v) { }
6861 bool operator()(int v) const { return v<_v; }
6867 InRange(int a, int b):_a(a),_b(b) { }
6868 bool operator()(int v) const { return v>=_a && v<_b; }
6873 * This method works only on data array with one component.
6874 * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
6875 * this[*id] in [\b vmin,\b vmax)
6877 * \param [in] vmin begin of range. This value is included in range (included).
6878 * \param [in] vmax end of range. This value is \b not included in range (excluded).
6879 * \return a newly allocated data array that the caller should deal with.
6881 * \sa DataArrayInt::findIdsNotInRange , DataArrayInt::findIdsStricltyNegative
6883 DataArrayInt *DataArrayInt::findIdsInRange(int vmin, int vmax) const
6885 InRange ir(vmin,vmax);
6886 MCAuto<DataArrayInt> ret(findIdsAdv(ir));
6892 NotInRange(int a, int b):_a(a),_b(b) { }
6893 bool operator()(int v) const { return v<_a || v>=_b; }
6898 * This method works only on data array with one component.
6899 * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
6900 * this[*id] \b not in [\b vmin,\b vmax)
6902 * \param [in] vmin begin of range. This value is \b not included in range (excluded).
6903 * \param [in] vmax end of range. This value is included in range (included).
6904 * \return a newly allocated data array that the caller should deal with.
6906 * \sa DataArrayInt::findIdsInRange , DataArrayInt::findIdsStricltyNegative
6908 DataArrayInt *DataArrayInt::findIdsNotInRange(int vmin, int vmax) const
6910 NotInRange nir(vmin,vmax);
6911 MCAuto<DataArrayInt> ret(findIdsAdv(nir));
6916 * This method works only on data array with one component. This method returns a newly allocated array storing stored ascendantly of tuple ids in \a this so that this[id]<0.
6918 * \return a newly allocated data array that the caller should deal with.
6919 * \sa DataArrayInt::findIdsInRange
6921 DataArrayInt *DataArrayInt::findIdsStricltyNegative() const
6924 MCAuto<DataArrayInt> ret(findIdsAdv(lt));
6928 MCAuto<DataArrayInt> DataArrayInt::findIdsGreaterOrEqualTo(int val) const
6931 return findIdsAdv(ge);
6934 MCAuto<DataArrayInt> DataArrayInt::findIdsGreaterThan(int val) const
6936 GreaterThan gt(val);
6937 return findIdsAdv(gt);
6940 MCAuto<DataArrayInt> DataArrayInt::findIdsLowerOrEqualTo(int val) const
6943 return findIdsAdv(le);
6946 MCAuto<DataArrayInt> DataArrayInt::findIdsLowerThan(int val) const
6949 return findIdsAdv(lt);
6953 * This method works only on data array with one component.
6954 * 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.
6956 * \param [in] vmin begin of range. This value is included in range (included).
6957 * \param [in] vmax end of range. This value is \b not included in range (excluded).
6958 * \return if all ids in \a this are so that (*this)[i]==i for all i in [ 0, \c this->getNumberOfTuples() ). */
6959 bool DataArrayInt::checkAllIdsInRange(int vmin, int vmax) const
6962 if(getNumberOfComponents()!=1)
6963 throw INTERP_KERNEL::Exception("DataArrayInt::checkAllIdsInRange : this must have exactly one component !");
6964 int nbOfTuples=getNumberOfTuples();
6966 const int *cptr=getConstPointer();
6967 for(int i=0;i<nbOfTuples;i++,cptr++)
6969 if(*cptr>=vmin && *cptr<vmax)
6970 { ret=ret && *cptr==i; }
6973 std::ostringstream oss; oss << "DataArrayInt::checkAllIdsInRange : tuple #" << i << " has value " << *cptr << " should be in [" << vmin << "," << vmax << ") !";
6974 throw INTERP_KERNEL::Exception(oss.str().c_str());
6981 * Modify all elements of \a this array, so that
6982 * an element _x_ becomes <em> val % x </em>.
6983 * \warning If an exception is thrown because of presence of an element <= 0 in \a this
6984 * array, all elements processed before detection of the zero element remain
6986 * \param [in] val - the divident used to modify array elements.
6987 * \throw If \a this is not allocated.
6988 * \throw If there is an element equal to or less than 0 in \a this array.
6990 void DataArrayInt::applyRModulus(int val)
6993 int *ptr=getPointer();
6994 std::size_t nbOfElems=getNbOfElems();
6995 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
7003 std::ostringstream oss; oss << "DataArrayInt::applyRModulus : presence of value <=0 in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
7005 throw INTERP_KERNEL::Exception(oss.str().c_str());
7012 * Modify all elements of \a this array, so that
7013 * an element _x_ becomes <em> val ^ x </em>.
7014 * \param [in] val - the value used to apply pow on all array elements.
7015 * \throw If \a this is not allocated.
7016 * \throw If \a val < 0.
7018 void DataArrayInt::applyPow(int val)
7022 throw INTERP_KERNEL::Exception("DataArrayInt::applyPow : input pow in < 0 !");
7023 int *ptr=getPointer();
7024 std::size_t nbOfElems=getNbOfElems();
7027 std::fill(ptr,ptr+nbOfElems,1);
7030 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
7033 for(int j=0;j<val;j++)
7041 * Modify all elements of \a this array, so that
7042 * an element _x_ becomes \f$ val ^ x \f$.
7043 * \param [in] val - the value used to apply pow on all array elements.
7044 * \throw If \a this is not allocated.
7045 * \throw If there is an element < 0 in \a this array.
7046 * \warning If an exception is thrown because of presence of 0 element in \a this
7047 * array, all elements processed before detection of the zero element remain
7050 void DataArrayInt::applyRPow(int val)
7053 int *ptr=getPointer();
7054 std::size_t nbOfElems=getNbOfElems();
7055 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
7060 for(int j=0;j<*ptr;j++)
7066 std::ostringstream oss; oss << "DataArrayInt::applyRPow : presence of negative value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
7068 throw INTERP_KERNEL::Exception(oss.str().c_str());
7075 * Returns a new DataArrayInt by aggregating two given arrays, so that (1) the number
7076 * of components in the result array is a sum of the number of components of given arrays
7077 * and (2) the number of tuples in the result array is same as that of each of given
7078 * arrays. In other words the i-th tuple of result array includes all components of
7079 * i-th tuples of all given arrays.
7080 * Number of tuples in the given arrays must be the same.
7081 * \param [in] a1 - an array to include in the result array.
7082 * \param [in] a2 - another array to include in the result array.
7083 * \return DataArrayInt * - the new instance of DataArrayInt.
7084 * The caller is to delete this result array using decrRef() as it is no more
7086 * \throw If both \a a1 and \a a2 are NULL.
7087 * \throw If any given array is not allocated.
7088 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
7090 DataArrayInt *DataArrayInt::Meld(const DataArrayInt *a1, const DataArrayInt *a2)
7092 std::vector<const DataArrayInt *> arr(2);
7093 arr[0]=a1; arr[1]=a2;
7098 * Returns a new DataArrayInt by aggregating all given arrays, so that (1) the number
7099 * of components in the result array is a sum of the number of components of given arrays
7100 * and (2) the number of tuples in the result array is same as that of each of given
7101 * arrays. In other words the i-th tuple of result array includes all components of
7102 * i-th tuples of all given arrays.
7103 * Number of tuples in the given arrays must be the same.
7104 * \param [in] arr - a sequence of arrays to include in the result array.
7105 * \return DataArrayInt * - the new instance of DataArrayInt.
7106 * The caller is to delete this result array using decrRef() as it is no more
7108 * \throw If all arrays within \a arr are NULL.
7109 * \throw If any given array is not allocated.
7110 * \throw If getNumberOfTuples() of arrays within \a arr is different.
7112 DataArrayInt *DataArrayInt::Meld(const std::vector<const DataArrayInt *>& arr)
7114 std::vector<const DataArrayInt *> a;
7115 for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
7119 throw INTERP_KERNEL::Exception("DataArrayInt::Meld : array must be NON empty !");
7120 std::vector<const DataArrayInt *>::const_iterator it;
7121 for(it=a.begin();it!=a.end();it++)
7122 (*it)->checkAllocated();
7124 int nbOfTuples=(*it)->getNumberOfTuples();
7125 std::vector<int> nbc(a.size());
7126 std::vector<const int *> pts(a.size());
7127 nbc[0]=(*it)->getNumberOfComponents();
7128 pts[0]=(*it++)->getConstPointer();
7129 for(int i=1;it!=a.end();it++,i++)
7131 if(nbOfTuples!=(*it)->getNumberOfTuples())
7132 throw INTERP_KERNEL::Exception("DataArrayInt::meld : mismatch of number of tuples !");
7133 nbc[i]=(*it)->getNumberOfComponents();
7134 pts[i]=(*it)->getConstPointer();
7136 int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
7137 DataArrayInt *ret=DataArrayInt::New();
7138 ret->alloc(nbOfTuples,totalNbOfComp);
7139 int *retPtr=ret->getPointer();
7140 for(int i=0;i<nbOfTuples;i++)
7141 for(int j=0;j<(int)a.size();j++)
7143 retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
7147 for(int i=0;i<(int)a.size();i++)
7148 for(int j=0;j<nbc[i];j++,k++)
7149 ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j));
7154 * Returns a new DataArrayInt which is a minimal partition of elements of \a groups.
7155 * The i-th item of the result array is an ID of a set of elements belonging to a
7156 * unique set of groups, which the i-th element is a part of. This set of elements
7157 * belonging to a unique set of groups is called \a family, so the result array contains
7158 * IDs of families each element belongs to.
7160 * \b Example: if we have two groups of elements: \a group1 [0,4] and \a group2 [ 0,1,2 ],
7161 * then there are 3 families:
7162 * - \a family1 (with ID 1) contains element [0] belonging to ( \a group1 + \a group2 ),
7163 * - \a family2 (with ID 2) contains elements [4] belonging to ( \a group1 ),
7164 * - \a family3 (with ID 3) contains element [1,2] belonging to ( \a group2 ), <br>
7165 * and the result array contains IDs of families [ 1,3,3,0,2 ]. <br> Note a family ID 0 which
7166 * stands for the element #3 which is in none of groups.
7168 * \param [in] groups - sequence of groups of element IDs.
7169 * \param [in] newNb - total number of elements; it must be more than max ID of element
7171 * \param [out] fidsOfGroups - IDs of families the elements of each group belong to.
7172 * \return DataArrayInt * - a new instance of DataArrayInt containing IDs of families
7173 * each element with ID from range [0, \a newNb ) belongs to. The caller is to
7174 * delete this array using decrRef() as it is no more needed.
7175 * \throw If any element ID in \a groups violates condition ( 0 <= ID < \a newNb ).
7177 DataArrayInt *DataArrayInt::MakePartition(const std::vector<const DataArrayInt *>& groups, int newNb, std::vector< std::vector<int> >& fidsOfGroups)
7179 std::vector<const DataArrayInt *> groups2;
7180 for(std::vector<const DataArrayInt *>::const_iterator it4=groups.begin();it4!=groups.end();it4++)
7182 groups2.push_back(*it4);
7183 MCAuto<DataArrayInt> ret=DataArrayInt::New();
7184 ret->alloc(newNb,1);
7185 int *retPtr=ret->getPointer();
7186 std::fill(retPtr,retPtr+newNb,0);
7188 for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++)
7190 const int *ptr=(*iter)->getConstPointer();
7191 std::size_t nbOfElem=(*iter)->getNbOfElems();
7193 for(int j=0;j<sfid;j++)
7196 for(std::size_t i=0;i<nbOfElem;i++)
7198 if(ptr[i]>=0 && ptr[i]<newNb)
7200 if(retPtr[ptr[i]]==j)
7208 std::ostringstream oss; oss << "DataArrayInt::MakePartition : In group \"" << (*iter)->getName() << "\" in tuple #" << i << " value = " << ptr[i] << " ! Should be in [0," << newNb;
7210 throw INTERP_KERNEL::Exception(oss.str().c_str());
7217 fidsOfGroups.clear();
7218 fidsOfGroups.resize(groups2.size());
7220 for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++,grId++)
7223 const int *ptr=(*iter)->getConstPointer();
7224 std::size_t nbOfElem=(*iter)->getNbOfElems();
7225 for(const int *p=ptr;p!=ptr+nbOfElem;p++)
7226 tmp.insert(retPtr[*p]);
7227 fidsOfGroups[grId].insert(fidsOfGroups[grId].end(),tmp.begin(),tmp.end());
7233 * Returns a new DataArrayInt which contains all elements of given one-dimensional
7234 * arrays. The result array does not contain any duplicates and its values
7235 * are sorted in ascending order.
7236 * \param [in] arr - sequence of DataArrayInt's to unite.
7237 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7238 * array using decrRef() as it is no more needed.
7239 * \throw If any \a arr[i] is not allocated.
7240 * \throw If \a arr[i]->getNumberOfComponents() != 1.
7242 DataArrayInt *DataArrayInt::BuildUnion(const std::vector<const DataArrayInt *>& arr)
7244 std::vector<const DataArrayInt *> a;
7245 for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
7248 for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
7250 (*it)->checkAllocated();
7251 if((*it)->getNumberOfComponents()!=1)
7252 throw INTERP_KERNEL::Exception("DataArrayInt::BuildUnion : only single component allowed !");
7256 for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
7258 const int *pt=(*it)->getConstPointer();
7259 int nbOfTuples=(*it)->getNumberOfTuples();
7260 r.insert(pt,pt+nbOfTuples);
7262 DataArrayInt *ret=DataArrayInt::New();
7263 ret->alloc((int)r.size(),1);
7264 std::copy(r.begin(),r.end(),ret->getPointer());
7269 * Returns a new DataArrayInt which contains elements present in each of given one-dimensional
7270 * arrays. The result array does not contain any duplicates and its values
7271 * are sorted in ascending order.
7272 * \param [in] arr - sequence of DataArrayInt's to intersect.
7273 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7274 * array using decrRef() as it is no more needed.
7275 * \throw If any \a arr[i] is not allocated.
7276 * \throw If \a arr[i]->getNumberOfComponents() != 1.
7278 DataArrayInt *DataArrayInt::BuildIntersection(const std::vector<const DataArrayInt *>& arr)
7280 std::vector<const DataArrayInt *> a;
7281 for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
7284 for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
7286 (*it)->checkAllocated();
7287 if((*it)->getNumberOfComponents()!=1)
7288 throw INTERP_KERNEL::Exception("DataArrayInt::BuildIntersection : only single component allowed !");
7292 for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
7294 const int *pt=(*it)->getConstPointer();
7295 int nbOfTuples=(*it)->getNumberOfTuples();
7296 std::set<int> s1(pt,pt+nbOfTuples);
7300 std::set_intersection(r.begin(),r.end(),s1.begin(),s1.end(),inserter(r2,r2.end()));
7306 DataArrayInt *ret(DataArrayInt::New());
7307 ret->alloc((int)r.size(),1);
7308 std::copy(r.begin(),r.end(),ret->getPointer());
7313 namespace MEDCouplingImpl
7318 OpSwitchedOn(int *pt):_pt(pt),_cnt(0) { }
7319 void operator()(const bool& b) { if(b) *_pt++=_cnt; _cnt++; }
7328 OpSwitchedOff(int *pt):_pt(pt),_cnt(0) { }
7329 void operator()(const bool& b) { if(!b) *_pt++=_cnt; _cnt++; }
7338 * This method returns the list of ids in ascending mode so that v[id]==true.
7340 DataArrayInt *DataArrayInt::BuildListOfSwitchedOn(const std::vector<bool>& v)
7342 int sz((int)std::count(v.begin(),v.end(),true));
7343 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
7344 std::for_each(v.begin(),v.end(),MEDCouplingImpl::OpSwitchedOn(ret->getPointer()));
7349 * This method returns the list of ids in ascending mode so that v[id]==false.
7351 DataArrayInt *DataArrayInt::BuildListOfSwitchedOff(const std::vector<bool>& v)
7353 int sz((int)std::count(v.begin(),v.end(),false));
7354 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
7355 std::for_each(v.begin(),v.end(),MEDCouplingImpl::OpSwitchedOff(ret->getPointer()));
7360 * This method allows to put a vector of vector of integer into a more compact data stucture (skyline).
7361 * This method is not available into python because no available optimized data structure available to map std::vector< std::vector<int> >.
7363 * \param [in] v the input data structure to be translate into skyline format.
7364 * \param [out] data the first element of the skyline format. The user is expected to deal with newly allocated array.
7365 * \param [out] dataIndex the second element of the skyline format.
7367 void DataArrayInt::PutIntoToSkylineFrmt(const std::vector< std::vector<int> >& v, DataArrayInt *& data, DataArrayInt *& dataIndex)
7369 int sz((int)v.size());
7370 MCAuto<DataArrayInt> ret0(DataArrayInt::New()),ret1(DataArrayInt::New());
7371 ret1->alloc(sz+1,1);
7372 int *pt(ret1->getPointer()); *pt=0;
7373 for(int i=0;i<sz;i++,pt++)
7374 pt[1]=pt[0]+(int)v[i].size();
7375 ret0->alloc(ret1->back(),1);
7376 pt=ret0->getPointer();
7377 for(int i=0;i<sz;i++)
7378 pt=std::copy(v[i].begin(),v[i].end(),pt);
7379 data=ret0.retn(); dataIndex=ret1.retn();
7383 * Returns a new DataArrayInt which contains a complement of elements of \a this
7384 * one-dimensional array. I.e. the result array contains all elements from the range [0,
7385 * \a nbOfElement) not present in \a this array.
7386 * \param [in] nbOfElement - maximal size of the result array.
7387 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7388 * array using decrRef() as it is no more needed.
7389 * \throw If \a this is not allocated.
7390 * \throw If \a this->getNumberOfComponents() != 1.
7391 * \throw If any element \a x of \a this array violates condition ( 0 <= \a x < \a
7394 DataArrayInt *DataArrayInt::buildComplement(int nbOfElement) const
7397 if(getNumberOfComponents()!=1)
7398 throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : only single component allowed !");
7399 std::vector<bool> tmp(nbOfElement);
7400 const int *pt=getConstPointer();
7401 int nbOfTuples=getNumberOfTuples();
7402 for(const int *w=pt;w!=pt+nbOfTuples;w++)
7403 if(*w>=0 && *w<nbOfElement)
7406 throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : an element is not in valid range : [0,nbOfElement) !");
7407 int nbOfRetVal=(int)std::count(tmp.begin(),tmp.end(),false);
7408 DataArrayInt *ret=DataArrayInt::New();
7409 ret->alloc(nbOfRetVal,1);
7411 int *retPtr=ret->getPointer();
7412 for(int i=0;i<nbOfElement;i++)
7419 * Returns a new DataArrayInt containing elements of \a this one-dimensional missing
7420 * from an \a other one-dimensional array.
7421 * \param [in] other - a DataArrayInt containing elements not to include in the result array.
7422 * \return DataArrayInt * - a new instance of DataArrayInt with one component. The
7423 * caller is to delete this array using decrRef() as it is no more needed.
7424 * \throw If \a other is NULL.
7425 * \throw If \a other is not allocated.
7426 * \throw If \a other->getNumberOfComponents() != 1.
7427 * \throw If \a this is not allocated.
7428 * \throw If \a this->getNumberOfComponents() != 1.
7429 * \sa DataArrayInt::buildSubstractionOptimized()
7431 DataArrayInt *DataArrayInt::buildSubstraction(const DataArrayInt *other) const
7434 throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : DataArrayInt pointer in input is NULL !");
7436 other->checkAllocated();
7437 if(getNumberOfComponents()!=1)
7438 throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed !");
7439 if(other->getNumberOfComponents()!=1)
7440 throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed for other type !");
7441 const int *pt=getConstPointer();
7442 int nbOfTuples=getNumberOfTuples();
7443 std::set<int> s1(pt,pt+nbOfTuples);
7444 pt=other->getConstPointer();
7445 nbOfTuples=other->getNumberOfTuples();
7446 std::set<int> s2(pt,pt+nbOfTuples);
7448 std::set_difference(s1.begin(),s1.end(),s2.begin(),s2.end(),std::back_insert_iterator< std::vector<int> >(r));
7449 DataArrayInt *ret=DataArrayInt::New();
7450 ret->alloc((int)r.size(),1);
7451 std::copy(r.begin(),r.end(),ret->getPointer());
7456 * \a this is expected to have one component and to be sorted ascendingly (as for \a other).
7457 * \a other is expected to be a part of \a this. If not DataArrayInt::buildSubstraction should be called instead.
7459 * \param [in] other an array with one component and expected to be sorted ascendingly.
7460 * \ret list of ids in \a this but not in \a other.
7461 * \sa DataArrayInt::buildSubstraction
7463 DataArrayInt *DataArrayInt::buildSubstractionOptimized(const DataArrayInt *other) const
7465 static const char *MSG="DataArrayInt::buildSubstractionOptimized : only single component allowed !";
7466 if(!other) throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstractionOptimized : NULL input array !");
7467 checkAllocated(); other->checkAllocated();
7468 if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
7469 if(other->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
7470 const int *pt1Bg(begin()),*pt1End(end()),*pt2Bg(other->begin()),*pt2End(other->end());
7471 const int *work1(pt1Bg),*work2(pt2Bg);
7472 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
7473 for(;work1!=pt1End;work1++)
7475 if(work2!=pt2End && *work1==*work2)
7478 ret->pushBackSilent(*work1);
7485 * Returns a new DataArrayInt which contains all elements of \a this and a given
7486 * one-dimensional arrays. The result array does not contain any duplicates
7487 * and its values are sorted in ascending order.
7488 * \param [in] other - an array to unite with \a this one.
7489 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7490 * array using decrRef() as it is no more needed.
7491 * \throw If \a this or \a other is not allocated.
7492 * \throw If \a this->getNumberOfComponents() != 1.
7493 * \throw If \a other->getNumberOfComponents() != 1.
7495 DataArrayInt *DataArrayInt::buildUnion(const DataArrayInt *other) const
7497 std::vector<const DataArrayInt *>arrs(2);
7498 arrs[0]=this; arrs[1]=other;
7499 return BuildUnion(arrs);
7504 * Returns a new DataArrayInt which contains elements present in both \a this and a given
7505 * one-dimensional arrays. The result array does not contain any duplicates
7506 * and its values are sorted in ascending order.
7507 * \param [in] other - an array to intersect with \a this one.
7508 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7509 * array using decrRef() as it is no more needed.
7510 * \throw If \a this or \a other is not allocated.
7511 * \throw If \a this->getNumberOfComponents() != 1.
7512 * \throw If \a other->getNumberOfComponents() != 1.
7514 DataArrayInt *DataArrayInt::buildIntersection(const DataArrayInt *other) const
7516 std::vector<const DataArrayInt *>arrs(2);
7517 arrs[0]=this; arrs[1]=other;
7518 return BuildIntersection(arrs);
7522 * This method can be applied on allocated with one component DataArrayInt instance.
7523 * This method is typically relevant for sorted arrays. All consecutive duplicated items in \a this will appear only once in returned DataArrayInt instance.
7524 * 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]
7526 * \return a newly allocated array that contain the result of the unique operation applied on \a this.
7527 * \throw if \a this is not allocated or if \a this has not exactly one component.
7528 * \sa DataArrayInt::buildUniqueNotSorted
7530 DataArrayInt *DataArrayInt::buildUnique() const
7533 if(getNumberOfComponents()!=1)
7534 throw INTERP_KERNEL::Exception("DataArrayInt::buildUnique : only single component allowed !");
7535 int nbOfTuples=getNumberOfTuples();
7536 MCAuto<DataArrayInt> tmp=deepCopy();
7537 int *data=tmp->getPointer();
7538 int *last=std::unique(data,data+nbOfTuples);
7539 MCAuto<DataArrayInt> ret=DataArrayInt::New();
7540 ret->alloc(std::distance(data,last),1);
7541 std::copy(data,last,ret->getPointer());
7546 * This method can be applied on allocated with one component DataArrayInt instance.
7547 * This method keep elements only once by keeping the same order in \a this that is not expected to be sorted.
7549 * \return a newly allocated array that contain the result of the unique operation applied on \a this.
7551 * \throw if \a this is not allocated or if \a this has not exactly one component.
7553 * \sa DataArrayInt::buildUnique
7555 DataArrayInt *DataArrayInt::buildUniqueNotSorted() const
7558 if(getNumberOfComponents()!=1)
7559 throw INTERP_KERNEL::Exception("DataArrayInt::buildUniqueNotSorted : only single component allowed !");
7561 getMinMaxValues(minVal,maxVal);
7562 std::vector<bool> b(maxVal-minVal+1,false);
7563 const int *ptBg(begin()),*endBg(end());
7564 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
7565 for(const int *pt=ptBg;pt!=endBg;pt++)
7569 ret->pushBackSilent(*pt);
7573 ret->copyStringInfoFrom(*this);
7578 * Returns a new DataArrayInt which contains size of every of groups described by \a this
7579 * "index" array. Such "index" array is returned for example by
7580 * \ref MEDCoupling::MEDCouplingUMesh::buildDescendingConnectivity
7581 * "MEDCouplingUMesh::buildDescendingConnectivity" and
7582 * \ref MEDCoupling::MEDCouplingUMesh::getNodalConnectivityIndex
7583 * "MEDCouplingUMesh::getNodalConnectivityIndex" etc.
7584 * This method preforms the reverse operation of DataArrayInt::computeOffsetsFull.
7585 * \return DataArrayInt * - a new instance of DataArrayInt, whose number of tuples
7586 * equals to \a this->getNumberOfComponents() - 1, and number of components is 1.
7587 * The caller is to delete this array using decrRef() as it is no more needed.
7588 * \throw If \a this is not allocated.
7589 * \throw If \a this->getNumberOfComponents() != 1.
7590 * \throw If \a this->getNumberOfTuples() < 2.
7593 * - this contains [1,3,6,7,7,9,15]
7594 * - result array contains [2,3,1,0,2,6],
7595 * where 2 = 3 - 1, 3 = 6 - 3, 1 = 7 - 6 etc.
7597 * \sa DataArrayInt::computeOffsetsFull
7599 DataArrayInt *DataArrayInt::deltaShiftIndex() const
7602 if(getNumberOfComponents()!=1)
7603 throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : only single component allowed !");
7604 int nbOfTuples=getNumberOfTuples();
7606 throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : 1 tuple at least must be present in 'this' !");
7607 const int *ptr=getConstPointer();
7608 DataArrayInt *ret=DataArrayInt::New();
7609 ret->alloc(nbOfTuples-1,1);
7610 int *out=ret->getPointer();
7611 std::transform(ptr+1,ptr+nbOfTuples,ptr,out,std::minus<int>());
7616 * Modifies \a this one-dimensional array so that value of each element \a x
7617 * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
7618 * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number of tuples
7619 * and components remains the same.<br>
7620 * This method is useful for allToAllV in MPI with contiguous policy. This method
7621 * differs from computeOffsetsFull() in that the number of tuples is \b not changed by
7623 * \throw If \a this is not allocated.
7624 * \throw If \a this->getNumberOfComponents() != 1.
7627 * - Before \a this contains [3,5,1,2,0,8]
7628 * - After \a this contains [0,3,8,9,11,11]<br>
7629 * Note that the last element 19 = 11 + 8 is missing because size of \a this
7630 * array is retained and thus there is no space to store the last element.
7632 void DataArrayInt::computeOffsets()
7635 if(getNumberOfComponents()!=1)
7636 throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets : only single component allowed !");
7637 int nbOfTuples=getNumberOfTuples();
7640 int *work=getPointer();
7643 for(int i=1;i<nbOfTuples;i++)
7646 work[i]=work[i-1]+tmp;
7654 * Modifies \a this one-dimensional array so that value of each element \a x
7655 * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
7656 * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number
7657 * components remains the same and number of tuples is inceamented by one.<br>
7658 * This method is useful for allToAllV in MPI with contiguous policy. This method
7659 * differs from computeOffsets() in that the number of tuples is changed by this one.
7660 * This method preforms the reverse operation of DataArrayInt::deltaShiftIndex.
7661 * \throw If \a this is not allocated.
7662 * \throw If \a this->getNumberOfComponents() != 1.
7665 * - Before \a this contains [3,5,1,2,0,8]
7666 * - After \a this contains [0,3,8,9,11,11,19]<br>
7667 * \sa DataArrayInt::deltaShiftIndex
7669 void DataArrayInt::computeOffsetsFull()
7672 if(getNumberOfComponents()!=1)
7673 throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsetsFull : only single component allowed !");
7674 int nbOfTuples=getNumberOfTuples();
7675 int *ret=(int *)malloc((nbOfTuples+1)*sizeof(int));
7676 const int *work=getConstPointer();
7678 for(int i=0;i<nbOfTuples;i++)
7679 ret[i+1]=work[i]+ret[i];
7680 useArray(ret,true,C_DEALLOC,nbOfTuples+1,1);
7685 * Returns two new DataArrayInt instances whose contents is computed from that of \a this and \a listOfIds arrays as follows.
7686 * \a this is expected to be an offset format ( as returned by DataArrayInt::computeOffsetsFull ) that is to say with one component
7687 * and ** sorted strictly increasingly **. \a listOfIds is expected to be sorted ascendingly (not strictly needed for \a listOfIds).
7688 * This methods searches in \a this, considered as a set of contiguous \c this->getNumberOfComponents() ranges, all ids in \a listOfIds
7689 * filling completely one of the ranges in \a this.
7691 * \param [in] listOfIds a list of ids that has to be sorted ascendingly.
7692 * \param [out] rangeIdsFetched the range ids fetched
7693 * \param [out] idsInInputListThatFetch contains the list of ids in \a listOfIds that are \b fully included in a range in \a this. So
7694 * \a idsInInputListThatFetch is a part of input \a listOfIds.
7696 * \sa DataArrayInt::computeOffsetsFull
7699 * - \a this : [0,3,7,9,15,18]
7700 * - \a listOfIds contains [0,1,2,3,7,8,15,16,17]
7701 * - \a rangeIdsFetched result array: [0,2,4]
7702 * - \a idsInInputListThatFetch result array: [0,1,2,7,8,15,16,17]
7703 * In this example id 3 in input \a listOfIds is alone so it do not appear in output \a idsInInputListThatFetch.
7706 void DataArrayInt::findIdsRangesInListOfIds(const DataArrayInt *listOfIds, DataArrayInt *& rangeIdsFetched, DataArrayInt *& idsInInputListThatFetch) const
7709 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : input list of ids is null !");
7710 listOfIds->checkAllocated(); checkAllocated();
7711 if(listOfIds->getNumberOfComponents()!=1)
7712 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : input list of ids must have exactly one component !");
7713 if(getNumberOfComponents()!=1)
7714 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : this must have exactly one component !");
7715 MCAuto<DataArrayInt> ret0=DataArrayInt::New(); ret0->alloc(0,1);
7716 MCAuto<DataArrayInt> ret1=DataArrayInt::New(); ret1->alloc(0,1);
7717 const int *tupEnd(listOfIds->end()),*offBg(begin()),*offEnd(end()-1);
7718 const int *tupPtr(listOfIds->begin()),*offPtr(offBg);
7719 while(tupPtr!=tupEnd && offPtr!=offEnd)
7721 if(*tupPtr==*offPtr)
7724 while(i<offPtr[1] && *tupPtr==i && tupPtr!=tupEnd) { i++; tupPtr++; }
7727 ret0->pushBackSilent((int)std::distance(offBg,offPtr));
7728 ret1->pushBackValsSilent(tupPtr-(offPtr[1]-offPtr[0]),tupPtr);
7733 { if(*tupPtr<*offPtr) tupPtr++; else offPtr++; }
7735 rangeIdsFetched=ret0.retn();
7736 idsInInputListThatFetch=ret1.retn();
7740 * Returns a new DataArrayInt whose contents is computed from that of \a this and \a
7741 * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
7742 * "index" array of a "iota" array, thus, whose each element gives an index of a group
7743 * beginning within the "iota" array. And \a this is a one-dimensional array
7744 * considered as a selector of groups described by \a offsets to include into the result array.
7745 * \throw If \a offsets is NULL.
7746 * \throw If \a offsets is not allocated.
7747 * \throw If \a offsets->getNumberOfComponents() != 1.
7748 * \throw If \a offsets is not monotonically increasing.
7749 * \throw If \a this is not allocated.
7750 * \throw If \a this->getNumberOfComponents() != 1.
7751 * \throw If any element of \a this is not a valid index for \a offsets array.
7754 * - \a this: [0,2,3]
7755 * - \a offsets: [0,3,6,10,14,20]
7756 * - result array: [0,1,2,6,7,8,9,10,11,12,13] == <br>
7757 * \c range(0,3) + \c range(6,10) + \c range(10,14) ==<br>
7758 * \c range( \a offsets[ \a this[0] ], offsets[ \a this[0]+1 ]) +
7759 * \c range( \a offsets[ \a this[1] ], offsets[ \a this[1]+1 ]) +
7760 * \c range( \a offsets[ \a this[2] ], offsets[ \a this[2]+1 ])
7762 DataArrayInt *DataArrayInt::buildExplicitArrByRanges(const DataArrayInt *offsets) const
7765 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : DataArrayInt pointer in input is NULL !");
7767 if(getNumberOfComponents()!=1)
7768 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : only single component allowed !");
7769 offsets->checkAllocated();
7770 if(offsets->getNumberOfComponents()!=1)
7771 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : input array should have only single component !");
7772 int othNbTuples=offsets->getNumberOfTuples()-1;
7773 int nbOfTuples=getNumberOfTuples();
7774 int retNbOftuples=0;
7775 const int *work=getConstPointer();
7776 const int *offPtr=offsets->getConstPointer();
7777 for(int i=0;i<nbOfTuples;i++)
7780 if(val>=0 && val<othNbTuples)
7782 int delta=offPtr[val+1]-offPtr[val];
7784 retNbOftuples+=delta;
7787 std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << val << " of offset array has a delta < 0 !";
7788 throw INTERP_KERNEL::Exception(oss.str().c_str());
7793 std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << i << " in this contains " << val;
7794 oss << " whereas offsets array is of size " << othNbTuples+1 << " !";
7795 throw INTERP_KERNEL::Exception(oss.str().c_str());
7798 MCAuto<DataArrayInt> ret=DataArrayInt::New();
7799 ret->alloc(retNbOftuples,1);
7800 int *retPtr=ret->getPointer();
7801 for(int i=0;i<nbOfTuples;i++)
7804 int start=offPtr[val];
7805 int off=offPtr[val+1]-start;
7806 for(int j=0;j<off;j++,retPtr++)
7813 * Returns a new DataArrayInt whose contents is computed using \a this that must be a
7814 * scaled array (monotonically increasing).
7815 from that of \a this and \a
7816 * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
7817 * "index" array of a "iota" array, thus, whose each element gives an index of a group
7818 * beginning within the "iota" array. And \a this is a one-dimensional array
7819 * considered as a selector of groups described by \a offsets to include into the result array.
7820 * \throw If \a is NULL.
7821 * \throw If \a this is not allocated.
7822 * \throw If \a this->getNumberOfComponents() != 1.
7823 * \throw If \a this->getNumberOfTuples() == 0.
7824 * \throw If \a this is not monotonically increasing.
7825 * \throw If any element of ids in ( \a bg \a stop \a step ) points outside the scale in \a this.
7828 * - \a bg , \a stop and \a step : (0,5,2)
7829 * - \a this: [0,3,6,10,14,20]
7830 * - result array: [0,0,0, 2,2,2,2, 4,4,4,4,4,4] == <br>
7832 DataArrayInt *DataArrayInt::buildExplicitArrOfSliceOnScaledArr(int bg, int stop, int step) const
7835 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : not allocated array !");
7836 if(getNumberOfComponents()!=1)
7837 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of components is expected to be equal to one !");
7838 int nbOfTuples(getNumberOfTuples());
7840 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of tuples must be != 0 !");
7841 const int *ids(begin());
7842 int nbOfEltsInSlc(GetNumberOfItemGivenBESRelative(bg,stop,step,"DataArrayInt::buildExplicitArrOfSliceOnScaledArr")),sz(0),pos(bg);
7843 for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
7845 if(pos>=0 && pos<nbOfTuples-1)
7847 int delta(ids[pos+1]-ids[pos]);
7851 std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " and at this pos this is not monotonically increasing !";
7852 throw INTERP_KERNEL::Exception(oss.str().c_str());
7857 std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " should be in [0," << nbOfTuples-1 << ") !";
7858 throw INTERP_KERNEL::Exception(oss.str().c_str());
7861 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
7862 int *retPtr(ret->getPointer());
7864 for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
7866 int delta(ids[pos+1]-ids[pos]);
7867 for(int j=0;j<delta;j++,retPtr++)
7874 * 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.
7875 * 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
7876 * in tuple **i** of returned DataArrayInt.
7877 * If ranges overlapped (in theory it should not) this method do not detect it and always returns the first range.
7879 * 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)]
7880 * The return DataArrayInt will contain : **[0,4,1,2,2,3]**
7882 * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
7883 * for lower value included and 2nd component is the upper value of corresponding range **excluded**.
7884 * \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
7885 * is thrown if no ranges in \a ranges contains value in \a this.
7887 * \sa DataArrayInt::findIdInRangeForEachTuple
7889 DataArrayInt *DataArrayInt::findRangeIdForEachTuple(const DataArrayInt *ranges) const
7892 throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : null input pointer !");
7893 if(ranges->getNumberOfComponents()!=2)
7894 throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : input DataArrayInt instance should have 2 components !");
7896 if(getNumberOfComponents()!=1)
7897 throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : this should have only one component !");
7898 int nbTuples=getNumberOfTuples();
7899 MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
7900 int nbOfRanges=ranges->getNumberOfTuples();
7901 const int *rangesPtr=ranges->getConstPointer();
7902 int *retPtr=ret->getPointer();
7903 const int *inPtr=getConstPointer();
7904 for(int i=0;i<nbTuples;i++,retPtr++)
7908 for(int j=0;j<nbOfRanges && !found;j++)
7909 if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
7910 { *retPtr=j; found=true; }
7915 std::ostringstream oss; oss << "DataArrayInt::findRangeIdForEachTuple : tuple #" << i << " not found by any ranges !";
7916 throw INTERP_KERNEL::Exception(oss.str().c_str());
7923 * 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.
7924 * 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
7925 * in tuple **i** of returned DataArrayInt.
7926 * If ranges overlapped (in theory it should not) this method do not detect it and always returns the sub position of the first range.
7928 * 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)]
7929 * The return DataArrayInt will contain : **[1,2,4,0,2,2]**
7930 * This method is often called in pair with DataArrayInt::findRangeIdForEachTuple method.
7932 * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
7933 * for lower value included and 2nd component is the upper value of corresponding range **excluded**.
7934 * \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
7935 * is thrown if no ranges in \a ranges contains value in \a this.
7936 * \sa DataArrayInt::findRangeIdForEachTuple
7938 DataArrayInt *DataArrayInt::findIdInRangeForEachTuple(const DataArrayInt *ranges) const
7941 throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : null input pointer !");
7942 if(ranges->getNumberOfComponents()!=2)
7943 throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : input DataArrayInt instance should have 2 components !");
7945 if(getNumberOfComponents()!=1)
7946 throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : this should have only one component !");
7947 int nbTuples=getNumberOfTuples();
7948 MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
7949 int nbOfRanges=ranges->getNumberOfTuples();
7950 const int *rangesPtr=ranges->getConstPointer();
7951 int *retPtr=ret->getPointer();
7952 const int *inPtr=getConstPointer();
7953 for(int i=0;i<nbTuples;i++,retPtr++)
7957 for(int j=0;j<nbOfRanges && !found;j++)
7958 if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
7959 { *retPtr=val-rangesPtr[2*j]; found=true; }
7964 std::ostringstream oss; oss << "DataArrayInt::findIdInRangeForEachTuple : tuple #" << i << " not found by any ranges !";
7965 throw INTERP_KERNEL::Exception(oss.str().c_str());
7972 * \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).
7973 * 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).
7974 * 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 !
7975 * If this method has correctly worked, \a this will be able to be considered as a linked list.
7976 * This method does nothing if number of tuples is lower of equal to 1.
7978 * This method is useful for users having an unstructured mesh having only SEG2 to rearrange internaly the connectibity without any coordinates consideration.
7980 * \sa MEDCouplingUMesh::orderConsecutiveCells1D, DataArrayInt::fromLinkedListOfPairToList
7982 void DataArrayInt::sortEachPairToMakeALinkedList()
7985 if(getNumberOfComponents()!=2)
7986 throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : Only works on DataArrayInt instance with nb of components equal to 2 !");
7987 int nbOfTuples(getNumberOfTuples());
7990 int *conn(getPointer());
7991 for(int i=1;i<nbOfTuples;i++,conn+=2)
7995 if(conn[2]==conn[3])
7997 std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " presence of a pair filled with same ids !";
7998 throw INTERP_KERNEL::Exception(oss.str().c_str());
8000 if(conn[2]!=conn[1] && conn[3]==conn[1] && conn[2]!=conn[0])
8001 std::swap(conn[2],conn[3]);
8002 //not(conn[2]==conn[1] && conn[3]!=conn[1] && conn[3]!=conn[0])
8003 if(conn[2]!=conn[1] || conn[3]==conn[1] || conn[3]==conn[0])
8005 std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " something is invalid !";
8006 throw INTERP_KERNEL::Exception(oss.str().c_str());
8011 if(conn[0]==conn[1] || conn[2]==conn[3])
8012 throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : In the 2 first tuples presence of a pair filled with same ids !");
8015 s.insert(conn,conn+4);
8017 throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : This can't be considered as a linked list regarding 2 first tuples !");
8018 if(std::count(conn,conn+4,conn[0])==2)
8023 if(conn[2]==conn[0])
8027 std::copy(tmp,tmp+4,conn);
8030 {//here we are sure to have (std::count(conn,conn+4,conn[1])==2)
8031 if(conn[1]==conn[3])
8032 std::swap(conn[2],conn[3]);
8039 * \a this is expected to be a correctly linked list of pairs.
8041 * \sa DataArrayInt::sortEachPairToMakeALinkedList
8043 MCAuto<DataArrayInt> DataArrayInt::fromLinkedListOfPairToList() const
8046 checkNbOfComps(2,"DataArrayInt::fromLinkedListOfPairToList : this is expected to have 2 components");
8047 int nbTuples(getNumberOfTuples());
8049 throw INTERP_KERNEL::Exception("DataArrayInt::fromLinkedListOfPairToList : no tuples in this ! Not a linked list !");
8050 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbTuples+1,1);
8051 const int *thisPtr(begin());
8052 int *retPtr(ret->getPointer());
8053 retPtr[0]=thisPtr[0];
8054 for(int i=0;i<nbTuples;i++)
8056 retPtr[i+1]=thisPtr[2*i+1];
8058 if(thisPtr[2*i+1]!=thisPtr[2*(i+1)+0])
8060 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 ?";
8061 throw INTERP_KERNEL::Exception(oss.str());
8069 * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayInt instance.
8070 * \a nbTimes should be at least equal to 1.
8071 * \return a newly allocated DataArrayInt having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
8072 * \throw if \a this is not allocated or if \a this has not number of components set to one or if \a nbTimes is lower than 1.
8074 DataArrayInt *DataArrayInt::duplicateEachTupleNTimes(int nbTimes) const
8077 if(getNumberOfComponents()!=1)
8078 throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : this should have only one component !");
8080 throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : nb times should be >= 1 !");
8081 int nbTuples=getNumberOfTuples();
8082 const int *inPtr=getConstPointer();
8083 MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTimes*nbTuples,1);
8084 int *retPtr=ret->getPointer();
8085 for(int i=0;i<nbTuples;i++,inPtr++)
8088 for(int j=0;j<nbTimes;j++,retPtr++)
8091 ret->copyStringInfoFrom(*this);
8096 * This method returns all different values found in \a this. This method throws if \a this has not been allocated.
8097 * But the number of components can be different from one.
8098 * \return a newly allocated array (that should be dealt by the caller) containing different values in \a this.
8100 DataArrayInt *DataArrayInt::getDifferentValues() const
8104 ret.insert(begin(),end());
8105 MCAuto<DataArrayInt> ret2=DataArrayInt::New(); ret2->alloc((int)ret.size(),1);
8106 std::copy(ret.begin(),ret.end(),ret2->getPointer());
8111 * This method is a refinement of DataArrayInt::getDifferentValues because it returns not only different values in \a this but also, for each of
8112 * them it tells which tuple id have this id.
8113 * This method works only on arrays with one component (if it is not the case call DataArrayInt::rearrange(1) ).
8114 * This method returns two arrays having same size.
8115 * 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.
8116 * 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]]
8118 std::vector<DataArrayInt *> DataArrayInt::partitionByDifferentValues(std::vector<int>& differentIds) const
8121 if(getNumberOfComponents()!=1)
8122 throw INTERP_KERNEL::Exception("DataArrayInt::partitionByDifferentValues : this should have only one component !");
8124 std::map<int,int> m,m2,m3;
8125 for(const int *w=begin();w!=end();w++)
8127 differentIds.resize(m.size());
8128 std::vector<DataArrayInt *> ret(m.size());
8129 std::vector<int *> retPtr(m.size());
8130 for(std::map<int,int>::const_iterator it=m.begin();it!=m.end();it++,id++)
8133 ret[id]=DataArrayInt::New();
8134 ret[id]->alloc((*it).second,1);
8135 retPtr[id]=ret[id]->getPointer();
8136 differentIds[id]=(*it).first;
8139 for(const int *w=begin();w!=end();w++,id++)
8141 retPtr[m2[*w]][m3[*w]++]=id;
8147 * This method split ids in [0, \c this->getNumberOfTuples() ) using \a this array as a field of weight (>=0 each).
8148 * The aim of this method is to return a set of \a nbOfSlices chunk of contiguous ids as balanced as possible.
8150 * \param [in] nbOfSlices - number of slices expected.
8151 * \return - a vector having a size equal to \a nbOfSlices giving the start (included) and the stop (excluded) of each chunks.
8153 * \sa DataArray::GetSlice
8154 * \throw If \a this is not allocated or not with exactly one component.
8155 * \throw If an element in \a this if < 0.
8157 std::vector< std::pair<int,int> > DataArrayInt::splitInBalancedSlices(int nbOfSlices) const
8159 if(!isAllocated() || getNumberOfComponents()!=1)
8160 throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : this array should have number of components equal to one and must be allocated !");
8162 throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : number of slices must be >= 1 !");
8163 int sum(accumulate(0)),nbOfTuples(getNumberOfTuples());
8164 int sumPerSlc(sum/nbOfSlices),pos(0);
8165 const int *w(begin());
8166 std::vector< std::pair<int,int> > ret(nbOfSlices);
8167 for(int i=0;i<nbOfSlices;i++)
8169 std::pair<int,int> p(pos,-1);
8171 while(locSum<sumPerSlc && pos<nbOfTuples) { pos++; locSum+=*w++; }
8175 p.second=nbOfTuples;
8182 * Returns a new DataArrayInt that is a sum of two given arrays. There are 3
8184 * 1. The arrays have same number of tuples and components. Then each value of
8185 * the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
8186 * i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
8187 * 2. The arrays have same number of tuples and one array, say _a2_, has one
8189 * _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
8190 * 3. The arrays have same number of components and one array, say _a2_, has one
8192 * _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
8194 * Info on components is copied either from the first array (in the first case) or from
8195 * the array with maximal number of elements (getNbOfElems()).
8196 * \param [in] a1 - an array to sum up.
8197 * \param [in] a2 - another array to sum up.
8198 * \return DataArrayInt * - the new instance of DataArrayInt.
8199 * The caller is to delete this result array using decrRef() as it is no more
8201 * \throw If either \a a1 or \a a2 is NULL.
8202 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
8203 * \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
8204 * none of them has number of tuples or components equal to 1.
8206 DataArrayInt *DataArrayInt::Add(const DataArrayInt *a1, const DataArrayInt *a2)
8209 throw INTERP_KERNEL::Exception("DataArrayInt::Add : input DataArrayInt instance is NULL !");
8210 int nbOfTuple=a1->getNumberOfTuples();
8211 int nbOfTuple2=a2->getNumberOfTuples();
8212 int nbOfComp=a1->getNumberOfComponents();
8213 int nbOfComp2=a2->getNumberOfComponents();
8214 MCAuto<DataArrayInt> ret=0;
8215 if(nbOfTuple==nbOfTuple2)
8217 if(nbOfComp==nbOfComp2)
8219 ret=DataArrayInt::New();
8220 ret->alloc(nbOfTuple,nbOfComp);
8221 std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<int>());
8222 ret->copyStringInfoFrom(*a1);
8226 int nbOfCompMin,nbOfCompMax;
8227 const DataArrayInt *aMin, *aMax;
8228 if(nbOfComp>nbOfComp2)
8230 nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
8235 nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
8240 ret=DataArrayInt::New();
8241 ret->alloc(nbOfTuple,nbOfCompMax);
8242 const int *aMinPtr=aMin->getConstPointer();
8243 const int *aMaxPtr=aMax->getConstPointer();
8244 int *res=ret->getPointer();
8245 for(int i=0;i<nbOfTuple;i++)
8246 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<int>(),aMinPtr[i]));
8247 ret->copyStringInfoFrom(*aMax);
8250 throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
8253 else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
8255 if(nbOfComp==nbOfComp2)
8257 int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
8258 const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
8259 const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
8260 const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
8261 ret=DataArrayInt::New();
8262 ret->alloc(nbOfTupleMax,nbOfComp);
8263 int *res=ret->getPointer();
8264 for(int i=0;i<nbOfTupleMax;i++)
8265 res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<int>());
8266 ret->copyStringInfoFrom(*aMax);
8269 throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
8272 throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
8277 * Adds values of another DataArrayInt to values of \a this one. There are 3
8279 * 1. The arrays have same number of tuples and components. Then each value of
8280 * \a other array is added to the corresponding value of \a this array, i.e.:
8281 * _a_ [ i, j ] += _other_ [ i, j ].
8282 * 2. The arrays have same number of tuples and \a other array has one component. Then
8283 * _a_ [ i, j ] += _other_ [ i, 0 ].
8284 * 3. The arrays have same number of components and \a other array has one tuple. Then
8285 * _a_ [ i, j ] += _a2_ [ 0, j ].
8287 * \param [in] other - an array to add to \a this one.
8288 * \throw If \a other is NULL.
8289 * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
8290 * \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
8291 * \a other has number of both tuples and components not equal to 1.
8293 void DataArrayInt::addEqual(const DataArrayInt *other)
8296 throw INTERP_KERNEL::Exception("DataArrayInt::addEqual : input DataArrayInt instance is NULL !");
8297 const char *msg="Nb of tuples mismatch for DataArrayInt::addEqual !";
8298 checkAllocated(); other->checkAllocated();
8299 int nbOfTuple=getNumberOfTuples();
8300 int nbOfTuple2=other->getNumberOfTuples();
8301 int nbOfComp=getNumberOfComponents();
8302 int nbOfComp2=other->getNumberOfComponents();
8303 if(nbOfTuple==nbOfTuple2)
8305 if(nbOfComp==nbOfComp2)
8307 std::transform(begin(),end(),other->begin(),getPointer(),std::plus<int>());
8309 else if(nbOfComp2==1)
8311 int *ptr=getPointer();
8312 const int *ptrc=other->getConstPointer();
8313 for(int i=0;i<nbOfTuple;i++)
8314 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<int>(),*ptrc++));
8317 throw INTERP_KERNEL::Exception(msg);
8319 else if(nbOfTuple2==1)
8321 if(nbOfComp2==nbOfComp)
8323 int *ptr=getPointer();
8324 const int *ptrc=other->getConstPointer();
8325 for(int i=0;i<nbOfTuple;i++)
8326 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<int>());
8329 throw INTERP_KERNEL::Exception(msg);
8332 throw INTERP_KERNEL::Exception(msg);
8337 * Returns a new DataArrayInt that is a subtraction of two given arrays. There are 3
8339 * 1. The arrays have same number of tuples and components. Then each value of
8340 * the result array (_a_) is a subtraction of the corresponding values of \a a1 and
8341 * \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
8342 * 2. The arrays have same number of tuples and one array, say _a2_, has one
8344 * _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
8345 * 3. The arrays have same number of components and one array, say _a2_, has one
8347 * _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
8349 * Info on components is copied either from the first array (in the first case) or from
8350 * the array with maximal number of elements (getNbOfElems()).
8351 * \param [in] a1 - an array to subtract from.
8352 * \param [in] a2 - an array to subtract.
8353 * \return DataArrayInt * - the new instance of DataArrayInt.
8354 * The caller is to delete this result array using decrRef() as it is no more
8356 * \throw If either \a a1 or \a a2 is NULL.
8357 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
8358 * \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
8359 * none of them has number of tuples or components equal to 1.
8361 DataArrayInt *DataArrayInt::Substract(const DataArrayInt *a1, const DataArrayInt *a2)
8364 throw INTERP_KERNEL::Exception("DataArrayInt::Substract : input DataArrayInt instance is NULL !");
8365 int nbOfTuple1=a1->getNumberOfTuples();
8366 int nbOfTuple2=a2->getNumberOfTuples();
8367 int nbOfComp1=a1->getNumberOfComponents();
8368 int nbOfComp2=a2->getNumberOfComponents();
8369 if(nbOfTuple2==nbOfTuple1)
8371 if(nbOfComp1==nbOfComp2)
8373 MCAuto<DataArrayInt> ret=DataArrayInt::New();
8374 ret->alloc(nbOfTuple2,nbOfComp1);
8375 std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<int>());
8376 ret->copyStringInfoFrom(*a1);
8379 else if(nbOfComp2==1)
8381 MCAuto<DataArrayInt> ret=DataArrayInt::New();
8382 ret->alloc(nbOfTuple1,nbOfComp1);
8383 const int *a2Ptr=a2->getConstPointer();
8384 const int *a1Ptr=a1->getConstPointer();
8385 int *res=ret->getPointer();
8386 for(int i=0;i<nbOfTuple1;i++)
8387 res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<int>(),a2Ptr[i]));
8388 ret->copyStringInfoFrom(*a1);
8393 a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
8397 else if(nbOfTuple2==1)
8399 a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
8400 MCAuto<DataArrayInt> ret=DataArrayInt::New();
8401 ret->alloc(nbOfTuple1,nbOfComp1);
8402 const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
8403 int *pt=ret->getPointer();
8404 for(int i=0;i<nbOfTuple1;i++)
8405 pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<int>());
8406 ret->copyStringInfoFrom(*a1);
8411 a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
8417 * Subtract values of another DataArrayInt from values of \a this one. There are 3
8419 * 1. The arrays have same number of tuples and components. Then each value of
8420 * \a other array is subtracted from the corresponding value of \a this array, i.e.:
8421 * _a_ [ i, j ] -= _other_ [ i, j ].
8422 * 2. The arrays have same number of tuples and \a other array has one component. Then
8423 * _a_ [ i, j ] -= _other_ [ i, 0 ].
8424 * 3. The arrays have same number of components and \a other array has one tuple. Then
8425 * _a_ [ i, j ] -= _a2_ [ 0, j ].
8427 * \param [in] other - an array to subtract from \a this one.
8428 * \throw If \a other is NULL.
8429 * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
8430 * \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
8431 * \a other has number of both tuples and components not equal to 1.
8433 void DataArrayInt::substractEqual(const DataArrayInt *other)
8436 throw INTERP_KERNEL::Exception("DataArrayInt::substractEqual : input DataArrayInt instance is NULL !");
8437 const char *msg="Nb of tuples mismatch for DataArrayInt::substractEqual !";
8438 checkAllocated(); other->checkAllocated();
8439 int nbOfTuple=getNumberOfTuples();
8440 int nbOfTuple2=other->getNumberOfTuples();
8441 int nbOfComp=getNumberOfComponents();
8442 int nbOfComp2=other->getNumberOfComponents();
8443 if(nbOfTuple==nbOfTuple2)
8445 if(nbOfComp==nbOfComp2)
8447 std::transform(begin(),end(),other->begin(),getPointer(),std::minus<int>());
8449 else if(nbOfComp2==1)
8451 int *ptr=getPointer();
8452 const int *ptrc=other->getConstPointer();
8453 for(int i=0;i<nbOfTuple;i++)
8454 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<int>(),*ptrc++));
8457 throw INTERP_KERNEL::Exception(msg);
8459 else if(nbOfTuple2==1)
8461 int *ptr=getPointer();
8462 const int *ptrc=other->getConstPointer();
8463 for(int i=0;i<nbOfTuple;i++)
8464 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<int>());
8467 throw INTERP_KERNEL::Exception(msg);
8472 * Returns a new DataArrayInt that is a product of two given arrays. There are 3
8474 * 1. The arrays have same number of tuples and components. Then each value of
8475 * the result array (_a_) is a product of the corresponding values of \a a1 and
8476 * \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
8477 * 2. The arrays have same number of tuples and one array, say _a2_, has one
8479 * _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
8480 * 3. The arrays have same number of components and one array, say _a2_, has one
8482 * _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
8484 * Info on components is copied either from the first array (in the first case) or from
8485 * the array with maximal number of elements (getNbOfElems()).
8486 * \param [in] a1 - a factor array.
8487 * \param [in] a2 - another factor array.
8488 * \return DataArrayInt * - the new instance of DataArrayInt.
8489 * The caller is to delete this result array using decrRef() as it is no more
8491 * \throw If either \a a1 or \a a2 is NULL.
8492 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
8493 * \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
8494 * none of them has number of tuples or components equal to 1.
8496 DataArrayInt *DataArrayInt::Multiply(const DataArrayInt *a1, const DataArrayInt *a2)
8499 throw INTERP_KERNEL::Exception("DataArrayInt::Multiply : input DataArrayInt instance is NULL !");
8500 int nbOfTuple=a1->getNumberOfTuples();
8501 int nbOfTuple2=a2->getNumberOfTuples();
8502 int nbOfComp=a1->getNumberOfComponents();
8503 int nbOfComp2=a2->getNumberOfComponents();
8504 MCAuto<DataArrayInt> ret=0;
8505 if(nbOfTuple==nbOfTuple2)
8507 if(nbOfComp==nbOfComp2)
8509 ret=DataArrayInt::New();
8510 ret->alloc(nbOfTuple,nbOfComp);
8511 std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<int>());
8512 ret->copyStringInfoFrom(*a1);
8516 int nbOfCompMin,nbOfCompMax;
8517 const DataArrayInt *aMin, *aMax;
8518 if(nbOfComp>nbOfComp2)
8520 nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
8525 nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
8530 ret=DataArrayInt::New();
8531 ret->alloc(nbOfTuple,nbOfCompMax);
8532 const int *aMinPtr=aMin->getConstPointer();
8533 const int *aMaxPtr=aMax->getConstPointer();
8534 int *res=ret->getPointer();
8535 for(int i=0;i<nbOfTuple;i++)
8536 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<int>(),aMinPtr[i]));
8537 ret->copyStringInfoFrom(*aMax);
8540 throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
8543 else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
8545 if(nbOfComp==nbOfComp2)
8547 int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
8548 const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
8549 const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
8550 const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
8551 ret=DataArrayInt::New();
8552 ret->alloc(nbOfTupleMax,nbOfComp);
8553 int *res=ret->getPointer();
8554 for(int i=0;i<nbOfTupleMax;i++)
8555 res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<int>());
8556 ret->copyStringInfoFrom(*aMax);
8559 throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
8562 throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
8568 * Multiply values of another DataArrayInt to values of \a this one. There are 3
8570 * 1. The arrays have same number of tuples and components. Then each value of
8571 * \a other array is multiplied to the corresponding value of \a this array, i.e.:
8572 * _a_ [ i, j ] *= _other_ [ i, j ].
8573 * 2. The arrays have same number of tuples and \a other array has one component. Then
8574 * _a_ [ i, j ] *= _other_ [ i, 0 ].
8575 * 3. The arrays have same number of components and \a other array has one tuple. Then
8576 * _a_ [ i, j ] *= _a2_ [ 0, j ].
8578 * \param [in] other - an array to multiply to \a this one.
8579 * \throw If \a other is NULL.
8580 * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
8581 * \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
8582 * \a other has number of both tuples and components not equal to 1.
8584 void DataArrayInt::multiplyEqual(const DataArrayInt *other)
8587 throw INTERP_KERNEL::Exception("DataArrayInt::multiplyEqual : input DataArrayInt instance is NULL !");
8588 const char *msg="Nb of tuples mismatch for DataArrayInt::multiplyEqual !";
8589 checkAllocated(); other->checkAllocated();
8590 int nbOfTuple=getNumberOfTuples();
8591 int nbOfTuple2=other->getNumberOfTuples();
8592 int nbOfComp=getNumberOfComponents();
8593 int nbOfComp2=other->getNumberOfComponents();
8594 if(nbOfTuple==nbOfTuple2)
8596 if(nbOfComp==nbOfComp2)
8598 std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<int>());
8600 else if(nbOfComp2==1)
8602 int *ptr=getPointer();
8603 const int *ptrc=other->getConstPointer();
8604 for(int i=0;i<nbOfTuple;i++)
8605 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<int>(),*ptrc++));
8608 throw INTERP_KERNEL::Exception(msg);
8610 else if(nbOfTuple2==1)
8612 if(nbOfComp2==nbOfComp)
8614 int *ptr=getPointer();
8615 const int *ptrc=other->getConstPointer();
8616 for(int i=0;i<nbOfTuple;i++)
8617 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<int>());
8620 throw INTERP_KERNEL::Exception(msg);
8623 throw INTERP_KERNEL::Exception(msg);
8629 * Returns a new DataArrayInt that is a division of two given arrays. There are 3
8631 * 1. The arrays have same number of tuples and components. Then each value of
8632 * the result array (_a_) is a division of the corresponding values of \a a1 and
8633 * \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
8634 * 2. The arrays have same number of tuples and one array, say _a2_, has one
8636 * _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
8637 * 3. The arrays have same number of components and one array, say _a2_, has one
8639 * _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
8641 * Info on components is copied either from the first array (in the first case) or from
8642 * the array with maximal number of elements (getNbOfElems()).
8643 * \warning No check of division by zero is performed!
8644 * \param [in] a1 - a numerator array.
8645 * \param [in] a2 - a denominator array.
8646 * \return DataArrayInt * - the new instance of DataArrayInt.
8647 * The caller is to delete this result array using decrRef() as it is no more
8649 * \throw If either \a a1 or \a a2 is NULL.
8650 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
8651 * \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
8652 * none of them has number of tuples or components equal to 1.
8654 DataArrayInt *DataArrayInt::Divide(const DataArrayInt *a1, const DataArrayInt *a2)
8657 throw INTERP_KERNEL::Exception("DataArrayInt::Divide : input DataArrayInt instance is NULL !");
8658 int nbOfTuple1=a1->getNumberOfTuples();
8659 int nbOfTuple2=a2->getNumberOfTuples();
8660 int nbOfComp1=a1->getNumberOfComponents();
8661 int nbOfComp2=a2->getNumberOfComponents();
8662 if(nbOfTuple2==nbOfTuple1)
8664 if(nbOfComp1==nbOfComp2)
8666 MCAuto<DataArrayInt> ret=DataArrayInt::New();
8667 ret->alloc(nbOfTuple2,nbOfComp1);
8668 std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<int>());
8669 ret->copyStringInfoFrom(*a1);
8672 else if(nbOfComp2==1)
8674 MCAuto<DataArrayInt> ret=DataArrayInt::New();
8675 ret->alloc(nbOfTuple1,nbOfComp1);
8676 const int *a2Ptr=a2->getConstPointer();
8677 const int *a1Ptr=a1->getConstPointer();
8678 int *res=ret->getPointer();
8679 for(int i=0;i<nbOfTuple1;i++)
8680 res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<int>(),a2Ptr[i]));
8681 ret->copyStringInfoFrom(*a1);
8686 a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
8690 else if(nbOfTuple2==1)
8692 a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
8693 MCAuto<DataArrayInt> ret=DataArrayInt::New();
8694 ret->alloc(nbOfTuple1,nbOfComp1);
8695 const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
8696 int *pt=ret->getPointer();
8697 for(int i=0;i<nbOfTuple1;i++)
8698 pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<int>());
8699 ret->copyStringInfoFrom(*a1);
8704 a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
8710 * Divide values of \a this array by values of another DataArrayInt. There are 3
8712 * 1. The arrays have same number of tuples and components. Then each value of
8713 * \a this array is divided by the corresponding value of \a other one, i.e.:
8714 * _a_ [ i, j ] /= _other_ [ i, j ].
8715 * 2. The arrays have same number of tuples and \a other array has one component. Then
8716 * _a_ [ i, j ] /= _other_ [ i, 0 ].
8717 * 3. The arrays have same number of components and \a other array has one tuple. Then
8718 * _a_ [ i, j ] /= _a2_ [ 0, j ].
8720 * \warning No check of division by zero is performed!
8721 * \param [in] other - an array to divide \a this one by.
8722 * \throw If \a other is NULL.
8723 * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
8724 * \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
8725 * \a other has number of both tuples and components not equal to 1.
8727 void DataArrayInt::divideEqual(const DataArrayInt *other)
8730 throw INTERP_KERNEL::Exception("DataArrayInt::divideEqual : input DataArrayInt instance is NULL !");
8731 const char *msg="Nb of tuples mismatch for DataArrayInt::divideEqual !";
8732 checkAllocated(); other->checkAllocated();
8733 int nbOfTuple=getNumberOfTuples();
8734 int nbOfTuple2=other->getNumberOfTuples();
8735 int nbOfComp=getNumberOfComponents();
8736 int nbOfComp2=other->getNumberOfComponents();
8737 if(nbOfTuple==nbOfTuple2)
8739 if(nbOfComp==nbOfComp2)
8741 std::transform(begin(),end(),other->begin(),getPointer(),std::divides<int>());
8743 else if(nbOfComp2==1)
8745 int *ptr=getPointer();
8746 const int *ptrc=other->getConstPointer();
8747 for(int i=0;i<nbOfTuple;i++)
8748 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<int>(),*ptrc++));
8751 throw INTERP_KERNEL::Exception(msg);
8753 else if(nbOfTuple2==1)
8755 if(nbOfComp2==nbOfComp)
8757 int *ptr=getPointer();
8758 const int *ptrc=other->getConstPointer();
8759 for(int i=0;i<nbOfTuple;i++)
8760 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<int>());
8763 throw INTERP_KERNEL::Exception(msg);
8766 throw INTERP_KERNEL::Exception(msg);
8772 * Returns a new DataArrayInt that is a modulus of two given arrays. There are 3
8774 * 1. The arrays have same number of tuples and components. Then each value of
8775 * the result array (_a_) is a division of the corresponding values of \a a1 and
8776 * \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, j ].
8777 * 2. The arrays have same number of tuples and one array, say _a2_, has one
8779 * _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, 0 ].
8780 * 3. The arrays have same number of components and one array, say _a2_, has one
8782 * _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ 0, j ].
8784 * Info on components is copied either from the first array (in the first case) or from
8785 * the array with maximal number of elements (getNbOfElems()).
8786 * \warning No check of division by zero is performed!
8787 * \param [in] a1 - a dividend array.
8788 * \param [in] a2 - a divisor array.
8789 * \return DataArrayInt * - the new instance of DataArrayInt.
8790 * The caller is to delete this result array using decrRef() as it is no more
8792 * \throw If either \a a1 or \a a2 is NULL.
8793 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
8794 * \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
8795 * none of them has number of tuples or components equal to 1.
8797 DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt *a2)
8800 throw INTERP_KERNEL::Exception("DataArrayInt::Modulus : input DataArrayInt instance is NULL !");
8801 int nbOfTuple1=a1->getNumberOfTuples();
8802 int nbOfTuple2=a2->getNumberOfTuples();
8803 int nbOfComp1=a1->getNumberOfComponents();
8804 int nbOfComp2=a2->getNumberOfComponents();
8805 if(nbOfTuple2==nbOfTuple1)
8807 if(nbOfComp1==nbOfComp2)
8809 MCAuto<DataArrayInt> ret=DataArrayInt::New();
8810 ret->alloc(nbOfTuple2,nbOfComp1);
8811 std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::modulus<int>());
8812 ret->copyStringInfoFrom(*a1);
8815 else if(nbOfComp2==1)
8817 MCAuto<DataArrayInt> ret=DataArrayInt::New();
8818 ret->alloc(nbOfTuple1,nbOfComp1);
8819 const int *a2Ptr=a2->getConstPointer();
8820 const int *a1Ptr=a1->getConstPointer();
8821 int *res=ret->getPointer();
8822 for(int i=0;i<nbOfTuple1;i++)
8823 res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::modulus<int>(),a2Ptr[i]));
8824 ret->copyStringInfoFrom(*a1);
8829 a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
8833 else if(nbOfTuple2==1)
8835 a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
8836 MCAuto<DataArrayInt> ret=DataArrayInt::New();
8837 ret->alloc(nbOfTuple1,nbOfComp1);
8838 const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
8839 int *pt=ret->getPointer();
8840 for(int i=0;i<nbOfTuple1;i++)
8841 pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::modulus<int>());
8842 ret->copyStringInfoFrom(*a1);
8847 a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Modulus !");//will always throw an exception
8853 * Modify \a this array so that each value becomes a modulus of division of this value by
8854 * a value of another DataArrayInt. There are 3 valid cases.
8855 * 1. The arrays have same number of tuples and components. Then each value of
8856 * \a this array is divided by the corresponding value of \a other one, i.e.:
8857 * _a_ [ i, j ] %= _other_ [ i, j ].
8858 * 2. The arrays have same number of tuples and \a other array has one component. Then
8859 * _a_ [ i, j ] %= _other_ [ i, 0 ].
8860 * 3. The arrays have same number of components and \a other array has one tuple. Then
8861 * _a_ [ i, j ] %= _a2_ [ 0, j ].
8863 * \warning No check of division by zero is performed!
8864 * \param [in] other - a divisor array.
8865 * \throw If \a other is NULL.
8866 * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
8867 * \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
8868 * \a other has number of both tuples and components not equal to 1.
8870 void DataArrayInt::modulusEqual(const DataArrayInt *other)
8873 throw INTERP_KERNEL::Exception("DataArrayInt::modulusEqual : input DataArrayInt instance is NULL !");
8874 const char *msg="Nb of tuples mismatch for DataArrayInt::modulusEqual !";
8875 checkAllocated(); other->checkAllocated();
8876 int nbOfTuple=getNumberOfTuples();
8877 int nbOfTuple2=other->getNumberOfTuples();
8878 int nbOfComp=getNumberOfComponents();
8879 int nbOfComp2=other->getNumberOfComponents();
8880 if(nbOfTuple==nbOfTuple2)
8882 if(nbOfComp==nbOfComp2)
8884 std::transform(begin(),end(),other->begin(),getPointer(),std::modulus<int>());
8886 else if(nbOfComp2==1)
8888 if(nbOfComp2==nbOfComp)
8890 int *ptr=getPointer();
8891 const int *ptrc=other->getConstPointer();
8892 for(int i=0;i<nbOfTuple;i++)
8893 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::modulus<int>(),*ptrc++));
8896 throw INTERP_KERNEL::Exception(msg);
8899 throw INTERP_KERNEL::Exception(msg);
8901 else if(nbOfTuple2==1)
8903 int *ptr=getPointer();
8904 const int *ptrc=other->getConstPointer();
8905 for(int i=0;i<nbOfTuple;i++)
8906 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::modulus<int>());
8909 throw INTERP_KERNEL::Exception(msg);
8914 * Returns a new DataArrayInt that is the result of pow of two given arrays. There are 3
8917 * \param [in] a1 - an array to pow up.
8918 * \param [in] a2 - another array to sum up.
8919 * \return DataArrayInt * - the new instance of DataArrayInt.
8920 * The caller is to delete this result array using decrRef() as it is no more
8922 * \throw If either \a a1 or \a a2 is NULL.
8923 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
8924 * \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
8925 * \throw If there is a negative value in \a a2.
8927 DataArrayInt *DataArrayInt::Pow(const DataArrayInt *a1, const DataArrayInt *a2)
8930 throw INTERP_KERNEL::Exception("DataArrayInt::Pow : at least one of input instances is null !");
8931 int nbOfTuple=a1->getNumberOfTuples();
8932 int nbOfTuple2=a2->getNumberOfTuples();
8933 int nbOfComp=a1->getNumberOfComponents();
8934 int nbOfComp2=a2->getNumberOfComponents();
8935 if(nbOfTuple!=nbOfTuple2)
8936 throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of tuples mismatches !");
8937 if(nbOfComp!=1 || nbOfComp2!=1)
8938 throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of components of both arrays must be equal to 1 !");
8939 MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuple,1);
8940 const int *ptr1(a1->begin()),*ptr2(a2->begin());
8941 int *ptr=ret->getPointer();
8942 for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
8947 for(int j=0;j<*ptr2;j++)
8953 std::ostringstream oss; oss << "DataArrayInt::Pow : on tuple #" << i << " of a2 value is < 0 (" << *ptr2 << ") !";
8954 throw INTERP_KERNEL::Exception(oss.str().c_str());
8961 * Apply pow on values of another DataArrayInt to values of \a this one.
8963 * \param [in] other - an array to pow to \a this one.
8964 * \throw If \a other is NULL.
8965 * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
8966 * \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
8967 * \throw If there is a negative value in \a other.
8969 void DataArrayInt::powEqual(const DataArrayInt *other)
8972 throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : input instance is null !");
8973 int nbOfTuple=getNumberOfTuples();
8974 int nbOfTuple2=other->getNumberOfTuples();
8975 int nbOfComp=getNumberOfComponents();
8976 int nbOfComp2=other->getNumberOfComponents();
8977 if(nbOfTuple!=nbOfTuple2)
8978 throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of tuples mismatches !");
8979 if(nbOfComp!=1 || nbOfComp2!=1)
8980 throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of components of both arrays must be equal to 1 !");
8981 int *ptr=getPointer();
8982 const int *ptrc=other->begin();
8983 for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
8988 for(int j=0;j<*ptrc;j++)
8994 std::ostringstream oss; oss << "DataArrayInt::powEqual : on tuple #" << i << " of other value is < 0 (" << *ptrc << ") !";
8995 throw INTERP_KERNEL::Exception(oss.str().c_str());
9002 * Returns a C array which is a renumbering map in "Old to New" mode for the input array.
9003 * This map, if applied to \a start array, would make it sorted. For example, if
9004 * \a start array contents are [9,10,0,6,4,11,3,7] then the contents of the result array is
9005 * [5,6,0,3,2,7,1,4].
9006 * \param [in] start - pointer to the first element of the array for which the
9007 * permutation map is computed.
9008 * \param [in] end - pointer specifying the end of the array \a start, so that
9009 * the last value of \a start is \a end[ -1 ].
9010 * \return int * - the result permutation array that the caller is to delete as it is no
9012 * \throw If there are equal values in the input array.
9014 int *DataArrayInt::CheckAndPreparePermutation(const int *start, const int *end)
9016 std::size_t sz=std::distance(start,end);
9017 int *ret=(int *)malloc(sz*sizeof(int));
9018 int *work=new int[sz];
9019 std::copy(start,end,work);
9020 std::sort(work,work+sz);
9021 if(std::unique(work,work+sz)!=work+sz)
9025 throw INTERP_KERNEL::Exception("Some elements are equals in the specified array !");
9027 std::map<int,int> m;
9028 for(int *workPt=work;workPt!=work+sz;workPt++)
9029 m[*workPt]=(int)std::distance(work,workPt);
9031 for(const int *iter=start;iter!=end;iter++,iter2++)
9038 * Returns a new DataArrayInt containing an arithmetic progression
9039 * that is equal to the sequence returned by Python \c range(\a begin,\a end,\a step )
9041 * \param [in] begin - the start value of the result sequence.
9042 * \param [in] end - limiting value, so that every value of the result array is less than
9044 * \param [in] step - specifies the increment or decrement.
9045 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9046 * array using decrRef() as it is no more needed.
9047 * \throw If \a step == 0.
9048 * \throw If \a end < \a begin && \a step > 0.
9049 * \throw If \a end > \a begin && \a step < 0.
9051 DataArrayInt *DataArrayInt::Range(int begin, int end, int step)
9053 int nbOfTuples=GetNumberOfItemGivenBESRelative(begin,end,step,"DataArrayInt::Range");
9054 MCAuto<DataArrayInt> ret=DataArrayInt::New();
9055 ret->alloc(nbOfTuples,1);
9056 int *ptr=ret->getPointer();
9059 for(int i=begin;i<end;i+=step,ptr++)
9064 for(int i=begin;i>end;i+=step,ptr++)
9071 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
9074 void DataArrayInt::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
9079 tinyInfo[0]=getNumberOfTuples();
9080 tinyInfo[1]=getNumberOfComponents();
9090 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
9093 void DataArrayInt::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
9097 int nbOfCompo=getNumberOfComponents();
9098 tinyInfo.resize(nbOfCompo+1);
9099 tinyInfo[0]=getName();
9100 for(int i=0;i<nbOfCompo;i++)
9101 tinyInfo[i+1]=getInfoOnComponent(i);
9106 tinyInfo[0]=getName();
9111 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
9112 * This method returns if a feeding is needed.
9114 bool DataArrayInt::resizeForUnserialization(const std::vector<int>& tinyInfoI)
9116 int nbOfTuple=tinyInfoI[0];
9117 int nbOfComp=tinyInfoI[1];
9118 if(nbOfTuple!=-1 || nbOfComp!=-1)
9120 alloc(nbOfTuple,nbOfComp);
9127 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
9128 * This method returns if a feeding is needed.
9130 void DataArrayInt::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
9132 setName(tinyInfoS[0]);
9135 int nbOfCompo=tinyInfoI[1];
9136 for(int i=0;i<nbOfCompo;i++)
9137 setInfoOnComponent(i,tinyInfoS[i+1]);
9141 DataArrayIntIterator::DataArrayIntIterator(DataArrayInt *da):_da(da),_pt(0),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
9146 if(_da->isAllocated())
9148 _nb_comp=da->getNumberOfComponents();
9149 _nb_tuple=da->getNumberOfTuples();
9150 _pt=da->getPointer();
9155 DataArrayIntIterator::~DataArrayIntIterator()
9161 DataArrayIntTuple *DataArrayIntIterator::nextt()
9163 if(_tuple_id<_nb_tuple)
9166 DataArrayIntTuple *ret=new DataArrayIntTuple(_pt,_nb_comp);
9174 DataArrayIntTuple::DataArrayIntTuple(int *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
9178 std::string DataArrayIntTuple::repr() const
9180 std::ostringstream oss; oss << "(";
9181 for(int i=0;i<_nb_of_compo-1;i++)
9182 oss << _pt[i] << ", ";
9183 oss << _pt[_nb_of_compo-1] << ")";
9187 int DataArrayIntTuple::intValue() const
9191 throw INTERP_KERNEL::Exception("DataArrayIntTuple::intValue : DataArrayIntTuple instance has not exactly 1 component -> Not possible to convert it into an integer !");
9195 * This method returns a newly allocated instance the caller should dealed with by a MEDCoupling::DataArrayInt::decrRef.
9196 * This method performs \b no copy of data. The content is only referenced using MEDCoupling::DataArrayInt::useArray with ownership set to \b false.
9197 * 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
9198 * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
9200 DataArrayInt *DataArrayIntTuple::buildDAInt(int nbOfTuples, int nbOfCompo) const
9202 if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
9204 DataArrayInt *ret=DataArrayInt::New();
9205 ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
9210 std::ostringstream oss; oss << "DataArrayIntTuple::buildDAInt : unable to build a requested DataArrayInt instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
9211 oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
9212 throw INTERP_KERNEL::Exception(oss.str().c_str());