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>;
44 template<int SPACEDIM>
45 void DataArrayDouble::findCommonTuplesAlg(const double *bbox, int nbNodes, int limitNodeId, double prec, DataArrayInt *c, DataArrayInt *cI) const
47 const double *coordsPtr=getConstPointer();
48 BBTreePts<SPACEDIM,int> myTree(bbox,0,0,nbNodes,prec);
49 std::vector<bool> isDone(nbNodes);
50 for(int i=0;i<nbNodes;i++)
54 std::vector<int> intersectingElems;
55 myTree.getElementsAroundPoint(coordsPtr+i*SPACEDIM,intersectingElems);
56 if(intersectingElems.size()>1)
58 std::vector<int> commonNodes;
59 for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
63 commonNodes.push_back(*it);
66 if(!commonNodes.empty())
68 cI->pushBackSilent(cI->back()+(int)commonNodes.size()+1);
70 c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
77 template<int SPACEDIM>
78 void DataArrayDouble::FindTupleIdsNearTuplesAlg(const BBTreePts<SPACEDIM,int>& myTree, const double *pos, int nbOfTuples, double eps,
79 DataArrayInt *c, DataArrayInt *cI)
81 for(int i=0;i<nbOfTuples;i++)
83 std::vector<int> intersectingElems;
84 myTree.getElementsAroundPoint(pos+i*SPACEDIM,intersectingElems);
85 std::vector<int> commonNodes;
86 for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
87 commonNodes.push_back(*it);
88 cI->pushBackSilent(cI->back()+(int)commonNodes.size());
89 c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
93 template<int SPACEDIM>
94 void DataArrayDouble::FindClosestTupleIdAlg(const BBTreePts<SPACEDIM,int>& myTree, double dist, const double *pos, int nbOfTuples, const double *thisPt, int thisNbOfTuples, int *res)
99 for(int i=0;i<nbOfTuples;i++,p+=SPACEDIM,r++)
104 double ret=myTree.getElementsAroundPoint2(p,distOpt,elem);
105 if(ret!=std::numeric_limits<double>::max())
107 distOpt=std::max(ret,1e-4);
112 { distOpt=2*distOpt; continue; }
117 int DataArray::EffectiveCircPerm(int nbOfShift, int nbOfTuples)
120 throw INTERP_KERNEL::Exception("DataArray::EffectiveCircPerm : number of tuples is expected to be > 0 !");
123 return nbOfShift%nbOfTuples;
129 return nbOfTuples-tmp;
133 std::size_t DataArray::getHeapMemorySizeWithoutChildren() const
135 std::size_t sz1=_name.capacity();
136 std::size_t sz2=_info_on_compo.capacity();
138 for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
139 sz3+=(*it).capacity();
143 std::vector<const BigMemoryObject *> DataArray::getDirectChildrenWithNull() const
145 return std::vector<const BigMemoryObject *>();
149 * Sets the attribute \a _name of \a this array.
150 * See \ref MEDCouplingArrayBasicsName "DataArrays infos" for more information.
151 * \param [in] name - new array name
153 void DataArray::setName(const std::string& name)
159 * Copies textual data from an \a other DataArray. The copied data are
160 * - the name attribute,
161 * - the information of components.
163 * For more information on these data see \ref MEDCouplingArrayBasicsName "DataArrays infos".
165 * \param [in] other - another instance of DataArray to copy the textual data from.
166 * \throw If number of components of \a this array differs from that of the \a other.
168 void DataArray::copyStringInfoFrom(const DataArray& other)
170 if(_info_on_compo.size()!=other._info_on_compo.size())
171 throw INTERP_KERNEL::Exception("Size of arrays mismatches on copyStringInfoFrom !");
173 _info_on_compo=other._info_on_compo;
176 void DataArray::copyPartOfStringInfoFrom(const DataArray& other, const std::vector<int>& compoIds)
178 int nbOfCompoOth=other.getNumberOfComponents();
179 std::size_t newNbOfCompo=compoIds.size();
180 for(std::size_t i=0;i<newNbOfCompo;i++)
181 if(compoIds[i]>=nbOfCompoOth || compoIds[i]<0)
183 std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompoOth << ")";
184 throw INTERP_KERNEL::Exception(oss.str().c_str());
186 for(std::size_t i=0;i<newNbOfCompo;i++)
187 setInfoOnComponent((int)i,other.getInfoOnComponent(compoIds[i]));
190 void DataArray::copyPartOfStringInfoFrom2(const std::vector<int>& compoIds, const DataArray& other)
192 int nbOfCompo=getNumberOfComponents();
193 std::size_t partOfCompoToSet=compoIds.size();
194 if((int)partOfCompoToSet!=other.getNumberOfComponents())
195 throw INTERP_KERNEL::Exception("Given compoIds has not the same size as number of components of given array !");
196 for(std::size_t i=0;i<partOfCompoToSet;i++)
197 if(compoIds[i]>=nbOfCompo || compoIds[i]<0)
199 std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompo << ")";
200 throw INTERP_KERNEL::Exception(oss.str().c_str());
202 for(std::size_t i=0;i<partOfCompoToSet;i++)
203 setInfoOnComponent(compoIds[i],other.getInfoOnComponent((int)i));
206 bool DataArray::areInfoEqualsIfNotWhy(const DataArray& other, std::string& reason) const
208 std::ostringstream oss;
209 if(_name!=other._name)
211 oss << "Names DataArray mismatch : this name=\"" << _name << " other name=\"" << other._name << "\" !";
215 if(_info_on_compo!=other._info_on_compo)
217 oss << "Components DataArray mismatch : \nThis components=";
218 for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
219 oss << "\"" << *it << "\",";
220 oss << "\nOther components=";
221 for(std::vector<std::string>::const_iterator it=other._info_on_compo.begin();it!=other._info_on_compo.end();it++)
222 oss << "\"" << *it << "\",";
230 * Compares textual information of \a this DataArray with that of an \a other one.
231 * The compared data are
232 * - the name attribute,
233 * - the information of components.
235 * For more information on these data see \ref MEDCouplingArrayBasicsName "DataArrays infos".
236 * \param [in] other - another instance of DataArray to compare the textual data of.
237 * \return bool - \a true if the textual information is same, \a false else.
239 bool DataArray::areInfoEquals(const DataArray& other) const
242 return areInfoEqualsIfNotWhy(other,tmp);
245 void DataArray::reprWithoutNameStream(std::ostream& stream) const
247 stream << "Number of components : "<< getNumberOfComponents() << "\n";
248 stream << "Info of these components : ";
249 for(std::vector<std::string>::const_iterator iter=_info_on_compo.begin();iter!=_info_on_compo.end();iter++)
250 stream << "\"" << *iter << "\" ";
254 std::string DataArray::cppRepr(const std::string& varName) const
256 std::ostringstream ret;
257 reprCppStream(varName,ret);
262 * Sets information on all components. To know more on format of this information
263 * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
264 * \param [in] info - a vector of strings.
265 * \throw If size of \a info differs from the number of components of \a this.
267 void DataArray::setInfoOnComponents(const std::vector<std::string>& info)
269 if(getNumberOfComponents()!=(int)info.size())
271 std::ostringstream oss; oss << "DataArray::setInfoOnComponents : input is of size " << info.size() << " whereas number of components is equal to " << getNumberOfComponents() << " !";
272 throw INTERP_KERNEL::Exception(oss.str().c_str());
278 * This method is only a dispatcher towards DataArrayDouble::setPartOfValues3, DataArrayInt::setPartOfValues3, DataArrayChar::setPartOfValues3 depending on the true
279 * type of \a this and \a aBase.
281 * \throw If \a aBase and \a this do not have the same type.
283 * \sa DataArrayDouble::setPartOfValues3, DataArrayInt::setPartOfValues3, DataArrayChar::setPartOfValues3.
285 void DataArray::setPartOfValuesBase3(const DataArray *aBase, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare)
288 throw INTERP_KERNEL::Exception("DataArray::setPartOfValuesBase3 : input aBase object is NULL !");
289 DataArrayDouble *this1(dynamic_cast<DataArrayDouble *>(this));
290 DataArrayInt *this2(dynamic_cast<DataArrayInt *>(this));
291 DataArrayChar *this3(dynamic_cast<DataArrayChar *>(this));
292 const DataArrayDouble *a1(dynamic_cast<const DataArrayDouble *>(aBase));
293 const DataArrayInt *a2(dynamic_cast<const DataArrayInt *>(aBase));
294 const DataArrayChar *a3(dynamic_cast<const DataArrayChar *>(aBase));
297 this1->setPartOfValues3(a1,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
302 this2->setPartOfValues3(a2,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
307 this3->setPartOfValues3(a3,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare);
310 throw INTERP_KERNEL::Exception("DataArray::setPartOfValuesBase3 : input aBase object and this do not have the same type !");
313 std::vector<std::string> DataArray::getVarsOnComponent() const
315 int nbOfCompo=(int)_info_on_compo.size();
316 std::vector<std::string> ret(nbOfCompo);
317 for(int i=0;i<nbOfCompo;i++)
318 ret[i]=getVarOnComponent(i);
322 std::vector<std::string> DataArray::getUnitsOnComponent() const
324 int nbOfCompo=(int)_info_on_compo.size();
325 std::vector<std::string> ret(nbOfCompo);
326 for(int i=0;i<nbOfCompo;i++)
327 ret[i]=getUnitOnComponent(i);
332 * Returns information on a component specified by an index.
333 * To know more on format of this information
334 * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
335 * \param [in] i - the index (zero based) of the component of interest.
336 * \return std::string - a string containing the information on \a i-th component.
337 * \throw If \a i is not a valid component index.
339 std::string DataArray::getInfoOnComponent(int i) const
341 if(i<(int)_info_on_compo.size() && i>=0)
342 return _info_on_compo[i];
345 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();
346 throw INTERP_KERNEL::Exception(oss.str().c_str());
351 * Returns the var part of the full information of the \a i-th component.
352 * For example, if \c getInfoOnComponent(0) returns "SIGXY [N/m^2]", then
353 * \c getVarOnComponent(0) returns "SIGXY".
354 * If a unit part of information is not detected by presence of
355 * two square brackets, then the full information is returned.
356 * To read more about the component information format, see
357 * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
358 * \param [in] i - the index (zero based) of the component of interest.
359 * \return std::string - a string containing the var information, or the full info.
360 * \throw If \a i is not a valid component index.
362 std::string DataArray::getVarOnComponent(int i) const
364 if(i<(int)_info_on_compo.size() && i>=0)
366 return GetVarNameFromInfo(_info_on_compo[i]);
370 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();
371 throw INTERP_KERNEL::Exception(oss.str().c_str());
376 * Returns the unit part of the full information of the \a i-th component.
377 * For example, if \c getInfoOnComponent(0) returns "SIGXY [ N/m^2]", then
378 * \c getUnitOnComponent(0) returns " N/m^2".
379 * If a unit part of information is not detected by presence of
380 * two square brackets, then an empty string is returned.
381 * To read more about the component information format, see
382 * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
383 * \param [in] i - the index (zero based) of the component of interest.
384 * \return std::string - a string containing the unit information, if any, or "".
385 * \throw If \a i is not a valid component index.
387 std::string DataArray::getUnitOnComponent(int i) const
389 if(i<(int)_info_on_compo.size() && i>=0)
391 return GetUnitFromInfo(_info_on_compo[i]);
395 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();
396 throw INTERP_KERNEL::Exception(oss.str().c_str());
401 * Returns the var part of the full component information.
402 * For example, if \a info == "SIGXY [N/m^2]", then this method returns "SIGXY".
403 * If a unit part of information is not detected by presence of
404 * two square brackets, then the whole \a info is returned.
405 * To read more about the component information format, see
406 * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
407 * \param [in] info - the full component information.
408 * \return std::string - a string containing only var information, or the \a info.
410 std::string DataArray::GetVarNameFromInfo(const std::string& info)
412 std::size_t p1=info.find_last_of('[');
413 std::size_t p2=info.find_last_of(']');
414 if(p1==std::string::npos || p2==std::string::npos)
419 return std::string();
420 std::size_t p3=info.find_last_not_of(' ',p1-1);
421 return info.substr(0,p3+1);
425 * Returns the unit part of the full component information.
426 * For example, if \a info == "SIGXY [ N/m^2]", then this method returns " N/m^2".
427 * If a unit part of information is not detected by presence of
428 * two square brackets, then an empty string is returned.
429 * To read more about the component information format, see
430 * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
431 * \param [in] info - the full component information.
432 * \return std::string - a string containing only unit information, if any, or "".
434 std::string DataArray::GetUnitFromInfo(const std::string& info)
436 std::size_t p1=info.find_last_of('[');
437 std::size_t p2=info.find_last_of(']');
438 if(p1==std::string::npos || p2==std::string::npos)
439 return std::string();
441 return std::string();
442 return info.substr(p1+1,p2-p1-1);
446 * This method put in info format the result of the merge of \a var and \a unit.
447 * The standard format for that is "var [unit]".
448 * Inversely you can retrieve the var part or the unit part of info string using resp. GetVarNameFromInfo and GetUnitFromInfo.
450 std::string DataArray::BuildInfoFromVarAndUnit(const std::string& var, const std::string& unit)
452 std::ostringstream oss;
453 oss << var << " [" << unit << "]";
457 std::string DataArray::GetAxisTypeRepr(MEDCouplingAxisType at)
462 return std::string("AX_CART");
464 return std::string("AX_CYL");
466 return std::string("AX_SPHER");
468 throw INTERP_KERNEL::Exception("DataArray::GetAxisTypeRepr : unrecognized axis type enum !");
473 * Returns a new DataArray by concatenating all given arrays, so that (1) the number
474 * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
475 * the number of component in the result array is same as that of each of given arrays.
476 * Info on components is copied from the first of the given arrays. Number of components
477 * in the given arrays must be the same.
478 * \param [in] arrs - a sequence of arrays to include in the result array. All arrays must have the same type.
479 * \return DataArray * - the new instance of DataArray (that can be either DataArrayInt, DataArrayDouble, DataArrayChar).
480 * The caller is to delete this result array using decrRef() as it is no more
482 * \throw If all arrays within \a arrs are NULL.
483 * \throw If all not null arrays in \a arrs have not the same type.
484 * \throw If getNumberOfComponents() of arrays within \a arrs.
486 DataArray *DataArray::Aggregate(const std::vector<const DataArray *>& arrs)
488 std::vector<const DataArray *> arr2;
489 for(std::vector<const DataArray *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
493 throw INTERP_KERNEL::Exception("DataArray::Aggregate : only null instance in input vector !");
494 std::vector<const DataArrayDouble *> arrd;
495 std::vector<const DataArrayInt *> arri;
496 std::vector<const DataArrayChar *> arrc;
497 for(std::vector<const DataArray *>::const_iterator it=arr2.begin();it!=arr2.end();it++)
499 const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(*it);
501 { arrd.push_back(a); continue; }
502 const DataArrayInt *b=dynamic_cast<const DataArrayInt *>(*it);
504 { arri.push_back(b); continue; }
505 const DataArrayChar *c=dynamic_cast<const DataArrayChar *>(*it);
507 { arrc.push_back(c); continue; }
508 throw INTERP_KERNEL::Exception("DataArray::Aggregate : presence of not null instance in inuput that is not in [DataArrayDouble, DataArrayInt, DataArrayChar] !");
510 if(arr2.size()==arrd.size())
511 return DataArrayDouble::Aggregate(arrd);
512 if(arr2.size()==arri.size())
513 return DataArrayInt::Aggregate(arri);
514 if(arr2.size()==arrc.size())
515 return DataArrayChar::Aggregate(arrc);
516 throw INTERP_KERNEL::Exception("DataArray::Aggregate : all input arrays must have the same type !");
520 * Sets information on a component specified by an index.
521 * To know more on format of this information
522 * see \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
523 * \warning Don't pass NULL as \a info!
524 * \param [in] i - the index (zero based) of the component of interest.
525 * \param [in] info - the string containing the information.
526 * \throw If \a i is not a valid component index.
528 void DataArray::setInfoOnComponent(int i, const std::string& info)
530 if(i<(int)_info_on_compo.size() && i>=0)
531 _info_on_compo[i]=info;
534 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();
535 throw INTERP_KERNEL::Exception(oss.str().c_str());
540 * Sets information on all components. This method can change number of components
541 * at certain conditions; if the conditions are not respected, an exception is thrown.
542 * The number of components can be changed in \a this only if \a this is not allocated.
543 * The condition of number of components must not be changed.
545 * To know more on format of the component information see
546 * \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
547 * \param [in] info - a vector of component infos.
548 * \throw If \a this->getNumberOfComponents() != \a info.size() && \a this->isAllocated()
550 void DataArray::setInfoAndChangeNbOfCompo(const std::vector<std::string>& info)
552 if(getNumberOfComponents()!=(int)info.size())
558 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 !";
559 throw INTERP_KERNEL::Exception(oss.str().c_str());
566 void DataArray::checkNbOfTuples(int nbOfTuples, const std::string& msg) const
568 if(getNumberOfTuples()!=nbOfTuples)
570 std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " << nbOfTuples << " having " << getNumberOfTuples() << " !";
571 throw INTERP_KERNEL::Exception(oss.str().c_str());
575 void DataArray::checkNbOfComps(int nbOfCompo, const std::string& msg) const
577 if(getNumberOfComponents()!=nbOfCompo)
579 std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << nbOfCompo << " having " << getNumberOfComponents() << " !";
580 throw INTERP_KERNEL::Exception(oss.str().c_str());
584 void DataArray::checkNbOfElems(std::size_t nbOfElems, const std::string& msg) const
586 if(getNbOfElems()!=nbOfElems)
588 std::ostringstream oss; oss << msg << " : mismatch number of elems : Expected " << nbOfElems << " having " << getNbOfElems() << " !";
589 throw INTERP_KERNEL::Exception(oss.str().c_str());
593 void DataArray::checkNbOfTuplesAndComp(const DataArray& other, const std::string& msg) const
595 if(getNumberOfTuples()!=other.getNumberOfTuples())
597 std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " << other.getNumberOfTuples() << " having " << getNumberOfTuples() << " !";
598 throw INTERP_KERNEL::Exception(oss.str().c_str());
600 if(getNumberOfComponents()!=other.getNumberOfComponents())
602 std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << other.getNumberOfComponents() << " having " << getNumberOfComponents() << " !";
603 throw INTERP_KERNEL::Exception(oss.str().c_str());
607 void DataArray::checkNbOfTuplesAndComp(int nbOfTuples, int nbOfCompo, const std::string& msg) const
609 checkNbOfTuples(nbOfTuples,msg);
610 checkNbOfComps(nbOfCompo,msg);
614 * Simply this method checks that \b value is in [0,\b ref).
616 void DataArray::CheckValueInRange(int ref, int value, const std::string& msg)
618 if(value<0 || value>=ref)
620 std::ostringstream oss; oss << "DataArray::CheckValueInRange : " << msg << " ! Expected in range [0," << ref << "[ having " << value << " !";
621 throw INTERP_KERNEL::Exception(oss.str().c_str());
626 * This method checks that [\b start, \b end) is compliant with ref length \b value.
627 * typicaly start in [0,\b value) and end in [0,\b value). If value==start and start==end, it is supported.
629 void DataArray::CheckValueInRangeEx(int value, int start, int end, const std::string& msg)
631 if(start<0 || start>=value)
633 if(value!=start || end!=start)
635 std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg << " ! Expected start " << start << " of input range, in [0," << value << "[ !";
636 throw INTERP_KERNEL::Exception(oss.str().c_str());
639 if(end<0 || end>value)
641 std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg << " ! Expected end " << end << " of input range, in [0," << value << "] !";
642 throw INTERP_KERNEL::Exception(oss.str().c_str());
646 void DataArray::CheckClosingParInRange(int ref, int value, const std::string& msg)
648 if(value<0 || value>ref)
650 std::ostringstream oss; oss << "DataArray::CheckClosingParInRange : " << msg << " ! Expected input range in [0," << ref << "] having closing open parenthesis " << value << " !";
651 throw INTERP_KERNEL::Exception(oss.str().c_str());
656 * 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,
657 * typically it is a whole slice of tuples of DataArray or cells, nodes of a mesh...
659 * The input \a sliceId should be an id in [0, \a nbOfSlices) that specifies the slice of work.
661 * \param [in] start - the start of the input slice of the whole work to perform splitted into slices.
662 * \param [in] stop - the stop of the input slice of the whole work to perform splitted into slices.
663 * \param [in] step - the step (that can be <0) of the input slice of the whole work to perform splitted into slices.
664 * \param [in] sliceId - the slice id considered
665 * \param [in] nbOfSlices - the number of slices (typically the number of cores on which the work is expected to be sliced)
666 * \param [out] startSlice - the start of the slice considered
667 * \param [out] stopSlice - the stop of the slice consided
669 * \throw If \a step == 0
670 * \throw If \a nbOfSlices not > 0
671 * \throw If \a sliceId not in [0,nbOfSlices)
673 void DataArray::GetSlice(int start, int stop, int step, int sliceId, int nbOfSlices, int& startSlice, int& stopSlice)
677 std::ostringstream oss; oss << "DataArray::GetSlice : nbOfSlices (" << nbOfSlices << ") must be > 0 !";
678 throw INTERP_KERNEL::Exception(oss.str().c_str());
680 if(sliceId<0 || sliceId>=nbOfSlices)
682 std::ostringstream oss; oss << "DataArray::GetSlice : sliceId (" << nbOfSlices << ") must be in [0 , nbOfSlices (" << nbOfSlices << ") ) !";
683 throw INTERP_KERNEL::Exception(oss.str().c_str());
685 int nbElems=GetNumberOfItemGivenBESRelative(start,stop,step,"DataArray::GetSlice");
686 int minNbOfElemsPerSlice=nbElems/nbOfSlices;
687 startSlice=start+minNbOfElemsPerSlice*step*sliceId;
688 if(sliceId<nbOfSlices-1)
689 stopSlice=start+minNbOfElemsPerSlice*step*(sliceId+1);
694 int DataArray::GetNumberOfItemGivenBES(int begin, int end, int step, const std::string& msg)
698 std::ostringstream oss; oss << msg << " : end before begin !";
699 throw INTERP_KERNEL::Exception(oss.str().c_str());
705 std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
706 throw INTERP_KERNEL::Exception(oss.str().c_str());
708 return (end-1-begin)/step+1;
711 int DataArray::GetNumberOfItemGivenBESRelative(int begin, int end, int step, const std::string& msg)
714 throw INTERP_KERNEL::Exception("DataArray::GetNumberOfItemGivenBES : step=0 is not allowed !");
715 if(end<begin && step>0)
717 std::ostringstream oss; oss << msg << " : end before begin whereas step is positive !";
718 throw INTERP_KERNEL::Exception(oss.str().c_str());
720 if(begin<end && step<0)
722 std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
723 throw INTERP_KERNEL::Exception(oss.str().c_str());
726 return (std::max(begin,end)-1-std::min(begin,end))/std::abs(step)+1;
731 int DataArray::GetPosOfItemGivenBESRelativeNoThrow(int value, int begin, int end, int step)
737 if(begin<=value && value<end)
739 if((value-begin)%step==0)
740 return (value-begin)/step;
749 if(begin>=value && value>end)
751 if((begin-value)%(-step)==0)
752 return (begin-value)/(-step);
765 * Returns a new instance of DataArrayDouble. The caller is to delete this array
766 * using decrRef() as it is no more needed.
768 DataArrayDouble *DataArrayDouble::New()
770 return new DataArrayDouble;
774 * Returns the only one value in \a this, if and only if number of elements
775 * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
776 * \return double - the sole value stored in \a this array.
777 * \throw If at least one of conditions stated above is not fulfilled.
779 double DataArrayDouble::doubleValue() const
783 if(getNbOfElems()==1)
785 return *getConstPointer();
788 throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is allocated but number of elements is not equal to 1 !");
791 throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is not allocated !");
795 * Returns a full copy of \a this. For more info on copying data arrays see
796 * \ref MEDCouplingArrayBasicsCopyDeep.
797 * \return DataArrayDouble * - a new instance of DataArrayDouble. The caller is to
798 * delete this array using decrRef() as it is no more needed.
800 DataArrayDouble *DataArrayDouble::deepCopy() const
802 return new DataArrayDouble(*this);
806 * Returns either a \a deep or \a shallow copy of this array. For more info see
807 * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
808 * \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
809 * \return DataArrayDouble * - either a new instance of DataArrayDouble (if \a dCpy
810 * == \a true) or \a this instance (if \a dCpy == \a false).
812 DataArrayDouble *DataArrayDouble::performCopyOrIncrRef(bool dCpy) const
819 return const_cast<DataArrayDouble *>(this);
824 * Assign zero to all values in \a this array. To know more on filling arrays see
825 * \ref MEDCouplingArrayFill.
826 * \throw If \a this is not allocated.
828 void DataArrayDouble::fillWithZero()
834 * Set all values in \a this array so that the i-th element equals to \a init + i
835 * (i starts from zero). To know more on filling arrays see \ref MEDCouplingArrayFill.
836 * \param [in] init - value to assign to the first element of array.
837 * \throw If \a this->getNumberOfComponents() != 1
838 * \throw If \a this is not allocated.
840 void DataArrayDouble::iota(double init)
843 if(getNumberOfComponents()!=1)
844 throw INTERP_KERNEL::Exception("DataArrayDouble::iota : works only for arrays with only one component, you can call 'rearrange' method before !");
845 double *ptr=getPointer();
846 int ntuples=getNumberOfTuples();
847 for(int i=0;i<ntuples;i++)
848 ptr[i]=init+double(i);
853 * Checks if all values in \a this array are equal to \a val at precision \a eps.
854 * \param [in] val - value to check equality of array values to.
855 * \param [in] eps - precision to check the equality.
856 * \return bool - \a true if all values are in range (_val_ - _eps_; _val_ + _eps_),
858 * \throw If \a this->getNumberOfComponents() != 1
859 * \throw If \a this is not allocated.
861 bool DataArrayDouble::isUniform(double val, double eps) const
864 if(getNumberOfComponents()!=1)
865 throw INTERP_KERNEL::Exception("DataArrayDouble::isUniform : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
866 int nbOfTuples=getNumberOfTuples();
867 const double *w=getConstPointer();
868 const double *end2=w+nbOfTuples;
869 const double vmin=val-eps;
870 const double vmax=val+eps;
872 if(*w<vmin || *w>vmax)
878 * Checks that \a this array is consistently **increasing** or **decreasing** in value,
879 * with at least absolute difference value of |\a eps| at each step.
880 * If not an exception is thrown.
881 * \param [in] increasing - if \a true, the array values should be increasing.
882 * \param [in] eps - minimal absolute difference between the neighbor values at which
883 * the values are considered different.
884 * \throw If sequence of values is not strictly monotonic in agreement with \a
886 * \throw If \a this->getNumberOfComponents() != 1.
887 * \throw If \a this is not allocated.
889 void DataArrayDouble::checkMonotonic(bool increasing, double eps) const
891 if(!isMonotonic(increasing,eps))
894 throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not INCREASING monotonic !");
896 throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not DECREASING monotonic !");
901 * Checks that \a this array is consistently **increasing** or **decreasing** in value,
902 * with at least absolute difference value of |\a eps| at each step.
903 * \param [in] increasing - if \a true, array values should be increasing.
904 * \param [in] eps - minimal absolute difference between the neighbor values at which
905 * the values are considered different.
906 * \return bool - \a true if values change in accordance with \a increasing arg.
907 * \throw If \a this->getNumberOfComponents() != 1.
908 * \throw If \a this is not allocated.
910 bool DataArrayDouble::isMonotonic(bool increasing, double eps) const
913 if(getNumberOfComponents()!=1)
914 throw INTERP_KERNEL::Exception("DataArrayDouble::isMonotonic : only supported with 'this' array with ONE component !");
915 int nbOfElements=getNumberOfTuples();
916 const double *ptr=getConstPointer();
920 double absEps=fabs(eps);
923 for(int i=1;i<nbOfElements;i++)
925 if(ptr[i]<(ref+absEps))
933 for(int i=1;i<nbOfElements;i++)
935 if(ptr[i]>(ref-absEps))
944 * Returns a textual and human readable representation of \a this instance of
945 * DataArrayDouble. This text is shown when a DataArrayDouble is printed in Python.
946 * \return std::string - text describing \a this DataArrayDouble.
948 * \sa reprNotTooLong, reprZip
950 std::string DataArrayDouble::repr() const
952 std::ostringstream ret;
957 std::string DataArrayDouble::reprZip() const
959 std::ostringstream ret;
965 * This method is close to repr method except that when \a this has more than 1000 tuples, all tuples are not
966 * printed out to avoid to consume too much space in interpretor.
969 std::string DataArrayDouble::reprNotTooLong() const
971 std::ostringstream ret;
972 reprNotTooLongStream(ret);
976 void DataArrayDouble::writeVTK(std::ostream& ofs, int indent, const std::string& nameInFile, DataArrayByte *byteArr) const
978 static const char SPACE[4]={' ',' ',' ',' '};
980 std::string idt(indent,' ');
982 ofs << idt << "<DataArray type=\"Float32\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
984 bool areAllEmpty(true);
985 for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
989 for(std::size_t i=0;i<_info_on_compo.size();i++)
990 ofs << " ComponentName" << i << "=\"" << _info_on_compo[i] << "\"";
994 ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
995 INTERP_KERNEL::AutoPtr<float> tmp(new float[getNbOfElems()]);
997 // to make Visual C++ happy : instead of std::copy(begin(),end(),(float *)tmp);
998 for(const double *src=begin();src!=end();src++,pt++)
1000 const char *data(reinterpret_cast<const char *>((float *)tmp));
1001 std::size_t sz(getNbOfElems()*sizeof(float));
1002 byteArr->insertAtTheEnd(data,data+sz);
1003 byteArr->insertAtTheEnd(SPACE,SPACE+4);
1007 ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
1008 std::copy(begin(),end(),std::ostream_iterator<double>(ofs," "));
1010 ofs << std::endl << idt << "</DataArray>\n";
1013 void DataArrayDouble::reprStream(std::ostream& stream) const
1015 stream << "Name of double array : \"" << _name << "\"\n";
1016 reprWithoutNameStream(stream);
1019 void DataArrayDouble::reprZipStream(std::ostream& stream) const
1021 stream << "Name of double array : \"" << _name << "\"\n";
1022 reprZipWithoutNameStream(stream);
1025 void DataArrayDouble::reprNotTooLongStream(std::ostream& stream) const
1027 stream << "Name of double array : \"" << _name << "\"\n";
1028 reprNotTooLongWithoutNameStream(stream);
1031 void DataArrayDouble::reprWithoutNameStream(std::ostream& stream) const
1033 DataArray::reprWithoutNameStream(stream);
1034 stream.precision(17);
1035 _mem.repr(getNumberOfComponents(),stream);
1038 void DataArrayDouble::reprZipWithoutNameStream(std::ostream& stream) const
1040 DataArray::reprWithoutNameStream(stream);
1041 stream.precision(17);
1042 _mem.reprZip(getNumberOfComponents(),stream);
1045 void DataArrayDouble::reprNotTooLongWithoutNameStream(std::ostream& stream) const
1047 DataArray::reprWithoutNameStream(stream);
1048 stream.precision(17);
1049 _mem.reprNotTooLong(getNumberOfComponents(),stream);
1052 void DataArrayDouble::reprCppStream(const std::string& varName, std::ostream& stream) const
1054 int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
1055 const double *data=getConstPointer();
1056 stream.precision(17);
1057 stream << "DataArrayDouble *" << varName << "=DataArrayDouble::New();" << std::endl;
1058 if(nbTuples*nbComp>=1)
1060 stream << "const double " << varName << "Data[" << nbTuples*nbComp << "]={";
1061 std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<double>(stream,","));
1062 stream << data[nbTuples*nbComp-1] << "};" << std::endl;
1063 stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
1066 stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
1067 stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
1071 * Method that gives a quick overvien of \a this for python.
1073 void DataArrayDouble::reprQuickOverview(std::ostream& stream) const
1075 static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
1076 stream << "DataArrayDouble C++ instance at " << this << ". ";
1079 int nbOfCompo=(int)_info_on_compo.size();
1082 int nbOfTuples=getNumberOfTuples();
1083 stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
1084 reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
1087 stream << "Number of components : 0.";
1090 stream << "*** No data allocated ****";
1093 void DataArrayDouble::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
1095 const double *data=begin();
1096 int nbOfTuples=getNumberOfTuples();
1097 int nbOfCompo=(int)_info_on_compo.size();
1098 std::ostringstream oss2; oss2 << "[";
1100 std::string oss2Str(oss2.str());
1101 bool isFinished=true;
1102 for(int i=0;i<nbOfTuples && isFinished;i++)
1107 for(int j=0;j<nbOfCompo;j++,data++)
1110 if(j!=nbOfCompo-1) oss2 << ", ";
1116 if(i!=nbOfTuples-1) oss2 << ", ";
1117 std::string oss3Str(oss2.str());
1118 if(oss3Str.length()<maxNbOfByteInRepr)
1130 * Equivalent to DataArrayDouble::isEqual except that if false the reason of
1131 * mismatch is given.
1133 * \param [in] other the instance to be compared with \a this
1134 * \param [in] prec the precision to compare numeric data of the arrays.
1135 * \param [out] reason In case of inequality returns the reason.
1136 * \sa DataArrayDouble::isEqual
1138 bool DataArrayDouble::isEqualIfNotWhy(const DataArrayDouble& other, double prec, std::string& reason) const
1140 if(!areInfoEqualsIfNotWhy(other,reason))
1142 return _mem.isEqual(other._mem,prec,reason);
1146 * Checks if \a this and another DataArrayDouble are fully equal. For more info see
1147 * \ref MEDCouplingArrayBasicsCompare.
1148 * \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1149 * \param [in] prec - precision value to compare numeric data of the arrays.
1150 * \return bool - \a true if the two arrays are equal, \a false else.
1152 bool DataArrayDouble::isEqual(const DataArrayDouble& other, double prec) const
1155 return isEqualIfNotWhy(other,prec,tmp);
1159 * Checks if values of \a this and another DataArrayDouble are equal. For more info see
1160 * \ref MEDCouplingArrayBasicsCompare.
1161 * \param [in] other - an instance of DataArrayDouble to compare with \a this one.
1162 * \param [in] prec - precision value to compare numeric data of the arrays.
1163 * \return bool - \a true if the values of two arrays are equal, \a false else.
1165 bool DataArrayDouble::isEqualWithoutConsideringStr(const DataArrayDouble& other, double prec) const
1168 return _mem.isEqual(other._mem,prec,tmp);
1172 * Creates a new DataArrayInt and assigns all (textual and numerical) data of \a this
1173 * array to the new one.
1174 * \return DataArrayInt * - the new instance of DataArrayInt.
1176 DataArrayInt *DataArrayDouble::convertToIntArr() const
1178 DataArrayInt *ret=DataArrayInt::New();
1179 ret->alloc(getNumberOfTuples(),getNumberOfComponents());
1180 int *dest=ret->getPointer();
1181 // to make Visual C++ happy : instead of std::size_t nbOfVals=getNbOfElems(); std::copy(src,src+nbOfVals,dest);
1182 for(const double *src=begin();src!=end();src++,dest++)
1184 ret->copyStringInfoFrom(*this);
1189 * Returns a new DataArrayDouble holding the same values as \a this array but differently
1190 * arranged in memory. If \a this array holds 2 components of 3 values:
1191 * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
1192 * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
1193 * \warning Do not confuse this method with transpose()!
1194 * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1195 * is to delete using decrRef() as it is no more needed.
1196 * \throw If \a this is not allocated.
1198 DataArrayDouble *DataArrayDouble::fromNoInterlace() const
1201 throw INTERP_KERNEL::Exception("DataArrayDouble::fromNoInterlace : Not defined array !");
1202 double *tab=_mem.fromNoInterlace(getNumberOfComponents());
1203 DataArrayDouble *ret=DataArrayDouble::New();
1204 ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
1209 * Returns a new DataArrayDouble holding the same values as \a this array but differently
1210 * arranged in memory. If \a this array holds 2 components of 3 values:
1211 * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
1212 * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
1213 * \warning Do not confuse this method with transpose()!
1214 * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1215 * is to delete using decrRef() as it is no more needed.
1216 * \throw If \a this is not allocated.
1218 DataArrayDouble *DataArrayDouble::toNoInterlace() const
1221 throw INTERP_KERNEL::Exception("DataArrayDouble::toNoInterlace : Not defined array !");
1222 double *tab=_mem.toNoInterlace(getNumberOfComponents());
1223 DataArrayDouble *ret=DataArrayDouble::New();
1224 ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
1229 * Appends components of another array to components of \a this one, tuple by tuple.
1230 * So that the number of tuples of \a this array remains the same and the number of
1231 * components increases.
1232 * \param [in] other - the DataArrayDouble to append to \a this one.
1233 * \throw If \a this is not allocated.
1234 * \throw If \a this and \a other arrays have different number of tuples.
1236 * \if ENABLE_EXAMPLES
1237 * \ref cpp_mcdataarraydouble_meldwith "Here is a C++ example".
1239 * \ref py_mcdataarraydouble_meldwith "Here is a Python example".
1242 void DataArrayDouble::meldWith(const DataArrayDouble *other)
1245 other->checkAllocated();
1246 int nbOfTuples=getNumberOfTuples();
1247 if(nbOfTuples!=other->getNumberOfTuples())
1248 throw INTERP_KERNEL::Exception("DataArrayDouble::meldWith : mismatch of number of tuples !");
1249 int nbOfComp1=getNumberOfComponents();
1250 int nbOfComp2=other->getNumberOfComponents();
1251 double *newArr=(double *)malloc((nbOfTuples*(nbOfComp1+nbOfComp2))*sizeof(double));
1253 const double *inp1=getConstPointer();
1254 const double *inp2=other->getConstPointer();
1255 for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
1257 w=std::copy(inp1,inp1+nbOfComp1,w);
1258 w=std::copy(inp2,inp2+nbOfComp2,w);
1260 useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
1261 std::vector<int> compIds(nbOfComp2);
1262 for(int i=0;i<nbOfComp2;i++)
1263 compIds[i]=nbOfComp1+i;
1264 copyPartOfStringInfoFrom2(compIds,*other);
1268 * This method checks that all tuples in \a other are in \a this.
1269 * If true, the output param \a tupleIds contains the tuples ids of \a this that correspond to tupes in \a this.
1270 * 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.
1272 * \param [in] other - the array having the same number of components than \a this.
1273 * \param [out] tupleIds - the tuple ids containing the same number of tuples than \a other has.
1274 * \sa DataArrayDouble::findCommonTuples
1276 bool DataArrayDouble::areIncludedInMe(const DataArrayDouble *other, double prec, DataArrayInt *&tupleIds) const
1279 throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : input array is NULL !");
1280 checkAllocated(); other->checkAllocated();
1281 if(getNumberOfComponents()!=other->getNumberOfComponents())
1282 throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : the number of components does not match !");
1283 MCAuto<DataArrayDouble> a=DataArrayDouble::Aggregate(this,other);
1284 DataArrayInt *c=0,*ci=0;
1285 a->findCommonTuples(prec,getNumberOfTuples(),c,ci);
1286 MCAuto<DataArrayInt> cSafe(c),ciSafe(ci);
1287 int newNbOfTuples=-1;
1288 MCAuto<DataArrayInt> ids=DataArrayInt::ConvertIndexArrayToO2N(a->getNumberOfTuples(),c->begin(),ci->begin(),ci->end(),newNbOfTuples);
1289 MCAuto<DataArrayInt> ret1=ids->selectByTupleIdSafeSlice(getNumberOfTuples(),a->getNumberOfTuples(),1);
1290 tupleIds=ret1.retn();
1291 return newNbOfTuples==getNumberOfTuples();
1295 * Searches for tuples coincident within \a prec tolerance. Each tuple is considered
1296 * as coordinates of a point in getNumberOfComponents()-dimensional space. The
1297 * distance separating two points is computed with the infinite norm.
1299 * Indices of coincident tuples are stored in output arrays.
1300 * A pair of arrays (\a comm, \a commIndex) is called "Surjective Format 2".
1302 * This method is typically used by MEDCouplingPointSet::findCommonNodes() and
1303 * MEDCouplingUMesh::mergeNodes().
1304 * \param [in] prec - minimal absolute distance between two tuples (infinite norm) at which they are
1305 * considered not coincident.
1306 * \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
1307 * tuples have id strictly lower than \a limitTupleId then they are not returned.
1308 * \param [out] comm - the array holding ids (== indices) of coincident tuples.
1309 * \a comm->getNumberOfComponents() == 1.
1310 * \a comm->getNumberOfTuples() == \a commIndex->back().
1311 * \param [out] commIndex - the array dividing all indices stored in \a comm into
1312 * groups of (indices of) coincident tuples. Its every value is a tuple
1313 * index where a next group of tuples begins. For example the second
1314 * group of tuples in \a comm is described by following range of indices:
1315 * [ \a commIndex[1], \a commIndex[2] ). \a commIndex->getNumberOfTuples()-1
1316 * gives the number of groups of coincident tuples.
1317 * \throw If \a this is not allocated.
1318 * \throw If the number of components is not in [1,2,3,4].
1320 * \if ENABLE_EXAMPLES
1321 * \ref cpp_mcdataarraydouble_findcommontuples "Here is a C++ example".
1323 * \ref py_mcdataarraydouble_findcommontuples "Here is a Python example".
1325 * \sa DataArrayInt::ConvertIndexArrayToO2N(), DataArrayDouble::areIncludedInMe
1327 void DataArrayDouble::findCommonTuples(double prec, int limitTupleId, DataArrayInt *&comm, DataArrayInt *&commIndex) const
1330 int nbOfCompo=getNumberOfComponents();
1331 if ((nbOfCompo<1) || (nbOfCompo>4)) //test before work
1332 throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : Unexpected spacedim of coords. Must be 1, 2, 3 or 4.");
1334 int nbOfTuples=getNumberOfTuples();
1336 MCAuto<DataArrayInt> c(DataArrayInt::New()),cI(DataArrayInt::New()); c->alloc(0,1); cI->pushBackSilent(0);
1340 findCommonTuplesAlg<4>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1343 findCommonTuplesAlg<3>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1346 findCommonTuplesAlg<2>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1349 findCommonTuplesAlg<1>(begin(),nbOfTuples,limitTupleId,prec,c,cI);
1352 throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : nb of components managed are 1,2,3 and 4 ! not implemented for other number of components !");
1355 commIndex=cI.retn();
1360 * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayDouble instance.
1361 * \a nbTimes should be at least equal to 1.
1362 * \return a newly allocated DataArrayDouble having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
1363 * \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.
1365 DataArrayDouble *DataArrayDouble::duplicateEachTupleNTimes(int nbTimes) const
1368 if(getNumberOfComponents()!=1)
1369 throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : this should have only one component !");
1371 throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : nb times should be >= 1 !");
1372 int nbTuples=getNumberOfTuples();
1373 const double *inPtr=getConstPointer();
1374 MCAuto<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbTimes*nbTuples,1);
1375 double *retPtr=ret->getPointer();
1376 for(int i=0;i<nbTuples;i++,inPtr++)
1379 for(int j=0;j<nbTimes;j++,retPtr++)
1382 ret->copyStringInfoFrom(*this);
1387 * This methods returns the minimal distance between the two set of points \a this and \a other.
1388 * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
1389 * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
1391 * \param [out] thisTupleId the tuple id in \a this corresponding to the returned minimal distance
1392 * \param [out] otherTupleId the tuple id in \a other corresponding to the returned minimal distance
1393 * \return the minimal distance between the two set of points \a this and \a other.
1394 * \sa DataArrayDouble::findClosestTupleId
1396 double DataArrayDouble::minimalDistanceTo(const DataArrayDouble *other, int& thisTupleId, int& otherTupleId) const
1398 MCAuto<DataArrayInt> part1=findClosestTupleId(other);
1399 int nbOfCompo(getNumberOfComponents());
1400 int otherNbTuples(other->getNumberOfTuples());
1401 const double *thisPt(begin()),*otherPt(other->begin());
1402 const int *part1Pt(part1->begin());
1403 double ret=std::numeric_limits<double>::max();
1404 for(int i=0;i<otherNbTuples;i++,part1Pt++,otherPt+=nbOfCompo)
1407 for(int j=0;j<nbOfCompo;j++)
1408 tmp+=(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j])*(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j]);
1410 { ret=tmp; thisTupleId=*part1Pt; otherTupleId=i; }
1416 * This methods returns for each tuple in \a other which tuple in \a this is the closest.
1417 * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
1418 * This method works only if number of components of \a this (equal to those of \a other) is in 1, 2 or 3.
1420 * \return a newly allocated (new object to be dealt by the caller) DataArrayInt having \c other->getNumberOfTuples() tuples and one components.
1421 * \sa DataArrayDouble::minimalDistanceTo
1423 DataArrayInt *DataArrayDouble::findClosestTupleId(const DataArrayDouble *other) const
1426 throw INTERP_KERNEL::Exception("DataArrayDouble::findClosestTupleId : other instance is NULL !");
1427 checkAllocated(); other->checkAllocated();
1428 int nbOfCompo=getNumberOfComponents();
1429 if(nbOfCompo!=other->getNumberOfComponents())
1431 std::ostringstream oss; oss << "DataArrayDouble::findClosestTupleId : number of components in this is " << nbOfCompo;
1432 oss << ", whereas number of components in other is " << other->getNumberOfComponents() << "! Should be equal !";
1433 throw INTERP_KERNEL::Exception(oss.str().c_str());
1435 int nbOfTuples=other->getNumberOfTuples();
1436 int thisNbOfTuples=getNumberOfTuples();
1437 MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuples,1);
1439 getMinMaxPerComponent(bounds);
1444 double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2])),zDelta(fabs(bounds[5]-bounds[4]));
1445 double delta=std::max(xDelta,yDelta); delta=std::max(delta,zDelta);
1446 double characSize=pow((delta*delta*delta)/((double)thisNbOfTuples),1./3.);
1447 BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1448 FindClosestTupleIdAlg<3>(myTree,3.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1453 double xDelta(fabs(bounds[1]-bounds[0])),yDelta(fabs(bounds[3]-bounds[2]));
1454 double delta=std::max(xDelta,yDelta);
1455 double characSize=sqrt(delta/(double)thisNbOfTuples);
1456 BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1457 FindClosestTupleIdAlg<2>(myTree,2.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1462 double characSize=fabs(bounds[1]-bounds[0])/thisNbOfTuples;
1463 BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),characSize*1e-12);
1464 FindClosestTupleIdAlg<1>(myTree,1.*characSize*characSize,other->begin(),nbOfTuples,begin(),thisNbOfTuples,ret->getPointer());
1468 throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for findClosestTupleId. Must be 1, 2 or 3.");
1474 * This method expects that \a this and \a otherBBoxFrmt arrays are bounding box arrays ( as the output of MEDCouplingPointSet::getBoundingBoxForBBTree method ).
1475 * 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
1476 * how many bounding boxes in \a otherBBoxFrmt.
1477 * So, this method expects that \a this and \a otherBBoxFrmt have the same number of components.
1479 * \param [in] otherBBoxFrmt - It is an array .
1480 * \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.
1481 * \sa MEDCouplingPointSet::getBoundingBoxForBBTree
1482 * \throw If \a this and \a otherBBoxFrmt have not the same number of components.
1483 * \throw If \a this and \a otherBBoxFrmt number of components is not even (BBox format).
1485 DataArrayInt *DataArrayDouble::computeNbOfInteractionsWith(const DataArrayDouble *otherBBoxFrmt, double eps) const
1488 throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : input array is NULL !");
1489 if(!isAllocated() || !otherBBoxFrmt->isAllocated())
1490 throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : this and input array must be allocated !");
1491 int nbOfComp(getNumberOfComponents()),nbOfTuples(getNumberOfTuples());
1492 if(nbOfComp!=otherBBoxFrmt->getNumberOfComponents())
1494 std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : this number of components (" << nbOfComp << ") must be equal to the number of components of input array (" << otherBBoxFrmt->getNumberOfComponents() << ") !";
1495 throw INTERP_KERNEL::Exception(oss.str().c_str());
1499 std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : Number of components (" << nbOfComp << ") is not even ! It should be to be compatible with bbox format !";
1500 throw INTERP_KERNEL::Exception(oss.str().c_str());
1502 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbOfTuples,1);
1503 const double *thisBBPtr(begin());
1504 int *retPtr(ret->getPointer());
1509 BBTree<3,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
1510 for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
1511 *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
1516 BBTree<2,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
1517 for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
1518 *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
1523 BBTree<1,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps);
1524 for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp)
1525 *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr);
1529 throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : space dimension supported are [1,2,3] !");
1536 * Returns a copy of \a this array by excluding coincident tuples. Each tuple is
1537 * considered as coordinates of a point in getNumberOfComponents()-dimensional
1538 * space. The distance between tuples is computed using norm2. If several tuples are
1539 * not far each from other than \a prec, only one of them remains in the result
1540 * array. The order of tuples in the result array is same as in \a this one except
1541 * that coincident tuples are excluded.
1542 * \param [in] prec - minimal absolute distance between two tuples at which they are
1543 * considered not coincident.
1544 * \param [in] limitTupleId - limit tuple id. If all tuples within a group of coincident
1545 * tuples have id strictly lower than \a limitTupleId then they are not excluded.
1546 * \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
1547 * is to delete using decrRef() as it is no more needed.
1548 * \throw If \a this is not allocated.
1549 * \throw If the number of components is not in [1,2,3,4].
1551 * \if ENABLE_EXAMPLES
1552 * \ref py_mcdataarraydouble_getdifferentvalues "Here is a Python example".
1555 DataArrayDouble *DataArrayDouble::getDifferentValues(double prec, int limitTupleId) const
1558 DataArrayInt *c0=0,*cI0=0;
1559 findCommonTuples(prec,limitTupleId,c0,cI0);
1560 MCAuto<DataArrayInt> c(c0),cI(cI0);
1561 int newNbOfTuples=-1;
1562 MCAuto<DataArrayInt> o2n=DataArrayInt::ConvertIndexArrayToO2N(getNumberOfTuples(),c0->begin(),cI0->begin(),cI0->end(),newNbOfTuples);
1563 return renumberAndReduce(o2n->getConstPointer(),newNbOfTuples);
1567 * Copy all components in a specified order from another DataArrayDouble.
1568 * Both numerical and textual data is copied. The number of tuples in \a this and
1569 * the other array can be different.
1570 * \param [in] a - the array to copy data from.
1571 * \param [in] compoIds - sequence of zero based indices of components, data of which is
1573 * \throw If \a a is NULL.
1574 * \throw If \a compoIds.size() != \a a->getNumberOfComponents().
1575 * \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
1577 * \if ENABLE_EXAMPLES
1578 * \ref py_mcdataarraydouble_setselectedcomponents "Here is a Python example".
1581 void DataArrayDouble::setSelectedComponents(const DataArrayDouble *a, const std::vector<int>& compoIds)
1584 throw INTERP_KERNEL::Exception("DataArrayDouble::setSelectedComponents : input DataArrayDouble is NULL !");
1586 copyPartOfStringInfoFrom2(compoIds,*a);
1587 std::size_t partOfCompoSz=compoIds.size();
1588 int nbOfCompo=getNumberOfComponents();
1589 int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
1590 const double *ac=a->getConstPointer();
1591 double *nc=getPointer();
1592 for(int i=0;i<nbOfTuples;i++)
1593 for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
1594 nc[nbOfCompo*i+compoIds[j]]=*ac;
1597 void DataArrayDouble::SetArrayIn(DataArrayDouble *newArray, DataArrayDouble* &arrayToSet)
1599 if(newArray!=arrayToSet)
1602 arrayToSet->decrRef();
1603 arrayToSet=newArray;
1605 arrayToSet->incrRef();
1609 void DataArrayDouble::aggregate(const DataArrayDouble *other)
1612 throw INTERP_KERNEL::Exception("DataArrayDouble::aggregate : null pointer !");
1613 if(getNumberOfComponents()!=other->getNumberOfComponents())
1614 throw INTERP_KERNEL::Exception("DataArrayDouble::aggregate : mismatch number of components !");
1615 _mem.insertAtTheEnd(other->begin(),other->end());
1619 * Checks if 0.0 value is present in \a this array. If it is the case, an exception
1621 * \throw If zero is found in \a this array.
1623 void DataArrayDouble::checkNoNullValues() const
1625 const double *tmp=getConstPointer();
1626 std::size_t nbOfElems=getNbOfElems();
1627 const double *where=std::find(tmp,tmp+nbOfElems,0.);
1628 if(where!=tmp+nbOfElems)
1629 throw INTERP_KERNEL::Exception("A value 0.0 have been detected !");
1633 * Computes minimal and maximal value in each component. An output array is filled
1634 * with \c 2 * \a this->getNumberOfComponents() values, so the caller is to allocate
1635 * enough memory before calling this method.
1636 * \param [out] bounds - array of size at least 2 *\a this->getNumberOfComponents().
1637 * It is filled as follows:<br>
1638 * \a bounds[0] = \c min_of_component_0 <br>
1639 * \a bounds[1] = \c max_of_component_0 <br>
1640 * \a bounds[2] = \c min_of_component_1 <br>
1641 * \a bounds[3] = \c max_of_component_1 <br>
1644 void DataArrayDouble::getMinMaxPerComponent(double *bounds) const
1647 int dim=getNumberOfComponents();
1648 for (int idim=0; idim<dim; idim++)
1650 bounds[idim*2]=std::numeric_limits<double>::max();
1651 bounds[idim*2+1]=-std::numeric_limits<double>::max();
1653 const double *ptr=getConstPointer();
1654 int nbOfTuples=getNumberOfTuples();
1655 for(int i=0;i<nbOfTuples;i++)
1657 for(int idim=0;idim<dim;idim++)
1659 if(bounds[idim*2]>ptr[i*dim+idim])
1661 bounds[idim*2]=ptr[i*dim+idim];
1663 if(bounds[idim*2+1]<ptr[i*dim+idim])
1665 bounds[idim*2+1]=ptr[i*dim+idim];
1672 * This method retrieves a newly allocated DataArrayDouble instance having same number of tuples than \a this and twice number of components than \a this
1673 * to store both the min and max per component of each tuples.
1674 * \param [in] epsilon the width of the bbox (identical in each direction) - 0.0 by default
1676 * \return a newly created DataArrayDouble instance having \c this->getNumberOfTuples() tuples and 2 * \c this->getNumberOfComponent() components
1678 * \throw If \a this is not allocated yet.
1680 DataArrayDouble *DataArrayDouble::computeBBoxPerTuple(double epsilon) const
1683 const double *dataPtr=getConstPointer();
1684 int nbOfCompo=getNumberOfComponents();
1685 int nbTuples=getNumberOfTuples();
1686 MCAuto<DataArrayDouble> bbox=DataArrayDouble::New();
1687 bbox->alloc(nbTuples,2*nbOfCompo);
1688 double *bboxPtr=bbox->getPointer();
1689 for(int i=0;i<nbTuples;i++)
1691 for(int j=0;j<nbOfCompo;j++)
1693 bboxPtr[2*nbOfCompo*i+2*j]=dataPtr[nbOfCompo*i+j]-epsilon;
1694 bboxPtr[2*nbOfCompo*i+2*j+1]=dataPtr[nbOfCompo*i+j]+epsilon;
1701 * For each tuples **t** in \a other, this method retrieves tuples in \a this that are equal to **t**.
1702 * Two tuples are considered equal if the euclidian distance between the two tuples is lower than \a eps.
1704 * \param [in] other a DataArrayDouble having same number of components than \a this.
1705 * \param [in] eps absolute precision representing distance (using infinite norm) between 2 tuples behind which 2 tuples are considered equal.
1706 * \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.
1707 * \a cI allows to extract information in \a c.
1708 * \param [out] cI is an indirection array that allows to extract the data contained in \a c.
1710 * \throw In case of:
1711 * - \a this is not allocated
1712 * - \a other is not allocated or null
1713 * - \a this and \a other do not have the same number of components
1714 * - if number of components of \a this is not in [1,2,3]
1716 * \sa MEDCouplingPointSet::getNodeIdsNearPoints, DataArrayDouble::getDifferentValues
1718 void DataArrayDouble::computeTupleIdsNearTuples(const DataArrayDouble *other, double eps, DataArrayInt *& c, DataArrayInt *& cI) const
1721 throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : input pointer other is null !");
1723 other->checkAllocated();
1724 int nbOfCompo=getNumberOfComponents();
1725 int otherNbOfCompo=other->getNumberOfComponents();
1726 if(nbOfCompo!=otherNbOfCompo)
1727 throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : number of components should be equal between this and other !");
1728 int nbOfTuplesOther=other->getNumberOfTuples();
1729 MCAuto<DataArrayInt> cArr(DataArrayInt::New()),cIArr(DataArrayInt::New()); cArr->alloc(0,1); cIArr->pushBackSilent(0);
1734 BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
1735 FindTupleIdsNearTuplesAlg<3>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
1740 BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
1741 FindTupleIdsNearTuplesAlg<2>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
1746 BBTreePts<1,int> myTree(begin(),0,0,getNumberOfTuples(),eps);
1747 FindTupleIdsNearTuplesAlg<1>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
1751 throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for computeTupleIdsNearTuples. Must be 1, 2 or 3.");
1753 c=cArr.retn(); cI=cIArr.retn();
1757 * 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
1758 * around origin of 'radius' 1.
1760 * \param [in] eps absolute epsilon. under that value of delta between max and min no scale is performed.
1762 void DataArrayDouble::recenterForMaxPrecision(double eps)
1765 int dim=getNumberOfComponents();
1766 std::vector<double> bounds(2*dim);
1767 getMinMaxPerComponent(&bounds[0]);
1768 for(int i=0;i<dim;i++)
1770 double delta=bounds[2*i+1]-bounds[2*i];
1771 double offset=(bounds[2*i]+bounds[2*i+1])/2.;
1773 applyLin(1./delta,-offset/delta,i);
1775 applyLin(1.,-offset,i);
1780 * Returns the maximal value and all its locations within \a this one-dimensional array.
1781 * \param [out] tupleIds - a new instance of DataArrayInt containg indices of
1782 * tuples holding the maximal value. The caller is to delete it using
1783 * decrRef() as it is no more needed.
1784 * \return double - the maximal value among all values of \a this array.
1785 * \throw If \a this->getNumberOfComponents() != 1
1786 * \throw If \a this->getNumberOfTuples() < 1
1788 double DataArrayDouble::getMaxValue2(DataArrayInt*& tupleIds) const
1792 double ret=getMaxValue(tmp);
1793 tupleIds=findIdsInRange(ret,ret);
1798 * Returns the minimal value and all its locations within \a this one-dimensional array.
1799 * \param [out] tupleIds - a new instance of DataArrayInt containg indices of
1800 * tuples holding the minimal value. The caller is to delete it using
1801 * decrRef() as it is no more needed.
1802 * \return double - the minimal value among all values of \a this array.
1803 * \throw If \a this->getNumberOfComponents() != 1
1804 * \throw If \a this->getNumberOfTuples() < 1
1806 double DataArrayDouble::getMinValue2(DataArrayInt*& tupleIds) const
1810 double ret=getMinValue(tmp);
1811 tupleIds=findIdsInRange(ret,ret);
1816 * 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.
1817 * This method only works for single component array.
1819 * \return a value in [ 0, \c this->getNumberOfTuples() )
1821 * \throw If \a this is not allocated
1824 int DataArrayDouble::count(double value, double eps) const
1828 if(getNumberOfComponents()!=1)
1829 throw INTERP_KERNEL::Exception("DataArrayDouble::count : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
1830 const double *vals=begin();
1831 int nbOfTuples=getNumberOfTuples();
1832 for(int i=0;i<nbOfTuples;i++,vals++)
1833 if(fabs(*vals-value)<=eps)
1839 * Returns the average value of \a this one-dimensional array.
1840 * \return double - the average value over all values of \a this array.
1841 * \throw If \a this->getNumberOfComponents() != 1
1842 * \throw If \a this->getNumberOfTuples() < 1
1844 double DataArrayDouble::getAverageValue() const
1846 if(getNumberOfComponents()!=1)
1847 throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
1848 int nbOfTuples=getNumberOfTuples();
1850 throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : array exists but number of tuples must be > 0 !");
1851 const double *vals=getConstPointer();
1852 double ret=std::accumulate(vals,vals+nbOfTuples,0.);
1853 return ret/nbOfTuples;
1857 * Returns the Euclidean norm of the vector defined by \a this array.
1858 * \return double - the value of the Euclidean norm, i.e.
1859 * the square root of the inner product of vector.
1860 * \throw If \a this is not allocated.
1862 double DataArrayDouble::norm2() const
1866 std::size_t nbOfElems=getNbOfElems();
1867 const double *pt=getConstPointer();
1868 for(std::size_t i=0;i<nbOfElems;i++,pt++)
1874 * Returns the maximum norm of the vector defined by \a this array.
1875 * This method works even if the number of components is diferent from one.
1876 * If the number of elements in \a this is 0, -1. is returned.
1877 * \return double - the value of the maximum norm, i.e.
1878 * the maximal absolute value among values of \a this array (whatever its number of components).
1879 * \throw If \a this is not allocated.
1881 double DataArrayDouble::normMax() const
1885 std::size_t nbOfElems(getNbOfElems());
1886 const double *pt(getConstPointer());
1887 for(std::size_t i=0;i<nbOfElems;i++,pt++)
1889 double val(std::abs(*pt));
1897 * Returns the minimum norm (absolute value) of the vector defined by \a this array.
1898 * This method works even if the number of components is diferent from one.
1899 * If the number of elements in \a this is 0, std::numeric_limits<double>::max() is returned.
1900 * \return double - the value of the minimum norm, i.e.
1901 * the minimal absolute value among values of \a this array (whatever its number of components).
1902 * \throw If \a this is not allocated.
1904 double DataArrayDouble::normMin() const
1907 double ret(std::numeric_limits<double>::max());
1908 std::size_t nbOfElems(getNbOfElems());
1909 const double *pt(getConstPointer());
1910 for(std::size_t i=0;i<nbOfElems;i++,pt++)
1912 double val(std::abs(*pt));
1920 * Accumulates values of each component of \a this array.
1921 * \param [out] res - an array of length \a this->getNumberOfComponents(), allocated
1922 * by the caller, that is filled by this method with sum value for each
1924 * \throw If \a this is not allocated.
1926 void DataArrayDouble::accumulate(double *res) const
1929 const double *ptr=getConstPointer();
1930 int nbTuple=getNumberOfTuples();
1931 int nbComps=getNumberOfComponents();
1932 std::fill(res,res+nbComps,0.);
1933 for(int i=0;i<nbTuple;i++)
1934 std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<double>());
1938 * This method returns the min distance from an external tuple defined by [ \a tupleBg , \a tupleEnd ) to \a this and
1939 * the first tuple in \a this that matches the returned distance. If there is no tuples in \a this an exception will be thrown.
1942 * \a this is expected to be allocated and expected to have a number of components equal to the distance from \a tupleBg to
1943 * \a tupleEnd. If not an exception will be thrown.
1945 * \param [in] tupleBg start pointer (included) of input external tuple
1946 * \param [in] tupleEnd end pointer (not included) of input external tuple
1947 * \param [out] tupleId the tuple id in \a this that matches the min of distance between \a this and input external tuple
1948 * \return the min distance.
1949 * \sa MEDCouplingUMesh::distanceToPoint
1951 double DataArrayDouble::distanceToTuple(const double *tupleBg, const double *tupleEnd, int& tupleId) const
1954 int nbTuple=getNumberOfTuples();
1955 int nbComps=getNumberOfComponents();
1956 if(nbComps!=(int)std::distance(tupleBg,tupleEnd))
1957 { 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()); }
1959 throw INTERP_KERNEL::Exception("DataArrayDouble::distanceToTuple : no tuple in this ! No distance to compute !");
1960 double ret0=std::numeric_limits<double>::max();
1962 const double *work=getConstPointer();
1963 for(int i=0;i<nbTuple;i++)
1966 for(int j=0;j<nbComps;j++,work++)
1967 val+=(*work-tupleBg[j])*((*work-tupleBg[j]));
1971 { ret0=val; tupleId=i; }
1977 * Accumulate values of the given component of \a this array.
1978 * \param [in] compId - the index of the component of interest.
1979 * \return double - a sum value of \a compId-th component.
1980 * \throw If \a this is not allocated.
1981 * \throw If \a the condition ( 0 <= \a compId < \a this->getNumberOfComponents() ) is
1984 double DataArrayDouble::accumulate(int compId) const
1987 const double *ptr=getConstPointer();
1988 int nbTuple=getNumberOfTuples();
1989 int nbComps=getNumberOfComponents();
1990 if(compId<0 || compId>=nbComps)
1991 throw INTERP_KERNEL::Exception("DataArrayDouble::accumulate : Invalid compId specified : No such nb of components !");
1993 for(int i=0;i<nbTuple;i++)
1994 ret+=ptr[i*nbComps+compId];
1999 * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
2000 * The returned array will have same number of components than \a this and number of tuples equal to
2001 * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
2003 * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
2004 * 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.
2006 * \param [in] bgOfIndex - begin (included) of the input index array.
2007 * \param [in] endOfIndex - end (excluded) of the input index array.
2008 * \return DataArrayDouble * - the new instance having the same number of components than \a this.
2010 * \throw If bgOfIndex or end is NULL.
2011 * \throw If input index array is not ascendingly sorted.
2012 * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
2013 * \throw If std::distance(bgOfIndex,endOfIndex)==0.
2015 DataArrayDouble *DataArrayDouble::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
2017 if(!bgOfIndex || !endOfIndex)
2018 throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : input pointer NULL !");
2020 int nbCompo=getNumberOfComponents();
2021 int nbOfTuples=getNumberOfTuples();
2022 int sz=(int)std::distance(bgOfIndex,endOfIndex);
2024 throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : invalid size of input index array !");
2026 MCAuto<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(sz,nbCompo);
2027 const int *w=bgOfIndex;
2028 if(*w<0 || *w>=nbOfTuples)
2029 throw INTERP_KERNEL::Exception("DataArrayDouble::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
2030 const double *srcPt=begin()+(*w)*nbCompo;
2031 double *tmp=ret->getPointer();
2032 for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
2034 std::fill(tmp,tmp+nbCompo,0.);
2037 for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
2039 if(j>=0 && j<nbOfTuples)
2040 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<double>());
2043 std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
2044 throw INTERP_KERNEL::Exception(oss.str().c_str());
2050 std::ostringstream oss; oss << "DataArrayDouble::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
2051 throw INTERP_KERNEL::Exception(oss.str().c_str());
2054 ret->copyStringInfoFrom(*this);
2059 * 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.
2060 * This method expects that \a this as only one component. The returned array will have \a this->getNumberOfTuples()+1 tuple with also one component.
2061 * The ith element of returned array is equal to the sum of elements in \a this with rank strictly lower than i.
2063 * \return DataArrayDouble - A newly built array containing cum sum of \a this.
2065 MCAuto<DataArrayDouble> DataArrayDouble::cumSum() const
2068 checkNbOfComps(1,"DataArrayDouble::cumSum : this is expected to be single component");
2069 int nbOfTuple(getNumberOfTuples());
2070 MCAuto<DataArrayDouble> ret(DataArrayDouble::New()); ret->alloc(nbOfTuple+1,1);
2071 double *ptr(ret->getPointer());
2073 const double *thisPtr(begin());
2074 for(int i=0;i<nbOfTuple;i++)
2075 ptr[i+1]=ptr[i]+thisPtr[i];
2080 * Converts each 2D point defined by the tuple of \a this array from the Polar to the
2081 * Cartesian coordinate system. The two components of the tuple of \a this array are
2082 * considered to contain (1) radius and (2) angle of the point in the Polar CS.
2083 * \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
2084 * contains X and Y coordinates of the point in the Cartesian CS. The caller
2085 * is to delete this array using decrRef() as it is no more needed. The array
2086 * does not contain any textual info on components.
2087 * \throw If \a this->getNumberOfComponents() != 2.
2088 * \sa fromCartToPolar
2090 DataArrayDouble *DataArrayDouble::fromPolarToCart() const
2093 int nbOfComp(getNumberOfComponents());
2095 throw INTERP_KERNEL::Exception("DataArrayDouble::fromPolarToCart : must be an array with exactly 2 components !");
2096 int nbOfTuple(getNumberOfTuples());
2097 DataArrayDouble *ret(DataArrayDouble::New());
2098 ret->alloc(nbOfTuple,2);
2099 double *w(ret->getPointer());
2100 const double *wIn(getConstPointer());
2101 for(int i=0;i<nbOfTuple;i++,w+=2,wIn+=2)
2103 w[0]=wIn[0]*cos(wIn[1]);
2104 w[1]=wIn[0]*sin(wIn[1]);
2110 * Converts each 3D point defined by the tuple of \a this array from the Cylindrical to
2111 * the Cartesian coordinate system. The three components of the tuple of \a this array
2112 * are considered to contain (1) radius, (2) azimuth and (3) altitude of the point in
2113 * the Cylindrical CS.
2114 * \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
2115 * contains X, Y and Z coordinates of the point in the Cartesian CS. The info
2116 * on the third component is copied from \a this array. The caller
2117 * is to delete this array using decrRef() as it is no more needed.
2118 * \throw If \a this->getNumberOfComponents() != 3.
2121 DataArrayDouble *DataArrayDouble::fromCylToCart() const
2124 int nbOfComp(getNumberOfComponents());
2126 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCylToCart : must be an array with exactly 3 components !");
2127 int nbOfTuple(getNumberOfTuples());
2128 DataArrayDouble *ret(DataArrayDouble::New());
2129 ret->alloc(getNumberOfTuples(),3);
2130 double *w(ret->getPointer());
2131 const double *wIn(getConstPointer());
2132 for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
2134 w[0]=wIn[0]*cos(wIn[1]);
2135 w[1]=wIn[0]*sin(wIn[1]);
2138 ret->setInfoOnComponent(2,getInfoOnComponent(2));
2143 * Converts each 3D point defined by the tuple of \a this array from the Spherical to
2144 * the Cartesian coordinate system. The three components of the tuple of \a this array
2145 * are considered to contain (1) radius, (2) polar angle and (3) azimuthal angle of the
2146 * point in the Cylindrical CS.
2147 * \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
2148 * contains X, Y and Z coordinates of the point in the Cartesian CS. The info
2149 * on the third component is copied from \a this array. The caller
2150 * is to delete this array using decrRef() as it is no more needed.
2151 * \throw If \a this->getNumberOfComponents() != 3.
2152 * \sa fromCartToSpher
2154 DataArrayDouble *DataArrayDouble::fromSpherToCart() const
2157 int nbOfComp(getNumberOfComponents());
2159 throw INTERP_KERNEL::Exception("DataArrayDouble::fromSpherToCart : must be an array with exactly 3 components !");
2160 int nbOfTuple(getNumberOfTuples());
2161 DataArrayDouble *ret(DataArrayDouble::New());
2162 ret->alloc(getNumberOfTuples(),3);
2163 double *w(ret->getPointer());
2164 const double *wIn(getConstPointer());
2165 for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3)
2167 w[0]=wIn[0]*cos(wIn[2])*sin(wIn[1]);
2168 w[1]=wIn[0]*sin(wIn[2])*sin(wIn[1]);
2169 w[2]=wIn[0]*cos(wIn[1]);
2175 * 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.
2176 * 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.
2177 * If \a at equals to AX_CYL the returned array will be the result of operation cylindric to cartesian of \a this...
2179 * \param [in] atOfThis - The axis type of \a this.
2180 * \return DataArrayDouble * - the new instance of DataArrayDouble (that must be dealed by caller) containing the result of the cartesianizification of \a this.
2182 DataArrayDouble *DataArrayDouble::cartesianize(MEDCouplingAxisType atOfThis) const
2185 int nbOfComp(getNumberOfComponents());
2186 MCAuto<DataArrayDouble> ret;
2194 ret=fromCylToCart();
2199 ret=fromPolarToCart();
2203 throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : For AX_CYL, number of components must be in [2,3] !");
2207 ret=fromSpherToCart();
2212 ret=fromPolarToCart();
2216 throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : For AX_CYL, number of components must be in [2,3] !");
2218 throw INTERP_KERNEL::Exception("DataArrayDouble::cartesianize : not recognized axis type ! Only AX_CART, AX_CYL and AX_SPHER supported !");
2220 ret->copyStringInfoFrom(*this);
2225 * This method returns a newly created array to be deallocated that contains the result of conversion from cartesian to polar.
2226 * This method expects that \a this has exactly 2 components.
2227 * \sa fromPolarToCart
2229 DataArrayDouble *DataArrayDouble::fromCartToPolar() const
2231 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2233 int nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2235 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToPolar : must be an array with exactly 2 components !");
2236 ret->alloc(nbTuples,2);
2237 double *retPtr(ret->getPointer());
2238 const double *ptr(begin());
2239 for(int i=0;i<nbTuples;i++,ptr+=2,retPtr+=2)
2241 retPtr[0]=sqrt(ptr[0]*ptr[0]+ptr[1]*ptr[1]);
2242 retPtr[1]=atan2(ptr[1],ptr[0]);
2248 * This method returns a newly created array to be deallocated that contains the result of conversion from cartesian to cylindrical.
2249 * This method expects that \a this has exactly 3 components.
2252 DataArrayDouble *DataArrayDouble::fromCartToCyl() const
2254 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2256 int nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2258 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCyl : must be an array with exactly 3 components !");
2259 ret->alloc(nbTuples,3);
2260 double *retPtr(ret->getPointer());
2261 const double *ptr(begin());
2262 for(int i=0;i<nbTuples;i++,ptr+=3,retPtr+=3)
2264 retPtr[0]=sqrt(ptr[0]*ptr[0]+ptr[1]*ptr[1]);
2265 retPtr[1]=atan2(ptr[1],ptr[0]);
2272 * This method returns a newly created array to be deallocated that contains the result of conversion from cartesian to spherical coordinates.
2273 * \sa fromSpherToCart
2275 DataArrayDouble *DataArrayDouble::fromCartToSpher() const
2277 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2279 int nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2281 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToSpher : must be an array with exactly 3 components !");
2282 ret->alloc(nbTuples,3);
2283 double *retPtr(ret->getPointer());
2284 const double *ptr(begin());
2285 for(int i=0;i<nbTuples;i++,ptr+=3,retPtr+=3)
2287 retPtr[0]=sqrt(ptr[0]*ptr[0]+ptr[1]*ptr[1]+ptr[2]*ptr[2]);
2288 retPtr[1]=acos(ptr[2]/retPtr[0]);
2289 retPtr[2]=atan2(ptr[1],ptr[0]);
2295 * 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.
2296 * This method expects that \a this has exactly 3 components.
2297 * \sa MEDCouplingFieldDouble::computeVectorFieldCyl
2299 DataArrayDouble *DataArrayDouble::fromCartToCylGiven(const DataArrayDouble *coords, const double center[3], const double vect[3]) const
2302 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : input coords are NULL !");
2303 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2304 checkAllocated(); coords->checkAllocated();
2305 int nbOfComp(getNumberOfComponents()),nbTuples(getNumberOfTuples());
2307 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : must be an array with exactly 3 components !");
2308 if(coords->getNumberOfComponents()!=3)
2309 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : coords array must have exactly 3 components !");
2310 if(coords->getNumberOfTuples()!=nbTuples)
2311 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : coords array must have the same number of tuples !");
2312 ret->alloc(nbTuples,nbOfComp);
2313 double magOfVect(sqrt(vect[0]*vect[0]+vect[1]*vect[1]+vect[2]*vect[2]));
2315 throw INTERP_KERNEL::Exception("DataArrayDouble::fromCartToCylGiven : magnitude of vect is too low !");
2316 double Ur[3],Uteta[3],Uz[3],*retPtr(ret->getPointer());
2317 const double *coo(coords->begin()),*vectField(begin());
2318 std::transform(vect,vect+3,Uz,std::bind2nd(std::multiplies<double>(),1./magOfVect));
2319 for(int i=0;i<nbTuples;i++,vectField+=3,retPtr+=3,coo+=3)
2321 std::transform(coo,coo+3,center,Ur,std::minus<double>());
2322 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];
2323 double magOfTeta(sqrt(Uteta[0]*Uteta[0]+Uteta[1]*Uteta[1]+Uteta[2]*Uteta[2]));
2324 std::transform(Uteta,Uteta+3,Uteta,std::bind2nd(std::multiplies<double>(),1./magOfTeta));
2325 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];
2326 retPtr[0]=Ur[0]*vectField[0]+Ur[1]*vectField[1]+Ur[2]*vectField[2];
2327 retPtr[1]=Uteta[0]*vectField[0]+Uteta[1]*vectField[1]+Uteta[2]*vectField[2];
2328 retPtr[2]=Uz[0]*vectField[0]+Uz[1]*vectField[1]+Uz[2]*vectField[2];
2330 ret->copyStringInfoFrom(*this);
2335 * Computes the doubly contracted product of every tensor defined by the tuple of \a this
2336 * array contating 6 components.
2337 * \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
2338 * is calculated from the tuple <em>(t)</em> of \a this array as follows:
2339 * \f$ t[0]^2+t[1]^2+t[2]^2+2*t[3]^2+2*t[4]^2+2*t[5]^2\f$.
2340 * The caller is to delete this result array using decrRef() as it is no more needed.
2341 * \throw If \a this->getNumberOfComponents() != 6.
2343 DataArrayDouble *DataArrayDouble::doublyContractedProduct() const
2346 int nbOfComp(getNumberOfComponents());
2348 throw INTERP_KERNEL::Exception("DataArrayDouble::doublyContractedProduct : must be an array with exactly 6 components !");
2349 DataArrayDouble *ret=DataArrayDouble::New();
2350 int nbOfTuple=getNumberOfTuples();
2351 ret->alloc(nbOfTuple,1);
2352 const double *src=getConstPointer();
2353 double *dest=ret->getPointer();
2354 for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
2355 *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];
2360 * Computes the determinant of every square matrix defined by the tuple of \a this
2361 * array, which contains either 4, 6 or 9 components. The case of 6 components
2362 * corresponds to that of the upper triangular matrix.
2363 * \return DataArrayDouble * - the new instance of DataArrayDouble, whose each tuple
2364 * is the determinant of matrix of the 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() is not in [4,6,9].
2369 DataArrayDouble *DataArrayDouble::determinant() const
2372 DataArrayDouble *ret=DataArrayDouble::New();
2373 int nbOfTuple=getNumberOfTuples();
2374 ret->alloc(nbOfTuple,1);
2375 const double *src=getConstPointer();
2376 double *dest=ret->getPointer();
2377 switch(getNumberOfComponents())
2380 for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
2381 *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];
2384 for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
2385 *dest=src[0]*src[3]-src[1]*src[2];
2388 for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
2389 *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];
2393 throw INTERP_KERNEL::Exception("DataArrayDouble::determinant : Invalid number of components ! must be in 4,6,9 !");
2398 * Computes 3 eigenvalues of every upper triangular matrix defined by the tuple of
2399 * \a this array, which contains 6 components.
2400 * \return DataArrayDouble * - the new instance of DataArrayDouble containing 3
2401 * components, whose each tuple contains the eigenvalues of the matrix of
2402 * corresponding tuple of \a this array.
2403 * The caller is to delete this result array using decrRef() as it is no more
2405 * \throw If \a this->getNumberOfComponents() != 6.
2407 DataArrayDouble *DataArrayDouble::eigenValues() const
2410 int nbOfComp=getNumberOfComponents();
2412 throw INTERP_KERNEL::Exception("DataArrayDouble::eigenValues : must be an array with exactly 6 components !");
2413 DataArrayDouble *ret=DataArrayDouble::New();
2414 int nbOfTuple=getNumberOfTuples();
2415 ret->alloc(nbOfTuple,3);
2416 const double *src=getConstPointer();
2417 double *dest=ret->getPointer();
2418 for(int i=0;i<nbOfTuple;i++,dest+=3,src+=6)
2419 INTERP_KERNEL::computeEigenValues6(src,dest);
2424 * Computes 3 eigenvectors of every upper triangular matrix defined by the tuple of
2425 * \a this array, which contains 6 components.
2426 * \return DataArrayDouble * - the new instance of DataArrayDouble containing 9
2427 * components, whose each tuple contains 3 eigenvectors of the matrix of
2428 * corresponding tuple of \a this array.
2429 * The caller is to delete this result array using decrRef() as it is no more
2431 * \throw If \a this->getNumberOfComponents() != 6.
2433 DataArrayDouble *DataArrayDouble::eigenVectors() const
2436 int nbOfComp=getNumberOfComponents();
2438 throw INTERP_KERNEL::Exception("DataArrayDouble::eigenVectors : must be an array with exactly 6 components !");
2439 DataArrayDouble *ret=DataArrayDouble::New();
2440 int nbOfTuple=getNumberOfTuples();
2441 ret->alloc(nbOfTuple,9);
2442 const double *src=getConstPointer();
2443 double *dest=ret->getPointer();
2444 for(int i=0;i<nbOfTuple;i++,src+=6)
2447 INTERP_KERNEL::computeEigenValues6(src,tmp);
2448 for(int j=0;j<3;j++,dest+=3)
2449 INTERP_KERNEL::computeEigenVectorForEigenValue6(src,tmp[j],1e-12,dest);
2455 * Computes the inverse matrix of every matrix defined by the tuple of \a this
2456 * array, which contains either 4, 6 or 9 components. The case of 6 components
2457 * corresponds to that of the upper triangular matrix.
2458 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2459 * same number of components as \a this one, whose each tuple is the inverse
2460 * matrix of the matrix of corresponding tuple of \a this array.
2461 * The caller is to delete this result array using decrRef() as it is no more
2463 * \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2465 DataArrayDouble *DataArrayDouble::inverse() const
2468 int nbOfComp=getNumberOfComponents();
2469 if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
2470 throw INTERP_KERNEL::Exception("DataArrayDouble::inversion : must be an array with 4,6 or 9 components !");
2471 DataArrayDouble *ret=DataArrayDouble::New();
2472 int nbOfTuple=getNumberOfTuples();
2473 ret->alloc(nbOfTuple,nbOfComp);
2474 const double *src=getConstPointer();
2475 double *dest=ret->getPointer();
2477 for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
2479 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];
2480 dest[0]=(src[1]*src[2]-src[4]*src[4])/det;
2481 dest[1]=(src[0]*src[2]-src[5]*src[5])/det;
2482 dest[2]=(src[0]*src[1]-src[3]*src[3])/det;
2483 dest[3]=(src[5]*src[4]-src[3]*src[2])/det;
2484 dest[4]=(src[5]*src[3]-src[0]*src[4])/det;
2485 dest[5]=(src[3]*src[4]-src[1]*src[5])/det;
2487 else if(nbOfComp==4)
2488 for(int i=0;i<nbOfTuple;i++,dest+=4,src+=4)
2490 double det=src[0]*src[3]-src[1]*src[2];
2492 dest[1]=-src[1]/det;
2493 dest[2]=-src[2]/det;
2497 for(int i=0;i<nbOfTuple;i++,dest+=9,src+=9)
2499 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];
2500 dest[0]=(src[4]*src[8]-src[7]*src[5])/det;
2501 dest[1]=(src[7]*src[2]-src[1]*src[8])/det;
2502 dest[2]=(src[1]*src[5]-src[4]*src[2])/det;
2503 dest[3]=(src[6]*src[5]-src[3]*src[8])/det;
2504 dest[4]=(src[0]*src[8]-src[6]*src[2])/det;
2505 dest[5]=(src[2]*src[3]-src[0]*src[5])/det;
2506 dest[6]=(src[3]*src[7]-src[6]*src[4])/det;
2507 dest[7]=(src[6]*src[1]-src[0]*src[7])/det;
2508 dest[8]=(src[0]*src[4]-src[1]*src[3])/det;
2514 * Computes the trace of every matrix defined by the tuple of \a this
2515 * array, which contains either 4, 6 or 9 components. The case of 6 components
2516 * corresponds to that of the upper triangular matrix.
2517 * \return DataArrayDouble * - the new instance of DataArrayDouble containing
2518 * 1 component, whose each tuple is the trace of
2519 * the matrix of corresponding tuple of \a this array.
2520 * The caller is to delete this result array using decrRef() as it is no more
2522 * \throw If \a this->getNumberOfComponents() is not in [4,6,9].
2524 DataArrayDouble *DataArrayDouble::trace() const
2527 int nbOfComp=getNumberOfComponents();
2528 if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
2529 throw INTERP_KERNEL::Exception("DataArrayDouble::trace : must be an array with 4,6 or 9 components !");
2530 DataArrayDouble *ret=DataArrayDouble::New();
2531 int nbOfTuple=getNumberOfTuples();
2532 ret->alloc(nbOfTuple,1);
2533 const double *src=getConstPointer();
2534 double *dest=ret->getPointer();
2536 for(int i=0;i<nbOfTuple;i++,dest++,src+=6)
2537 *dest=src[0]+src[1]+src[2];
2538 else if(nbOfComp==4)
2539 for(int i=0;i<nbOfTuple;i++,dest++,src+=4)
2540 *dest=src[0]+src[3];
2542 for(int i=0;i<nbOfTuple;i++,dest++,src+=9)
2543 *dest=src[0]+src[4]+src[8];
2548 * Computes the stress deviator tensor of every stress tensor defined by the tuple of
2549 * \a this array, which contains 6 components.
2550 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2551 * same number of components and tuples as \a this array.
2552 * The caller is to delete this result array using decrRef() as it is no more
2554 * \throw If \a this->getNumberOfComponents() != 6.
2556 DataArrayDouble *DataArrayDouble::deviator() const
2559 int nbOfComp=getNumberOfComponents();
2561 throw INTERP_KERNEL::Exception("DataArrayDouble::deviator : must be an array with exactly 6 components !");
2562 DataArrayDouble *ret=DataArrayDouble::New();
2563 int nbOfTuple=getNumberOfTuples();
2564 ret->alloc(nbOfTuple,6);
2565 const double *src=getConstPointer();
2566 double *dest=ret->getPointer();
2567 for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6)
2569 double tr=(src[0]+src[1]+src[2])/3.;
2581 * Computes the magnitude of every vector defined by the tuple of
2583 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2584 * same number of tuples as \a this array and one component.
2585 * The caller is to delete this result array using decrRef() as it is no more
2587 * \throw If \a this is not allocated.
2589 DataArrayDouble *DataArrayDouble::magnitude() const
2592 int nbOfComp=getNumberOfComponents();
2593 DataArrayDouble *ret=DataArrayDouble::New();
2594 int nbOfTuple=getNumberOfTuples();
2595 ret->alloc(nbOfTuple,1);
2596 const double *src=getConstPointer();
2597 double *dest=ret->getPointer();
2598 for(int i=0;i<nbOfTuple;i++,dest++)
2601 for(int j=0;j<nbOfComp;j++,src++)
2609 * Computes for each tuple the sum of number of components values in the tuple and return it.
2611 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2612 * same number of tuples as \a this array and one component.
2613 * The caller is to delete this result array using decrRef() as it is no more
2615 * \throw If \a this is not allocated.
2617 DataArrayDouble *DataArrayDouble::sumPerTuple() const
2620 int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
2621 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
2622 ret->alloc(nbOfTuple,1);
2623 const double *src(getConstPointer());
2624 double *dest(ret->getPointer());
2625 for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
2626 *dest=std::accumulate(src,src+nbOfComp,0.);
2631 * Computes the maximal value within every tuple of \a this array.
2632 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2633 * same number of tuples as \a this array and one component.
2634 * The caller is to delete this result array using decrRef() as it is no more
2636 * \throw If \a this is not allocated.
2637 * \sa DataArrayDouble::maxPerTupleWithCompoId
2639 DataArrayDouble *DataArrayDouble::maxPerTuple() const
2642 int nbOfComp=getNumberOfComponents();
2643 MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
2644 int nbOfTuple=getNumberOfTuples();
2645 ret->alloc(nbOfTuple,1);
2646 const double *src=getConstPointer();
2647 double *dest=ret->getPointer();
2648 for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
2649 *dest=*std::max_element(src,src+nbOfComp);
2654 * Computes the maximal value within every tuple of \a this array and it returns the first component
2655 * id for each tuple that corresponds to the maximal value within the tuple.
2657 * \param [out] compoIdOfMaxPerTuple - the new new instance of DataArrayInt containing the
2658 * same number of tuples and only one component.
2659 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2660 * same number of tuples as \a this array and one component.
2661 * The caller is to delete this result array using decrRef() as it is no more
2663 * \throw If \a this is not allocated.
2664 * \sa DataArrayDouble::maxPerTuple
2666 DataArrayDouble *DataArrayDouble::maxPerTupleWithCompoId(DataArrayInt* &compoIdOfMaxPerTuple) const
2669 int nbOfComp=getNumberOfComponents();
2670 MCAuto<DataArrayDouble> ret0=DataArrayDouble::New();
2671 MCAuto<DataArrayInt> ret1=DataArrayInt::New();
2672 int nbOfTuple=getNumberOfTuples();
2673 ret0->alloc(nbOfTuple,1); ret1->alloc(nbOfTuple,1);
2674 const double *src=getConstPointer();
2675 double *dest=ret0->getPointer(); int *dest1=ret1->getPointer();
2676 for(int i=0;i<nbOfTuple;i++,dest++,dest1++,src+=nbOfComp)
2678 const double *loc=std::max_element(src,src+nbOfComp);
2680 *dest1=(int)std::distance(src,loc);
2682 compoIdOfMaxPerTuple=ret1.retn();
2687 * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c this->getNumberOfTuples() tuples.
2688 * \n This returned array contains the euclidian distance for each tuple in \a this.
2689 * \n So the returned array can be seen as a dense symmetrical matrix whose diagonal elements are equal to 0.
2690 * \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)
2692 * \warning use this method with care because it can leads to big amount of consumed memory !
2694 * \return A newly allocated (huge) MEDCoupling::DataArrayDouble instance that the caller should deal with.
2696 * \throw If \a this is not allocated.
2698 * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrixWith
2700 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrix() const
2703 int nbOfComp=getNumberOfComponents();
2704 int nbOfTuples=getNumberOfTuples();
2705 const double *inData=getConstPointer();
2706 MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
2707 ret->alloc(nbOfTuples*nbOfTuples,1);
2708 double *outData=ret->getPointer();
2709 for(int i=0;i<nbOfTuples;i++)
2711 outData[i*nbOfTuples+i]=0.;
2712 for(int j=i+1;j<nbOfTuples;j++)
2715 for(int k=0;k<nbOfComp;k++)
2716 { double delta=inData[i*nbOfComp+k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
2718 outData[i*nbOfTuples+j]=dist;
2719 outData[j*nbOfTuples+i]=dist;
2726 * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c other->getNumberOfTuples() tuples.
2727 * \n This returned array contains the euclidian distance for each tuple in \a other with each tuple in \a this.
2728 * \n So the returned array can be seen as a dense rectangular matrix with \c other->getNumberOfTuples() rows and \c this->getNumberOfTuples() columns.
2729 * \n Output rectangular matrix is sorted along rows.
2730 * \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)
2732 * \warning use this method with care because it can leads to big amount of consumed memory !
2734 * \param [in] other DataArrayDouble instance having same number of components than \a this.
2735 * \return A newly allocated (huge) MEDCoupling::DataArrayDouble instance that the caller should deal with.
2737 * \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.
2739 * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrix
2741 DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrixWith(const DataArrayDouble *other) const
2744 throw INTERP_KERNEL::Exception("DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : input parameter is null !");
2746 other->checkAllocated();
2747 int nbOfComp=getNumberOfComponents();
2748 int otherNbOfComp=other->getNumberOfComponents();
2749 if(nbOfComp!=otherNbOfComp)
2751 std::ostringstream oss; oss << "DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : this nb of compo=" << nbOfComp << " and other nb of compo=" << otherNbOfComp << ". It should match !";
2752 throw INTERP_KERNEL::Exception(oss.str().c_str());
2754 int nbOfTuples=getNumberOfTuples();
2755 int otherNbOfTuples=other->getNumberOfTuples();
2756 const double *inData=getConstPointer();
2757 const double *inDataOther=other->getConstPointer();
2758 MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
2759 ret->alloc(otherNbOfTuples*nbOfTuples,1);
2760 double *outData=ret->getPointer();
2761 for(int i=0;i<otherNbOfTuples;i++,inDataOther+=nbOfComp)
2763 for(int j=0;j<nbOfTuples;j++)
2766 for(int k=0;k<nbOfComp;k++)
2767 { double delta=inDataOther[k]-inData[j*nbOfComp+k]; dist+=delta*delta; }
2769 outData[i*nbOfTuples+j]=dist;
2776 * Sorts value within every tuple of \a this array.
2777 * \param [in] asc - if \a true, the values are sorted in ascending order, else,
2778 * in descending order.
2779 * \throw If \a this is not allocated.
2781 void DataArrayDouble::sortPerTuple(bool asc)
2784 double *pt=getPointer();
2785 int nbOfTuple=getNumberOfTuples();
2786 int nbOfComp=getNumberOfComponents();
2788 for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
2789 std::sort(pt,pt+nbOfComp);
2791 for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp)
2792 std::sort(pt,pt+nbOfComp,std::greater<double>());
2797 * Converts every value of \a this array to its absolute value.
2798 * \b WARNING this method is non const. If a new DataArrayDouble instance should be built containing the result of abs DataArrayDouble::computeAbs
2799 * should be called instead.
2801 * \throw If \a this is not allocated.
2802 * \sa DataArrayDouble::computeAbs
2804 void DataArrayDouble::abs()
2807 double *ptr(getPointer());
2808 std::size_t nbOfElems(getNbOfElems());
2809 std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<double,double>(fabs));
2814 * This method builds a new instance of \a this object containing the result of std::abs applied of all elements in \a this.
2815 * This method is a const method (that do not change any values in \a this) contrary to DataArrayDouble::abs method.
2817 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2818 * same number of tuples and component as \a this array.
2819 * The caller is to delete this result array using decrRef() as it is no more
2821 * \throw If \a this is not allocated.
2822 * \sa DataArrayDouble::abs
2824 DataArrayDouble *DataArrayDouble::computeAbs() const
2827 DataArrayDouble *newArr(DataArrayDouble::New());
2828 int nbOfTuples(getNumberOfTuples());
2829 int nbOfComp(getNumberOfComponents());
2830 newArr->alloc(nbOfTuples,nbOfComp);
2831 std::transform(begin(),end(),newArr->getPointer(),std::ptr_fun<double,double>(fabs));
2832 newArr->copyStringInfoFrom(*this);
2837 * Apply a linear function to a given component of \a this array, so that
2838 * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
2839 * \param [in] a - the first coefficient of the function.
2840 * \param [in] b - the second coefficient of the function.
2841 * \param [in] compoId - the index of component to modify.
2842 * \throw If \a this is not allocated, or \a compoId is not in [0,\c this->getNumberOfComponents() ).
2844 void DataArrayDouble::applyLin(double a, double b, int compoId)
2847 double *ptr(getPointer()+compoId);
2848 int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
2849 if(compoId<0 || compoId>=nbOfComp)
2851 std::ostringstream oss; oss << "DataArrayDouble::applyLin : The compoId requested (" << compoId << ") is not valid ! Must be in [0," << nbOfComp << ") !";
2852 throw INTERP_KERNEL::Exception(oss.str().c_str());
2854 for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
2860 * Apply a linear function to all elements of \a this array, so that
2861 * an element _x_ becomes \f$ a * x + b \f$.
2862 * \param [in] a - the first coefficient of the function.
2863 * \param [in] b - the second coefficient of the function.
2864 * \throw If \a this is not allocated.
2866 void DataArrayDouble::applyLin(double a, double b)
2869 double *ptr=getPointer();
2870 std::size_t nbOfElems=getNbOfElems();
2871 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2877 * Modify all elements of \a this array, so that
2878 * an element _x_ becomes \f$ numerator / x \f$.
2879 * \warning If an exception is thrown because of presence of 0.0 element in \a this
2880 * array, all elements processed before detection of the zero element remain
2882 * \param [in] numerator - the numerator used to modify array elements.
2883 * \throw If \a this is not allocated.
2884 * \throw If there is an element equal to 0.0 in \a this array.
2886 void DataArrayDouble::applyInv(double numerator)
2889 double *ptr=getPointer();
2890 std::size_t nbOfElems=getNbOfElems();
2891 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2893 if(std::abs(*ptr)>std::numeric_limits<double>::min())
2895 *ptr=numerator/(*ptr);
2899 std::ostringstream oss; oss << "DataArrayDouble::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
2901 throw INTERP_KERNEL::Exception(oss.str().c_str());
2908 * Returns a full copy of \a this array except that sign of all elements is reversed.
2909 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
2910 * same number of tuples and component as \a this array.
2911 * The caller is to delete this result array using decrRef() as it is no more
2913 * \throw If \a this is not allocated.
2915 DataArrayDouble *DataArrayDouble::negate() const
2918 DataArrayDouble *newArr=DataArrayDouble::New();
2919 int nbOfTuples=getNumberOfTuples();
2920 int nbOfComp=getNumberOfComponents();
2921 newArr->alloc(nbOfTuples,nbOfComp);
2922 const double *cptr=getConstPointer();
2923 std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<double>());
2924 newArr->copyStringInfoFrom(*this);
2929 * Modify all elements of \a this array, so that
2930 * an element _x_ becomes <em> val ^ x </em>. Contrary to DataArrayInt::applyPow
2931 * all values in \a this have to be >= 0 if val is \b not integer.
2932 * \param [in] val - the value used to apply pow on all array elements.
2933 * \throw If \a this is not allocated.
2934 * \warning If an exception is thrown because of presence of 0 element in \a this
2935 * array and \a val is \b not integer, all elements processed before detection of the zero element remain
2938 void DataArrayDouble::applyPow(double val)
2941 double *ptr=getPointer();
2942 std::size_t nbOfElems=getNbOfElems();
2944 bool isInt=((double)val2)==val;
2947 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2953 std::ostringstream oss; oss << "DataArrayDouble::applyPow (double) : At elem # " << i << " value is " << *ptr << " ! must be >=0. !";
2954 throw INTERP_KERNEL::Exception(oss.str().c_str());
2960 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2961 *ptr=pow(*ptr,val2);
2967 * Modify all elements of \a this array, so that
2968 * an element _x_ becomes \f$ val ^ x \f$.
2969 * \param [in] val - the value used to apply pow on all array elements.
2970 * \throw If \a this is not allocated.
2971 * \throw If \a val < 0.
2972 * \warning If an exception is thrown because of presence of 0 element in \a this
2973 * array, all elements processed before detection of the zero element remain
2976 void DataArrayDouble::applyRPow(double val)
2980 throw INTERP_KERNEL::Exception("DataArrayDouble::applyRPow : the input value has to be >= 0 !");
2981 double *ptr=getPointer();
2982 std::size_t nbOfElems=getNbOfElems();
2983 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
2989 * Returns a new DataArrayDouble created from \a this one by applying \a
2990 * FunctionToEvaluate to every tuple of \a this array. Textual data is not copied.
2991 * For more info see \ref MEDCouplingArrayApplyFunc
2992 * \param [in] nbOfComp - number of components in the result array.
2993 * \param [in] func - the \a FunctionToEvaluate declared as
2994 * \c bool (*\a func)(\c const \c double *\a pos, \c double *\a res),
2995 * where \a pos points to the first component of a tuple of \a this array
2996 * and \a res points to the first component of a tuple of the result array.
2997 * Note that length (number of components) of \a pos can differ from
2999 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3000 * same number of tuples as \a this array.
3001 * The caller is to delete this result array using decrRef() as it is no more
3003 * \throw If \a this is not allocated.
3004 * \throw If \a func returns \a false.
3006 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, FunctionToEvaluate func) const
3009 DataArrayDouble *newArr=DataArrayDouble::New();
3010 int nbOfTuples=getNumberOfTuples();
3011 int oldNbOfComp=getNumberOfComponents();
3012 newArr->alloc(nbOfTuples,nbOfComp);
3013 const double *ptr=getConstPointer();
3014 double *ptrToFill=newArr->getPointer();
3015 for(int i=0;i<nbOfTuples;i++)
3017 if(!func(ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp))
3019 std::ostringstream oss; oss << "For tuple # " << i << " with value (";
3020 std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
3021 oss << ") : Evaluation of function failed !";
3023 throw INTERP_KERNEL::Exception(oss.str().c_str());
3030 * Returns a new DataArrayDouble created from \a this one by applying a function to every
3031 * tuple of \a this array. Textual data is not copied.
3032 * For more info see \ref MEDCouplingArrayApplyFunc1.
3033 * \param [in] nbOfComp - number of components in the result array.
3034 * \param [in] func - the expression defining how to transform a tuple of \a this array.
3035 * Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
3036 * \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
3037 * If false the computation is carried on without any notification. When false the evaluation is a little faster.
3038 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3039 * same number of tuples as \a this array and \a nbOfComp components.
3040 * The caller is to delete this result array using decrRef() as it is no more
3042 * \throw If \a this is not allocated.
3043 * \throw If computing \a func fails.
3045 DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, const std::string& func, bool isSafe) const
3047 INTERP_KERNEL::ExprParser expr(func);
3049 std::set<std::string> vars;
3050 expr.getTrueSetOfVars(vars);
3051 std::vector<std::string> varsV(vars.begin(),vars.end());
3052 return applyFuncNamedCompo(nbOfComp,varsV,func,isSafe);
3056 * Returns a new DataArrayDouble created from \a this one by applying a function to every
3057 * tuple of \a this array. Textual data is not copied. This method works by tuples (whatever its size).
3058 * If \a this is a one component array, call applyFuncOnThis instead that performs the same work faster.
3060 * For more info see \ref MEDCouplingArrayApplyFunc0.
3061 * \param [in] func - the expression defining how to transform a tuple of \a this array.
3062 * Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
3063 * \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
3064 * If false the computation is carried on without any notification. When false the evaluation is a little faster.
3065 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3066 * same number of tuples and components as \a this array.
3067 * The caller is to delete this result array using decrRef() as it is no more
3069 * \sa applyFuncOnThis
3070 * \throw If \a this is not allocated.
3071 * \throw If computing \a func fails.
3073 DataArrayDouble *DataArrayDouble::applyFunc(const std::string& func, bool isSafe) const
3075 int nbOfComp(getNumberOfComponents());
3077 throw INTERP_KERNEL::Exception("DataArrayDouble::applyFunc : output number of component must be > 0 !");
3079 int nbOfTuples(getNumberOfTuples());
3080 MCAuto<DataArrayDouble> newArr(DataArrayDouble::New());
3081 newArr->alloc(nbOfTuples,nbOfComp);
3082 INTERP_KERNEL::ExprParser expr(func);
3084 std::set<std::string> vars;
3085 expr.getTrueSetOfVars(vars);
3086 if((int)vars.size()>1)
3088 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 : ";
3089 std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
3090 throw INTERP_KERNEL::Exception(oss.str().c_str());
3094 expr.prepareFastEvaluator();
3095 newArr->rearrange(1);
3096 newArr->fillWithValue(expr.evaluateDouble());
3097 newArr->rearrange(nbOfComp);
3098 return newArr.retn();
3100 std::vector<std::string> vars2(vars.begin(),vars.end());
3101 double buff,*ptrToFill(newArr->getPointer());
3102 const double *ptr(begin());
3103 std::vector<double> stck;
3104 expr.prepareExprEvaluationDouble(vars2,1,1,0,&buff,&buff+1);
3105 expr.prepareFastEvaluator();
3108 for(int i=0;i<nbOfTuples;i++)
3110 for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
3113 expr.evaluateDoubleInternal(stck);
3114 *ptrToFill=stck.back();
3121 for(int i=0;i<nbOfTuples;i++)
3123 for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
3128 expr.evaluateDoubleInternalSafe(stck);
3130 catch(INTERP_KERNEL::Exception& e)
3132 std::ostringstream oss; oss << "For tuple # " << i << " component # " << iComp << " with value (";
3134 oss << ") : Evaluation of function failed !" << e.what();
3135 throw INTERP_KERNEL::Exception(oss.str().c_str());
3137 *ptrToFill=stck.back();
3142 return newArr.retn();
3146 * This method is a non const method that modify the array in \a this.
3147 * This method only works on one component array. It means that function \a func must
3148 * contain at most one variable.
3149 * This method is a specialization of applyFunc method with one parameter on one component array.
3151 * \param [in] func - the expression defining how to transform a tuple of \a this array.
3152 * Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
3153 * \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
3154 * If false the computation is carried on without any notification. When false the evaluation is a little faster.
3158 void DataArrayDouble::applyFuncOnThis(const std::string& func, bool isSafe)
3160 int nbOfComp(getNumberOfComponents());
3162 throw INTERP_KERNEL::Exception("DataArrayDouble::applyFuncOnThis : output number of component must be > 0 !");
3164 int nbOfTuples(getNumberOfTuples());
3165 INTERP_KERNEL::ExprParser expr(func);
3167 std::set<std::string> vars;
3168 expr.getTrueSetOfVars(vars);
3169 if((int)vars.size()>1)
3171 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 : ";
3172 std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
3173 throw INTERP_KERNEL::Exception(oss.str().c_str());
3177 expr.prepareFastEvaluator();
3178 std::vector<std::string> compInfo(getInfoOnComponents());
3180 fillWithValue(expr.evaluateDouble());
3181 rearrange(nbOfComp);
3182 setInfoOnComponents(compInfo);
3185 std::vector<std::string> vars2(vars.begin(),vars.end());
3186 double buff,*ptrToFill(getPointer());
3187 const double *ptr(begin());
3188 std::vector<double> stck;
3189 expr.prepareExprEvaluationDouble(vars2,1,1,0,&buff,&buff+1);
3190 expr.prepareFastEvaluator();
3193 for(int i=0;i<nbOfTuples;i++)
3195 for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
3198 expr.evaluateDoubleInternal(stck);
3199 *ptrToFill=stck.back();
3206 for(int i=0;i<nbOfTuples;i++)
3208 for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++)
3213 expr.evaluateDoubleInternalSafe(stck);
3215 catch(INTERP_KERNEL::Exception& e)
3217 std::ostringstream oss; oss << "For tuple # " << i << " component # " << iComp << " with value (";
3219 oss << ") : Evaluation of function failed !" << e.what();
3220 throw INTERP_KERNEL::Exception(oss.str().c_str());
3222 *ptrToFill=stck.back();
3230 * Returns a new DataArrayDouble created from \a this one by applying a function to every
3231 * tuple of \a this array. Textual data is not copied.
3232 * For more info see \ref MEDCouplingArrayApplyFunc2.
3233 * \param [in] nbOfComp - number of components in the result array.
3234 * \param [in] func - the expression defining how to transform a tuple of \a this array.
3235 * Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
3236 * \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
3237 * If false the computation is carried on without any notification. When false the evaluation is a little faster.
3238 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3239 * same number of tuples as \a this array.
3240 * The caller is to delete this result array using decrRef() as it is no more
3242 * \throw If \a this is not allocated.
3243 * \throw If \a func contains vars that are not in \a this->getInfoOnComponent().
3244 * \throw If computing \a func fails.
3246 DataArrayDouble *DataArrayDouble::applyFuncCompo(int nbOfComp, const std::string& func, bool isSafe) const
3248 return applyFuncNamedCompo(nbOfComp,getVarsOnComponent(),func,isSafe);
3252 * Returns a new DataArrayDouble created from \a this one by applying a function to every
3253 * tuple of \a this array. Textual data is not copied.
3254 * For more info see \ref MEDCouplingArrayApplyFunc3.
3255 * \param [in] nbOfComp - number of components in the result array.
3256 * \param [in] varsOrder - sequence of vars defining their order.
3257 * \param [in] func - the expression defining how to transform a tuple of \a this array.
3258 * Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here".
3259 * \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception.
3260 * If false the computation is carried on without any notification. When false the evaluation is a little faster.
3261 * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
3262 * same number of tuples as \a this array.
3263 * The caller is to delete this result array using decrRef() as it is no more
3265 * \throw If \a this is not allocated.
3266 * \throw If \a func contains vars not in \a varsOrder.
3267 * \throw If computing \a func fails.
3269 DataArrayDouble *DataArrayDouble::applyFuncNamedCompo(int nbOfComp, const std::vector<std::string>& varsOrder, const std::string& func, bool isSafe) const
3272 throw INTERP_KERNEL::Exception("DataArrayDouble::applyFuncNamedCompo : output number of component must be > 0 !");
3273 std::vector<std::string> varsOrder2(varsOrder);
3274 int oldNbOfComp(getNumberOfComponents());
3275 for(int i=(int)varsOrder.size();i<oldNbOfComp;i++)
3276 varsOrder2.push_back(std::string());
3278 int nbOfTuples(getNumberOfTuples());
3279 INTERP_KERNEL::ExprParser expr(func);
3281 std::set<std::string> vars;
3282 expr.getTrueSetOfVars(vars);
3283 if((int)vars.size()>oldNbOfComp)
3285 std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are ";
3286 oss << vars.size() << " variables : ";
3287 std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
3288 throw INTERP_KERNEL::Exception(oss.str().c_str());
3290 MCAuto<DataArrayDouble> newArr(DataArrayDouble::New());
3291 newArr->alloc(nbOfTuples,nbOfComp);
3292 INTERP_KERNEL::AutoPtr<double> buff(new double[oldNbOfComp]);
3293 double *buffPtr(buff),*ptrToFill;
3294 std::vector<double> stck;
3295 for(int iComp=0;iComp<nbOfComp;iComp++)
3297 expr.prepareExprEvaluationDouble(varsOrder2,oldNbOfComp,nbOfComp,iComp,buffPtr,buffPtr+oldNbOfComp);
3298 expr.prepareFastEvaluator();
3299 const double *ptr(getConstPointer());
3300 ptrToFill=newArr->getPointer()+iComp;
3303 for(int i=0;i<nbOfTuples;i++,ptrToFill+=nbOfComp,ptr+=oldNbOfComp)
3305 std::copy(ptr,ptr+oldNbOfComp,buffPtr);
3306 expr.evaluateDoubleInternal(stck);
3307 *ptrToFill=stck.back();
3313 for(int i=0;i<nbOfTuples;i++,ptrToFill+=nbOfComp,ptr+=oldNbOfComp)
3315 std::copy(ptr,ptr+oldNbOfComp,buffPtr);
3318 expr.evaluateDoubleInternalSafe(stck);
3319 *ptrToFill=stck.back();
3322 catch(INTERP_KERNEL::Exception& e)
3324 std::ostringstream oss; oss << "For tuple # " << i << " with value (";
3325 std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", "));
3326 oss << ") : Evaluation of function failed !" << e.what();
3327 throw INTERP_KERNEL::Exception(oss.str().c_str());
3332 return newArr.retn();
3335 void DataArrayDouble::applyFuncFast32(const std::string& func)
3338 INTERP_KERNEL::ExprParser expr(func);
3340 char *funcStr=expr.compileX86();
3342 *((void **)&funcPtr)=funcStr;//he he...
3344 double *ptr=getPointer();
3345 int nbOfComp=getNumberOfComponents();
3346 int nbOfTuples=getNumberOfTuples();
3347 int nbOfElems=nbOfTuples*nbOfComp;
3348 for(int i=0;i<nbOfElems;i++,ptr++)
3353 void DataArrayDouble::applyFuncFast64(const std::string& func)
3356 INTERP_KERNEL::ExprParser expr(func);
3358 char *funcStr=expr.compileX86_64();
3360 *((void **)&funcPtr)=funcStr;//he he...
3362 double *ptr=getPointer();
3363 int nbOfComp=getNumberOfComponents();
3364 int nbOfTuples=getNumberOfTuples();
3365 int nbOfElems=nbOfTuples*nbOfComp;
3366 for(int i=0;i<nbOfElems;i++,ptr++)
3372 * \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.
3374 MCAuto<DataArrayDouble> DataArrayDouble::symmetry3DPlane(const double point[3], const double normalVector[3]) const
3377 if(getNumberOfComponents()!=3)
3378 throw INTERP_KERNEL::Exception("DataArrayDouble::symmetry3DPlane : this is excepted to have 3 components !");
3379 int nbTuples(getNumberOfTuples());
3380 MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
3381 ret->alloc(nbTuples,3);
3382 Symmetry3DPlane(point,normalVector,nbTuples,begin(),ret->getPointer());
3386 DataArrayDoubleIterator *DataArrayDouble::iterator()
3388 return new DataArrayDoubleIterator(this);
3392 * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional
3393 * array whose values are within a given range. Textual data is not copied.
3394 * \param [in] vmin - a lowest acceptable value (included).
3395 * \param [in] vmax - a greatest acceptable value (included).
3396 * \return DataArrayInt * - the new instance of DataArrayInt.
3397 * The caller is to delete this result array using decrRef() as it is no more
3399 * \throw If \a this->getNumberOfComponents() != 1.
3401 * \sa DataArrayDouble::findIdsNotInRange
3403 * \if ENABLE_EXAMPLES
3404 * \ref cpp_mcdataarraydouble_getidsinrange "Here is a C++ example".<br>
3405 * \ref py_mcdataarraydouble_getidsinrange "Here is a Python example".
3408 DataArrayInt *DataArrayDouble::findIdsInRange(double vmin, double vmax) const
3411 if(getNumberOfComponents()!=1)
3412 throw INTERP_KERNEL::Exception("DataArrayDouble::findIdsInRange : this must have exactly one component !");
3413 const double *cptr(begin());
3414 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
3415 int nbOfTuples(getNumberOfTuples());
3416 for(int i=0;i<nbOfTuples;i++,cptr++)
3417 if(*cptr>=vmin && *cptr<=vmax)
3418 ret->pushBackSilent(i);
3423 * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional
3424 * array whose values are not within a given range. Textual data is not copied.
3425 * \param [in] vmin - a lowest not acceptable value (excluded).
3426 * \param [in] vmax - a greatest not acceptable value (excluded).
3427 * \return DataArrayInt * - the new instance of DataArrayInt.
3428 * The caller is to delete this result array using decrRef() as it is no more
3430 * \throw If \a this->getNumberOfComponents() != 1.
3432 * \sa DataArrayDouble::findIdsInRange
3434 DataArrayInt *DataArrayDouble::findIdsNotInRange(double vmin, double vmax) const
3437 if(getNumberOfComponents()!=1)
3438 throw INTERP_KERNEL::Exception("DataArrayDouble::findIdsNotInRange : this must have exactly one component !");
3439 const double *cptr(begin());
3440 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
3441 int nbOfTuples(getNumberOfTuples());
3442 for(int i=0;i<nbOfTuples;i++,cptr++)
3443 if(*cptr<vmin || *cptr>vmax)
3444 ret->pushBackSilent(i);
3449 * Returns a new DataArrayDouble by concatenating two given arrays, so that (1) the number
3450 * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
3451 * the number of component in the result array is same as that of each of given arrays.
3452 * Info on components is copied from the first of the given arrays. Number of components
3453 * in the given arrays must be the same.
3454 * \param [in] a1 - an array to include in the result array.
3455 * \param [in] a2 - another array to include in the result array.
3456 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3457 * The caller is to delete this result array using decrRef() as it is no more
3459 * \throw If both \a a1 and \a a2 are NULL.
3460 * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
3462 DataArrayDouble *DataArrayDouble::Aggregate(const DataArrayDouble *a1, const DataArrayDouble *a2)
3464 std::vector<const DataArrayDouble *> tmp(2);
3465 tmp[0]=a1; tmp[1]=a2;
3466 return Aggregate(tmp);
3470 * Returns a new DataArrayDouble by concatenating all given arrays, so that (1) the number
3471 * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
3472 * the number of component in the result array is same as that of each of given arrays.
3473 * Info on components is copied from the first of the given arrays. Number of components
3474 * in the given arrays must be the same.
3475 * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it
3476 * not the object itself.
3477 * \param [in] arr - a sequence of arrays to include in the result array.
3478 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3479 * The caller is to delete this result array using decrRef() as it is no more
3481 * \throw If all arrays within \a arr are NULL.
3482 * \throw If getNumberOfComponents() of arrays within \a arr.
3484 DataArrayDouble *DataArrayDouble::Aggregate(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::Aggregate : input list must contain at least one NON EMPTY DataArrayDouble !");
3492 std::vector<const DataArrayDouble *>::const_iterator it=a.begin();
3493 int nbOfComp=(*it)->getNumberOfComponents();
3494 int nbt=(*it++)->getNumberOfTuples();
3495 for(int i=1;it!=a.end();it++,i++)
3497 if((*it)->getNumberOfComponents()!=nbOfComp)
3498 throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : Nb of components mismatch for array aggregation !");
3499 nbt+=(*it)->getNumberOfTuples();
3501 MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
3502 ret->alloc(nbt,nbOfComp);
3503 double *pt=ret->getPointer();
3504 for(it=a.begin();it!=a.end();it++)
3505 pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
3506 ret->copyStringInfoFrom(*(a[0]));
3511 * Returns a new DataArrayDouble by aggregating two given arrays, so that (1) the number
3512 * of components in the result array is a sum of the number of components of given arrays
3513 * and (2) the number of tuples in the result array is same as that of each of given
3514 * arrays. In other words the i-th tuple of result array includes all components of
3515 * i-th tuples of all given arrays.
3516 * Number of tuples in the given arrays must be the same.
3517 * \param [in] a1 - an array to include in the result array.
3518 * \param [in] a2 - another array to include in the result array.
3519 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3520 * The caller is to delete this result array using decrRef() as it is no more
3522 * \throw If both \a a1 and \a a2 are NULL.
3523 * \throw If any given array is not allocated.
3524 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3526 DataArrayDouble *DataArrayDouble::Meld(const DataArrayDouble *a1, const DataArrayDouble *a2)
3528 std::vector<const DataArrayDouble *> arr(2);
3529 arr[0]=a1; arr[1]=a2;
3534 * Returns a new DataArrayDouble by aggregating all given arrays, so that (1) the number
3535 * of components in the result array is a sum of the number of components of given arrays
3536 * and (2) the number of tuples in the result array is same as that of each of given
3537 * arrays. In other words the i-th tuple of result array includes all components of
3538 * i-th tuples of all given arrays.
3539 * Number of tuples in the given arrays must be the same.
3540 * \param [in] arr - a sequence of arrays to include in the result array.
3541 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3542 * The caller is to delete this result array using decrRef() as it is no more
3544 * \throw If all arrays within \a arr are NULL.
3545 * \throw If any given array is not allocated.
3546 * \throw If getNumberOfTuples() of arrays within \a arr is different.
3548 DataArrayDouble *DataArrayDouble::Meld(const std::vector<const DataArrayDouble *>& arr)
3550 std::vector<const DataArrayDouble *> a;
3551 for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
3555 throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : input list must contain at least one NON EMPTY DataArrayDouble !");
3556 std::vector<const DataArrayDouble *>::const_iterator it;
3557 for(it=a.begin();it!=a.end();it++)
3558 (*it)->checkAllocated();
3560 int nbOfTuples=(*it)->getNumberOfTuples();
3561 std::vector<int> nbc(a.size());
3562 std::vector<const double *> pts(a.size());
3563 nbc[0]=(*it)->getNumberOfComponents();
3564 pts[0]=(*it++)->getConstPointer();
3565 for(int i=1;it!=a.end();it++,i++)
3567 if(nbOfTuples!=(*it)->getNumberOfTuples())
3568 throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : mismatch of number of tuples !");
3569 nbc[i]=(*it)->getNumberOfComponents();
3570 pts[i]=(*it)->getConstPointer();
3572 int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
3573 DataArrayDouble *ret=DataArrayDouble::New();
3574 ret->alloc(nbOfTuples,totalNbOfComp);
3575 double *retPtr=ret->getPointer();
3576 for(int i=0;i<nbOfTuples;i++)
3577 for(int j=0;j<(int)a.size();j++)
3579 retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
3583 for(int i=0;i<(int)a.size();i++)
3584 for(int j=0;j<nbc[i];j++,k++)
3585 ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j));
3590 * Returns a new DataArrayDouble containing a dot product of two given arrays, so that
3591 * the i-th tuple of the result array is a sum of products of j-th components of i-th
3592 * tuples of given arrays (\f$ a_i = \sum_{j=1}^n a1_j * a2_j \f$).
3593 * Info on components and name is copied from the first of the given arrays.
3594 * Number of tuples and components in the given arrays must be the same.
3595 * \param [in] a1 - a given array.
3596 * \param [in] a2 - another given array.
3597 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3598 * The caller is to delete this result array using decrRef() as it is no more
3600 * \throw If either \a a1 or \a a2 is NULL.
3601 * \throw If any given array is not allocated.
3602 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3603 * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
3605 DataArrayDouble *DataArrayDouble::Dot(const DataArrayDouble *a1, const DataArrayDouble *a2)
3608 throw INTERP_KERNEL::Exception("DataArrayDouble::Dot : input DataArrayDouble instance is NULL !");
3609 a1->checkAllocated();
3610 a2->checkAllocated();
3611 int nbOfComp=a1->getNumberOfComponents();
3612 if(nbOfComp!=a2->getNumberOfComponents())
3613 throw INTERP_KERNEL::Exception("Nb of components mismatch for array Dot !");
3614 int nbOfTuple=a1->getNumberOfTuples();
3615 if(nbOfTuple!=a2->getNumberOfTuples())
3616 throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Dot !");
3617 DataArrayDouble *ret=DataArrayDouble::New();
3618 ret->alloc(nbOfTuple,1);
3619 double *retPtr=ret->getPointer();
3620 const double *a1Ptr=a1->getConstPointer();
3621 const double *a2Ptr=a2->getConstPointer();
3622 for(int i=0;i<nbOfTuple;i++)
3625 for(int j=0;j<nbOfComp;j++)
3626 sum+=a1Ptr[i*nbOfComp+j]*a2Ptr[i*nbOfComp+j];
3629 ret->setInfoOnComponent(0,a1->getInfoOnComponent(0));
3630 ret->setName(a1->getName());
3635 * Returns a new DataArrayDouble containing a cross product of two given arrays, so that
3636 * the i-th tuple of the result array contains 3 components of a vector which is a cross
3637 * product of two vectors defined by the i-th tuples of given arrays.
3638 * Info on components is copied from the first of the given arrays.
3639 * Number of tuples in the given arrays must be the same.
3640 * Number of components in the given arrays must be 3.
3641 * \param [in] a1 - a given array.
3642 * \param [in] a2 - another given array.
3643 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3644 * The caller is to delete this result array using decrRef() as it is no more
3646 * \throw If either \a a1 or \a a2 is NULL.
3647 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3648 * \throw If \a a1->getNumberOfComponents() != 3
3649 * \throw If \a a2->getNumberOfComponents() != 3
3651 DataArrayDouble *DataArrayDouble::CrossProduct(const DataArrayDouble *a1, const DataArrayDouble *a2)
3654 throw INTERP_KERNEL::Exception("DataArrayDouble::CrossProduct : input DataArrayDouble instance is NULL !");
3655 int nbOfComp=a1->getNumberOfComponents();
3656 if(nbOfComp!=a2->getNumberOfComponents())
3657 throw INTERP_KERNEL::Exception("Nb of components mismatch for array crossProduct !");
3659 throw INTERP_KERNEL::Exception("Nb of components must be equal to 3 for array crossProduct !");
3660 int nbOfTuple=a1->getNumberOfTuples();
3661 if(nbOfTuple!=a2->getNumberOfTuples())
3662 throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array crossProduct !");
3663 DataArrayDouble *ret=DataArrayDouble::New();
3664 ret->alloc(nbOfTuple,3);
3665 double *retPtr=ret->getPointer();
3666 const double *a1Ptr=a1->getConstPointer();
3667 const double *a2Ptr=a2->getConstPointer();
3668 for(int i=0;i<nbOfTuple;i++)
3670 retPtr[3*i]=a1Ptr[3*i+1]*a2Ptr[3*i+2]-a1Ptr[3*i+2]*a2Ptr[3*i+1];
3671 retPtr[3*i+1]=a1Ptr[3*i+2]*a2Ptr[3*i]-a1Ptr[3*i]*a2Ptr[3*i+2];
3672 retPtr[3*i+2]=a1Ptr[3*i]*a2Ptr[3*i+1]-a1Ptr[3*i+1]*a2Ptr[3*i];
3674 ret->copyStringInfoFrom(*a1);
3679 * Returns a new DataArrayDouble containing maximal values of two given arrays.
3680 * Info on components is copied from the first of the given arrays.
3681 * Number of tuples and components in the given arrays must be the same.
3682 * \param [in] a1 - an array to compare values with another one.
3683 * \param [in] a2 - another array to compare values with the first one.
3684 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3685 * The caller is to delete this result array using decrRef() as it is no more
3687 * \throw If either \a a1 or \a a2 is NULL.
3688 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3689 * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
3691 DataArrayDouble *DataArrayDouble::Max(const DataArrayDouble *a1, const DataArrayDouble *a2)
3694 throw INTERP_KERNEL::Exception("DataArrayDouble::Max : input DataArrayDouble instance is NULL !");
3695 int nbOfComp=a1->getNumberOfComponents();
3696 if(nbOfComp!=a2->getNumberOfComponents())
3697 throw INTERP_KERNEL::Exception("Nb of components mismatch for array Max !");
3698 int nbOfTuple=a1->getNumberOfTuples();
3699 if(nbOfTuple!=a2->getNumberOfTuples())
3700 throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Max !");
3701 DataArrayDouble *ret=DataArrayDouble::New();
3702 ret->alloc(nbOfTuple,nbOfComp);
3703 double *retPtr=ret->getPointer();
3704 const double *a1Ptr=a1->getConstPointer();
3705 const double *a2Ptr=a2->getConstPointer();
3706 int nbElem=nbOfTuple*nbOfComp;
3707 for(int i=0;i<nbElem;i++)
3708 retPtr[i]=std::max(a1Ptr[i],a2Ptr[i]);
3709 ret->copyStringInfoFrom(*a1);
3714 * Returns a new DataArrayDouble containing minimal values of two given arrays.
3715 * Info on components is copied from the first of the given arrays.
3716 * Number of tuples and components in the given arrays must be the same.
3717 * \param [in] a1 - an array to compare values with another one.
3718 * \param [in] a2 - another array to compare values with the first one.
3719 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3720 * The caller is to delete this result array using decrRef() as it is no more
3722 * \throw If either \a a1 or \a a2 is NULL.
3723 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
3724 * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents()
3726 DataArrayDouble *DataArrayDouble::Min(const DataArrayDouble *a1, const DataArrayDouble *a2)
3729 throw INTERP_KERNEL::Exception("DataArrayDouble::Min : input DataArrayDouble instance is NULL !");
3730 int nbOfComp=a1->getNumberOfComponents();
3731 if(nbOfComp!=a2->getNumberOfComponents())
3732 throw INTERP_KERNEL::Exception("Nb of components mismatch for array min !");
3733 int nbOfTuple=a1->getNumberOfTuples();
3734 if(nbOfTuple!=a2->getNumberOfTuples())
3735 throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array min !");
3736 DataArrayDouble *ret=DataArrayDouble::New();
3737 ret->alloc(nbOfTuple,nbOfComp);
3738 double *retPtr=ret->getPointer();
3739 const double *a1Ptr=a1->getConstPointer();
3740 const double *a2Ptr=a2->getConstPointer();
3741 int nbElem=nbOfTuple*nbOfComp;
3742 for(int i=0;i<nbElem;i++)
3743 retPtr[i]=std::min(a1Ptr[i],a2Ptr[i]);
3744 ret->copyStringInfoFrom(*a1);
3749 * Returns a new DataArrayDouble that is a sum of two given arrays. There are 3
3751 * 1. The arrays have same number of tuples and components. Then each value of
3752 * the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
3753 * i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
3754 * 2. The arrays have same number of tuples and one array, say _a2_, has one
3756 * _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
3757 * 3. The arrays have same number of components and one array, say _a2_, has one
3759 * _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
3761 * Info on components is copied either from the first array (in the first case) or from
3762 * the array with maximal number of elements (getNbOfElems()).
3763 * \param [in] a1 - an array to sum up.
3764 * \param [in] a2 - another array to sum up.
3765 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3766 * The caller is to delete this result array using decrRef() as it is no more
3768 * \throw If either \a a1 or \a a2 is NULL.
3769 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
3770 * \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
3771 * none of them has number of tuples or components equal to 1.
3773 DataArrayDouble *DataArrayDouble::Add(const DataArrayDouble *a1, const DataArrayDouble *a2)
3776 throw INTERP_KERNEL::Exception("DataArrayDouble::Add : input DataArrayDouble instance is NULL !");
3777 int nbOfTuple=a1->getNumberOfTuples();
3778 int nbOfTuple2=a2->getNumberOfTuples();
3779 int nbOfComp=a1->getNumberOfComponents();
3780 int nbOfComp2=a2->getNumberOfComponents();
3781 MCAuto<DataArrayDouble> ret=0;
3782 if(nbOfTuple==nbOfTuple2)
3784 if(nbOfComp==nbOfComp2)
3786 ret=DataArrayDouble::New();
3787 ret->alloc(nbOfTuple,nbOfComp);
3788 std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<double>());
3789 ret->copyStringInfoFrom(*a1);
3793 int nbOfCompMin,nbOfCompMax;
3794 const DataArrayDouble *aMin, *aMax;
3795 if(nbOfComp>nbOfComp2)
3797 nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
3802 nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
3807 ret=DataArrayDouble::New();
3808 ret->alloc(nbOfTuple,nbOfCompMax);
3809 const double *aMinPtr=aMin->getConstPointer();
3810 const double *aMaxPtr=aMax->getConstPointer();
3811 double *res=ret->getPointer();
3812 for(int i=0;i<nbOfTuple;i++)
3813 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<double>(),aMinPtr[i]));
3814 ret->copyStringInfoFrom(*aMax);
3817 throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
3820 else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
3822 if(nbOfComp==nbOfComp2)
3824 int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
3825 const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
3826 const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
3827 const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
3828 ret=DataArrayDouble::New();
3829 ret->alloc(nbOfTupleMax,nbOfComp);
3830 double *res=ret->getPointer();
3831 for(int i=0;i<nbOfTupleMax;i++)
3832 res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<double>());
3833 ret->copyStringInfoFrom(*aMax);
3836 throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
3839 throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
3844 * Adds values of another DataArrayDouble to values of \a this one. There are 3
3846 * 1. The arrays have same number of tuples and components. Then each value of
3847 * \a other array is added to the corresponding value of \a this array, i.e.:
3848 * _a_ [ i, j ] += _other_ [ i, j ].
3849 * 2. The arrays have same number of tuples and \a other array has one component. Then
3850 * _a_ [ i, j ] += _other_ [ i, 0 ].
3851 * 3. The arrays have same number of components and \a other array has one tuple. Then
3852 * _a_ [ i, j ] += _a2_ [ 0, j ].
3854 * \param [in] other - an array to add to \a this one.
3855 * \throw If \a other is NULL.
3856 * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
3857 * \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
3858 * \a other has number of both tuples and components not equal to 1.
3860 void DataArrayDouble::addEqual(const DataArrayDouble *other)
3863 throw INTERP_KERNEL::Exception("DataArrayDouble::addEqual : input DataArrayDouble instance is NULL !");
3864 const char *msg="Nb of tuples mismatch for DataArrayDouble::addEqual !";
3866 other->checkAllocated();
3867 int nbOfTuple=getNumberOfTuples();
3868 int nbOfTuple2=other->getNumberOfTuples();
3869 int nbOfComp=getNumberOfComponents();
3870 int nbOfComp2=other->getNumberOfComponents();
3871 if(nbOfTuple==nbOfTuple2)
3873 if(nbOfComp==nbOfComp2)
3875 std::transform(begin(),end(),other->begin(),getPointer(),std::plus<double>());
3877 else if(nbOfComp2==1)
3879 double *ptr=getPointer();
3880 const double *ptrc=other->getConstPointer();
3881 for(int i=0;i<nbOfTuple;i++)
3882 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<double>(),*ptrc++));
3885 throw INTERP_KERNEL::Exception(msg);
3887 else if(nbOfTuple2==1)
3889 if(nbOfComp2==nbOfComp)
3891 double *ptr=getPointer();
3892 const double *ptrc=other->getConstPointer();
3893 for(int i=0;i<nbOfTuple;i++)
3894 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<double>());
3897 throw INTERP_KERNEL::Exception(msg);
3900 throw INTERP_KERNEL::Exception(msg);
3905 * Returns a new DataArrayDouble that is a subtraction of two given arrays. There are 3
3907 * 1. The arrays have same number of tuples and components. Then each value of
3908 * the result array (_a_) is a subtraction of the corresponding values of \a a1 and
3909 * \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
3910 * 2. The arrays have same number of tuples and one array, say _a2_, has one
3912 * _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
3913 * 3. The arrays have same number of components and one array, say _a2_, has one
3915 * _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
3917 * Info on components is copied either from the first array (in the first case) or from
3918 * the array with maximal number of elements (getNbOfElems()).
3919 * \param [in] a1 - an array to subtract from.
3920 * \param [in] a2 - an array to subtract.
3921 * \return DataArrayDouble * - the new instance of DataArrayDouble.
3922 * The caller is to delete this result array using decrRef() as it is no more
3924 * \throw If either \a a1 or \a a2 is NULL.
3925 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
3926 * \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
3927 * none of them has number of tuples or components equal to 1.
3929 DataArrayDouble *DataArrayDouble::Substract(const DataArrayDouble *a1, const DataArrayDouble *a2)
3932 throw INTERP_KERNEL::Exception("DataArrayDouble::Substract : input DataArrayDouble instance is NULL !");
3933 int nbOfTuple1=a1->getNumberOfTuples();
3934 int nbOfTuple2=a2->getNumberOfTuples();
3935 int nbOfComp1=a1->getNumberOfComponents();
3936 int nbOfComp2=a2->getNumberOfComponents();
3937 if(nbOfTuple2==nbOfTuple1)
3939 if(nbOfComp1==nbOfComp2)
3941 MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
3942 ret->alloc(nbOfTuple2,nbOfComp1);
3943 std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<double>());
3944 ret->copyStringInfoFrom(*a1);
3947 else if(nbOfComp2==1)
3949 MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
3950 ret->alloc(nbOfTuple1,nbOfComp1);
3951 const double *a2Ptr=a2->getConstPointer();
3952 const double *a1Ptr=a1->getConstPointer();
3953 double *res=ret->getPointer();
3954 for(int i=0;i<nbOfTuple1;i++)
3955 res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<double>(),a2Ptr[i]));
3956 ret->copyStringInfoFrom(*a1);
3961 a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
3965 else if(nbOfTuple2==1)
3967 a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
3968 MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
3969 ret->alloc(nbOfTuple1,nbOfComp1);
3970 const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
3971 double *pt=ret->getPointer();
3972 for(int i=0;i<nbOfTuple1;i++)
3973 pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<double>());
3974 ret->copyStringInfoFrom(*a1);
3979 a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
3985 * Subtract values of another DataArrayDouble from values of \a this one. There are 3
3987 * 1. The arrays have same number of tuples and components. Then each value of
3988 * \a other array is subtracted from the corresponding value of \a this array, i.e.:
3989 * _a_ [ i, j ] -= _other_ [ i, j ].
3990 * 2. The arrays have same number of tuples and \a other array has one component. Then
3991 * _a_ [ i, j ] -= _other_ [ i, 0 ].
3992 * 3. The arrays have same number of components and \a other array has one tuple. Then
3993 * _a_ [ i, j ] -= _a2_ [ 0, j ].
3995 * \param [in] other - an array to subtract from \a this one.
3996 * \throw If \a other is NULL.
3997 * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
3998 * \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
3999 * \a other has number of both tuples and components not equal to 1.
4001 void DataArrayDouble::substractEqual(const DataArrayDouble *other)
4004 throw INTERP_KERNEL::Exception("DataArrayDouble::substractEqual : input DataArrayDouble instance is NULL !");
4005 const char *msg="Nb of tuples mismatch for DataArrayDouble::substractEqual !";
4007 other->checkAllocated();
4008 int nbOfTuple=getNumberOfTuples();
4009 int nbOfTuple2=other->getNumberOfTuples();
4010 int nbOfComp=getNumberOfComponents();
4011 int nbOfComp2=other->getNumberOfComponents();
4012 if(nbOfTuple==nbOfTuple2)
4014 if(nbOfComp==nbOfComp2)
4016 std::transform(begin(),end(),other->begin(),getPointer(),std::minus<double>());
4018 else if(nbOfComp2==1)
4020 double *ptr=getPointer();
4021 const double *ptrc=other->getConstPointer();
4022 for(int i=0;i<nbOfTuple;i++)
4023 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<double>(),*ptrc++));
4026 throw INTERP_KERNEL::Exception(msg);
4028 else if(nbOfTuple2==1)
4030 if(nbOfComp2==nbOfComp)
4032 double *ptr=getPointer();
4033 const double *ptrc=other->getConstPointer();
4034 for(int i=0;i<nbOfTuple;i++)
4035 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<double>());
4038 throw INTERP_KERNEL::Exception(msg);
4041 throw INTERP_KERNEL::Exception(msg);
4046 * Returns a new DataArrayDouble that is a product of two given arrays. There are 3
4048 * 1. The arrays have same number of tuples and components. Then each value of
4049 * the result array (_a_) is a product of the corresponding values of \a a1 and
4050 * \a a2, i.e. _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
4051 * 2. The arrays have same number of tuples and one array, say _a2_, has one
4053 * _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
4054 * 3. The arrays have same number of components and one array, say _a2_, has one
4056 * _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
4058 * Info on components is copied either from the first array (in the first case) or from
4059 * the array with maximal number of elements (getNbOfElems()).
4060 * \param [in] a1 - a factor array.
4061 * \param [in] a2 - another factor array.
4062 * \return DataArrayDouble * - the new instance of DataArrayDouble.
4063 * The caller is to delete this result array using decrRef() as it is no more
4065 * \throw If either \a a1 or \a a2 is NULL.
4066 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
4067 * \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
4068 * none of them has number of tuples or components equal to 1.
4070 DataArrayDouble *DataArrayDouble::Multiply(const DataArrayDouble *a1, const DataArrayDouble *a2)
4073 throw INTERP_KERNEL::Exception("DataArrayDouble::Multiply : input DataArrayDouble instance is NULL !");
4074 int nbOfTuple=a1->getNumberOfTuples();
4075 int nbOfTuple2=a2->getNumberOfTuples();
4076 int nbOfComp=a1->getNumberOfComponents();
4077 int nbOfComp2=a2->getNumberOfComponents();
4078 MCAuto<DataArrayDouble> ret=0;
4079 if(nbOfTuple==nbOfTuple2)
4081 if(nbOfComp==nbOfComp2)
4083 ret=DataArrayDouble::New();
4084 ret->alloc(nbOfTuple,nbOfComp);
4085 std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<double>());
4086 ret->copyStringInfoFrom(*a1);
4090 int nbOfCompMin,nbOfCompMax;
4091 const DataArrayDouble *aMin, *aMax;
4092 if(nbOfComp>nbOfComp2)
4094 nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
4099 nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
4104 ret=DataArrayDouble::New();
4105 ret->alloc(nbOfTuple,nbOfCompMax);
4106 const double *aMinPtr=aMin->getConstPointer();
4107 const double *aMaxPtr=aMax->getConstPointer();
4108 double *res=ret->getPointer();
4109 for(int i=0;i<nbOfTuple;i++)
4110 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<double>(),aMinPtr[i]));
4111 ret->copyStringInfoFrom(*aMax);
4114 throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
4117 else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
4119 if(nbOfComp==nbOfComp2)
4121 int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
4122 const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
4123 const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
4124 const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
4125 ret=DataArrayDouble::New();
4126 ret->alloc(nbOfTupleMax,nbOfComp);
4127 double *res=ret->getPointer();
4128 for(int i=0;i<nbOfTupleMax;i++)
4129 res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<double>());
4130 ret->copyStringInfoFrom(*aMax);
4133 throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
4136 throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
4141 * Multiply values of another DataArrayDouble to values of \a this one. There are 3
4143 * 1. The arrays have same number of tuples and components. Then each value of
4144 * \a other array is multiplied to the corresponding value of \a this array, i.e.
4145 * _this_ [ i, j ] *= _other_ [ i, j ].
4146 * 2. The arrays have same number of tuples and \a other array has one component. Then
4147 * _this_ [ i, j ] *= _other_ [ i, 0 ].
4148 * 3. The arrays have same number of components and \a other array has one tuple. Then
4149 * _this_ [ i, j ] *= _a2_ [ 0, j ].
4151 * \param [in] other - an array to multiply to \a this one.
4152 * \throw If \a other is NULL.
4153 * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
4154 * \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
4155 * \a other has number of both tuples and components not equal to 1.
4157 void DataArrayDouble::multiplyEqual(const DataArrayDouble *other)
4160 throw INTERP_KERNEL::Exception("DataArrayDouble::multiplyEqual : input DataArrayDouble instance is NULL !");
4161 const char *msg="Nb of tuples mismatch for DataArrayDouble::multiplyEqual !";
4163 other->checkAllocated();
4164 int nbOfTuple=getNumberOfTuples();
4165 int nbOfTuple2=other->getNumberOfTuples();
4166 int nbOfComp=getNumberOfComponents();
4167 int nbOfComp2=other->getNumberOfComponents();
4168 if(nbOfTuple==nbOfTuple2)
4170 if(nbOfComp==nbOfComp2)
4172 std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<double>());
4174 else if(nbOfComp2==1)
4176 double *ptr=getPointer();
4177 const double *ptrc=other->getConstPointer();
4178 for(int i=0;i<nbOfTuple;i++)
4179 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<double>(),*ptrc++));
4182 throw INTERP_KERNEL::Exception(msg);
4184 else if(nbOfTuple2==1)
4186 if(nbOfComp2==nbOfComp)
4188 double *ptr=getPointer();
4189 const double *ptrc=other->getConstPointer();
4190 for(int i=0;i<nbOfTuple;i++)
4191 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<double>());
4194 throw INTERP_KERNEL::Exception(msg);
4197 throw INTERP_KERNEL::Exception(msg);
4202 * Returns a new DataArrayDouble that is a division of two given arrays. There are 3
4204 * 1. The arrays have same number of tuples and components. Then each value of
4205 * the result array (_a_) is a division of the corresponding values of \a a1 and
4206 * \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
4207 * 2. The arrays have same number of tuples and one array, say _a2_, has one
4209 * _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
4210 * 3. The arrays have same number of components and one array, say _a2_, has one
4212 * _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
4214 * Info on components is copied either from the first array (in the first case) or from
4215 * the array with maximal number of elements (getNbOfElems()).
4216 * \warning No check of division by zero is performed!
4217 * \param [in] a1 - a numerator array.
4218 * \param [in] a2 - a denominator array.
4219 * \return DataArrayDouble * - the new instance of DataArrayDouble.
4220 * The caller is to delete this result array using decrRef() as it is no more
4222 * \throw If either \a a1 or \a a2 is NULL.
4223 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
4224 * \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
4225 * none of them has number of tuples or components equal to 1.
4227 DataArrayDouble *DataArrayDouble::Divide(const DataArrayDouble *a1, const DataArrayDouble *a2)
4230 throw INTERP_KERNEL::Exception("DataArrayDouble::Divide : input DataArrayDouble instance is NULL !");
4231 int nbOfTuple1=a1->getNumberOfTuples();
4232 int nbOfTuple2=a2->getNumberOfTuples();
4233 int nbOfComp1=a1->getNumberOfComponents();
4234 int nbOfComp2=a2->getNumberOfComponents();
4235 if(nbOfTuple2==nbOfTuple1)
4237 if(nbOfComp1==nbOfComp2)
4239 MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
4240 ret->alloc(nbOfTuple2,nbOfComp1);
4241 std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<double>());
4242 ret->copyStringInfoFrom(*a1);
4245 else if(nbOfComp2==1)
4247 MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
4248 ret->alloc(nbOfTuple1,nbOfComp1);
4249 const double *a2Ptr=a2->getConstPointer();
4250 const double *a1Ptr=a1->getConstPointer();
4251 double *res=ret->getPointer();
4252 for(int i=0;i<nbOfTuple1;i++)
4253 res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<double>(),a2Ptr[i]));
4254 ret->copyStringInfoFrom(*a1);
4259 a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
4263 else if(nbOfTuple2==1)
4265 a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
4266 MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
4267 ret->alloc(nbOfTuple1,nbOfComp1);
4268 const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
4269 double *pt=ret->getPointer();
4270 for(int i=0;i<nbOfTuple1;i++)
4271 pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<double>());
4272 ret->copyStringInfoFrom(*a1);
4277 a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
4283 * Divide values of \a this array by values of another DataArrayDouble. There are 3
4285 * 1. The arrays have same number of tuples and components. Then each value of
4286 * \a this array is divided by the corresponding value of \a other one, i.e.:
4287 * _a_ [ i, j ] /= _other_ [ i, j ].
4288 * 2. The arrays have same number of tuples and \a other array has one component. Then
4289 * _a_ [ i, j ] /= _other_ [ i, 0 ].
4290 * 3. The arrays have same number of components and \a other array has one tuple. Then
4291 * _a_ [ i, j ] /= _a2_ [ 0, j ].
4293 * \warning No check of division by zero is performed!
4294 * \param [in] other - an array to divide \a this one by.
4295 * \throw If \a other is NULL.
4296 * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
4297 * \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
4298 * \a other has number of both tuples and components not equal to 1.
4300 void DataArrayDouble::divideEqual(const DataArrayDouble *other)
4303 throw INTERP_KERNEL::Exception("DataArrayDouble::divideEqual : input DataArrayDouble instance is NULL !");
4304 const char *msg="Nb of tuples mismatch for DataArrayDouble::divideEqual !";
4306 other->checkAllocated();
4307 int nbOfTuple=getNumberOfTuples();
4308 int nbOfTuple2=other->getNumberOfTuples();
4309 int nbOfComp=getNumberOfComponents();
4310 int nbOfComp2=other->getNumberOfComponents();
4311 if(nbOfTuple==nbOfTuple2)
4313 if(nbOfComp==nbOfComp2)
4315 std::transform(begin(),end(),other->begin(),getPointer(),std::divides<double>());
4317 else if(nbOfComp2==1)
4319 double *ptr=getPointer();
4320 const double *ptrc=other->getConstPointer();
4321 for(int i=0;i<nbOfTuple;i++)
4322 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<double>(),*ptrc++));
4325 throw INTERP_KERNEL::Exception(msg);
4327 else if(nbOfTuple2==1)
4329 if(nbOfComp2==nbOfComp)
4331 double *ptr=getPointer();
4332 const double *ptrc=other->getConstPointer();
4333 for(int i=0;i<nbOfTuple;i++)
4334 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<double>());
4337 throw INTERP_KERNEL::Exception(msg);
4340 throw INTERP_KERNEL::Exception(msg);
4345 * Returns a new DataArrayDouble that is the result of pow of two given arrays. There are 3
4348 * \param [in] a1 - an array to pow up.
4349 * \param [in] a2 - another array to sum up.
4350 * \return DataArrayDouble * - the new instance of DataArrayDouble.
4351 * The caller is to delete this result array using decrRef() as it is no more
4353 * \throw If either \a a1 or \a a2 is NULL.
4354 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
4355 * \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
4356 * \throw If there is a negative value in \a a1.
4358 DataArrayDouble *DataArrayDouble::Pow(const DataArrayDouble *a1, const DataArrayDouble *a2)
4361 throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : at least one of input instances is null !");
4362 int nbOfTuple=a1->getNumberOfTuples();
4363 int nbOfTuple2=a2->getNumberOfTuples();
4364 int nbOfComp=a1->getNumberOfComponents();
4365 int nbOfComp2=a2->getNumberOfComponents();
4366 if(nbOfTuple!=nbOfTuple2)
4367 throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of tuples mismatches !");
4368 if(nbOfComp!=1 || nbOfComp2!=1)
4369 throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of components of both arrays must be equal to 1 !");
4370 MCAuto<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbOfTuple,1);
4371 const double *ptr1(a1->begin()),*ptr2(a2->begin());
4372 double *ptr=ret->getPointer();
4373 for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
4377 *ptr=pow(*ptr1,*ptr2);
4381 std::ostringstream oss; oss << "DataArrayDouble::Pow : on tuple #" << i << " of a1 value is < 0 (" << *ptr1 << ") !";
4382 throw INTERP_KERNEL::Exception(oss.str().c_str());
4389 * Apply pow on values of another DataArrayDouble to values of \a this one.
4391 * \param [in] other - an array to pow to \a this one.
4392 * \throw If \a other is NULL.
4393 * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
4394 * \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
4395 * \throw If there is a negative value in \a this.
4397 void DataArrayDouble::powEqual(const DataArrayDouble *other)
4400 throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : input instance is null !");
4401 int nbOfTuple=getNumberOfTuples();
4402 int nbOfTuple2=other->getNumberOfTuples();
4403 int nbOfComp=getNumberOfComponents();
4404 int nbOfComp2=other->getNumberOfComponents();
4405 if(nbOfTuple!=nbOfTuple2)
4406 throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of tuples mismatches !");
4407 if(nbOfComp!=1 || nbOfComp2!=1)
4408 throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of components of both arrays must be equal to 1 !");
4409 double *ptr=getPointer();
4410 const double *ptrc=other->begin();
4411 for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
4414 *ptr=pow(*ptr,*ptrc);
4417 std::ostringstream oss; oss << "DataArrayDouble::powEqual : on tuple #" << i << " of this value is < 0 (" << *ptr << ") !";
4418 throw INTERP_KERNEL::Exception(oss.str().c_str());
4425 * This method is \b NOT wrapped into python because it can be useful only for performance reasons in C++ context.
4426 * All values in \a this must be 0. or 1. within eps error. 0 means false, 1 means true.
4427 * If an another value than 0 or 1 appear (within eps precision) an INTERP_KERNEL::Exception will be thrown.
4429 * \throw if \a this is not allocated.
4430 * \throw if \a this has not exactly one component.
4432 std::vector<bool> DataArrayDouble::toVectorOfBool(double eps) const
4435 if(getNumberOfComponents()!=1)
4436 throw INTERP_KERNEL::Exception("DataArrayDouble::toVectorOfBool : must be applied on single component array !");
4437 int nbt(getNumberOfTuples());
4438 std::vector<bool> ret(nbt);
4439 const double *pt(begin());
4440 for(int i=0;i<nbt;i++)
4444 else if(fabs(pt[i]-1.)<eps)
4448 std::ostringstream oss; oss << "DataArrayDouble::toVectorOfBool : the tuple #" << i << " has value " << pt[i] << " is invalid ! must be 0. or 1. !";
4449 throw INTERP_KERNEL::Exception(oss.str().c_str());
4456 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
4459 void DataArrayDouble::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
4464 tinyInfo[0]=getNumberOfTuples();
4465 tinyInfo[1]=getNumberOfComponents();
4475 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
4478 void DataArrayDouble::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
4482 int nbOfCompo=getNumberOfComponents();
4483 tinyInfo.resize(nbOfCompo+1);
4484 tinyInfo[0]=getName();
4485 for(int i=0;i<nbOfCompo;i++)
4486 tinyInfo[i+1]=getInfoOnComponent(i);
4491 tinyInfo[0]=getName();
4496 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
4497 * This method returns if a feeding is needed.
4499 bool DataArrayDouble::resizeForUnserialization(const std::vector<int>& tinyInfoI)
4501 int nbOfTuple=tinyInfoI[0];
4502 int nbOfComp=tinyInfoI[1];
4503 if(nbOfTuple!=-1 || nbOfComp!=-1)
4505 alloc(nbOfTuple,nbOfComp);
4512 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
4514 void DataArrayDouble::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
4516 setName(tinyInfoS[0]);
4519 int nbOfCompo=getNumberOfComponents();
4520 for(int i=0;i<nbOfCompo;i++)
4521 setInfoOnComponent(i,tinyInfoS[i+1]);
4526 * Low static method that operates 3D rotation of 'nbNodes' 3D nodes whose coordinates are arranged in \a coordsIn
4527 * around an axe ( \a center, \a vect) and with angle \a angle.
4529 void DataArrayDouble::Rotate3DAlg(const double *center, const double *vect, double angle, int nbNodes, const double *coordsIn, double *coordsOut)
4531 if(!center || !vect)
4532 throw INTERP_KERNEL::Exception("DataArrayDouble::Rotate3DAlg : null vector in input !");
4533 double sina(sin(angle));
4534 double cosa(cos(angle));
4535 double vectorNorm[3];
4537 double matrixTmp[9];
4538 double norm(sqrt(vect[0]*vect[0]+vect[1]*vect[1]+vect[2]*vect[2]));
4539 if(norm<std::numeric_limits<double>::min())
4540 throw INTERP_KERNEL::Exception("DataArrayDouble::Rotate3DAlg : magnitude of input vector is too close of 0. !");
4541 std::transform(vect,vect+3,vectorNorm,std::bind2nd(std::multiplies<double>(),1/norm));
4542 //rotation matrix computation
4543 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;
4544 matrixTmp[0]=vectorNorm[0]*vectorNorm[0]; matrixTmp[1]=vectorNorm[0]*vectorNorm[1]; matrixTmp[2]=vectorNorm[0]*vectorNorm[2];
4545 matrixTmp[3]=vectorNorm[1]*vectorNorm[0]; matrixTmp[4]=vectorNorm[1]*vectorNorm[1]; matrixTmp[5]=vectorNorm[1]*vectorNorm[2];
4546 matrixTmp[6]=vectorNorm[2]*vectorNorm[0]; matrixTmp[7]=vectorNorm[2]*vectorNorm[1]; matrixTmp[8]=vectorNorm[2]*vectorNorm[2];
4547 std::transform(matrixTmp,matrixTmp+9,matrixTmp,std::bind2nd(std::multiplies<double>(),1-cosa));
4548 std::transform(matrix,matrix+9,matrixTmp,matrix,std::plus<double>());
4549 matrixTmp[0]=0.; matrixTmp[1]=-vectorNorm[2]; matrixTmp[2]=vectorNorm[1];
4550 matrixTmp[3]=vectorNorm[2]; matrixTmp[4]=0.; matrixTmp[5]=-vectorNorm[0];
4551 matrixTmp[6]=-vectorNorm[1]; matrixTmp[7]=vectorNorm[0]; matrixTmp[8]=0.;
4552 std::transform(matrixTmp,matrixTmp+9,matrixTmp,std::bind2nd(std::multiplies<double>(),sina));
4553 std::transform(matrix,matrix+9,matrixTmp,matrix,std::plus<double>());
4554 //rotation matrix computed.
4556 for(int i=0; i<nbNodes; i++)
4558 std::transform(coordsIn+i*3,coordsIn+(i+1)*3,center,tmp,std::minus<double>());
4559 coordsOut[i*3]=matrix[0]*tmp[0]+matrix[1]*tmp[1]+matrix[2]*tmp[2]+center[0];
4560 coordsOut[i*3+1]=matrix[3]*tmp[0]+matrix[4]*tmp[1]+matrix[5]*tmp[2]+center[1];
4561 coordsOut[i*3+2]=matrix[6]*tmp[0]+matrix[7]*tmp[1]+matrix[8]*tmp[2]+center[2];
4565 void DataArrayDouble::Symmetry3DPlane(const double point[3], const double normalVector[3], int nbNodes, const double *coordsIn, double *coordsOut)
4567 double matrix[9],matrix2[9],matrix3[9];
4568 double vect[3],crossVect[3];
4569 INTERP_KERNEL::orthogonalVect3(normalVector,vect);
4570 crossVect[0]=normalVector[1]*vect[2]-normalVector[2]*vect[1];
4571 crossVect[1]=normalVector[2]*vect[0]-normalVector[0]*vect[2];
4572 crossVect[2]=normalVector[0]*vect[1]-normalVector[1]*vect[0];
4573 double nv(INTERP_KERNEL::norm<3>(vect)),ni(INTERP_KERNEL::norm<3>(normalVector)),nc(INTERP_KERNEL::norm<3>(crossVect));
4574 matrix[0]=vect[0]/nv; matrix[1]=crossVect[0]/nc; matrix[2]=-normalVector[0]/ni;
4575 matrix[3]=vect[1]/nv; matrix[4]=crossVect[1]/nc; matrix[5]=-normalVector[1]/ni;
4576 matrix[6]=vect[2]/nv; matrix[7]=crossVect[2]/nc; matrix[8]=-normalVector[2]/ni;
4577 matrix2[0]=vect[0]/nv; matrix2[1]=vect[1]/nv; matrix2[2]=vect[2]/nv;
4578 matrix2[3]=crossVect[0]/nc; matrix2[4]=crossVect[1]/nc; matrix2[5]=crossVect[2]/nc;
4579 matrix2[6]=normalVector[0]/ni; matrix2[7]=normalVector[1]/ni; matrix2[8]=normalVector[2]/ni;
4580 for(int i=0;i<3;i++)
4581 for(int j=0;j<3;j++)
4584 for(int k=0;k<3;k++)
4585 val+=matrix[3*i+k]*matrix2[3*k+j];
4588 //rotation matrix computed.
4590 for(int i=0; i<nbNodes; i++)
4592 std::transform(coordsIn+i*3,coordsIn+(i+1)*3,point,tmp,std::minus<double>());
4593 coordsOut[i*3]=matrix3[0]*tmp[0]+matrix3[1]*tmp[1]+matrix3[2]*tmp[2]+point[0];
4594 coordsOut[i*3+1]=matrix3[3]*tmp[0]+matrix3[4]*tmp[1]+matrix3[5]*tmp[2]+point[1];
4595 coordsOut[i*3+2]=matrix3[6]*tmp[0]+matrix3[7]*tmp[1]+matrix3[8]*tmp[2]+point[2];
4599 void DataArrayDouble::GiveBaseForPlane(const double normalVector[3], double baseOfPlane[9])
4601 double vect[3],crossVect[3];
4602 INTERP_KERNEL::orthogonalVect3(normalVector,vect);
4603 crossVect[0]=normalVector[1]*vect[2]-normalVector[2]*vect[1];
4604 crossVect[1]=normalVector[2]*vect[0]-normalVector[0]*vect[2];
4605 crossVect[2]=normalVector[0]*vect[1]-normalVector[1]*vect[0];
4606 double nv(INTERP_KERNEL::norm<3>(vect)),ni(INTERP_KERNEL::norm<3>(normalVector)),nc(INTERP_KERNEL::norm<3>(crossVect));
4607 baseOfPlane[0]=vect[0]/nv; baseOfPlane[1]=vect[1]/nv; baseOfPlane[2]=vect[2]/nv;
4608 baseOfPlane[3]=crossVect[0]/nc; baseOfPlane[4]=crossVect[1]/nc; baseOfPlane[5]=crossVect[2]/nc;
4609 baseOfPlane[6]=normalVector[0]/ni; baseOfPlane[7]=normalVector[1]/ni; baseOfPlane[8]=normalVector[2]/ni;
4613 * Low static method that operates 3D rotation of \a nbNodes 3D nodes whose coordinates are arranged in \a coords
4614 * around the center point \a center and with angle \a angle.
4616 void DataArrayDouble::Rotate2DAlg(const double *center, double angle, int nbNodes, const double *coordsIn, double *coordsOut)
4618 double cosa=cos(angle);
4619 double sina=sin(angle);
4621 matrix[0]=cosa; matrix[1]=-sina; matrix[2]=sina; matrix[3]=cosa;
4623 for(int i=0; i<nbNodes; i++)
4625 std::transform(coordsIn+i*2,coordsIn+(i+1)*2,center,tmp,std::minus<double>());
4626 coordsOut[i*2]=matrix[0]*tmp[0]+matrix[1]*tmp[1]+center[0];
4627 coordsOut[i*2+1]=matrix[2]*tmp[0]+matrix[3]*tmp[1]+center[1];
4631 DataArrayDoubleIterator::DataArrayDoubleIterator(DataArrayDouble *da):_da(da),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
4636 if(_da->isAllocated())
4638 _nb_comp=da->getNumberOfComponents();
4639 _nb_tuple=da->getNumberOfTuples();
4640 _pt=da->getPointer();
4645 DataArrayDoubleIterator::~DataArrayDoubleIterator()
4651 DataArrayDoubleTuple *DataArrayDoubleIterator::nextt()
4653 if(_tuple_id<_nb_tuple)
4656 DataArrayDoubleTuple *ret=new DataArrayDoubleTuple(_pt,_nb_comp);
4664 DataArrayDoubleTuple::DataArrayDoubleTuple(double *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
4669 std::string DataArrayDoubleTuple::repr() const
4671 std::ostringstream oss; oss.precision(17); oss << "(";
4672 for(int i=0;i<_nb_of_compo-1;i++)
4673 oss << _pt[i] << ", ";
4674 oss << _pt[_nb_of_compo-1] << ")";
4678 double DataArrayDoubleTuple::doubleValue() const
4682 throw INTERP_KERNEL::Exception("DataArrayDoubleTuple::doubleValue : DataArrayDoubleTuple instance has not exactly 1 component -> Not possible to convert it into a double precision float !");
4686 * This method returns a newly allocated instance the caller should dealed with by a MEDCoupling::DataArrayDouble::decrRef.
4687 * This method performs \b no copy of data. The content is only referenced using MEDCoupling::DataArrayDouble::useArray with ownership set to \b false.
4688 * 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
4689 * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
4691 DataArrayDouble *DataArrayDoubleTuple::buildDADouble(int nbOfTuples, int nbOfCompo) const
4693 if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
4695 DataArrayDouble *ret=DataArrayDouble::New();
4696 ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
4701 std::ostringstream oss; oss << "DataArrayDoubleTuple::buildDADouble : unable to build a requested DataArrayDouble instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
4702 oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
4703 throw INTERP_KERNEL::Exception(oss.str().c_str());
4708 * Returns a new instance of DataArrayInt. The caller is to delete this array
4709 * using decrRef() as it is no more needed.
4711 DataArrayInt *DataArrayInt::New()
4713 return new DataArrayInt;
4717 * Returns the only one value in \a this, if and only if number of elements
4718 * (nb of tuples * nb of components) is equal to 1, and that \a this is allocated.
4719 * \return double - the sole value stored in \a this array.
4720 * \throw If at least one of conditions stated above is not fulfilled.
4722 int DataArrayInt::intValue() const
4726 if(getNbOfElems()==1)
4728 return *getConstPointer();
4731 throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is allocated but number of elements is not equal to 1 !");
4734 throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is not allocated !");
4738 * Returns an integer value characterizing \a this array, which is useful for a quick
4739 * comparison of many instances of DataArrayInt.
4740 * \return int - the hash value.
4741 * \throw If \a this is not allocated.
4743 int DataArrayInt::getHashCode() const
4746 std::size_t nbOfElems=getNbOfElems();
4747 int ret=nbOfElems*65536;
4752 const int *pt=begin();
4753 for(std::size_t i=0;i<nbOfElems;i+=delta)
4754 ret0+=pt[i] & 0x1FFF;
4759 * Returns a full copy of \a this. For more info on copying data arrays see
4760 * \ref MEDCouplingArrayBasicsCopyDeep.
4761 * \return DataArrayInt * - a new instance of DataArrayInt.
4763 DataArrayInt *DataArrayInt::deepCopy() const
4765 return new DataArrayInt(*this);
4769 * Returns either a \a deep or \a shallow copy of this array. For more info see
4770 * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
4771 * \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
4772 * \return DataArrayInt * - either a new instance of DataArrayInt (if \a dCpy
4773 * == \a true) or \a this instance (if \a dCpy == \a false).
4775 DataArrayInt *DataArrayInt::performCopyOrIncrRef(bool dCpy) const
4782 return const_cast<DataArrayInt *>(this);
4787 * Assign zero to all values in \a this array. To know more on filling arrays see
4788 * \ref MEDCouplingArrayFill.
4789 * \throw If \a this is not allocated.
4791 void DataArrayInt::fillWithZero()
4797 * Set all values in \a this array so that the i-th element equals to \a init + i
4798 * (i starts from zero). To know more on filling arrays see \ref MEDCouplingArrayFill.
4799 * \param [in] init - value to assign to the first element of array.
4800 * \throw If \a this->getNumberOfComponents() != 1
4801 * \throw If \a this is not allocated.
4803 void DataArrayInt::iota(int init)
4806 if(getNumberOfComponents()!=1)
4807 throw INTERP_KERNEL::Exception("DataArrayInt::iota : works only for arrays with only one component, you can call 'rearrange' method before !");
4808 int *ptr=getPointer();
4809 int ntuples=getNumberOfTuples();
4810 for(int i=0;i<ntuples;i++)
4816 * Returns a textual and human readable representation of \a this instance of
4817 * DataArrayInt. This text is shown when a DataArrayInt is printed in Python.
4818 * \return std::string - text describing \a this DataArrayInt.
4820 * \sa reprNotTooLong, reprZip
4822 std::string DataArrayInt::repr() const
4824 std::ostringstream ret;
4829 std::string DataArrayInt::reprZip() const
4831 std::ostringstream ret;
4837 * This method is close to repr method except that when \a this has more than 1000 tuples, all tuples are not
4838 * printed out to avoid to consume too much space in interpretor.
4841 std::string DataArrayInt::reprNotTooLong() const
4843 std::ostringstream ret;
4844 reprNotTooLongStream(ret);
4848 void DataArrayInt::writeVTK(std::ostream& ofs, int indent, const std::string& type, const std::string& nameInFile, DataArrayByte *byteArr) const
4850 static const char SPACE[4]={' ',' ',' ',' '};
4852 std::string idt(indent,' ');
4853 ofs << idt << "<DataArray type=\"" << type << "\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
4856 ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">";
4857 if(std::string(type)=="Int32")
4859 const char *data(reinterpret_cast<const char *>(begin()));
4860 std::size_t sz(getNbOfElems()*sizeof(int));
4861 byteArr->insertAtTheEnd(data,data+sz);
4862 byteArr->insertAtTheEnd(SPACE,SPACE+4);
4864 else if(std::string(type)=="Int8")
4866 INTERP_KERNEL::AutoPtr<char> tmp(new char[getNbOfElems()]);
4867 std::copy(begin(),end(),(char *)tmp);
4868 byteArr->insertAtTheEnd((char *)tmp,(char *)tmp+getNbOfElems());
4869 byteArr->insertAtTheEnd(SPACE,SPACE+4);
4871 else if(std::string(type)=="UInt8")
4873 INTERP_KERNEL::AutoPtr<unsigned char> tmp(new unsigned char[getNbOfElems()]);
4874 std::copy(begin(),end(),(unsigned char *)tmp);
4875 byteArr->insertAtTheEnd((unsigned char *)tmp,(unsigned char *)tmp+getNbOfElems());
4876 byteArr->insertAtTheEnd(SPACE,SPACE+4);
4879 throw INTERP_KERNEL::Exception("DataArrayInt::writeVTK : Only Int32, Int8 and UInt8 supported !");
4883 ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt;
4884 std::copy(begin(),end(),std::ostream_iterator<int>(ofs," "));
4886 ofs << std::endl << idt << "</DataArray>\n";
4889 void DataArrayInt::reprStream(std::ostream& stream) const
4891 stream << "Name of int array : \"" << _name << "\"\n";
4892 reprWithoutNameStream(stream);
4895 void DataArrayInt::reprZipStream(std::ostream& stream) const
4897 stream << "Name of int array : \"" << _name << "\"\n";
4898 reprZipWithoutNameStream(stream);
4901 void DataArrayInt::reprNotTooLongStream(std::ostream& stream) const
4903 stream << "Name of int array : \"" << _name << "\"\n";
4904 reprNotTooLongWithoutNameStream(stream);
4907 void DataArrayInt::reprWithoutNameStream(std::ostream& stream) const
4909 DataArray::reprWithoutNameStream(stream);
4910 _mem.repr(getNumberOfComponents(),stream);
4913 void DataArrayInt::reprZipWithoutNameStream(std::ostream& stream) const
4915 DataArray::reprWithoutNameStream(stream);
4916 _mem.reprZip(getNumberOfComponents(),stream);
4919 void DataArrayInt::reprNotTooLongWithoutNameStream(std::ostream& stream) const
4921 DataArray::reprWithoutNameStream(stream);
4922 stream.precision(17);
4923 _mem.reprNotTooLong(getNumberOfComponents(),stream);
4926 void DataArrayInt::reprCppStream(const std::string& varName, std::ostream& stream) const
4928 int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
4929 const int *data=getConstPointer();
4930 stream << "DataArrayInt *" << varName << "=DataArrayInt::New();" << std::endl;
4931 if(nbTuples*nbComp>=1)
4933 stream << "const int " << varName << "Data[" << nbTuples*nbComp << "]={";
4934 std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<int>(stream,","));
4935 stream << data[nbTuples*nbComp-1] << "};" << std::endl;
4936 stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
4939 stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
4940 stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
4944 * Method that gives a quick overvien of \a this for python.
4946 void DataArrayInt::reprQuickOverview(std::ostream& stream) const
4948 static const std::size_t MAX_NB_OF_BYTE_IN_REPR=300;
4949 stream << "DataArrayInt C++ instance at " << this << ". ";
4952 int nbOfCompo=(int)_info_on_compo.size();
4955 int nbOfTuples=getNumberOfTuples();
4956 stream << "Number of tuples : " << nbOfTuples << ". Number of components : " << nbOfCompo << "." << std::endl;
4957 reprQuickOverviewData(stream,MAX_NB_OF_BYTE_IN_REPR);
4960 stream << "Number of components : 0.";
4963 stream << "*** No data allocated ****";
4966 void DataArrayInt::reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const
4968 const int *data=begin();
4969 int nbOfTuples=getNumberOfTuples();
4970 int nbOfCompo=(int)_info_on_compo.size();
4971 std::ostringstream oss2; oss2 << "[";
4972 std::string oss2Str(oss2.str());
4973 bool isFinished=true;
4974 for(int i=0;i<nbOfTuples && isFinished;i++)
4979 for(int j=0;j<nbOfCompo;j++,data++)
4982 if(j!=nbOfCompo-1) oss2 << ", ";
4988 if(i!=nbOfTuples-1) oss2 << ", ";
4989 std::string oss3Str(oss2.str());
4990 if(oss3Str.length()<maxNbOfByteInRepr)
5002 * Modifies in place \a this one-dimensional array so that each value \a v = \a indArrBg[ \a v ],
5003 * i.e. a current value is used as in index to get a new value from \a indArrBg.
5004 * \param [in] indArrBg - pointer to the first element of array of new values to assign
5006 * \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
5007 * the last value of \a indArrBg is \a indArrEnd[ -1 ].
5008 * \throw If \a this->getNumberOfComponents() != 1
5009 * \throw If any value of \a this can't be used as a valid index for
5010 * [\a indArrBg, \a indArrEnd).
5014 void DataArrayInt::transformWithIndArr(const int *indArrBg, const int *indArrEnd)
5017 if(getNumberOfComponents()!=1)
5018 throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
5019 int nbElemsIn((int)std::distance(indArrBg,indArrEnd)),nbOfTuples(getNumberOfTuples()),*pt(getPointer());
5020 for(int i=0;i<nbOfTuples;i++,pt++)
5022 if(*pt>=0 && *pt<nbElemsIn)
5026 std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " of this value is " << *pt << ", should be in [0," << nbElemsIn << ") !";
5027 throw INTERP_KERNEL::Exception(oss.str().c_str());
5034 * Computes distribution of values of \a this one-dimensional array between given value
5035 * ranges (casts). This method is typically useful for entity number spliting by types,
5037 * \warning The values contained in \a arrBg should be sorted ascendently. No
5038 * check of this is be done. If not, the result is not warranted.
5039 * \param [in] arrBg - the array of ascending values defining the value ranges. The i-th
5040 * value of \a arrBg (\a arrBg[ i ]) gives the lowest value of the i-th range,
5041 * and the greatest value of the i-th range equals to \a arrBg[ i+1 ] - 1. \a
5042 * arrBg containing \a n values defines \a n-1 ranges. The last value of \a arrBg
5043 * should be more than every value in \a this array.
5044 * \param [in] arrEnd - specifies the end of the array \a arrBg, so that
5045 * the last value of \a arrBg is \a arrEnd[ -1 ].
5046 * \param [out] castArr - a new instance of DataArrayInt, of same size as \a this array
5047 * (same number of tuples and components), the caller is to delete
5048 * using decrRef() as it is no more needed.
5049 * This array contains indices of ranges for every value of \a this array. I.e.
5050 * the i-th value of \a castArr gives the index of range the i-th value of \a this
5051 * belongs to. Or, in other words, this parameter contains for each tuple in \a
5052 * this in which cast it holds.
5053 * \param [out] rankInsideCast - a new instance of DataArrayInt, of same size as \a this
5054 * array, the caller is to delete using decrRef() as it is no more needed.
5055 * This array contains ranks of values of \a this array within ranges
5056 * they belongs to. I.e. the i-th value of \a rankInsideCast gives the rank of
5057 * the i-th value of \a this array within the \a castArr[ i ]-th range, to which
5058 * the i-th value of \a this belongs to. Or, in other words, this param contains
5059 * for each tuple its rank inside its cast. The rank is computed as difference
5060 * between the value and the lowest value of range.
5061 * \param [out] castsPresent - a new instance of DataArrayInt, containing indices of
5062 * ranges (casts) to which at least one value of \a this array belongs.
5063 * Or, in other words, this param contains the casts that \a this contains.
5064 * The caller is to delete this array using decrRef() as it is no more needed.
5066 * \b Example: If \a this contains [6,5,0,3,2,7,8,1,4] and \a arrBg contains [0,4,9] then
5067 * the output of this method will be :
5068 * - \a castArr : [1,1,0,0,0,1,1,0,1]
5069 * - \a rankInsideCast: [2,1,0,3,2,3,4,1,0]
5070 * - \a castsPresent : [0,1]
5072 * I.e. values of \a this array belong to 2 ranges: #0 and #1. Value 6 belongs to the
5073 * range #1 and its rank within this range is 2; etc.
5075 * \throw If \a this->getNumberOfComponents() != 1.
5076 * \throw If \a arrEnd - arrBg < 2.
5077 * \throw If any value of \a this is not less than \a arrEnd[-1].
5079 void DataArrayInt::splitByValueRange(const int *arrBg, const int *arrEnd,
5080 DataArrayInt *& castArr, DataArrayInt *& rankInsideCast, DataArrayInt *& castsPresent) const
5083 if(getNumberOfComponents()!=1)
5084 throw INTERP_KERNEL::Exception("Call splitByValueRange method on DataArrayInt with only one component, you can call 'rearrange' method before !");
5085 int nbOfTuples=getNumberOfTuples();
5086 std::size_t nbOfCast=std::distance(arrBg,arrEnd);
5088 throw INTERP_KERNEL::Exception("DataArrayInt::splitByValueRange : The input array giving the cast range values should be of size >=2 !");
5090 const int *work=getConstPointer();
5091 typedef std::reverse_iterator<const int *> rintstart;
5092 rintstart bg(arrEnd);//OK no problem because size of 'arr' is greater or equal 2
5093 rintstart end2(arrBg);
5094 MCAuto<DataArrayInt> ret1=DataArrayInt::New();
5095 MCAuto<DataArrayInt> ret2=DataArrayInt::New();
5096 MCAuto<DataArrayInt> ret3=DataArrayInt::New();
5097 ret1->alloc(nbOfTuples,1);
5098 ret2->alloc(nbOfTuples,1);
5099 int *ret1Ptr=ret1->getPointer();
5100 int *ret2Ptr=ret2->getPointer();
5101 std::set<std::size_t> castsDetected;
5102 for(int i=0;i<nbOfTuples;i++)
5104 rintstart res=std::find_if(bg,end2,std::bind2nd(std::less_equal<int>(), work[i]));
5105 std::size_t pos=std::distance(bg,res);
5106 std::size_t pos2=nbOfCast-pos;
5109 ret1Ptr[i]=(int)pos2;
5110 ret2Ptr[i]=work[i]-arrBg[pos2];
5111 castsDetected.insert(pos2);
5115 std::ostringstream oss; oss << "DataArrayInt::splitByValueRange : At rank #" << i << " the value is " << work[i] << " should be in [0," << *bg << ") !";
5116 throw INTERP_KERNEL::Exception(oss.str().c_str());
5119 ret3->alloc((int)castsDetected.size(),1);
5120 std::copy(castsDetected.begin(),castsDetected.end(),ret3->getPointer());
5121 castArr=ret1.retn();
5122 rankInsideCast=ret2.retn();
5123 castsPresent=ret3.retn();
5127 * 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 ).
5128 * 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 ).
5129 * This method works only if \a this is allocated and single component. If not an exception will be thrown.
5131 * \param [out] strt - the start of the range (included) if true is returned.
5132 * \param [out] sttoopp - the end of the range (not included) if true is returned.
5133 * \param [out] stteepp - the step of the range if true is returned.
5134 * \return the verdict of the check.
5136 * \sa DataArray::GetNumberOfItemGivenBES
5138 bool DataArrayInt::isRange(int& strt, int& sttoopp, int& stteepp) const
5141 if(getNumberOfComponents()!=1)
5142 throw INTERP_KERNEL::Exception("DataArrayInt::isRange : this must be single component array !");
5143 int nbTuples(getNumberOfTuples());
5145 { strt=0; sttoopp=0; stteepp=1; return true; }
5146 const int *pt(begin());
5149 { sttoopp=strt+1; stteepp=1; return true; }
5150 strt=*pt; sttoopp=pt[nbTuples-1];
5156 int a(sttoopp-1-strt),tmp(strt);
5157 if(a%(nbTuples-1)!=0)
5159 stteepp=a/(nbTuples-1);
5160 for(int i=0;i<nbTuples;i++,tmp+=stteepp)
5168 int a(strt-sttoopp-1),tmp(strt);
5169 if(a%(nbTuples-1)!=0)
5171 stteepp=-(a/(nbTuples-1));
5172 for(int i=0;i<nbTuples;i++,tmp+=stteepp)
5180 * Creates a one-dimensional DataArrayInt (\a res) whose contents are computed from
5181 * values of \a this (\a a) and the given (\a indArr) arrays as follows:
5182 * \a res[ \a indArr[ \a a[ i ]]] = i. I.e. for each value in place i \a v = \a a[ i ],
5183 * new value in place \a indArr[ \a v ] is i.
5184 * \param [in] indArrBg - the array holding indices within the result array to assign
5185 * indices of values of \a this array pointing to values of \a indArrBg.
5186 * \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
5187 * the last value of \a indArrBg is \a indArrEnd[ -1 ].
5188 * \return DataArrayInt * - the new instance of DataArrayInt.
5189 * The caller is to delete this result array using decrRef() as it is no more
5191 * \throw If \a this->getNumberOfComponents() != 1.
5192 * \throw If any value of \a this array is not a valid index for \a indArrBg array.
5193 * \throw If any value of \a indArrBg is not a valid index for \a this array.
5195 DataArrayInt *DataArrayInt::transformWithIndArrR(const int *indArrBg, const int *indArrEnd) const
5198 if(getNumberOfComponents()!=1)
5199 throw INTERP_KERNEL::Exception("Call transformWithIndArrR method on DataArrayInt with only one component, you can call 'rearrange' method before !");
5200 int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
5201 int nbOfTuples=getNumberOfTuples();
5202 const int *pt=getConstPointer();
5203 MCAuto<DataArrayInt> ret=DataArrayInt::New();
5204 ret->alloc(nbOfTuples,1);
5205 ret->fillWithValue(-1);
5206 int *tmp=ret->getPointer();
5207 for(int i=0;i<nbOfTuples;i++,pt++)
5209 if(*pt>=0 && *pt<nbElemsIn)
5211 int pos=indArrBg[*pt];
5212 if(pos>=0 && pos<nbOfTuples)
5216 std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value of new pos is " << pos << " ( indArrBg[" << *pt << "]) ! Should be in [0," << nbOfTuples << ") !";
5217 throw INTERP_KERNEL::Exception(oss.str().c_str());
5222 std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn << " !";
5223 throw INTERP_KERNEL::Exception(oss.str().c_str());
5230 * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
5231 * from values of \a this array, which is supposed to contain a renumbering map in
5232 * "Old to New" mode. The result array contains a renumbering map in "New to Old" mode.
5233 * To know how to use the renumbering maps see \ref numbering.
5234 * \param [in] newNbOfElem - the number of tuples in the result array.
5235 * \return DataArrayInt * - the new instance of DataArrayInt.
5236 * The caller is to delete this result array using decrRef() as it is no more
5239 * \if ENABLE_EXAMPLES
5240 * \ref cpp_mcdataarrayint_invertarrayo2n2n2o "Here is a C++ example".<br>
5241 * \ref py_mcdataarrayint_invertarrayo2n2n2o "Here is a Python example".
5244 DataArrayInt *DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const
5246 MCAuto<DataArrayInt> ret=DataArrayInt::New();
5247 ret->alloc(newNbOfElem,1);
5248 int nbOfOldNodes=getNumberOfTuples();
5249 const int *old2New=getConstPointer();
5250 int *pt=ret->getPointer();
5251 for(int i=0;i!=nbOfOldNodes;i++)
5253 int newp(old2New[i]);
5256 if(newp>=0 && newp<newNbOfElem)
5260 std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2O : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
5261 throw INTERP_KERNEL::Exception(oss.str().c_str());
5269 * This method is similar to DataArrayInt::invertArrayO2N2N2O except that
5270 * 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]
5272 DataArrayInt *DataArrayInt::invertArrayO2N2N2OBis(int newNbOfElem) const
5274 MCAuto<DataArrayInt> ret=DataArrayInt::New();
5275 ret->alloc(newNbOfElem,1);
5276 int nbOfOldNodes=getNumberOfTuples();
5277 const int *old2New=getConstPointer();
5278 int *pt=ret->getPointer();
5279 for(int i=nbOfOldNodes-1;i>=0;i--)
5281 int newp(old2New[i]);
5284 if(newp>=0 && newp<newNbOfElem)
5288 std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2OBis : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
5289 throw INTERP_KERNEL::Exception(oss.str().c_str());
5297 * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
5298 * from values of \a this array, which is supposed to contain a renumbering map in
5299 * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
5300 * To know how to use the renumbering maps see \ref numbering.
5301 * \param [in] newNbOfElem - the number of tuples in the result array.
5302 * \return DataArrayInt * - the new instance of DataArrayInt.
5303 * The caller is to delete this result array using decrRef() as it is no more
5306 * \if ENABLE_EXAMPLES
5307 * \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
5309 * \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
5312 DataArrayInt *DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const
5315 MCAuto<DataArrayInt> ret=DataArrayInt::New();
5316 ret->alloc(oldNbOfElem,1);
5317 const int *new2Old=getConstPointer();
5318 int *pt=ret->getPointer();
5319 std::fill(pt,pt+oldNbOfElem,-1);
5320 int nbOfNewElems=getNumberOfTuples();
5321 for(int i=0;i<nbOfNewElems;i++)
5324 if(v>=0 && v<oldNbOfElem)
5328 std::ostringstream oss; oss << "DataArrayInt::invertArrayN2O2O2N : in new id #" << i << " old value is " << v << " expected to be in [0," << oldNbOfElem << ") !";
5329 throw INTERP_KERNEL::Exception(oss.str().c_str());
5336 * Equivalent to DataArrayInt::isEqual except that if false the reason of
5337 * mismatch is given.
5339 * \param [in] other the instance to be compared with \a this
5340 * \param [out] reason In case of inequality returns the reason.
5341 * \sa DataArrayInt::isEqual
5343 bool DataArrayInt::isEqualIfNotWhy(const DataArrayInt& other, std::string& reason) const
5345 if(!areInfoEqualsIfNotWhy(other,reason))
5347 return _mem.isEqual(other._mem,0,reason);
5351 * Checks if \a this and another DataArrayInt are fully equal. For more info see
5352 * \ref MEDCouplingArrayBasicsCompare.
5353 * \param [in] other - an instance of DataArrayInt to compare with \a this one.
5354 * \return bool - \a true if the two arrays are equal, \a false else.
5356 bool DataArrayInt::isEqual(const DataArrayInt& other) const
5359 return isEqualIfNotWhy(other,tmp);
5363 * Checks if values of \a this and another DataArrayInt are equal. For more info see
5364 * \ref MEDCouplingArrayBasicsCompare.
5365 * \param [in] other - an instance of DataArrayInt to compare with \a this one.
5366 * \return bool - \a true if the values of two arrays are equal, \a false else.
5368 bool DataArrayInt::isEqualWithoutConsideringStr(const DataArrayInt& other) const
5371 return _mem.isEqual(other._mem,0,tmp);
5375 * Checks if values of \a this and another DataArrayInt are equal. Comparison is
5376 * performed on sorted value sequences.
5377 * For more info see\ref MEDCouplingArrayBasicsCompare.
5378 * \param [in] other - an instance of DataArrayInt to compare with \a this one.
5379 * \return bool - \a true if the sorted values of two arrays are equal, \a false else.
5381 bool DataArrayInt::isEqualWithoutConsideringStrAndOrder(const DataArrayInt& other) const
5383 MCAuto<DataArrayInt> a=deepCopy();
5384 MCAuto<DataArrayInt> b=other.deepCopy();
5387 return a->isEqualWithoutConsideringStr(*b);
5391 * This method compares content of input vector \a v and \a this.
5392 * 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.
5393 * For performance reasons \a this is expected to be sorted ascendingly. If not an exception will be thrown.
5395 * \param [in] v - the vector of 'flags' to be compared with \a this.
5397 * \throw If \a this is not sorted ascendingly.
5398 * \throw If \a this has not exactly one component.
5399 * \throw If \a this is not allocated.
5401 bool DataArrayInt::isFittingWith(const std::vector<bool>& v) const
5404 if(getNumberOfComponents()!=1)
5405 throw INTERP_KERNEL::Exception("DataArrayInt::isFittingWith : number of components of this should be equal to one !");
5406 const int *w(begin()),*end2(end());
5407 int refVal=-std::numeric_limits<int>::max();
5409 std::vector<bool>::const_iterator it(v.begin());
5410 for(;it!=v.end();it++,i++)
5422 std::ostringstream oss; oss << "DataArrayInt::isFittingWith : At pos #" << std::distance(begin(),w-1) << " this is not sorted ascendingly !";
5423 throw INTERP_KERNEL::Exception(oss.str().c_str());
5437 * 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
5438 * put True to the corresponding entry in \a vec.
5439 * \a vec is expected to be with the same size than the number of tuples of \a this.
5441 * \sa DataArrayInt::switchOnTupleNotEqualTo.
5443 void DataArrayInt::switchOnTupleEqualTo(int val, std::vector<bool>& vec) const
5446 if(getNumberOfComponents()!=1)
5447 throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleEqualTo : number of components of this should be equal to one !");
5448 int nbOfTuples(getNumberOfTuples());
5449 if(nbOfTuples!=(int)vec.size())
5450 throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleEqualTo : number of tuples of this should be equal to size of input vector of bool !");
5451 const int *pt(begin());
5452 for(int i=0;i<nbOfTuples;i++)
5458 * 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
5459 * put True to the corresponding entry in \a vec.
5460 * \a vec is expected to be with the same size than the number of tuples of \a this.
5462 * \sa DataArrayInt::switchOnTupleEqualTo.
5464 void DataArrayInt::switchOnTupleNotEqualTo(int val, std::vector<bool>& vec) const
5467 if(getNumberOfComponents()!=1)
5468 throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleNotEqualTo : number of components of this should be equal to one !");
5469 int nbOfTuples(getNumberOfTuples());
5470 if(nbOfTuples!=(int)vec.size())
5471 throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleNotEqualTo : number of tuples of this should be equal to size of input vector of bool !");
5472 const int *pt(begin());
5473 for(int i=0;i<nbOfTuples;i++)
5479 * Computes for each tuple the sum of number of components values in the tuple and return it.
5481 * \return DataArrayInt * - the new instance of DataArrayInt containing the
5482 * same number of tuples as \a this array and one component.
5483 * The caller is to delete this result array using decrRef() as it is no more
5485 * \throw If \a this is not allocated.
5487 DataArrayInt *DataArrayInt::sumPerTuple() const
5490 int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
5491 MCAuto<DataArrayInt> ret(DataArrayInt::New());
5492 ret->alloc(nbOfTuple,1);
5493 const int *src(getConstPointer());
5494 int *dest(ret->getPointer());
5495 for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
5496 *dest=std::accumulate(src,src+nbOfComp,0);
5501 * Checks that \a this array is consistently **increasing** or **decreasing** in value.
5502 * If not an exception is thrown.
5503 * \param [in] increasing - if \a true, the array values should be increasing.
5504 * \throw If sequence of values is not strictly monotonic in agreement with \a
5506 * \throw If \a this->getNumberOfComponents() != 1.
5507 * \throw If \a this is not allocated.
5509 void DataArrayInt::checkMonotonic(bool increasing) const
5511 if(!isMonotonic(increasing))
5514 throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not INCREASING monotonic !");
5516 throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not DECREASING monotonic !");
5521 * Checks that \a this array is consistently **increasing** or **decreasing** in value.
5522 * \param [in] increasing - if \a true, array values should be increasing.
5523 * \return bool - \a true if values change in accordance with \a increasing arg.
5524 * \throw If \a this->getNumberOfComponents() != 1.
5525 * \throw If \a this is not allocated.
5527 bool DataArrayInt::isMonotonic(bool increasing) const
5530 if(getNumberOfComponents()!=1)
5531 throw INTERP_KERNEL::Exception("DataArrayInt::isMonotonic : only supported with 'this' array with ONE component !");
5532 int nbOfElements=getNumberOfTuples();
5533 const int *ptr=getConstPointer();
5539 for(int i=1;i<nbOfElements;i++)
5549 for(int i=1;i<nbOfElements;i++)
5561 * This method check that array consistently INCREASING or DECREASING in value.
5563 bool DataArrayInt::isStrictlyMonotonic(bool increasing) const
5566 if(getNumberOfComponents()!=1)
5567 throw INTERP_KERNEL::Exception("DataArrayInt::isStrictlyMonotonic : only supported with 'this' array with ONE component !");
5568 int nbOfElements=getNumberOfTuples();
5569 const int *ptr=getConstPointer();
5575 for(int i=1;i<nbOfElements;i++)
5585 for(int i=1;i<nbOfElements;i++)
5597 * This method check that array consistently INCREASING or DECREASING in value.
5599 void DataArrayInt::checkStrictlyMonotonic(bool increasing) const
5601 if(!isStrictlyMonotonic(increasing))
5604 throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly INCREASING monotonic !");
5606 throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly DECREASING monotonic !");
5611 * Creates a new one-dimensional DataArrayInt of the same size as \a this and a given
5612 * one-dimensional arrays that must be of the same length. The result array describes
5613 * correspondence between \a this and \a other arrays, so that
5614 * <em> other.getIJ(i,0) == this->getIJ(ret->getIJ(i),0)</em>. If such a permutation is
5615 * not possible because some element in \a other is not in \a this, an exception is thrown.
5616 * \param [in] other - an array to compute permutation to.
5617 * \return DataArrayInt * - a new instance of DataArrayInt, which is a permutation array
5618 * from \a this to \a other. The caller is to delete this array using decrRef() as it is
5620 * \throw If \a this->getNumberOfComponents() != 1.
5621 * \throw If \a other->getNumberOfComponents() != 1.
5622 * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples().
5623 * \throw If \a other includes a value which is not in \a this array.
5625 * \if ENABLE_EXAMPLES
5626 * \ref cpp_mcdataarrayint_buildpermutationarr "Here is a C++ example".
5628 * \ref py_mcdataarrayint_buildpermutationarr "Here is a Python example".
5631 DataArrayInt *DataArrayInt::buildPermutationArr(const DataArrayInt& other) const
5634 if(getNumberOfComponents()!=1 || other.getNumberOfComponents()!=1)
5635 throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' have to have exactly ONE component !");
5636 int nbTuple=getNumberOfTuples();
5637 other.checkAllocated();
5638 if(nbTuple!=other.getNumberOfTuples())
5639 throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' must have the same number of tuple !");
5640 MCAuto<DataArrayInt> ret=DataArrayInt::New();
5641 ret->alloc(nbTuple,1);
5642 ret->fillWithValue(-1);
5643 const int *pt=getConstPointer();
5644 std::map<int,int> mm;
5645 for(int i=0;i<nbTuple;i++)
5647 pt=other.getConstPointer();
5648 int *retToFill=ret->getPointer();
5649 for(int i=0;i<nbTuple;i++)
5651 std::map<int,int>::const_iterator it=mm.find(pt[i]);
5654 std::ostringstream oss; oss << "DataArrayInt::buildPermutationArr : Arrays mismatch : element (" << pt[i] << ") in 'other' not findable in 'this' !";
5655 throw INTERP_KERNEL::Exception(oss.str().c_str());
5657 retToFill[i]=(*it).second;
5663 * Elements of \a partOfThis are expected to be included in \a this.
5664 * The returned array \a ret is so that this[ret]==partOfThis
5666 * 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]
5667 * the return array will contain [3,2,5,7].
5669 * \a this is expected to be a 1 compo allocated array.
5670 * \param [in] partOfThis - A 1 compo allocated array
5671 * \return - A newly allocated array to be dealed by caller having the same number of tuples than \a partOfThis.
5672 * \throw if two same element is present twice in \a this
5673 * \throw if an element in \a partOfThis is \b NOT in \a this.
5675 DataArrayInt *DataArrayInt::indicesOfSubPart(const DataArrayInt& partOfThis) const
5677 if(getNumberOfComponents()!=1 || partOfThis.getNumberOfComponents()!=1)
5678 throw INTERP_KERNEL::Exception("DataArrayInt::indicesOfSubPart : this and input array must be one component array !");
5679 checkAllocated(); partOfThis.checkAllocated();
5680 int thisNbTuples(getNumberOfTuples()),nbTuples(partOfThis.getNumberOfTuples());
5681 const int *thisPt(begin()),*pt(partOfThis.begin());
5682 MCAuto<DataArrayInt> ret(DataArrayInt::New());
5683 ret->alloc(nbTuples,1);
5684 int *retPt(ret->getPointer());
5685 std::map<int,int> m;
5686 for(int i=0;i<thisNbTuples;i++,thisPt++)
5688 if(m.size()!=thisNbTuples)
5689 throw INTERP_KERNEL::Exception("DataArrayInt::indicesOfSubPart : some elements appears more than once !");
5690 for(int i=0;i<nbTuples;i++,retPt++,pt++)
5692 std::map<int,int>::const_iterator it(m.find(*pt));
5694 *retPt=(*it).second;
5697 std::ostringstream oss; oss << "DataArrayInt::indicesOfSubPart : At pos #" << i << " of input array value is " << *pt << " not in this !";
5698 throw INTERP_KERNEL::Exception(oss.str());
5704 void DataArrayInt::aggregate(const DataArrayInt *other)
5707 throw INTERP_KERNEL::Exception("DataArrayInt::aggregate : null pointer !");
5708 if(getNumberOfComponents()!=other->getNumberOfComponents())
5709 throw INTERP_KERNEL::Exception("DataArrayInt::aggregate : mismatch number of components !");
5710 _mem.insertAtTheEnd(other->begin(),other->end());
5714 * Returns a new DataArrayInt holding the same values as \a this array but differently
5715 * arranged in memory. If \a this array holds 2 components of 3 values:
5716 * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
5717 * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
5718 * \warning Do not confuse this method with transpose()!
5719 * \return DataArrayInt * - the new instance of DataArrayInt that the caller
5720 * is to delete using decrRef() as it is no more needed.
5721 * \throw If \a this is not allocated.
5723 DataArrayInt *DataArrayInt::fromNoInterlace() const
5727 throw INTERP_KERNEL::Exception("DataArrayInt::fromNoInterlace : Not defined array !");
5728 int *tab=_mem.fromNoInterlace(getNumberOfComponents());
5729 DataArrayInt *ret=DataArrayInt::New();
5730 ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
5735 * Returns a new DataArrayInt holding the same values as \a this array but differently
5736 * arranged in memory. If \a this array holds 2 components of 3 values:
5737 * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
5738 * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
5739 * \warning Do not confuse this method with transpose()!
5740 * \return DataArrayInt * - the new instance of DataArrayInt that the caller
5741 * is to delete using decrRef() as it is no more needed.
5742 * \throw If \a this is not allocated.
5744 DataArrayInt *DataArrayInt::toNoInterlace() const
5748 throw INTERP_KERNEL::Exception("DataArrayInt::toNoInterlace : Not defined array !");
5749 int *tab=_mem.toNoInterlace(getNumberOfComponents());
5750 DataArrayInt *ret=DataArrayInt::New();
5751 ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
5756 * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode.
5757 * This map, if applied to \a this array, would make it sorted. For example, if
5758 * \a this array contents are [9,10,0,6,4,11,3,7] then the contents of the result array
5759 * are [5,6,0,3,2,7,1,4]; if this result array (\a res) is used as an argument in call
5760 * \a this->renumber(\a res) then the returned array contains [0,3,4,6,7,9,10,11].
5761 * This method is useful for renumbering (in MED file for example). For more info
5762 * on renumbering see \ref numbering.
5763 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5764 * array using decrRef() as it is no more needed.
5765 * \throw If \a this is not allocated.
5766 * \throw If \a this->getNumberOfComponents() != 1.
5767 * \throw If there are equal values in \a this array.
5769 DataArrayInt *DataArrayInt::checkAndPreparePermutation() const
5772 if(getNumberOfComponents()!=1)
5773 throw INTERP_KERNEL::Exception("DataArrayInt::checkAndPreparePermutation : number of components must == 1 !");
5774 int nbTuples=getNumberOfTuples();
5775 const int *pt=getConstPointer();
5776 int *pt2=CheckAndPreparePermutation(pt,pt+nbTuples);
5777 DataArrayInt *ret=DataArrayInt::New();
5778 ret->useArray(pt2,true,C_DEALLOC,nbTuples,1);
5783 * 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
5784 * input array \a ids2.
5785 * \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.
5786 * 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
5788 * In case of success (no throw) : \c ids1->renumber(ret)->isEqual(ids2) where \a ret is the return of this method.
5790 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5791 * array using decrRef() as it is no more needed.
5792 * \throw If either ids1 or ids2 is null not allocated or not with one components.
5795 DataArrayInt *DataArrayInt::FindPermutationFromFirstToSecond(const DataArrayInt *ids1, const DataArrayInt *ids2)
5798 throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be not null !");
5799 if(!ids1->isAllocated() || !ids2->isAllocated())
5800 throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be allocated !");
5801 if(ids1->getNumberOfComponents()!=1 || ids2->getNumberOfComponents()!=1)
5802 throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays have exactly one component !");
5803 if(ids1->getNumberOfTuples()!=ids2->getNumberOfTuples())
5805 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 !";
5806 throw INTERP_KERNEL::Exception(oss.str().c_str());
5808 MCAuto<DataArrayInt> p1(ids1->deepCopy());
5809 MCAuto<DataArrayInt> p2(ids2->deepCopy());
5810 p1->sort(true); p2->sort(true);
5811 if(!p1->isEqualWithoutConsideringStr(*p2))
5812 throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two arrays are not lying on same ids ! Impossible to find a permutation between the 2 arrays !");
5813 p1=ids1->checkAndPreparePermutation();
5814 p2=ids2->checkAndPreparePermutation();
5815 p2=p2->invertArrayO2N2N2O(p2->getNumberOfTuples());
5816 p2=p2->selectByTupleIdSafe(p1->begin(),p1->end());
5821 * Returns two arrays describing a surjective mapping from \a this set of values (\a A)
5822 * onto a set of values of size \a targetNb (\a B). The surjective function is
5823 * \a B[ \a A[ i ]] = i. That is to say that for each \a id in [0,\a targetNb), where \a
5824 * targetNb < \a this->getNumberOfTuples(), there exists at least one tupleId (\a tid) so
5825 * that <em> this->getIJ( tid, 0 ) == id</em>. <br>
5826 * The first of out arrays returns indices of elements of \a this array, grouped by their
5827 * place in the set \a B. The second out array is the index of the first one; it shows how
5828 * many elements of \a A are mapped into each element of \a B. <br>
5830 * mapping and its usage in renumbering see \ref numbering. <br>
5832 * - \a this: [0,3,2,3,2,2,1,2]
5834 * - \a arr: [0, 6, 2,4,5,7, 1,3]
5835 * - \a arrI: [0,1,2,6,8]
5837 * This result means: <br>
5838 * the element of \a B 0 encounters within \a A once (\a arrI[ 0+1 ] - \a arrI[ 0 ]) and
5839 * its index within \a A is 0 ( \a arr[ 0:1 ] == \a arr[ \a arrI[ 0 ] : \a arrI[ 0+1 ]]);<br>
5840 * the element of \a B 2 encounters within \a A 4 times (\a arrI[ 2+1 ] - \a arrI[ 2 ]) and
5841 * its indices within \a A are [2,4,5,7] ( \a arr[ 2:6 ] == \a arr[ \a arrI[ 2 ] :
5842 * \a arrI[ 2+1 ]]); <br> etc.
5843 * \param [in] targetNb - the size of the set \a B. \a targetNb must be equal or more
5844 * than the maximal value of \a A.
5845 * \param [out] arr - a new instance of DataArrayInt returning indices of
5846 * elements of \a this, grouped by their place in the set \a B. The caller is to delete
5847 * this array using decrRef() as it is no more needed.
5848 * \param [out] arrI - a new instance of DataArrayInt returning size of groups of equal
5849 * elements of \a this. The caller is to delete this array using decrRef() as it
5850 * is no more needed.
5851 * \throw If \a this is not allocated.
5852 * \throw If \a this->getNumberOfComponents() != 1.
5853 * \throw If any value in \a this is more or equal to \a targetNb.
5855 void DataArrayInt::changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, DataArrayInt *&arrI) const
5858 if(getNumberOfComponents()!=1)
5859 throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : number of components must == 1 !");
5860 int nbOfTuples=getNumberOfTuples();
5861 MCAuto<DataArrayInt> ret(DataArrayInt::New());
5862 MCAuto<DataArrayInt> retI(DataArrayInt::New());
5863 retI->alloc(targetNb+1,1);
5864 const int *input=getConstPointer();
5865 std::vector< std::vector<int> > tmp(targetNb);
5866 for(int i=0;i<nbOfTuples;i++)
5869 if(tmp2>=0 && tmp2<targetNb)
5870 tmp[tmp2].push_back(i);
5873 std::ostringstream oss; oss << "DataArrayInt::changeSurjectiveFormat : At pos " << i << " presence of element " << tmp2 << " ! should be in [0," << targetNb << ") !";
5874 throw INTERP_KERNEL::Exception(oss.str().c_str());
5877 int *retIPtr=retI->getPointer();
5879 for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++,retIPtr++)
5880 retIPtr[1]=retIPtr[0]+(int)((*it1).size());
5881 if(nbOfTuples!=retI->getIJ(targetNb,0))
5882 throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : big problem should never happen !");
5883 ret->alloc(nbOfTuples,1);
5884 int *retPtr=ret->getPointer();
5885 for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++)
5886 retPtr=std::copy((*it1).begin(),(*it1).end(),retPtr);
5893 * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode computed
5894 * from a zip representation of a surjective format (returned e.g. by
5895 * \ref MEDCoupling::DataArrayDouble::findCommonTuples() "DataArrayDouble::findCommonTuples()"
5896 * for example). The result array minimizes the permutation. <br>
5897 * For more info on renumbering see \ref numbering. <br>
5899 * - \a nbOfOldTuples: 10
5900 * - \a arr : [0,3, 5,7,9]
5901 * - \a arrIBg : [0,2,5]
5902 * - \a newNbOfTuples: 7
5903 * - result array : [0,1,2,0,3,4,5,4,6,4]
5905 * \param [in] nbOfOldTuples - number of tuples in the initial array \a arr.
5906 * \param [in] arr - the array of tuple indices grouped by \a arrIBg array.
5907 * \param [in] arrIBg - the array dividing all indices stored in \a arr into groups of
5908 * (indices of) equal values. Its every element (except the last one) points to
5909 * the first element of a group of equal values.
5910 * \param [in] arrIEnd - specifies the end of \a arrIBg, so that the last element of \a
5911 * arrIBg is \a arrIEnd[ -1 ].
5912 * \param [out] newNbOfTuples - number of tuples after surjection application.
5913 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5914 * array using decrRef() as it is no more needed.
5915 * \throw If any value of \a arr breaks condition ( 0 <= \a arr[ i ] < \a nbOfOldTuples ).
5917 DataArrayInt *DataArrayInt::ConvertIndexArrayToO2N(int nbOfOldTuples, const int *arr, const int *arrIBg, const int *arrIEnd, int &newNbOfTuples)
5919 MCAuto<DataArrayInt> ret=DataArrayInt::New();
5920 ret->alloc(nbOfOldTuples,1);
5921 int *pt=ret->getPointer();
5922 std::fill(pt,pt+nbOfOldTuples,-1);
5923 int nbOfGrps=((int)std::distance(arrIBg,arrIEnd))-1;
5924 const int *cIPtr=arrIBg;
5925 for(int i=0;i<nbOfGrps;i++)
5926 pt[arr[cIPtr[i]]]=-(i+2);
5928 for(int iNode=0;iNode<nbOfOldTuples;iNode++)
5936 int grpId=-(pt[iNode]+2);
5937 for(int j=cIPtr[grpId];j<cIPtr[grpId+1];j++)
5939 if(arr[j]>=0 && arr[j]<nbOfOldTuples)
5943 std::ostringstream oss; oss << "DataArrayInt::ConvertIndexArrayToO2N : With element #" << j << " value is " << arr[j] << " should be in [0," << nbOfOldTuples << ") !";
5944 throw INTERP_KERNEL::Exception(oss.str().c_str());
5951 newNbOfTuples=newNb;
5956 * Returns a new DataArrayInt containing a renumbering map in "New to Old" mode,
5957 * which if applied to \a this array would make it sorted ascendingly.
5958 * For more info on renumbering see \ref numbering. <br>
5960 * - \a this: [2,0,1,1,0,1,2,0,1,1,0,0]
5961 * - result: [10,0,5,6,1,7,11,2,8,9,3,4]
5962 * - after applying result to \a this: [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2]
5964 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
5965 * array using decrRef() as it is no more needed.
5966 * \throw If \a this is not allocated.
5967 * \throw If \a this->getNumberOfComponents() != 1.
5969 DataArrayInt *DataArrayInt::buildPermArrPerLevel() const
5972 if(getNumberOfComponents()!=1)
5973 throw INTERP_KERNEL::Exception("DataArrayInt::buildPermArrPerLevel : number of components must == 1 !");
5974 int nbOfTuples=getNumberOfTuples();
5975 const int *pt=getConstPointer();
5976 std::map<int,int> m;
5977 MCAuto<DataArrayInt> ret=DataArrayInt::New();
5978 ret->alloc(nbOfTuples,1);
5979 int *opt=ret->getPointer();
5980 for(int i=0;i<nbOfTuples;i++,pt++,opt++)
5983 std::map<int,int>::iterator it=m.find(val);
5992 m.insert(std::pair<int,int>(val,1));
5996 for(std::map<int,int>::iterator it=m.begin();it!=m.end();it++)
5998 int vt=(*it).second;
6002 pt=getConstPointer();
6003 opt=ret->getPointer();
6004 for(int i=0;i<nbOfTuples;i++,pt++,opt++)
6011 * Checks if \a this array has the given size, and if its contents is equal to an array filled with
6012 * iota(). This method is particularly useful for DataArrayInt instances that represent
6013 * a renumbering array, to check if there is a real need in renumbering.
6014 * This method checks than \a this can be considered as an identity mapping
6015 * of a set having \a sizeExpected elements into itself.
6017 * \param [in] sizeExpected - The number of elements expected.
6018 * \return bool - \a true if \a this array contents == \a range( \a this->getNumberOfTuples())
6019 * \throw If \a this is not allocated.
6020 * \throw If \a this->getNumberOfComponents() != 1.
6022 bool DataArrayInt::isIota(int sizeExpected) const
6025 if(getNumberOfComponents()!=1)
6027 int nbOfTuples(getNumberOfTuples());
6028 if(nbOfTuples!=sizeExpected)
6030 const int *pt=getConstPointer();
6031 for(int i=0;i<nbOfTuples;i++,pt++)
6038 * Checks if all values in \a this array are equal to \a val.
6039 * \param [in] val - value to check equality of array values to.
6040 * \return bool - \a true if all values are \a val.
6041 * \throw If \a this is not allocated.
6042 * \throw If \a this->getNumberOfComponents() != 1
6044 bool DataArrayInt::isUniform(int val) const
6047 if(getNumberOfComponents()!=1)
6048 throw INTERP_KERNEL::Exception("DataArrayInt::isUniform : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
6049 int nbOfTuples=getNumberOfTuples();
6050 const int *w=getConstPointer();
6051 const int *end2=w+nbOfTuples;
6059 * Checks if all values in \a this array are unique.
6060 * \return bool - \a true if condition above is true
6061 * \throw If \a this is not allocated.
6062 * \throw If \a this->getNumberOfComponents() != 1
6064 bool DataArrayInt::hasUniqueValues() const
6067 if(getNumberOfComponents()!=1)
6068 throw INTERP_KERNEL::Exception("DataArrayInt::hasOnlyUniqueValues: must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
6069 int nbOfTuples(getNumberOfTuples());
6070 std::set<int> s(begin(),end()); // in C++11, should use unordered_set (O(1) complexity)
6071 if (s.size() != nbOfTuples)
6077 * Creates a new DataArrayDouble and assigns all (textual and numerical) data of \a this
6078 * array to the new one.
6079 * \return DataArrayDouble * - the new instance of DataArrayInt.
6081 DataArrayDouble *DataArrayInt::convertToDblArr() const
6084 DataArrayDouble *ret=DataArrayDouble::New();
6085 ret->alloc(getNumberOfTuples(),getNumberOfComponents());
6086 std::size_t nbOfVals=getNbOfElems();
6087 const int *src=getConstPointer();
6088 double *dest=ret->getPointer();
6089 std::copy(src,src+nbOfVals,dest);
6090 ret->copyStringInfoFrom(*this);
6095 * Appends components of another array to components of \a this one, tuple by tuple.
6096 * So that the number of tuples of \a this array remains the same and the number of
6097 * components increases.
6098 * \param [in] other - the DataArrayInt to append to \a this one.
6099 * \throw If \a this is not allocated.
6100 * \throw If \a this and \a other arrays have different number of tuples.
6102 * \if ENABLE_EXAMPLES
6103 * \ref cpp_mcdataarrayint_meldwith "Here is a C++ example".
6105 * \ref py_mcdataarrayint_meldwith "Here is a Python example".
6108 void DataArrayInt::meldWith(const DataArrayInt *other)
6111 throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : DataArrayInt pointer in input is NULL !");
6113 other->checkAllocated();
6114 int nbOfTuples=getNumberOfTuples();
6115 if(nbOfTuples!=other->getNumberOfTuples())
6116 throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : mismatch of number of tuples !");
6117 int nbOfComp1=getNumberOfComponents();
6118 int nbOfComp2=other->getNumberOfComponents();
6119 int *newArr=(int *)malloc(nbOfTuples*(nbOfComp1+nbOfComp2)*sizeof(int));
6121 const int *inp1=getConstPointer();
6122 const int *inp2=other->getConstPointer();
6123 for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
6125 w=std::copy(inp1,inp1+nbOfComp1,w);
6126 w=std::copy(inp2,inp2+nbOfComp2,w);
6128 useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
6129 std::vector<int> compIds(nbOfComp2);
6130 for(int i=0;i<nbOfComp2;i++)
6131 compIds[i]=nbOfComp1+i;
6132 copyPartOfStringInfoFrom2(compIds,*other);
6136 * Copy all components in a specified order from another DataArrayInt.
6137 * The specified components become the first ones in \a this array.
6138 * Both numerical and textual data is copied. The number of tuples in \a this and
6139 * the other array can be different.
6140 * \param [in] a - the array to copy data from.
6141 * \param [in] compoIds - sequence of zero based indices of components, data of which is
6143 * \throw If \a a is NULL.
6144 * \throw If \a compoIds.size() != \a a->getNumberOfComponents().
6145 * \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents().
6147 * \if ENABLE_EXAMPLES
6148 * \ref py_mcdataarrayint_setselectedcomponents "Here is a Python example".
6151 void DataArrayInt::setSelectedComponents(const DataArrayInt *a, const std::vector<int>& compoIds)
6154 throw INTERP_KERNEL::Exception("DataArrayInt::setSelectedComponents : input DataArrayInt is NULL !");
6156 a->checkAllocated();
6157 copyPartOfStringInfoFrom2(compoIds,*a);
6158 std::size_t partOfCompoSz=compoIds.size();
6159 int nbOfCompo=getNumberOfComponents();
6160 int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
6161 const int *ac=a->getConstPointer();
6162 int *nc=getPointer();
6163 for(int i=0;i<nbOfTuples;i++)
6164 for(std::size_t j=0;j<partOfCompoSz;j++,ac++)
6165 nc[nbOfCompo*i+compoIds[j]]=*ac;
6169 * Assign pointer to one array to a pointer to another appay. Reference counter of
6170 * \a arrayToSet is incremented / decremented.
6171 * \param [in] newArray - the pointer to array to assign to \a arrayToSet.
6172 * \param [in,out] arrayToSet - the pointer to array to assign to.
6174 void DataArrayInt::SetArrayIn(DataArrayInt *newArray, DataArrayInt* &arrayToSet)
6176 if(newArray!=arrayToSet)
6179 arrayToSet->decrRef();
6180 arrayToSet=newArray;
6182 arrayToSet->incrRef();
6186 DataArrayIntIterator *DataArrayInt::iterator()
6188 return new DataArrayIntIterator(this);
6192 * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to a
6193 * given one. The ids are sorted in the ascending order.
6194 * \param [in] val - the value to find within \a this.
6195 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6196 * array using decrRef() as it is no more needed.
6197 * \throw If \a this is not allocated.
6198 * \throw If \a this->getNumberOfComponents() != 1.
6199 * \sa DataArrayInt::findIdsEqualTuple
6201 DataArrayInt *DataArrayInt::findIdsEqual(int val) const
6204 if(getNumberOfComponents()!=1)
6205 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqual : the array must have only one component, you can call 'rearrange' method before !");
6206 const int *cptr(getConstPointer());
6207 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6208 int nbOfTuples=getNumberOfTuples();
6209 for(int i=0;i<nbOfTuples;i++,cptr++)
6211 ret->pushBackSilent(i);
6216 * Creates a new DataArrayInt containing IDs (indices) of tuples holding value \b not
6217 * equal to a given one.
6218 * \param [in] val - the value to ignore within \a this.
6219 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6220 * array using decrRef() as it is no more needed.
6221 * \throw If \a this is not allocated.
6222 * \throw If \a this->getNumberOfComponents() != 1.
6224 DataArrayInt *DataArrayInt::findIdsNotEqual(int val) const
6227 if(getNumberOfComponents()!=1)
6228 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotEqual : the array must have only one component, you can call 'rearrange' method before !");
6229 const int *cptr(getConstPointer());
6230 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6231 int nbOfTuples=getNumberOfTuples();
6232 for(int i=0;i<nbOfTuples;i++,cptr++)
6234 ret->pushBackSilent(i);
6239 * Creates a new DataArrayInt containing IDs (indices) of tuples holding tuple equal to those defined by [ \a tupleBg , \a tupleEnd )
6240 * This method is an extension of DataArrayInt::findIdsEqual method.
6242 * \param [in] tupleBg - the begin (included) of the input tuple to find within \a this.
6243 * \param [in] tupleEnd - the end (excluded) of the input tuple to find within \a this.
6244 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6245 * array using decrRef() as it is no more needed.
6246 * \throw If \a this is not allocated.
6247 * \throw If \a this->getNumberOfComponents() != std::distance(tupleBg,tupleEnd).
6248 * \throw If \a this->getNumberOfComponents() is equal to 0.
6249 * \sa DataArrayInt::findIdsEqual
6251 DataArrayInt *DataArrayInt::findIdsEqualTuple(const int *tupleBg, const int *tupleEnd) const
6253 std::size_t nbOfCompoExp(std::distance(tupleBg,tupleEnd));
6255 if(getNumberOfComponents()!=(int)nbOfCompoExp)
6257 std::ostringstream oss; oss << "DataArrayInt::findIdsEqualTuple : mismatch of number of components. Input tuple has " << nbOfCompoExp << " whereas this array has " << getNumberOfComponents() << " components !";
6258 throw INTERP_KERNEL::Exception(oss.str().c_str());
6261 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqualTuple : number of components should be > 0 !");
6262 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6263 const int *bg(begin()),*end2(end()),*work(begin());
6266 work=std::search(work,end2,tupleBg,tupleEnd);
6269 std::size_t pos(std::distance(bg,work));
6270 if(pos%nbOfCompoExp==0)
6271 ret->pushBackSilent(pos/nbOfCompoExp);
6279 * Assigns \a newValue to all elements holding \a oldValue within \a this
6280 * one-dimensional array.
6281 * \param [in] oldValue - the value to replace.
6282 * \param [in] newValue - the value to assign.
6283 * \return int - number of replacements performed.
6284 * \throw If \a this is not allocated.
6285 * \throw If \a this->getNumberOfComponents() != 1.
6287 int DataArrayInt::changeValue(int oldValue, int newValue)
6290 if(getNumberOfComponents()!=1)
6291 throw INTERP_KERNEL::Exception("DataArrayInt::changeValue : the array must have only one component, you can call 'rearrange' method before !");
6292 if(oldValue==newValue)
6294 int *start(getPointer()),*end2(start+getNbOfElems());
6296 for(int *val=start;val!=end2;val++)
6310 * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to
6311 * one of given values.
6312 * \param [in] valsBg - an array of values to find within \a this array.
6313 * \param [in] valsEnd - specifies the end of the array \a valsBg, so that
6314 * the last value of \a valsBg is \a valsEnd[ -1 ].
6315 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6316 * array using decrRef() as it is no more needed.
6317 * \throw If \a this->getNumberOfComponents() != 1.
6319 DataArrayInt *DataArrayInt::findIdsEqualList(const int *valsBg, const int *valsEnd) const
6321 if(getNumberOfComponents()!=1)
6322 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsEqualList : the array must have only one component, you can call 'rearrange' method before !");
6323 std::set<int> vals2(valsBg,valsEnd);
6324 const int *cptr(getConstPointer());
6325 std::vector<int> res;
6326 int nbOfTuples(getNumberOfTuples());
6327 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6328 for(int i=0;i<nbOfTuples;i++,cptr++)
6329 if(vals2.find(*cptr)!=vals2.end())
6330 ret->pushBackSilent(i);
6335 * Creates a new DataArrayInt containing IDs (indices) of tuples holding values \b not
6336 * equal to any of given values.
6337 * \param [in] valsBg - an array of values to ignore within \a this array.
6338 * \param [in] valsEnd - specifies the end of the array \a valsBg, so that
6339 * the last value of \a valsBg is \a valsEnd[ -1 ].
6340 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
6341 * array using decrRef() as it is no more needed.
6342 * \throw If \a this->getNumberOfComponents() != 1.
6344 DataArrayInt *DataArrayInt::findIdsNotEqualList(const int *valsBg, const int *valsEnd) const
6346 if(getNumberOfComponents()!=1)
6347 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotEqualList : the array must have only one component, you can call 'rearrange' method before !");
6348 std::set<int> vals2(valsBg,valsEnd);
6349 const int *cptr=getConstPointer();
6350 std::vector<int> res;
6351 int nbOfTuples=getNumberOfTuples();
6352 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
6353 for(int i=0;i<nbOfTuples;i++,cptr++)
6354 if(vals2.find(*cptr)==vals2.end())
6355 ret->pushBackSilent(i);
6360 * This method is an extension of DataArrayInt::findIdFirstEqual method because this method works for DataArrayInt with
6361 * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
6362 * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
6363 * If any the tuple id is returned. If not -1 is returned.
6365 * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
6366 * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
6368 * \return tuple id where \b tupl is. -1 if no such tuple exists in \b this.
6369 * \sa DataArrayInt::findIdSequence, DataArrayInt::presenceOfTuple.
6371 int DataArrayInt::findIdFirstEqualTuple(const std::vector<int>& tupl) const
6374 int nbOfCompo=getNumberOfComponents();
6376 throw INTERP_KERNEL::Exception("DataArrayInt::findIdFirstEqualTuple : 0 components in 'this' !");
6377 if(nbOfCompo!=(int)tupl.size())
6379 std::ostringstream oss; oss << "DataArrayInt::findIdFirstEqualTuple : 'this' contains " << nbOfCompo << " components and searching for a tuple of length " << tupl.size() << " !";
6380 throw INTERP_KERNEL::Exception(oss.str().c_str());
6382 const int *cptr=getConstPointer();
6383 std::size_t nbOfVals=getNbOfElems();
6384 for(const int *work=cptr;work!=cptr+nbOfVals;)
6386 work=std::search(work,cptr+nbOfVals,tupl.begin(),tupl.end());
6387 if(work!=cptr+nbOfVals)
6389 if(std::distance(cptr,work)%nbOfCompo!=0)
6392 return std::distance(cptr,work)/nbOfCompo;
6399 * This method searches the sequence specified in input parameter \b vals in \b this.
6400 * This works only for DataArrayInt having number of components equal to one (if not an INTERP_KERNEL::Exception will be thrown).
6401 * This method differs from DataArrayInt::findIdFirstEqualTuple in that the position is internal raw data is not considered here contrary to DataArrayInt::findIdFirstEqualTuple.
6402 * \sa DataArrayInt::findIdFirstEqualTuple
6404 int DataArrayInt::findIdSequence(const std::vector<int>& vals) const
6407 int nbOfCompo=getNumberOfComponents();
6409 throw INTERP_KERNEL::Exception("DataArrayInt::findIdSequence : works only for DataArrayInt instance with one component !");
6410 const int *cptr=getConstPointer();
6411 std::size_t nbOfVals=getNbOfElems();
6412 const int *loc=std::search(cptr,cptr+nbOfVals,vals.begin(),vals.end());
6413 if(loc!=cptr+nbOfVals)
6414 return std::distance(cptr,loc);
6419 * This method expects to be called when number of components of this is equal to one.
6420 * This method returns the tuple id, if it exists, of the first tuple equal to \b value.
6421 * If not any tuple contains \b value -1 is returned.
6422 * \sa DataArrayInt::presenceOfValue
6424 int DataArrayInt::findIdFirstEqual(int value) const
6427 if(getNumberOfComponents()!=1)
6428 throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
6429 const int *cptr=getConstPointer();
6430 int nbOfTuples=getNumberOfTuples();
6431 const int *ret=std::find(cptr,cptr+nbOfTuples,value);
6432 if(ret!=cptr+nbOfTuples)
6433 return std::distance(cptr,ret);
6438 * This method expects to be called when number of components of this is equal to one.
6439 * This method returns the tuple id, if it exists, of the first tuple so that the value is contained in \b vals.
6440 * If not any tuple contains one of the values contained in 'vals' -1 is returned.
6441 * \sa DataArrayInt::presenceOfValue
6443 int DataArrayInt::findIdFirstEqual(const std::vector<int>& vals) const
6446 if(getNumberOfComponents()!=1)
6447 throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
6448 std::set<int> vals2(vals.begin(),vals.end());
6449 const int *cptr=getConstPointer();
6450 int nbOfTuples=getNumberOfTuples();
6451 for(const int *w=cptr;w!=cptr+nbOfTuples;w++)
6452 if(vals2.find(*w)!=vals2.end())
6453 return std::distance(cptr,w);
6458 * This method returns the number of values in \a this that are equals to input parameter \a value.
6459 * This method only works for single component array.
6461 * \return a value in [ 0, \c this->getNumberOfTuples() )
6463 * \throw If \a this is not allocated
6466 int DataArrayInt::count(int value) const
6470 if(getNumberOfComponents()!=1)
6471 throw INTERP_KERNEL::Exception("DataArrayInt::count : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
6472 const int *vals=begin();
6473 int nbOfTuples=getNumberOfTuples();
6474 for(int i=0;i<nbOfTuples;i++,vals++)
6481 * This method is an extension of DataArrayInt::presenceOfValue method because this method works for DataArrayInt with
6482 * any number of components excepted 0 (an INTERP_KERNEL::Exception is thrown in this case).
6483 * This method searches in \b this is there is a tuple that matched the input parameter \b tupl.
6484 * This method throws an INTERP_KERNEL::Exception if the number of components in \b this mismatches with the size of
6485 * the input vector. An INTERP_KERNEL::Exception is thrown too if \b this is not allocated.
6486 * \sa DataArrayInt::findIdFirstEqualTuple
6488 bool DataArrayInt::presenceOfTuple(const std::vector<int>& tupl) const
6490 return findIdFirstEqualTuple(tupl)!=-1;
6495 * Returns \a true if a given value is present within \a this one-dimensional array.
6496 * \param [in] value - the value to find within \a this array.
6497 * \return bool - \a true in case if \a value is present within \a this array.
6498 * \throw If \a this is not allocated.
6499 * \throw If \a this->getNumberOfComponents() != 1.
6500 * \sa findIdFirstEqual()
6502 bool DataArrayInt::presenceOfValue(int value) const
6504 return findIdFirstEqual(value)!=-1;
6508 * This method expects to be called when number of components of this is equal to one.
6509 * This method returns true if it exists a tuple so that the value is contained in \b vals.
6510 * If not any tuple contains one of the values contained in 'vals' false is returned.
6511 * \sa DataArrayInt::findIdFirstEqual
6513 bool DataArrayInt::presenceOfValue(const std::vector<int>& vals) const
6515 return findIdFirstEqual(vals)!=-1;
6519 * Accumulates values of each component of \a this array.
6520 * \param [out] res - an array of length \a this->getNumberOfComponents(), allocated
6521 * by the caller, that is filled by this method with sum value for each
6523 * \throw If \a this is not allocated.
6525 void DataArrayInt::accumulate(int *res) const
6528 const int *ptr=getConstPointer();
6529 int nbTuple=getNumberOfTuples();
6530 int nbComps=getNumberOfComponents();
6531 std::fill(res,res+nbComps,0);
6532 for(int i=0;i<nbTuple;i++)
6533 std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<int>());
6536 int DataArrayInt::accumulate(int compId) const
6539 const int *ptr=getConstPointer();
6540 int nbTuple=getNumberOfTuples();
6541 int nbComps=getNumberOfComponents();
6542 if(compId<0 || compId>=nbComps)
6543 throw INTERP_KERNEL::Exception("DataArrayInt::accumulate : Invalid compId specified : No such nb of components !");
6545 for(int i=0;i<nbTuple;i++)
6546 ret+=ptr[i*nbComps+compId];
6551 * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ).
6552 * The returned array will have same number of components than \a this and number of tuples equal to
6553 * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one.
6555 * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples).
6557 * \param [in] bgOfIndex - begin (included) of the input index array.
6558 * \param [in] endOfIndex - end (excluded) of the input index array.
6559 * \return DataArrayInt * - the new instance having the same number of components than \a this.
6561 * \throw If bgOfIndex or end is NULL.
6562 * \throw If input index array is not ascendingly sorted.
6563 * \throw If there is an id in [ \a bgOfIndex, \a endOfIndex ) not in [0, \c this->getNumberOfTuples).
6564 * \throw If std::distance(bgOfIndex,endOfIndex)==0.
6566 DataArrayInt *DataArrayInt::accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const
6568 if(!bgOfIndex || !endOfIndex)
6569 throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : input pointer NULL !");
6571 int nbCompo=getNumberOfComponents();
6572 int nbOfTuples=getNumberOfTuples();
6573 int sz=(int)std::distance(bgOfIndex,endOfIndex);
6575 throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : invalid size of input index array !");
6577 MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(sz,nbCompo);
6578 const int *w=bgOfIndex;
6579 if(*w<0 || *w>=nbOfTuples)
6580 throw INTERP_KERNEL::Exception("DataArrayInt::accumulatePerChunck : The first element of the input index not in [0,nbOfTuples) !");
6581 const int *srcPt=begin()+(*w)*nbCompo;
6582 int *tmp=ret->getPointer();
6583 for(int i=0;i<sz;i++,tmp+=nbCompo,w++)
6585 std::fill(tmp,tmp+nbCompo,0);
6588 for(int j=w[0];j<w[1];j++,srcPt+=nbCompo)
6590 if(j>=0 && j<nbOfTuples)
6591 std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<int>());
6594 std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array points to id " << j << " should be in [0," << nbOfTuples << ") !";
6595 throw INTERP_KERNEL::Exception(oss.str().c_str());
6601 std::ostringstream oss; oss << "DataArrayInt::accumulatePerChunck : At rank #" << i << " the input index array is not in ascendingly sorted.";
6602 throw INTERP_KERNEL::Exception(oss.str().c_str());
6605 ret->copyStringInfoFrom(*this);
6610 * Returns a new DataArrayInt by concatenating two given arrays, so that (1) the number
6611 * of tuples in the result array is <em> a1->getNumberOfTuples() + a2->getNumberOfTuples() -
6612 * offsetA2</em> and (2)
6613 * the number of component in the result array is same as that of each of given arrays.
6614 * First \a offsetA2 tuples of \a a2 are skipped and thus are missing from the result array.
6615 * Info on components is copied from the first of the given arrays. Number of components
6616 * in the given arrays must be the same.
6617 * \param [in] a1 - an array to include in the result array.
6618 * \param [in] a2 - another array to include in the result array.
6619 * \param [in] offsetA2 - number of tuples of \a a2 to skip.
6620 * \return DataArrayInt * - the new instance of DataArrayInt.
6621 * The caller is to delete this result array using decrRef() as it is no more
6623 * \throw If either \a a1 or \a a2 is NULL.
6624 * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents().
6626 DataArrayInt *DataArrayInt::Aggregate(const DataArrayInt *a1, const DataArrayInt *a2, int offsetA2)
6629 throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input DataArrayInt instance is NULL !");
6630 int nbOfComp=a1->getNumberOfComponents();
6631 if(nbOfComp!=a2->getNumberOfComponents())
6632 throw INTERP_KERNEL::Exception("Nb of components mismatch for array Aggregation !");
6633 int nbOfTuple1=a1->getNumberOfTuples();
6634 int nbOfTuple2=a2->getNumberOfTuples();
6635 DataArrayInt *ret=DataArrayInt::New();
6636 ret->alloc(nbOfTuple1+nbOfTuple2-offsetA2,nbOfComp);
6637 int *pt=std::copy(a1->getConstPointer(),a1->getConstPointer()+nbOfTuple1*nbOfComp,ret->getPointer());
6638 std::copy(a2->getConstPointer()+offsetA2*nbOfComp,a2->getConstPointer()+nbOfTuple2*nbOfComp,pt);
6639 ret->copyStringInfoFrom(*a1);
6644 * Returns a new DataArrayInt by concatenating all given arrays, so that (1) the number
6645 * of tuples in the result array is a sum of the number of tuples of given arrays and (2)
6646 * the number of component in the result array is same as that of each of given arrays.
6647 * Info on components is copied from the first of the given arrays. Number of components
6648 * in the given arrays must be the same.
6649 * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it
6650 * not the object itself.
6651 * \param [in] arr - a sequence of arrays to include in the result array.
6652 * \return DataArrayInt * - the new instance of DataArrayInt.
6653 * The caller is to delete this result array using decrRef() as it is no more
6655 * \throw If all arrays within \a arr are NULL.
6656 * \throw If getNumberOfComponents() of arrays within \a arr.
6658 DataArrayInt *DataArrayInt::Aggregate(const std::vector<const DataArrayInt *>& arr)
6660 std::vector<const DataArrayInt *> a;
6661 for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
6665 throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input list must be NON EMPTY !");
6666 std::vector<const DataArrayInt *>::const_iterator it=a.begin();
6667 int nbOfComp=(*it)->getNumberOfComponents();
6668 int nbt=(*it++)->getNumberOfTuples();
6669 for(int i=1;it!=a.end();it++,i++)
6671 if((*it)->getNumberOfComponents()!=nbOfComp)
6672 throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : Nb of components mismatch for array aggregation !");
6673 nbt+=(*it)->getNumberOfTuples();
6675 MCAuto<DataArrayInt> ret=DataArrayInt::New();
6676 ret->alloc(nbt,nbOfComp);
6677 int *pt=ret->getPointer();
6678 for(it=a.begin();it!=a.end();it++)
6679 pt=std::copy((*it)->getConstPointer(),(*it)->getConstPointer()+(*it)->getNbOfElems(),pt);
6680 ret->copyStringInfoFrom(*(a[0]));
6685 * This method takes as input a list of DataArrayInt instances \a arrs that represent each a packed index arrays.
6686 * A packed index array is an allocated array with one component, and at least one tuple. The first element
6687 * of each array in \a arrs must be 0. Each array in \a arrs is expected to be increasingly monotonic.
6688 * 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.
6690 * \return DataArrayInt * - a new object to be managed by the caller.
6692 DataArrayInt *DataArrayInt::AggregateIndexes(const std::vector<const DataArrayInt *>& arrs)
6695 for(std::vector<const DataArrayInt *>::const_iterator it4=arrs.begin();it4!=arrs.end();it4++)
6699 (*it4)->checkAllocated();
6700 if((*it4)->getNumberOfComponents()!=1)
6702 std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of compo != 1 at pos " << std::distance(arrs.begin(),it4) << " !";
6703 throw INTERP_KERNEL::Exception(oss.str().c_str());
6705 int nbTupl=(*it4)->getNumberOfTuples();
6708 std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of tuples < 1 at pos " << std::distance(arrs.begin(),it4) << " !";
6709 throw INTERP_KERNEL::Exception(oss.str().c_str());
6711 if((*it4)->front()!=0)
6713 std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with front value != 0 at pos " << std::distance(arrs.begin(),it4) << " !";
6714 throw INTERP_KERNEL::Exception(oss.str().c_str());
6720 std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a null instance at pos " << std::distance(arrs.begin(),it4) << " !";
6721 throw INTERP_KERNEL::Exception(oss.str().c_str());
6725 throw INTERP_KERNEL::Exception("DataArrayInt::AggregateIndexes : input list must be NON EMPTY !");
6726 MCAuto<DataArrayInt> ret=DataArrayInt::New();
6727 ret->alloc(retSz,1);
6728 int *pt=ret->getPointer(); *pt++=0;
6729 for(std::vector<const DataArrayInt *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
6730 pt=std::transform((*it)->begin()+1,(*it)->end(),pt,std::bind2nd(std::plus<int>(),pt[-1]));
6731 ret->copyStringInfoFrom(*(arrs[0]));
6736 * Returns in a single walk in \a this the min value and the max value in \a this.
6737 * \a this is expected to be single component array.
6739 * \param [out] minValue - the min value in \a this.
6740 * \param [out] maxValue - the max value in \a this.
6742 * \sa getMinValueInArray, getMinValue, getMaxValueInArray, getMaxValue
6744 void DataArrayInt::getMinMaxValues(int& minValue, int& maxValue) const
6747 if(getNumberOfComponents()!=1)
6748 throw INTERP_KERNEL::Exception("DataArrayInt::getMinMaxValues : must be applied on DataArrayInt with only one component !");
6749 int nbTuples(getNumberOfTuples());
6750 const int *pt(begin());
6751 minValue=std::numeric_limits<int>::max(); maxValue=-std::numeric_limits<int>::max();
6752 for(int i=0;i<nbTuples;i++,pt++)
6762 * Converts every value of \a this array to its absolute value.
6763 * \b WARNING this method is non const. If a new DataArrayInt instance should be built containing the result of abs DataArrayInt::computeAbs
6764 * should be called instead.
6766 * \throw If \a this is not allocated.
6767 * \sa DataArrayInt::computeAbs
6769 void DataArrayInt::abs()
6772 int *ptr(getPointer());
6773 std::size_t nbOfElems(getNbOfElems());
6774 std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<int,int>(std::abs));
6779 * This method builds a new instance of \a this object containing the result of std::abs applied of all elements in \a this.
6780 * This method is a const method (that do not change any values in \a this) contrary to DataArrayInt::abs method.
6782 * \return DataArrayInt * - the new instance of DataArrayInt containing the
6783 * same number of tuples and component as \a this array.
6784 * The caller is to delete this result array using decrRef() as it is no more
6786 * \throw If \a this is not allocated.
6787 * \sa DataArrayInt::abs
6789 DataArrayInt *DataArrayInt::computeAbs() const
6792 DataArrayInt *newArr(DataArrayInt::New());
6793 int nbOfTuples(getNumberOfTuples());
6794 int nbOfComp(getNumberOfComponents());
6795 newArr->alloc(nbOfTuples,nbOfComp);
6796 std::transform(begin(),end(),newArr->getPointer(),std::ptr_fun<int,int>(std::abs));
6797 newArr->copyStringInfoFrom(*this);
6802 * Apply a liner function to a given component of \a this array, so that
6803 * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
6804 * \param [in] a - the first coefficient of the function.
6805 * \param [in] b - the second coefficient of the function.
6806 * \param [in] compoId - the index of component to modify.
6807 * \throw If \a this is not allocated.
6809 void DataArrayInt::applyLin(int a, int b, int compoId)
6812 int *ptr=getPointer()+compoId;
6813 int nbOfComp=getNumberOfComponents();
6814 int nbOfTuple=getNumberOfTuples();
6815 for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
6821 * Apply a liner function to all elements of \a this array, so that
6822 * an element _x_ becomes \f$ a * x + b \f$.
6823 * \param [in] a - the first coefficient of the function.
6824 * \param [in] b - the second coefficient of the function.
6825 * \throw If \a this is not allocated.
6827 void DataArrayInt::applyLin(int a, int b)
6830 int *ptr=getPointer();
6831 std::size_t nbOfElems=getNbOfElems();
6832 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
6838 * Returns a full copy of \a this array except that sign of all elements is reversed.
6839 * \return DataArrayInt * - the new instance of DataArrayInt containing the
6840 * same number of tuples and component as \a this array.
6841 * The caller is to delete this result array using decrRef() as it is no more
6843 * \throw If \a this is not allocated.
6845 DataArrayInt *DataArrayInt::negate() const
6848 DataArrayInt *newArr=DataArrayInt::New();
6849 int nbOfTuples=getNumberOfTuples();
6850 int nbOfComp=getNumberOfComponents();
6851 newArr->alloc(nbOfTuples,nbOfComp);
6852 const int *cptr=getConstPointer();
6853 std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<int>());
6854 newArr->copyStringInfoFrom(*this);
6859 * Modify all elements of \a this array, so that
6860 * an element _x_ becomes \f$ numerator / x \f$.
6861 * \warning If an exception is thrown because of presence of 0 element in \a this
6862 * array, all elements processed before detection of the zero element remain
6864 * \param [in] numerator - the numerator used to modify array elements.
6865 * \throw If \a this is not allocated.
6866 * \throw If there is an element equal to 0 in \a this array.
6868 void DataArrayInt::applyInv(int numerator)
6871 int *ptr=getPointer();
6872 std::size_t nbOfElems=getNbOfElems();
6873 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
6877 *ptr=numerator/(*ptr);
6881 std::ostringstream oss; oss << "DataArrayInt::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
6883 throw INTERP_KERNEL::Exception(oss.str().c_str());
6890 * Modify all elements of \a this array, so that
6891 * an element _x_ becomes \f$ x / val \f$.
6892 * \param [in] val - the denominator used to modify array elements.
6893 * \throw If \a this is not allocated.
6894 * \throw If \a val == 0.
6896 void DataArrayInt::applyDivideBy(int val)
6899 throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to divide by 0 !");
6901 int *ptr=getPointer();
6902 std::size_t nbOfElems=getNbOfElems();
6903 std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::divides<int>(),val));
6908 * Modify all elements of \a this array, so that
6909 * an element _x_ becomes <em> x % val </em>.
6910 * \param [in] val - the divisor used to modify array elements.
6911 * \throw If \a this is not allocated.
6912 * \throw If \a val <= 0.
6914 void DataArrayInt::applyModulus(int val)
6917 throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to operate modulus on value <= 0 !");
6919 int *ptr=getPointer();
6920 std::size_t nbOfElems=getNbOfElems();
6921 std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::modulus<int>(),val));
6927 GreatEqual(int v):_v(v) { }
6928 bool operator()(int v) const { return v>=_v; }
6934 GreaterThan(int v):_v(v) { }
6935 bool operator()(int v) const { return v>_v; }
6941 LowerEqual(int v):_v(v) { }
6942 bool operator()(int v) const { return v<=_v; }
6948 LowerThan(int v):_v(v) { }
6949 bool operator()(int v) const { return v<_v; }
6955 InRange(int a, int b):_a(a),_b(b) { }
6956 bool operator()(int v) const { return v>=_a && v<_b; }
6961 * This method works only on data array with one component.
6962 * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
6963 * this[*id] in [\b vmin,\b vmax)
6965 * \param [in] vmin begin of range. This value is included in range (included).
6966 * \param [in] vmax end of range. This value is \b not included in range (excluded).
6967 * \return a newly allocated data array that the caller should deal with.
6969 * \sa DataArrayInt::findIdsNotInRange , DataArrayInt::findIdsStricltyNegative
6971 DataArrayInt *DataArrayInt::findIdsInRange(int vmin, int vmax) const
6973 InRange ir(vmin,vmax);
6974 MCAuto<DataArrayInt> ret(findIdsAdv(ir));
6980 NotInRange(int a, int b):_a(a),_b(b) { }
6981 bool operator()(int v) const { return v<_a || v>=_b; }
6986 * This method works only on data array with one component.
6987 * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
6988 * this[*id] \b not in [\b vmin,\b vmax)
6990 * \param [in] vmin begin of range. This value is \b not included in range (excluded).
6991 * \param [in] vmax end of range. This value is included in range (included).
6992 * \return a newly allocated data array that the caller should deal with.
6994 * \sa DataArrayInt::findIdsInRange , DataArrayInt::findIdsStricltyNegative
6996 DataArrayInt *DataArrayInt::findIdsNotInRange(int vmin, int vmax) const
6998 NotInRange nir(vmin,vmax);
6999 MCAuto<DataArrayInt> ret(findIdsAdv(nir));
7004 * 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.
7006 * \return a newly allocated data array that the caller should deal with.
7007 * \sa DataArrayInt::findIdsInRange
7009 DataArrayInt *DataArrayInt::findIdsStricltyNegative() const
7012 MCAuto<DataArrayInt> ret(findIdsAdv(lt));
7016 MCAuto<DataArrayInt> DataArrayInt::findIdsGreaterOrEqualTo(int val) const
7019 return findIdsAdv(ge);
7022 MCAuto<DataArrayInt> DataArrayInt::findIdsGreaterThan(int val) const
7024 GreaterThan gt(val);
7025 return findIdsAdv(gt);
7028 MCAuto<DataArrayInt> DataArrayInt::findIdsLowerOrEqualTo(int val) const
7031 return findIdsAdv(le);
7034 MCAuto<DataArrayInt> DataArrayInt::findIdsLowerThan(int val) const
7037 return findIdsAdv(lt);
7041 * This method works only on data array with one component.
7042 * 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.
7044 * \param [in] vmin begin of range. This value is included in range (included).
7045 * \param [in] vmax end of range. This value is \b not included in range (excluded).
7046 * \return if all ids in \a this are so that (*this)[i]==i for all i in [ 0, \c this->getNumberOfTuples() ). */
7047 bool DataArrayInt::checkAllIdsInRange(int vmin, int vmax) const
7050 if(getNumberOfComponents()!=1)
7051 throw INTERP_KERNEL::Exception("DataArrayInt::checkAllIdsInRange : this must have exactly one component !");
7052 int nbOfTuples=getNumberOfTuples();
7054 const int *cptr=getConstPointer();
7055 for(int i=0;i<nbOfTuples;i++,cptr++)
7057 if(*cptr>=vmin && *cptr<vmax)
7058 { ret=ret && *cptr==i; }
7061 std::ostringstream oss; oss << "DataArrayInt::checkAllIdsInRange : tuple #" << i << " has value " << *cptr << " should be in [" << vmin << "," << vmax << ") !";
7062 throw INTERP_KERNEL::Exception(oss.str().c_str());
7069 * Modify all elements of \a this array, so that
7070 * an element _x_ becomes <em> val % x </em>.
7071 * \warning If an exception is thrown because of presence of an element <= 0 in \a this
7072 * array, all elements processed before detection of the zero element remain
7074 * \param [in] val - the divident used to modify array elements.
7075 * \throw If \a this is not allocated.
7076 * \throw If there is an element equal to or less than 0 in \a this array.
7078 void DataArrayInt::applyRModulus(int val)
7081 int *ptr=getPointer();
7082 std::size_t nbOfElems=getNbOfElems();
7083 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
7091 std::ostringstream oss; oss << "DataArrayInt::applyRModulus : presence of value <=0 in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
7093 throw INTERP_KERNEL::Exception(oss.str().c_str());
7100 * Modify all elements of \a this array, so that
7101 * an element _x_ becomes <em> val ^ x </em>.
7102 * \param [in] val - the value used to apply pow on all array elements.
7103 * \throw If \a this is not allocated.
7104 * \throw If \a val < 0.
7106 void DataArrayInt::applyPow(int val)
7110 throw INTERP_KERNEL::Exception("DataArrayInt::applyPow : input pow in < 0 !");
7111 int *ptr=getPointer();
7112 std::size_t nbOfElems=getNbOfElems();
7115 std::fill(ptr,ptr+nbOfElems,1);
7118 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
7121 for(int j=0;j<val;j++)
7129 * Modify all elements of \a this array, so that
7130 * an element _x_ becomes \f$ val ^ x \f$.
7131 * \param [in] val - the value used to apply pow on all array elements.
7132 * \throw If \a this is not allocated.
7133 * \throw If there is an element < 0 in \a this array.
7134 * \warning If an exception is thrown because of presence of 0 element in \a this
7135 * array, all elements processed before detection of the zero element remain
7138 void DataArrayInt::applyRPow(int val)
7141 int *ptr=getPointer();
7142 std::size_t nbOfElems=getNbOfElems();
7143 for(std::size_t i=0;i<nbOfElems;i++,ptr++)
7148 for(int j=0;j<*ptr;j++)
7154 std::ostringstream oss; oss << "DataArrayInt::applyRPow : presence of negative value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
7156 throw INTERP_KERNEL::Exception(oss.str().c_str());
7163 * Returns a new DataArrayInt by aggregating two given arrays, so that (1) the number
7164 * of components in the result array is a sum of the number of components of given arrays
7165 * and (2) the number of tuples in the result array is same as that of each of given
7166 * arrays. In other words the i-th tuple of result array includes all components of
7167 * i-th tuples of all given arrays.
7168 * Number of tuples in the given arrays must be the same.
7169 * \param [in] a1 - an array to include in the result array.
7170 * \param [in] a2 - another array to include in the result array.
7171 * \return DataArrayInt * - the new instance of DataArrayInt.
7172 * The caller is to delete this result array using decrRef() as it is no more
7174 * \throw If both \a a1 and \a a2 are NULL.
7175 * \throw If any given array is not allocated.
7176 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
7178 DataArrayInt *DataArrayInt::Meld(const DataArrayInt *a1, const DataArrayInt *a2)
7180 std::vector<const DataArrayInt *> arr(2);
7181 arr[0]=a1; arr[1]=a2;
7186 * Returns a new DataArrayInt by aggregating all given arrays, so that (1) the number
7187 * of components in the result array is a sum of the number of components of given arrays
7188 * and (2) the number of tuples in the result array is same as that of each of given
7189 * arrays. In other words the i-th tuple of result array includes all components of
7190 * i-th tuples of all given arrays.
7191 * Number of tuples in the given arrays must be the same.
7192 * \param [in] arr - a sequence of arrays to include in the result array.
7193 * \return DataArrayInt * - the new instance of DataArrayInt.
7194 * The caller is to delete this result array using decrRef() as it is no more
7196 * \throw If all arrays within \a arr are NULL.
7197 * \throw If any given array is not allocated.
7198 * \throw If getNumberOfTuples() of arrays within \a arr is different.
7200 DataArrayInt *DataArrayInt::Meld(const std::vector<const DataArrayInt *>& arr)
7202 std::vector<const DataArrayInt *> a;
7203 for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
7207 throw INTERP_KERNEL::Exception("DataArrayInt::Meld : array must be NON empty !");
7208 std::vector<const DataArrayInt *>::const_iterator it;
7209 for(it=a.begin();it!=a.end();it++)
7210 (*it)->checkAllocated();
7212 int nbOfTuples=(*it)->getNumberOfTuples();
7213 std::vector<int> nbc(a.size());
7214 std::vector<const int *> pts(a.size());
7215 nbc[0]=(*it)->getNumberOfComponents();
7216 pts[0]=(*it++)->getConstPointer();
7217 for(int i=1;it!=a.end();it++,i++)
7219 if(nbOfTuples!=(*it)->getNumberOfTuples())
7220 throw INTERP_KERNEL::Exception("DataArrayInt::meld : mismatch of number of tuples !");
7221 nbc[i]=(*it)->getNumberOfComponents();
7222 pts[i]=(*it)->getConstPointer();
7224 int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
7225 DataArrayInt *ret=DataArrayInt::New();
7226 ret->alloc(nbOfTuples,totalNbOfComp);
7227 int *retPtr=ret->getPointer();
7228 for(int i=0;i<nbOfTuples;i++)
7229 for(int j=0;j<(int)a.size();j++)
7231 retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
7235 for(int i=0;i<(int)a.size();i++)
7236 for(int j=0;j<nbc[i];j++,k++)
7237 ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j));
7242 * Returns a new DataArrayInt which is a minimal partition of elements of \a groups.
7243 * The i-th item of the result array is an ID of a set of elements belonging to a
7244 * unique set of groups, which the i-th element is a part of. This set of elements
7245 * belonging to a unique set of groups is called \a family, so the result array contains
7246 * IDs of families each element belongs to.
7248 * \b Example: if we have two groups of elements: \a group1 [0,4] and \a group2 [ 0,1,2 ],
7249 * then there are 3 families:
7250 * - \a family1 (with ID 1) contains element [0] belonging to ( \a group1 + \a group2 ),
7251 * - \a family2 (with ID 2) contains elements [4] belonging to ( \a group1 ),
7252 * - \a family3 (with ID 3) contains element [1,2] belonging to ( \a group2 ), <br>
7253 * and the result array contains IDs of families [ 1,3,3,0,2 ]. <br> Note a family ID 0 which
7254 * stands for the element #3 which is in none of groups.
7256 * \param [in] groups - sequence of groups of element IDs.
7257 * \param [in] newNb - total number of elements; it must be more than max ID of element
7259 * \param [out] fidsOfGroups - IDs of families the elements of each group belong to.
7260 * \return DataArrayInt * - a new instance of DataArrayInt containing IDs of families
7261 * each element with ID from range [0, \a newNb ) belongs to. The caller is to
7262 * delete this array using decrRef() as it is no more needed.
7263 * \throw If any element ID in \a groups violates condition ( 0 <= ID < \a newNb ).
7265 DataArrayInt *DataArrayInt::MakePartition(const std::vector<const DataArrayInt *>& groups, int newNb, std::vector< std::vector<int> >& fidsOfGroups)
7267 std::vector<const DataArrayInt *> groups2;
7268 for(std::vector<const DataArrayInt *>::const_iterator it4=groups.begin();it4!=groups.end();it4++)
7270 groups2.push_back(*it4);
7271 MCAuto<DataArrayInt> ret=DataArrayInt::New();
7272 ret->alloc(newNb,1);
7273 int *retPtr=ret->getPointer();
7274 std::fill(retPtr,retPtr+newNb,0);
7276 for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++)
7278 const int *ptr=(*iter)->getConstPointer();
7279 std::size_t nbOfElem=(*iter)->getNbOfElems();
7281 for(int j=0;j<sfid;j++)
7284 for(std::size_t i=0;i<nbOfElem;i++)
7286 if(ptr[i]>=0 && ptr[i]<newNb)
7288 if(retPtr[ptr[i]]==j)
7296 std::ostringstream oss; oss << "DataArrayInt::MakePartition : In group \"" << (*iter)->getName() << "\" in tuple #" << i << " value = " << ptr[i] << " ! Should be in [0," << newNb;
7298 throw INTERP_KERNEL::Exception(oss.str().c_str());
7305 fidsOfGroups.clear();
7306 fidsOfGroups.resize(groups2.size());
7308 for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++,grId++)
7311 const int *ptr=(*iter)->getConstPointer();
7312 std::size_t nbOfElem=(*iter)->getNbOfElems();
7313 for(const int *p=ptr;p!=ptr+nbOfElem;p++)
7314 tmp.insert(retPtr[*p]);
7315 fidsOfGroups[grId].insert(fidsOfGroups[grId].end(),tmp.begin(),tmp.end());
7321 * Returns a new DataArrayInt which contains all elements of given one-dimensional
7322 * arrays. The result array does not contain any duplicates and its values
7323 * are sorted in ascending order.
7324 * \param [in] arr - sequence of DataArrayInt's to unite.
7325 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7326 * array using decrRef() as it is no more needed.
7327 * \throw If any \a arr[i] is not allocated.
7328 * \throw If \a arr[i]->getNumberOfComponents() != 1.
7330 DataArrayInt *DataArrayInt::BuildUnion(const std::vector<const DataArrayInt *>& arr)
7332 std::vector<const DataArrayInt *> a;
7333 for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
7336 for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
7338 (*it)->checkAllocated();
7339 if((*it)->getNumberOfComponents()!=1)
7340 throw INTERP_KERNEL::Exception("DataArrayInt::BuildUnion : only single component allowed !");
7344 for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
7346 const int *pt=(*it)->getConstPointer();
7347 int nbOfTuples=(*it)->getNumberOfTuples();
7348 r.insert(pt,pt+nbOfTuples);
7350 DataArrayInt *ret=DataArrayInt::New();
7351 ret->alloc((int)r.size(),1);
7352 std::copy(r.begin(),r.end(),ret->getPointer());
7357 * Returns a new DataArrayInt which contains elements present in each of given one-dimensional
7358 * arrays. The result array does not contain any duplicates and its values
7359 * are sorted in ascending order.
7360 * \param [in] arr - sequence of DataArrayInt's to intersect.
7361 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7362 * array using decrRef() as it is no more needed.
7363 * \throw If any \a arr[i] is not allocated.
7364 * \throw If \a arr[i]->getNumberOfComponents() != 1.
7366 DataArrayInt *DataArrayInt::BuildIntersection(const std::vector<const DataArrayInt *>& arr)
7368 std::vector<const DataArrayInt *> a;
7369 for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
7372 for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
7374 (*it)->checkAllocated();
7375 if((*it)->getNumberOfComponents()!=1)
7376 throw INTERP_KERNEL::Exception("DataArrayInt::BuildIntersection : only single component allowed !");
7380 for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
7382 const int *pt=(*it)->getConstPointer();
7383 int nbOfTuples=(*it)->getNumberOfTuples();
7384 std::set<int> s1(pt,pt+nbOfTuples);
7388 std::set_intersection(r.begin(),r.end(),s1.begin(),s1.end(),inserter(r2,r2.end()));
7394 DataArrayInt *ret(DataArrayInt::New());
7395 ret->alloc((int)r.size(),1);
7396 std::copy(r.begin(),r.end(),ret->getPointer());
7401 namespace MEDCouplingImpl
7406 OpSwitchedOn(int *pt):_pt(pt),_cnt(0) { }
7407 void operator()(const bool& b) { if(b) *_pt++=_cnt; _cnt++; }
7416 OpSwitchedOff(int *pt):_pt(pt),_cnt(0) { }
7417 void operator()(const bool& b) { if(!b) *_pt++=_cnt; _cnt++; }
7426 * This method returns the list of ids in ascending mode so that v[id]==true.
7428 DataArrayInt *DataArrayInt::BuildListOfSwitchedOn(const std::vector<bool>& v)
7430 int sz((int)std::count(v.begin(),v.end(),true));
7431 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
7432 std::for_each(v.begin(),v.end(),MEDCouplingImpl::OpSwitchedOn(ret->getPointer()));
7437 * This method returns the list of ids in ascending mode so that v[id]==false.
7439 DataArrayInt *DataArrayInt::BuildListOfSwitchedOff(const std::vector<bool>& v)
7441 int sz((int)std::count(v.begin(),v.end(),false));
7442 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
7443 std::for_each(v.begin(),v.end(),MEDCouplingImpl::OpSwitchedOff(ret->getPointer()));
7448 * This method allows to put a vector of vector of integer into a more compact data stucture (skyline).
7449 * This method is not available into python because no available optimized data structure available to map std::vector< std::vector<int> >.
7451 * \param [in] v the input data structure to be translate into skyline format.
7452 * \param [out] data the first element of the skyline format. The user is expected to deal with newly allocated array.
7453 * \param [out] dataIndex the second element of the skyline format.
7455 void DataArrayInt::PutIntoToSkylineFrmt(const std::vector< std::vector<int> >& v, DataArrayInt *& data, DataArrayInt *& dataIndex)
7457 int sz((int)v.size());
7458 MCAuto<DataArrayInt> ret0(DataArrayInt::New()),ret1(DataArrayInt::New());
7459 ret1->alloc(sz+1,1);
7460 int *pt(ret1->getPointer()); *pt=0;
7461 for(int i=0;i<sz;i++,pt++)
7462 pt[1]=pt[0]+(int)v[i].size();
7463 ret0->alloc(ret1->back(),1);
7464 pt=ret0->getPointer();
7465 for(int i=0;i<sz;i++)
7466 pt=std::copy(v[i].begin(),v[i].end(),pt);
7467 data=ret0.retn(); dataIndex=ret1.retn();
7471 * Returns a new DataArrayInt which contains a complement of elements of \a this
7472 * one-dimensional array. I.e. the result array contains all elements from the range [0,
7473 * \a nbOfElement) not present in \a this array.
7474 * \param [in] nbOfElement - maximal size of the result array.
7475 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7476 * array using decrRef() as it is no more needed.
7477 * \throw If \a this is not allocated.
7478 * \throw If \a this->getNumberOfComponents() != 1.
7479 * \throw If any element \a x of \a this array violates condition ( 0 <= \a x < \a
7482 DataArrayInt *DataArrayInt::buildComplement(int nbOfElement) const
7485 if(getNumberOfComponents()!=1)
7486 throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : only single component allowed !");
7487 std::vector<bool> tmp(nbOfElement);
7488 const int *pt=getConstPointer();
7489 int nbOfTuples=getNumberOfTuples();
7490 for(const int *w=pt;w!=pt+nbOfTuples;w++)
7491 if(*w>=0 && *w<nbOfElement)
7494 throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : an element is not in valid range : [0,nbOfElement) !");
7495 int nbOfRetVal=(int)std::count(tmp.begin(),tmp.end(),false);
7496 DataArrayInt *ret=DataArrayInt::New();
7497 ret->alloc(nbOfRetVal,1);
7499 int *retPtr=ret->getPointer();
7500 for(int i=0;i<nbOfElement;i++)
7507 * Returns a new DataArrayInt containing elements of \a this one-dimensional missing
7508 * from an \a other one-dimensional array.
7509 * \param [in] other - a DataArrayInt containing elements not to include in the result array.
7510 * \return DataArrayInt * - a new instance of DataArrayInt with one component. The
7511 * caller is to delete this array using decrRef() as it is no more needed.
7512 * \throw If \a other is NULL.
7513 * \throw If \a other is not allocated.
7514 * \throw If \a other->getNumberOfComponents() != 1.
7515 * \throw If \a this is not allocated.
7516 * \throw If \a this->getNumberOfComponents() != 1.
7517 * \sa DataArrayInt::buildSubstractionOptimized()
7519 DataArrayInt *DataArrayInt::buildSubstraction(const DataArrayInt *other) const
7522 throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : DataArrayInt pointer in input is NULL !");
7524 other->checkAllocated();
7525 if(getNumberOfComponents()!=1)
7526 throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed !");
7527 if(other->getNumberOfComponents()!=1)
7528 throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed for other type !");
7529 const int *pt=getConstPointer();
7530 int nbOfTuples=getNumberOfTuples();
7531 std::set<int> s1(pt,pt+nbOfTuples);
7532 pt=other->getConstPointer();
7533 nbOfTuples=other->getNumberOfTuples();
7534 std::set<int> s2(pt,pt+nbOfTuples);
7536 std::set_difference(s1.begin(),s1.end(),s2.begin(),s2.end(),std::back_insert_iterator< std::vector<int> >(r));
7537 DataArrayInt *ret=DataArrayInt::New();
7538 ret->alloc((int)r.size(),1);
7539 std::copy(r.begin(),r.end(),ret->getPointer());
7544 * \a this is expected to have one component and to be sorted ascendingly (as for \a other).
7545 * \a other is expected to be a part of \a this. If not DataArrayInt::buildSubstraction should be called instead.
7547 * \param [in] other an array with one component and expected to be sorted ascendingly.
7548 * \ret list of ids in \a this but not in \a other.
7549 * \sa DataArrayInt::buildSubstraction
7551 DataArrayInt *DataArrayInt::buildSubstractionOptimized(const DataArrayInt *other) const
7553 static const char *MSG="DataArrayInt::buildSubstractionOptimized : only single component allowed !";
7554 if(!other) throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstractionOptimized : NULL input array !");
7555 checkAllocated(); other->checkAllocated();
7556 if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
7557 if(other->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
7558 const int *pt1Bg(begin()),*pt1End(end()),*pt2Bg(other->begin()),*pt2End(other->end());
7559 const int *work1(pt1Bg),*work2(pt2Bg);
7560 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
7561 for(;work1!=pt1End;work1++)
7563 if(work2!=pt2End && *work1==*work2)
7566 ret->pushBackSilent(*work1);
7573 * Returns a new DataArrayInt which contains all elements of \a this and a given
7574 * one-dimensional arrays. The result array does not contain any duplicates
7575 * and its values are sorted in ascending order.
7576 * \param [in] other - an array to unite with \a this one.
7577 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7578 * array using decrRef() as it is no more needed.
7579 * \throw If \a this or \a other is not allocated.
7580 * \throw If \a this->getNumberOfComponents() != 1.
7581 * \throw If \a other->getNumberOfComponents() != 1.
7583 DataArrayInt *DataArrayInt::buildUnion(const DataArrayInt *other) const
7585 std::vector<const DataArrayInt *>arrs(2);
7586 arrs[0]=this; arrs[1]=other;
7587 return BuildUnion(arrs);
7592 * Returns a new DataArrayInt which contains elements present in both \a this and a given
7593 * one-dimensional arrays. The result array does not contain any duplicates
7594 * and its values are sorted in ascending order.
7595 * \param [in] other - an array to intersect with \a this one.
7596 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
7597 * array using decrRef() as it is no more needed.
7598 * \throw If \a this or \a other is not allocated.
7599 * \throw If \a this->getNumberOfComponents() != 1.
7600 * \throw If \a other->getNumberOfComponents() != 1.
7602 DataArrayInt *DataArrayInt::buildIntersection(const DataArrayInt *other) const
7604 std::vector<const DataArrayInt *>arrs(2);
7605 arrs[0]=this; arrs[1]=other;
7606 return BuildIntersection(arrs);
7610 * This method can be applied on allocated with one component DataArrayInt instance.
7611 * This method is typically relevant for sorted arrays. All consecutive duplicated items in \a this will appear only once in returned DataArrayInt instance.
7612 * 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]
7614 * \return a newly allocated array that contain the result of the unique operation applied on \a this.
7615 * \throw if \a this is not allocated or if \a this has not exactly one component.
7616 * \sa DataArrayInt::buildUniqueNotSorted
7618 DataArrayInt *DataArrayInt::buildUnique() const
7621 if(getNumberOfComponents()!=1)
7622 throw INTERP_KERNEL::Exception("DataArrayInt::buildUnique : only single component allowed !");
7623 int nbOfTuples=getNumberOfTuples();
7624 MCAuto<DataArrayInt> tmp=deepCopy();
7625 int *data=tmp->getPointer();
7626 int *last=std::unique(data,data+nbOfTuples);
7627 MCAuto<DataArrayInt> ret=DataArrayInt::New();
7628 ret->alloc(std::distance(data,last),1);
7629 std::copy(data,last,ret->getPointer());
7634 * This method can be applied on allocated with one component DataArrayInt instance.
7635 * This method keep elements only once by keeping the same order in \a this that is not expected to be sorted.
7637 * \return a newly allocated array that contain the result of the unique operation applied on \a this.
7639 * \throw if \a this is not allocated or if \a this has not exactly one component.
7641 * \sa DataArrayInt::buildUnique
7643 DataArrayInt *DataArrayInt::buildUniqueNotSorted() const
7646 if(getNumberOfComponents()!=1)
7647 throw INTERP_KERNEL::Exception("DataArrayInt::buildUniqueNotSorted : only single component allowed !");
7649 getMinMaxValues(minVal,maxVal);
7650 std::vector<bool> b(maxVal-minVal+1,false);
7651 const int *ptBg(begin()),*endBg(end());
7652 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
7653 for(const int *pt=ptBg;pt!=endBg;pt++)
7657 ret->pushBackSilent(*pt);
7661 ret->copyStringInfoFrom(*this);
7666 * Returns a new DataArrayInt which contains size of every of groups described by \a this
7667 * "index" array. Such "index" array is returned for example by
7668 * \ref MEDCoupling::MEDCouplingUMesh::buildDescendingConnectivity
7669 * "MEDCouplingUMesh::buildDescendingConnectivity" and
7670 * \ref MEDCoupling::MEDCouplingUMesh::getNodalConnectivityIndex
7671 * "MEDCouplingUMesh::getNodalConnectivityIndex" etc.
7672 * This method preforms the reverse operation of DataArrayInt::computeOffsetsFull.
7673 * \return DataArrayInt * - a new instance of DataArrayInt, whose number of tuples
7674 * equals to \a this->getNumberOfComponents() - 1, and number of components is 1.
7675 * The caller is to delete this array using decrRef() as it is no more needed.
7676 * \throw If \a this is not allocated.
7677 * \throw If \a this->getNumberOfComponents() != 1.
7678 * \throw If \a this->getNumberOfTuples() < 2.
7681 * - this contains [1,3,6,7,7,9,15]
7682 * - result array contains [2,3,1,0,2,6],
7683 * where 2 = 3 - 1, 3 = 6 - 3, 1 = 7 - 6 etc.
7685 * \sa DataArrayInt::computeOffsetsFull
7687 DataArrayInt *DataArrayInt::deltaShiftIndex() const
7690 if(getNumberOfComponents()!=1)
7691 throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : only single component allowed !");
7692 int nbOfTuples=getNumberOfTuples();
7694 throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : 1 tuple at least must be present in 'this' !");
7695 const int *ptr=getConstPointer();
7696 DataArrayInt *ret=DataArrayInt::New();
7697 ret->alloc(nbOfTuples-1,1);
7698 int *out=ret->getPointer();
7699 std::transform(ptr+1,ptr+nbOfTuples,ptr,out,std::minus<int>());
7704 * Modifies \a this one-dimensional array so that value of each element \a x
7705 * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
7706 * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number of tuples
7707 * and components remains the same.<br>
7708 * This method is useful for allToAllV in MPI with contiguous policy. This method
7709 * differs from computeOffsetsFull() in that the number of tuples is \b not changed by
7711 * \throw If \a this is not allocated.
7712 * \throw If \a this->getNumberOfComponents() != 1.
7715 * - Before \a this contains [3,5,1,2,0,8]
7716 * - After \a this contains [0,3,8,9,11,11]<br>
7717 * Note that the last element 19 = 11 + 8 is missing because size of \a this
7718 * array is retained and thus there is no space to store the last element.
7720 void DataArrayInt::computeOffsets()
7723 if(getNumberOfComponents()!=1)
7724 throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets : only single component allowed !");
7725 int nbOfTuples=getNumberOfTuples();
7728 int *work=getPointer();
7731 for(int i=1;i<nbOfTuples;i++)
7734 work[i]=work[i-1]+tmp;
7742 * Modifies \a this one-dimensional array so that value of each element \a x
7743 * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
7744 * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number
7745 * components remains the same and number of tuples is inceamented by one.<br>
7746 * This method is useful for allToAllV in MPI with contiguous policy. This method
7747 * differs from computeOffsets() in that the number of tuples is changed by this one.
7748 * This method preforms the reverse operation of DataArrayInt::deltaShiftIndex.
7749 * \throw If \a this is not allocated.
7750 * \throw If \a this->getNumberOfComponents() != 1.
7753 * - Before \a this contains [3,5,1,2,0,8]
7754 * - After \a this contains [0,3,8,9,11,11,19]<br>
7755 * \sa DataArrayInt::deltaShiftIndex
7757 void DataArrayInt::computeOffsetsFull()
7760 if(getNumberOfComponents()!=1)
7761 throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsetsFull : only single component allowed !");
7762 int nbOfTuples=getNumberOfTuples();
7763 int *ret=(int *)malloc((nbOfTuples+1)*sizeof(int));
7764 const int *work=getConstPointer();
7766 for(int i=0;i<nbOfTuples;i++)
7767 ret[i+1]=work[i]+ret[i];
7768 useArray(ret,true,C_DEALLOC,nbOfTuples+1,1);
7773 * Returns two new DataArrayInt instances whose contents is computed from that of \a this and \a listOfIds arrays as follows.
7774 * \a this is expected to be an offset format ( as returned by DataArrayInt::computeOffsetsFull ) that is to say with one component
7775 * and ** sorted strictly increasingly **. \a listOfIds is expected to be sorted ascendingly (not strictly needed for \a listOfIds).
7776 * This methods searches in \a this, considered as a set of contiguous \c this->getNumberOfComponents() ranges, all ids in \a listOfIds
7777 * filling completely one of the ranges in \a this.
7779 * \param [in] listOfIds a list of ids that has to be sorted ascendingly.
7780 * \param [out] rangeIdsFetched the range ids fetched
7781 * \param [out] idsInInputListThatFetch contains the list of ids in \a listOfIds that are \b fully included in a range in \a this. So
7782 * \a idsInInputListThatFetch is a part of input \a listOfIds.
7784 * \sa DataArrayInt::computeOffsetsFull
7787 * - \a this : [0,3,7,9,15,18]
7788 * - \a listOfIds contains [0,1,2,3,7,8,15,16,17]
7789 * - \a rangeIdsFetched result array: [0,2,4]
7790 * - \a idsInInputListThatFetch result array: [0,1,2,7,8,15,16,17]
7791 * In this example id 3 in input \a listOfIds is alone so it do not appear in output \a idsInInputListThatFetch.
7794 void DataArrayInt::findIdsRangesInListOfIds(const DataArrayInt *listOfIds, DataArrayInt *& rangeIdsFetched, DataArrayInt *& idsInInputListThatFetch) const
7797 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : input list of ids is null !");
7798 listOfIds->checkAllocated(); checkAllocated();
7799 if(listOfIds->getNumberOfComponents()!=1)
7800 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : input list of ids must have exactly one component !");
7801 if(getNumberOfComponents()!=1)
7802 throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : this must have exactly one component !");
7803 MCAuto<DataArrayInt> ret0=DataArrayInt::New(); ret0->alloc(0,1);
7804 MCAuto<DataArrayInt> ret1=DataArrayInt::New(); ret1->alloc(0,1);
7805 const int *tupEnd(listOfIds->end()),*offBg(begin()),*offEnd(end()-1);
7806 const int *tupPtr(listOfIds->begin()),*offPtr(offBg);
7807 while(tupPtr!=tupEnd && offPtr!=offEnd)
7809 if(*tupPtr==*offPtr)
7812 while(i<offPtr[1] && *tupPtr==i && tupPtr!=tupEnd) { i++; tupPtr++; }
7815 ret0->pushBackSilent((int)std::distance(offBg,offPtr));
7816 ret1->pushBackValsSilent(tupPtr-(offPtr[1]-offPtr[0]),tupPtr);
7821 { if(*tupPtr<*offPtr) tupPtr++; else offPtr++; }
7823 rangeIdsFetched=ret0.retn();
7824 idsInInputListThatFetch=ret1.retn();
7828 * Returns a new DataArrayInt whose contents is computed from that of \a this and \a
7829 * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
7830 * "index" array of a "iota" array, thus, whose each element gives an index of a group
7831 * beginning within the "iota" array. And \a this is a one-dimensional array
7832 * considered as a selector of groups described by \a offsets to include into the result array.
7833 * \throw If \a offsets is NULL.
7834 * \throw If \a offsets is not allocated.
7835 * \throw If \a offsets->getNumberOfComponents() != 1.
7836 * \throw If \a offsets is not monotonically increasing.
7837 * \throw If \a this is not allocated.
7838 * \throw If \a this->getNumberOfComponents() != 1.
7839 * \throw If any element of \a this is not a valid index for \a offsets array.
7842 * - \a this: [0,2,3]
7843 * - \a offsets: [0,3,6,10,14,20]
7844 * - result array: [0,1,2,6,7,8,9,10,11,12,13] == <br>
7845 * \c range(0,3) + \c range(6,10) + \c range(10,14) ==<br>
7846 * \c range( \a offsets[ \a this[0] ], offsets[ \a this[0]+1 ]) +
7847 * \c range( \a offsets[ \a this[1] ], offsets[ \a this[1]+1 ]) +
7848 * \c range( \a offsets[ \a this[2] ], offsets[ \a this[2]+1 ])
7850 DataArrayInt *DataArrayInt::buildExplicitArrByRanges(const DataArrayInt *offsets) const
7853 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : DataArrayInt pointer in input is NULL !");
7855 if(getNumberOfComponents()!=1)
7856 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : only single component allowed !");
7857 offsets->checkAllocated();
7858 if(offsets->getNumberOfComponents()!=1)
7859 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : input array should have only single component !");
7860 int othNbTuples=offsets->getNumberOfTuples()-1;
7861 int nbOfTuples=getNumberOfTuples();
7862 int retNbOftuples=0;
7863 const int *work=getConstPointer();
7864 const int *offPtr=offsets->getConstPointer();
7865 for(int i=0;i<nbOfTuples;i++)
7868 if(val>=0 && val<othNbTuples)
7870 int delta=offPtr[val+1]-offPtr[val];
7872 retNbOftuples+=delta;
7875 std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << val << " of offset array has a delta < 0 !";
7876 throw INTERP_KERNEL::Exception(oss.str().c_str());
7881 std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << i << " in this contains " << val;
7882 oss << " whereas offsets array is of size " << othNbTuples+1 << " !";
7883 throw INTERP_KERNEL::Exception(oss.str().c_str());
7886 MCAuto<DataArrayInt> ret=DataArrayInt::New();
7887 ret->alloc(retNbOftuples,1);
7888 int *retPtr=ret->getPointer();
7889 for(int i=0;i<nbOfTuples;i++)
7892 int start=offPtr[val];
7893 int off=offPtr[val+1]-start;
7894 for(int j=0;j<off;j++,retPtr++)
7901 * Returns a new DataArrayInt whose contents is computed using \a this that must be a
7902 * scaled array (monotonically increasing).
7903 from that of \a this and \a
7904 * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
7905 * "index" array of a "iota" array, thus, whose each element gives an index of a group
7906 * beginning within the "iota" array. And \a this is a one-dimensional array
7907 * considered as a selector of groups described by \a offsets to include into the result array.
7908 * \throw If \a is NULL.
7909 * \throw If \a this is not allocated.
7910 * \throw If \a this->getNumberOfComponents() != 1.
7911 * \throw If \a this->getNumberOfTuples() == 0.
7912 * \throw If \a this is not monotonically increasing.
7913 * \throw If any element of ids in ( \a bg \a stop \a step ) points outside the scale in \a this.
7916 * - \a bg , \a stop and \a step : (0,5,2)
7917 * - \a this: [0,3,6,10,14,20]
7918 * - result array: [0,0,0, 2,2,2,2, 4,4,4,4,4,4] == <br>
7920 DataArrayInt *DataArrayInt::buildExplicitArrOfSliceOnScaledArr(int bg, int stop, int step) const
7923 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : not allocated array !");
7924 if(getNumberOfComponents()!=1)
7925 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of components is expected to be equal to one !");
7926 int nbOfTuples(getNumberOfTuples());
7928 throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of tuples must be != 0 !");
7929 const int *ids(begin());
7930 int nbOfEltsInSlc(GetNumberOfItemGivenBESRelative(bg,stop,step,"DataArrayInt::buildExplicitArrOfSliceOnScaledArr")),sz(0),pos(bg);
7931 for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
7933 if(pos>=0 && pos<nbOfTuples-1)
7935 int delta(ids[pos+1]-ids[pos]);
7939 std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " and at this pos this is not monotonically increasing !";
7940 throw INTERP_KERNEL::Exception(oss.str().c_str());
7945 std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " should be in [0," << nbOfTuples-1 << ") !";
7946 throw INTERP_KERNEL::Exception(oss.str().c_str());
7949 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
7950 int *retPtr(ret->getPointer());
7952 for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
7954 int delta(ids[pos+1]-ids[pos]);
7955 for(int j=0;j<delta;j++,retPtr++)
7962 * 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.
7963 * 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
7964 * in tuple **i** of returned DataArrayInt.
7965 * If ranges overlapped (in theory it should not) this method do not detect it and always returns the first range.
7967 * 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)]
7968 * The return DataArrayInt will contain : **[0,4,1,2,2,3]**
7970 * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
7971 * for lower value included and 2nd component is the upper value of corresponding range **excluded**.
7972 * \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
7973 * is thrown if no ranges in \a ranges contains value in \a this.
7975 * \sa DataArrayInt::findIdInRangeForEachTuple
7977 DataArrayInt *DataArrayInt::findRangeIdForEachTuple(const DataArrayInt *ranges) const
7980 throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : null input pointer !");
7981 if(ranges->getNumberOfComponents()!=2)
7982 throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : input DataArrayInt instance should have 2 components !");
7984 if(getNumberOfComponents()!=1)
7985 throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : this should have only one component !");
7986 int nbTuples=getNumberOfTuples();
7987 MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
7988 int nbOfRanges=ranges->getNumberOfTuples();
7989 const int *rangesPtr=ranges->getConstPointer();
7990 int *retPtr=ret->getPointer();
7991 const int *inPtr=getConstPointer();
7992 for(int i=0;i<nbTuples;i++,retPtr++)
7996 for(int j=0;j<nbOfRanges && !found;j++)
7997 if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
7998 { *retPtr=j; found=true; }
8003 std::ostringstream oss; oss << "DataArrayInt::findRangeIdForEachTuple : tuple #" << i << " not found by any ranges !";
8004 throw INTERP_KERNEL::Exception(oss.str().c_str());
8011 * 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.
8012 * 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
8013 * in tuple **i** of returned DataArrayInt.
8014 * If ranges overlapped (in theory it should not) this method do not detect it and always returns the sub position of the first range.
8016 * 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)]
8017 * The return DataArrayInt will contain : **[1,2,4,0,2,2]**
8018 * This method is often called in pair with DataArrayInt::findRangeIdForEachTuple method.
8020 * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
8021 * for lower value included and 2nd component is the upper value of corresponding range **excluded**.
8022 * \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
8023 * is thrown if no ranges in \a ranges contains value in \a this.
8024 * \sa DataArrayInt::findRangeIdForEachTuple
8026 DataArrayInt *DataArrayInt::findIdInRangeForEachTuple(const DataArrayInt *ranges) const
8029 throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : null input pointer !");
8030 if(ranges->getNumberOfComponents()!=2)
8031 throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : input DataArrayInt instance should have 2 components !");
8033 if(getNumberOfComponents()!=1)
8034 throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : this should have only one component !");
8035 int nbTuples=getNumberOfTuples();
8036 MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
8037 int nbOfRanges=ranges->getNumberOfTuples();
8038 const int *rangesPtr=ranges->getConstPointer();
8039 int *retPtr=ret->getPointer();
8040 const int *inPtr=getConstPointer();
8041 for(int i=0;i<nbTuples;i++,retPtr++)
8045 for(int j=0;j<nbOfRanges && !found;j++)
8046 if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
8047 { *retPtr=val-rangesPtr[2*j]; found=true; }
8052 std::ostringstream oss; oss << "DataArrayInt::findIdInRangeForEachTuple : tuple #" << i << " not found by any ranges !";
8053 throw INTERP_KERNEL::Exception(oss.str().c_str());
8060 * \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).
8061 * 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).
8062 * 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 !
8063 * If this method has correctly worked, \a this will be able to be considered as a linked list.
8064 * This method does nothing if number of tuples is lower of equal to 1.
8066 * This method is useful for users having an unstructured mesh having only SEG2 to rearrange internaly the connectibity without any coordinates consideration.
8068 * \sa MEDCouplingUMesh::orderConsecutiveCells1D, DataArrayInt::fromLinkedListOfPairToList
8070 void DataArrayInt::sortEachPairToMakeALinkedList()
8073 if(getNumberOfComponents()!=2)
8074 throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : Only works on DataArrayInt instance with nb of components equal to 2 !");
8075 int nbOfTuples(getNumberOfTuples());
8078 int *conn(getPointer());
8079 for(int i=1;i<nbOfTuples;i++,conn+=2)
8083 if(conn[2]==conn[3])
8085 std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " presence of a pair filled with same ids !";
8086 throw INTERP_KERNEL::Exception(oss.str().c_str());
8088 if(conn[2]!=conn[1] && conn[3]==conn[1] && conn[2]!=conn[0])
8089 std::swap(conn[2],conn[3]);
8090 //not(conn[2]==conn[1] && conn[3]!=conn[1] && conn[3]!=conn[0])
8091 if(conn[2]!=conn[1] || conn[3]==conn[1] || conn[3]==conn[0])
8093 std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " something is invalid !";
8094 throw INTERP_KERNEL::Exception(oss.str().c_str());
8099 if(conn[0]==conn[1] || conn[2]==conn[3])
8100 throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : In the 2 first tuples presence of a pair filled with same ids !");
8103 s.insert(conn,conn+4);
8105 throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : This can't be considered as a linked list regarding 2 first tuples !");
8106 if(std::count(conn,conn+4,conn[0])==2)
8111 if(conn[2]==conn[0])
8115 std::copy(tmp,tmp+4,conn);
8118 {//here we are sure to have (std::count(conn,conn+4,conn[1])==2)
8119 if(conn[1]==conn[3])
8120 std::swap(conn[2],conn[3]);
8127 * \a this is expected to be a correctly linked list of pairs.
8129 * \sa DataArrayInt::sortEachPairToMakeALinkedList
8131 MCAuto<DataArrayInt> DataArrayInt::fromLinkedListOfPairToList() const
8134 checkNbOfComps(2,"DataArrayInt::fromLinkedListOfPairToList : this is expected to have 2 components");
8135 int nbTuples(getNumberOfTuples());
8137 throw INTERP_KERNEL::Exception("DataArrayInt::fromLinkedListOfPairToList : no tuples in this ! Not a linked list !");
8138 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbTuples+1,1);
8139 const int *thisPtr(begin());
8140 int *retPtr(ret->getPointer());
8141 retPtr[0]=thisPtr[0];
8142 for(int i=0;i<nbTuples;i++)
8144 retPtr[i+1]=thisPtr[2*i+1];
8146 if(thisPtr[2*i+1]!=thisPtr[2*(i+1)+0])
8148 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 ?";
8149 throw INTERP_KERNEL::Exception(oss.str());
8157 * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayInt instance.
8158 * \a nbTimes should be at least equal to 1.
8159 * \return a newly allocated DataArrayInt having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
8160 * \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.
8162 DataArrayInt *DataArrayInt::duplicateEachTupleNTimes(int nbTimes) const
8165 if(getNumberOfComponents()!=1)
8166 throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : this should have only one component !");
8168 throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : nb times should be >= 1 !");
8169 int nbTuples=getNumberOfTuples();
8170 const int *inPtr=getConstPointer();
8171 MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTimes*nbTuples,1);
8172 int *retPtr=ret->getPointer();
8173 for(int i=0;i<nbTuples;i++,inPtr++)
8176 for(int j=0;j<nbTimes;j++,retPtr++)
8179 ret->copyStringInfoFrom(*this);
8184 * This method returns all different values found in \a this. This method throws if \a this has not been allocated.
8185 * But the number of components can be different from one.
8186 * \return a newly allocated array (that should be dealt by the caller) containing different values in \a this.
8188 DataArrayInt *DataArrayInt::getDifferentValues() const
8192 ret.insert(begin(),end());
8193 MCAuto<DataArrayInt> ret2=DataArrayInt::New(); ret2->alloc((int)ret.size(),1);
8194 std::copy(ret.begin(),ret.end(),ret2->getPointer());
8199 * This method is a refinement of DataArrayInt::getDifferentValues because it returns not only different values in \a this but also, for each of
8200 * them it tells which tuple id have this id.
8201 * This method works only on arrays with one component (if it is not the case call DataArrayInt::rearrange(1) ).
8202 * This method returns two arrays having same size.
8203 * 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.
8204 * 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]]
8206 std::vector<DataArrayInt *> DataArrayInt::partitionByDifferentValues(std::vector<int>& differentIds) const
8209 if(getNumberOfComponents()!=1)
8210 throw INTERP_KERNEL::Exception("DataArrayInt::partitionByDifferentValues : this should have only one component !");
8212 std::map<int,int> m,m2,m3;
8213 for(const int *w=begin();w!=end();w++)
8215 differentIds.resize(m.size());
8216 std::vector<DataArrayInt *> ret(m.size());
8217 std::vector<int *> retPtr(m.size());
8218 for(std::map<int,int>::const_iterator it=m.begin();it!=m.end();it++,id++)
8221 ret[id]=DataArrayInt::New();
8222 ret[id]->alloc((*it).second,1);
8223 retPtr[id]=ret[id]->getPointer();
8224 differentIds[id]=(*it).first;
8227 for(const int *w=begin();w!=end();w++,id++)
8229 retPtr[m2[*w]][m3[*w]++]=id;
8235 * This method split ids in [0, \c this->getNumberOfTuples() ) using \a this array as a field of weight (>=0 each).
8236 * The aim of this method is to return a set of \a nbOfSlices chunk of contiguous ids as balanced as possible.
8238 * \param [in] nbOfSlices - number of slices expected.
8239 * \return - a vector having a size equal to \a nbOfSlices giving the start (included) and the stop (excluded) of each chunks.
8241 * \sa DataArray::GetSlice
8242 * \throw If \a this is not allocated or not with exactly one component.
8243 * \throw If an element in \a this if < 0.
8245 std::vector< std::pair<int,int> > DataArrayInt::splitInBalancedSlices(int nbOfSlices) const
8247 if(!isAllocated() || getNumberOfComponents()!=1)
8248 throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : this array should have number of components equal to one and must be allocated !");
8250 throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : number of slices must be >= 1 !");
8251 int sum(accumulate(0)),nbOfTuples(getNumberOfTuples());
8252 int sumPerSlc(sum/nbOfSlices),pos(0);
8253 const int *w(begin());
8254 std::vector< std::pair<int,int> > ret(nbOfSlices);
8255 for(int i=0;i<nbOfSlices;i++)
8257 std::pair<int,int> p(pos,-1);
8259 while(locSum<sumPerSlc && pos<nbOfTuples) { pos++; locSum+=*w++; }
8263 p.second=nbOfTuples;
8270 * Returns a new DataArrayInt that is a sum of two given arrays. There are 3
8272 * 1. The arrays have same number of tuples and components. Then each value of
8273 * the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
8274 * i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
8275 * 2. The arrays have same number of tuples and one array, say _a2_, has one
8277 * _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
8278 * 3. The arrays have same number of components and one array, say _a2_, has one
8280 * _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
8282 * Info on components is copied either from the first array (in the first case) or from
8283 * the array with maximal number of elements (getNbOfElems()).
8284 * \param [in] a1 - an array to sum up.
8285 * \param [in] a2 - another array to sum up.
8286 * \return DataArrayInt * - the new instance of DataArrayInt.
8287 * The caller is to delete this result array using decrRef() as it is no more
8289 * \throw If either \a a1 or \a a2 is NULL.
8290 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
8291 * \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
8292 * none of them has number of tuples or components equal to 1.
8294 DataArrayInt *DataArrayInt::Add(const DataArrayInt *a1, const DataArrayInt *a2)
8297 throw INTERP_KERNEL::Exception("DataArrayInt::Add : input DataArrayInt instance is NULL !");
8298 int nbOfTuple=a1->getNumberOfTuples();
8299 int nbOfTuple2=a2->getNumberOfTuples();
8300 int nbOfComp=a1->getNumberOfComponents();
8301 int nbOfComp2=a2->getNumberOfComponents();
8302 MCAuto<DataArrayInt> ret=0;
8303 if(nbOfTuple==nbOfTuple2)
8305 if(nbOfComp==nbOfComp2)
8307 ret=DataArrayInt::New();
8308 ret->alloc(nbOfTuple,nbOfComp);
8309 std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<int>());
8310 ret->copyStringInfoFrom(*a1);
8314 int nbOfCompMin,nbOfCompMax;
8315 const DataArrayInt *aMin, *aMax;
8316 if(nbOfComp>nbOfComp2)
8318 nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
8323 nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
8328 ret=DataArrayInt::New();
8329 ret->alloc(nbOfTuple,nbOfCompMax);
8330 const int *aMinPtr=aMin->getConstPointer();
8331 const int *aMaxPtr=aMax->getConstPointer();
8332 int *res=ret->getPointer();
8333 for(int i=0;i<nbOfTuple;i++)
8334 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<int>(),aMinPtr[i]));
8335 ret->copyStringInfoFrom(*aMax);
8338 throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
8341 else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
8343 if(nbOfComp==nbOfComp2)
8345 int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
8346 const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
8347 const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
8348 const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
8349 ret=DataArrayInt::New();
8350 ret->alloc(nbOfTupleMax,nbOfComp);
8351 int *res=ret->getPointer();
8352 for(int i=0;i<nbOfTupleMax;i++)
8353 res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<int>());
8354 ret->copyStringInfoFrom(*aMax);
8357 throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
8360 throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
8365 * Adds values of another DataArrayInt to values of \a this one. There are 3
8367 * 1. The arrays have same number of tuples and components. Then each value of
8368 * \a other array is added to the corresponding value of \a this array, i.e.:
8369 * _a_ [ i, j ] += _other_ [ i, j ].
8370 * 2. The arrays have same number of tuples and \a other array has one component. Then
8371 * _a_ [ i, j ] += _other_ [ i, 0 ].
8372 * 3. The arrays have same number of components and \a other array has one tuple. Then
8373 * _a_ [ i, j ] += _a2_ [ 0, j ].
8375 * \param [in] other - an array to add to \a this one.
8376 * \throw If \a other is NULL.
8377 * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
8378 * \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
8379 * \a other has number of both tuples and components not equal to 1.
8381 void DataArrayInt::addEqual(const DataArrayInt *other)
8384 throw INTERP_KERNEL::Exception("DataArrayInt::addEqual : input DataArrayInt instance is NULL !");
8385 const char *msg="Nb of tuples mismatch for DataArrayInt::addEqual !";
8386 checkAllocated(); other->checkAllocated();
8387 int nbOfTuple=getNumberOfTuples();
8388 int nbOfTuple2=other->getNumberOfTuples();
8389 int nbOfComp=getNumberOfComponents();
8390 int nbOfComp2=other->getNumberOfComponents();
8391 if(nbOfTuple==nbOfTuple2)
8393 if(nbOfComp==nbOfComp2)
8395 std::transform(begin(),end(),other->begin(),getPointer(),std::plus<int>());
8397 else if(nbOfComp2==1)
8399 int *ptr=getPointer();
8400 const int *ptrc=other->getConstPointer();
8401 for(int i=0;i<nbOfTuple;i++)
8402 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<int>(),*ptrc++));
8405 throw INTERP_KERNEL::Exception(msg);
8407 else if(nbOfTuple2==1)
8409 if(nbOfComp2==nbOfComp)
8411 int *ptr=getPointer();
8412 const int *ptrc=other->getConstPointer();
8413 for(int i=0;i<nbOfTuple;i++)
8414 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<int>());
8417 throw INTERP_KERNEL::Exception(msg);
8420 throw INTERP_KERNEL::Exception(msg);
8425 * Returns a new DataArrayInt that is a subtraction of two given arrays. There are 3
8427 * 1. The arrays have same number of tuples and components. Then each value of
8428 * the result array (_a_) is a subtraction of the corresponding values of \a a1 and
8429 * \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
8430 * 2. The arrays have same number of tuples and one array, say _a2_, has one
8432 * _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
8433 * 3. The arrays have same number of components and one array, say _a2_, has one
8435 * _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
8437 * Info on components is copied either from the first array (in the first case) or from
8438 * the array with maximal number of elements (getNbOfElems()).
8439 * \param [in] a1 - an array to subtract from.
8440 * \param [in] a2 - an array to subtract.
8441 * \return DataArrayInt * - the new instance of DataArrayInt.
8442 * The caller is to delete this result array using decrRef() as it is no more
8444 * \throw If either \a a1 or \a a2 is NULL.
8445 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
8446 * \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
8447 * none of them has number of tuples or components equal to 1.
8449 DataArrayInt *DataArrayInt::Substract(const DataArrayInt *a1, const DataArrayInt *a2)
8452 throw INTERP_KERNEL::Exception("DataArrayInt::Substract : input DataArrayInt instance is NULL !");
8453 int nbOfTuple1=a1->getNumberOfTuples();
8454 int nbOfTuple2=a2->getNumberOfTuples();
8455 int nbOfComp1=a1->getNumberOfComponents();
8456 int nbOfComp2=a2->getNumberOfComponents();
8457 if(nbOfTuple2==nbOfTuple1)
8459 if(nbOfComp1==nbOfComp2)
8461 MCAuto<DataArrayInt> ret=DataArrayInt::New();
8462 ret->alloc(nbOfTuple2,nbOfComp1);
8463 std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<int>());
8464 ret->copyStringInfoFrom(*a1);
8467 else if(nbOfComp2==1)
8469 MCAuto<DataArrayInt> ret=DataArrayInt::New();
8470 ret->alloc(nbOfTuple1,nbOfComp1);
8471 const int *a2Ptr=a2->getConstPointer();
8472 const int *a1Ptr=a1->getConstPointer();
8473 int *res=ret->getPointer();
8474 for(int i=0;i<nbOfTuple1;i++)
8475 res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<int>(),a2Ptr[i]));
8476 ret->copyStringInfoFrom(*a1);
8481 a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
8485 else if(nbOfTuple2==1)
8487 a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
8488 MCAuto<DataArrayInt> ret=DataArrayInt::New();
8489 ret->alloc(nbOfTuple1,nbOfComp1);
8490 const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
8491 int *pt=ret->getPointer();
8492 for(int i=0;i<nbOfTuple1;i++)
8493 pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<int>());
8494 ret->copyStringInfoFrom(*a1);
8499 a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
8505 * Subtract values of another DataArrayInt from values of \a this one. There are 3
8507 * 1. The arrays have same number of tuples and components. Then each value of
8508 * \a other array is subtracted from the corresponding value of \a this array, i.e.:
8509 * _a_ [ i, j ] -= _other_ [ i, j ].
8510 * 2. The arrays have same number of tuples and \a other array has one component. Then
8511 * _a_ [ i, j ] -= _other_ [ i, 0 ].
8512 * 3. The arrays have same number of components and \a other array has one tuple. Then
8513 * _a_ [ i, j ] -= _a2_ [ 0, j ].
8515 * \param [in] other - an array to subtract from \a this one.
8516 * \throw If \a other is NULL.
8517 * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
8518 * \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
8519 * \a other has number of both tuples and components not equal to 1.
8521 void DataArrayInt::substractEqual(const DataArrayInt *other)
8524 throw INTERP_KERNEL::Exception("DataArrayInt::substractEqual : input DataArrayInt instance is NULL !");
8525 const char *msg="Nb of tuples mismatch for DataArrayInt::substractEqual !";
8526 checkAllocated(); other->checkAllocated();
8527 int nbOfTuple=getNumberOfTuples();
8528 int nbOfTuple2=other->getNumberOfTuples();
8529 int nbOfComp=getNumberOfComponents();
8530 int nbOfComp2=other->getNumberOfComponents();
8531 if(nbOfTuple==nbOfTuple2)
8533 if(nbOfComp==nbOfComp2)
8535 std::transform(begin(),end(),other->begin(),getPointer(),std::minus<int>());
8537 else if(nbOfComp2==1)
8539 int *ptr=getPointer();
8540 const int *ptrc=other->getConstPointer();
8541 for(int i=0;i<nbOfTuple;i++)
8542 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<int>(),*ptrc++));
8545 throw INTERP_KERNEL::Exception(msg);
8547 else if(nbOfTuple2==1)
8549 int *ptr=getPointer();
8550 const int *ptrc=other->getConstPointer();
8551 for(int i=0;i<nbOfTuple;i++)
8552 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<int>());
8555 throw INTERP_KERNEL::Exception(msg);
8560 * Returns a new DataArrayInt that is a product of two given arrays. There are 3
8562 * 1. The arrays have same number of tuples and components. Then each value of
8563 * the result array (_a_) is a product of the corresponding values of \a a1 and
8564 * \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
8565 * 2. The arrays have same number of tuples and one array, say _a2_, has one
8567 * _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
8568 * 3. The arrays have same number of components and one array, say _a2_, has one
8570 * _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
8572 * Info on components is copied either from the first array (in the first case) or from
8573 * the array with maximal number of elements (getNbOfElems()).
8574 * \param [in] a1 - a factor array.
8575 * \param [in] a2 - another factor array.
8576 * \return DataArrayInt * - the new instance of DataArrayInt.
8577 * The caller is to delete this result array using decrRef() as it is no more
8579 * \throw If either \a a1 or \a a2 is NULL.
8580 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
8581 * \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
8582 * none of them has number of tuples or components equal to 1.
8584 DataArrayInt *DataArrayInt::Multiply(const DataArrayInt *a1, const DataArrayInt *a2)
8587 throw INTERP_KERNEL::Exception("DataArrayInt::Multiply : input DataArrayInt instance is NULL !");
8588 int nbOfTuple=a1->getNumberOfTuples();
8589 int nbOfTuple2=a2->getNumberOfTuples();
8590 int nbOfComp=a1->getNumberOfComponents();
8591 int nbOfComp2=a2->getNumberOfComponents();
8592 MCAuto<DataArrayInt> ret=0;
8593 if(nbOfTuple==nbOfTuple2)
8595 if(nbOfComp==nbOfComp2)
8597 ret=DataArrayInt::New();
8598 ret->alloc(nbOfTuple,nbOfComp);
8599 std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<int>());
8600 ret->copyStringInfoFrom(*a1);
8604 int nbOfCompMin,nbOfCompMax;
8605 const DataArrayInt *aMin, *aMax;
8606 if(nbOfComp>nbOfComp2)
8608 nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
8613 nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
8618 ret=DataArrayInt::New();
8619 ret->alloc(nbOfTuple,nbOfCompMax);
8620 const int *aMinPtr=aMin->getConstPointer();
8621 const int *aMaxPtr=aMax->getConstPointer();
8622 int *res=ret->getPointer();
8623 for(int i=0;i<nbOfTuple;i++)
8624 res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<int>(),aMinPtr[i]));
8625 ret->copyStringInfoFrom(*aMax);
8628 throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
8631 else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
8633 if(nbOfComp==nbOfComp2)
8635 int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
8636 const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
8637 const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
8638 const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
8639 ret=DataArrayInt::New();
8640 ret->alloc(nbOfTupleMax,nbOfComp);
8641 int *res=ret->getPointer();
8642 for(int i=0;i<nbOfTupleMax;i++)
8643 res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<int>());
8644 ret->copyStringInfoFrom(*aMax);
8647 throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
8650 throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
8656 * Multiply values of another DataArrayInt to values of \a this one. There are 3
8658 * 1. The arrays have same number of tuples and components. Then each value of
8659 * \a other array is multiplied to the corresponding value of \a this array, i.e.:
8660 * _a_ [ i, j ] *= _other_ [ i, j ].
8661 * 2. The arrays have same number of tuples and \a other array has one component. Then
8662 * _a_ [ i, j ] *= _other_ [ i, 0 ].
8663 * 3. The arrays have same number of components and \a other array has one tuple. Then
8664 * _a_ [ i, j ] *= _a2_ [ 0, j ].
8666 * \param [in] other - an array to multiply to \a this one.
8667 * \throw If \a other is NULL.
8668 * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
8669 * \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
8670 * \a other has number of both tuples and components not equal to 1.
8672 void DataArrayInt::multiplyEqual(const DataArrayInt *other)
8675 throw INTERP_KERNEL::Exception("DataArrayInt::multiplyEqual : input DataArrayInt instance is NULL !");
8676 const char *msg="Nb of tuples mismatch for DataArrayInt::multiplyEqual !";
8677 checkAllocated(); other->checkAllocated();
8678 int nbOfTuple=getNumberOfTuples();
8679 int nbOfTuple2=other->getNumberOfTuples();
8680 int nbOfComp=getNumberOfComponents();
8681 int nbOfComp2=other->getNumberOfComponents();
8682 if(nbOfTuple==nbOfTuple2)
8684 if(nbOfComp==nbOfComp2)
8686 std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<int>());
8688 else if(nbOfComp2==1)
8690 int *ptr=getPointer();
8691 const int *ptrc=other->getConstPointer();
8692 for(int i=0;i<nbOfTuple;i++)
8693 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<int>(),*ptrc++));
8696 throw INTERP_KERNEL::Exception(msg);
8698 else if(nbOfTuple2==1)
8700 if(nbOfComp2==nbOfComp)
8702 int *ptr=getPointer();
8703 const int *ptrc=other->getConstPointer();
8704 for(int i=0;i<nbOfTuple;i++)
8705 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<int>());
8708 throw INTERP_KERNEL::Exception(msg);
8711 throw INTERP_KERNEL::Exception(msg);
8717 * Returns a new DataArrayInt that is a division of two given arrays. There are 3
8719 * 1. The arrays have same number of tuples and components. Then each value of
8720 * the result array (_a_) is a division of the corresponding values of \a a1 and
8721 * \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
8722 * 2. The arrays have same number of tuples and one array, say _a2_, has one
8724 * _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
8725 * 3. The arrays have same number of components and one array, say _a2_, has one
8727 * _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
8729 * Info on components is copied either from the first array (in the first case) or from
8730 * the array with maximal number of elements (getNbOfElems()).
8731 * \warning No check of division by zero is performed!
8732 * \param [in] a1 - a numerator array.
8733 * \param [in] a2 - a denominator array.
8734 * \return DataArrayInt * - the new instance of DataArrayInt.
8735 * The caller is to delete this result array using decrRef() as it is no more
8737 * \throw If either \a a1 or \a a2 is NULL.
8738 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
8739 * \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
8740 * none of them has number of tuples or components equal to 1.
8742 DataArrayInt *DataArrayInt::Divide(const DataArrayInt *a1, const DataArrayInt *a2)
8745 throw INTERP_KERNEL::Exception("DataArrayInt::Divide : input DataArrayInt instance is NULL !");
8746 int nbOfTuple1=a1->getNumberOfTuples();
8747 int nbOfTuple2=a2->getNumberOfTuples();
8748 int nbOfComp1=a1->getNumberOfComponents();
8749 int nbOfComp2=a2->getNumberOfComponents();
8750 if(nbOfTuple2==nbOfTuple1)
8752 if(nbOfComp1==nbOfComp2)
8754 MCAuto<DataArrayInt> ret=DataArrayInt::New();
8755 ret->alloc(nbOfTuple2,nbOfComp1);
8756 std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<int>());
8757 ret->copyStringInfoFrom(*a1);
8760 else if(nbOfComp2==1)
8762 MCAuto<DataArrayInt> ret=DataArrayInt::New();
8763 ret->alloc(nbOfTuple1,nbOfComp1);
8764 const int *a2Ptr=a2->getConstPointer();
8765 const int *a1Ptr=a1->getConstPointer();
8766 int *res=ret->getPointer();
8767 for(int i=0;i<nbOfTuple1;i++)
8768 res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<int>(),a2Ptr[i]));
8769 ret->copyStringInfoFrom(*a1);
8774 a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
8778 else if(nbOfTuple2==1)
8780 a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
8781 MCAuto<DataArrayInt> ret=DataArrayInt::New();
8782 ret->alloc(nbOfTuple1,nbOfComp1);
8783 const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
8784 int *pt=ret->getPointer();
8785 for(int i=0;i<nbOfTuple1;i++)
8786 pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<int>());
8787 ret->copyStringInfoFrom(*a1);
8792 a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
8798 * Divide values of \a this array by values of another DataArrayInt. There are 3
8800 * 1. The arrays have same number of tuples and components. Then each value of
8801 * \a this array is divided by the corresponding value of \a other one, i.e.:
8802 * _a_ [ i, j ] /= _other_ [ i, j ].
8803 * 2. The arrays have same number of tuples and \a other array has one component. Then
8804 * _a_ [ i, j ] /= _other_ [ i, 0 ].
8805 * 3. The arrays have same number of components and \a other array has one tuple. Then
8806 * _a_ [ i, j ] /= _a2_ [ 0, j ].
8808 * \warning No check of division by zero is performed!
8809 * \param [in] other - an array to divide \a this one by.
8810 * \throw If \a other is NULL.
8811 * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
8812 * \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
8813 * \a other has number of both tuples and components not equal to 1.
8815 void DataArrayInt::divideEqual(const DataArrayInt *other)
8818 throw INTERP_KERNEL::Exception("DataArrayInt::divideEqual : input DataArrayInt instance is NULL !");
8819 const char *msg="Nb of tuples mismatch for DataArrayInt::divideEqual !";
8820 checkAllocated(); other->checkAllocated();
8821 int nbOfTuple=getNumberOfTuples();
8822 int nbOfTuple2=other->getNumberOfTuples();
8823 int nbOfComp=getNumberOfComponents();
8824 int nbOfComp2=other->getNumberOfComponents();
8825 if(nbOfTuple==nbOfTuple2)
8827 if(nbOfComp==nbOfComp2)
8829 std::transform(begin(),end(),other->begin(),getPointer(),std::divides<int>());
8831 else if(nbOfComp2==1)
8833 int *ptr=getPointer();
8834 const int *ptrc=other->getConstPointer();
8835 for(int i=0;i<nbOfTuple;i++)
8836 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<int>(),*ptrc++));
8839 throw INTERP_KERNEL::Exception(msg);
8841 else if(nbOfTuple2==1)
8843 if(nbOfComp2==nbOfComp)
8845 int *ptr=getPointer();
8846 const int *ptrc=other->getConstPointer();
8847 for(int i=0;i<nbOfTuple;i++)
8848 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<int>());
8851 throw INTERP_KERNEL::Exception(msg);
8854 throw INTERP_KERNEL::Exception(msg);
8860 * Returns a new DataArrayInt that is a modulus of two given arrays. There are 3
8862 * 1. The arrays have same number of tuples and components. Then each value of
8863 * the result array (_a_) is a division of the corresponding values of \a a1 and
8864 * \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, j ].
8865 * 2. The arrays have same number of tuples and one array, say _a2_, has one
8867 * _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ i, 0 ].
8868 * 3. The arrays have same number of components and one array, say _a2_, has one
8870 * _a_ [ i, j ] = _a1_ [ i, j ] % _a2_ [ 0, j ].
8872 * Info on components is copied either from the first array (in the first case) or from
8873 * the array with maximal number of elements (getNbOfElems()).
8874 * \warning No check of division by zero is performed!
8875 * \param [in] a1 - a dividend array.
8876 * \param [in] a2 - a divisor array.
8877 * \return DataArrayInt * - the new instance of DataArrayInt.
8878 * The caller is to delete this result array using decrRef() as it is no more
8880 * \throw If either \a a1 or \a a2 is NULL.
8881 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
8882 * \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
8883 * none of them has number of tuples or components equal to 1.
8885 DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt *a2)
8888 throw INTERP_KERNEL::Exception("DataArrayInt::Modulus : input DataArrayInt instance is NULL !");
8889 int nbOfTuple1=a1->getNumberOfTuples();
8890 int nbOfTuple2=a2->getNumberOfTuples();
8891 int nbOfComp1=a1->getNumberOfComponents();
8892 int nbOfComp2=a2->getNumberOfComponents();
8893 if(nbOfTuple2==nbOfTuple1)
8895 if(nbOfComp1==nbOfComp2)
8897 MCAuto<DataArrayInt> ret=DataArrayInt::New();
8898 ret->alloc(nbOfTuple2,nbOfComp1);
8899 std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::modulus<int>());
8900 ret->copyStringInfoFrom(*a1);
8903 else if(nbOfComp2==1)
8905 MCAuto<DataArrayInt> ret=DataArrayInt::New();
8906 ret->alloc(nbOfTuple1,nbOfComp1);
8907 const int *a2Ptr=a2->getConstPointer();
8908 const int *a1Ptr=a1->getConstPointer();
8909 int *res=ret->getPointer();
8910 for(int i=0;i<nbOfTuple1;i++)
8911 res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::modulus<int>(),a2Ptr[i]));
8912 ret->copyStringInfoFrom(*a1);
8917 a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
8921 else if(nbOfTuple2==1)
8923 a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !");
8924 MCAuto<DataArrayInt> ret=DataArrayInt::New();
8925 ret->alloc(nbOfTuple1,nbOfComp1);
8926 const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
8927 int *pt=ret->getPointer();
8928 for(int i=0;i<nbOfTuple1;i++)
8929 pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::modulus<int>());
8930 ret->copyStringInfoFrom(*a1);
8935 a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Modulus !");//will always throw an exception
8941 * Modify \a this array so that each value becomes a modulus of division of this value by
8942 * a value of another DataArrayInt. There are 3 valid cases.
8943 * 1. The arrays have same number of tuples and components. Then each value of
8944 * \a this array is divided by the corresponding value of \a other one, i.e.:
8945 * _a_ [ i, j ] %= _other_ [ i, j ].
8946 * 2. The arrays have same number of tuples and \a other array has one component. Then
8947 * _a_ [ i, j ] %= _other_ [ i, 0 ].
8948 * 3. The arrays have same number of components and \a other array has one tuple. Then
8949 * _a_ [ i, j ] %= _a2_ [ 0, j ].
8951 * \warning No check of division by zero is performed!
8952 * \param [in] other - a divisor array.
8953 * \throw If \a other is NULL.
8954 * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
8955 * \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
8956 * \a other has number of both tuples and components not equal to 1.
8958 void DataArrayInt::modulusEqual(const DataArrayInt *other)
8961 throw INTERP_KERNEL::Exception("DataArrayInt::modulusEqual : input DataArrayInt instance is NULL !");
8962 const char *msg="Nb of tuples mismatch for DataArrayInt::modulusEqual !";
8963 checkAllocated(); other->checkAllocated();
8964 int nbOfTuple=getNumberOfTuples();
8965 int nbOfTuple2=other->getNumberOfTuples();
8966 int nbOfComp=getNumberOfComponents();
8967 int nbOfComp2=other->getNumberOfComponents();
8968 if(nbOfTuple==nbOfTuple2)
8970 if(nbOfComp==nbOfComp2)
8972 std::transform(begin(),end(),other->begin(),getPointer(),std::modulus<int>());
8974 else if(nbOfComp2==1)
8976 if(nbOfComp2==nbOfComp)
8978 int *ptr=getPointer();
8979 const int *ptrc=other->getConstPointer();
8980 for(int i=0;i<nbOfTuple;i++)
8981 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::modulus<int>(),*ptrc++));
8984 throw INTERP_KERNEL::Exception(msg);
8987 throw INTERP_KERNEL::Exception(msg);
8989 else if(nbOfTuple2==1)
8991 int *ptr=getPointer();
8992 const int *ptrc=other->getConstPointer();
8993 for(int i=0;i<nbOfTuple;i++)
8994 std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::modulus<int>());
8997 throw INTERP_KERNEL::Exception(msg);
9002 * Returns a new DataArrayInt that is the result of pow of two given arrays. There are 3
9005 * \param [in] a1 - an array to pow up.
9006 * \param [in] a2 - another array to sum up.
9007 * \return DataArrayInt * - the new instance of DataArrayInt.
9008 * The caller is to delete this result array using decrRef() as it is no more
9010 * \throw If either \a a1 or \a a2 is NULL.
9011 * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
9012 * \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
9013 * \throw If there is a negative value in \a a2.
9015 DataArrayInt *DataArrayInt::Pow(const DataArrayInt *a1, const DataArrayInt *a2)
9018 throw INTERP_KERNEL::Exception("DataArrayInt::Pow : at least one of input instances is null !");
9019 int nbOfTuple=a1->getNumberOfTuples();
9020 int nbOfTuple2=a2->getNumberOfTuples();
9021 int nbOfComp=a1->getNumberOfComponents();
9022 int nbOfComp2=a2->getNumberOfComponents();
9023 if(nbOfTuple!=nbOfTuple2)
9024 throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of tuples mismatches !");
9025 if(nbOfComp!=1 || nbOfComp2!=1)
9026 throw INTERP_KERNEL::Exception("DataArrayInt::Pow : number of components of both arrays must be equal to 1 !");
9027 MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuple,1);
9028 const int *ptr1(a1->begin()),*ptr2(a2->begin());
9029 int *ptr=ret->getPointer();
9030 for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
9035 for(int j=0;j<*ptr2;j++)
9041 std::ostringstream oss; oss << "DataArrayInt::Pow : on tuple #" << i << " of a2 value is < 0 (" << *ptr2 << ") !";
9042 throw INTERP_KERNEL::Exception(oss.str().c_str());
9049 * Apply pow on values of another DataArrayInt to values of \a this one.
9051 * \param [in] other - an array to pow to \a this one.
9052 * \throw If \a other is NULL.
9053 * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
9054 * \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
9055 * \throw If there is a negative value in \a other.
9057 void DataArrayInt::powEqual(const DataArrayInt *other)
9060 throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : input instance is null !");
9061 int nbOfTuple=getNumberOfTuples();
9062 int nbOfTuple2=other->getNumberOfTuples();
9063 int nbOfComp=getNumberOfComponents();
9064 int nbOfComp2=other->getNumberOfComponents();
9065 if(nbOfTuple!=nbOfTuple2)
9066 throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of tuples mismatches !");
9067 if(nbOfComp!=1 || nbOfComp2!=1)
9068 throw INTERP_KERNEL::Exception("DataArrayInt::powEqual : number of components of both arrays must be equal to 1 !");
9069 int *ptr=getPointer();
9070 const int *ptrc=other->begin();
9071 for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
9076 for(int j=0;j<*ptrc;j++)
9082 std::ostringstream oss; oss << "DataArrayInt::powEqual : on tuple #" << i << " of other value is < 0 (" << *ptrc << ") !";
9083 throw INTERP_KERNEL::Exception(oss.str().c_str());
9090 * Returns a C array which is a renumbering map in "Old to New" mode for the input array.
9091 * This map, if applied to \a start array, would make it sorted. For example, if
9092 * \a start array contents are [9,10,0,6,4,11,3,7] then the contents of the result array is
9093 * [5,6,0,3,2,7,1,4].
9094 * \param [in] start - pointer to the first element of the array for which the
9095 * permutation map is computed.
9096 * \param [in] end - pointer specifying the end of the array \a start, so that
9097 * the last value of \a start is \a end[ -1 ].
9098 * \return int * - the result permutation array that the caller is to delete as it is no
9100 * \throw If there are equal values in the input array.
9102 int *DataArrayInt::CheckAndPreparePermutation(const int *start, const int *end)
9104 std::size_t sz=std::distance(start,end);
9105 int *ret=(int *)malloc(sz*sizeof(int));
9106 int *work=new int[sz];
9107 std::copy(start,end,work);
9108 std::sort(work,work+sz);
9109 if(std::unique(work,work+sz)!=work+sz)
9113 throw INTERP_KERNEL::Exception("Some elements are equals in the specified array !");
9115 std::map<int,int> m;
9116 for(int *workPt=work;workPt!=work+sz;workPt++)
9117 m[*workPt]=(int)std::distance(work,workPt);
9119 for(const int *iter=start;iter!=end;iter++,iter2++)
9126 * Returns a new DataArrayInt containing an arithmetic progression
9127 * that is equal to the sequence returned by Python \c range(\a begin,\a end,\a step )
9129 * \param [in] begin - the start value of the result sequence.
9130 * \param [in] end - limiting value, so that every value of the result array is less than
9132 * \param [in] step - specifies the increment or decrement.
9133 * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
9134 * array using decrRef() as it is no more needed.
9135 * \throw If \a step == 0.
9136 * \throw If \a end < \a begin && \a step > 0.
9137 * \throw If \a end > \a begin && \a step < 0.
9139 DataArrayInt *DataArrayInt::Range(int begin, int end, int step)
9141 int nbOfTuples=GetNumberOfItemGivenBESRelative(begin,end,step,"DataArrayInt::Range");
9142 MCAuto<DataArrayInt> ret=DataArrayInt::New();
9143 ret->alloc(nbOfTuples,1);
9144 int *ptr=ret->getPointer();
9147 for(int i=begin;i<end;i+=step,ptr++)
9152 for(int i=begin;i>end;i+=step,ptr++)
9159 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
9162 void DataArrayInt::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
9167 tinyInfo[0]=getNumberOfTuples();
9168 tinyInfo[1]=getNumberOfComponents();
9178 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
9181 void DataArrayInt::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
9185 int nbOfCompo=getNumberOfComponents();
9186 tinyInfo.resize(nbOfCompo+1);
9187 tinyInfo[0]=getName();
9188 for(int i=0;i<nbOfCompo;i++)
9189 tinyInfo[i+1]=getInfoOnComponent(i);
9194 tinyInfo[0]=getName();
9199 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
9200 * This method returns if a feeding is needed.
9202 bool DataArrayInt::resizeForUnserialization(const std::vector<int>& tinyInfoI)
9204 int nbOfTuple=tinyInfoI[0];
9205 int nbOfComp=tinyInfoI[1];
9206 if(nbOfTuple!=-1 || nbOfComp!=-1)
9208 alloc(nbOfTuple,nbOfComp);
9215 * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
9216 * This method returns if a feeding is needed.
9218 void DataArrayInt::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
9220 setName(tinyInfoS[0]);
9223 int nbOfCompo=tinyInfoI[1];
9224 for(int i=0;i<nbOfCompo;i++)
9225 setInfoOnComponent(i,tinyInfoS[i+1]);
9229 DataArrayIntIterator::DataArrayIntIterator(DataArrayInt *da):_da(da),_pt(0),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
9234 if(_da->isAllocated())
9236 _nb_comp=da->getNumberOfComponents();
9237 _nb_tuple=da->getNumberOfTuples();
9238 _pt=da->getPointer();
9243 DataArrayIntIterator::~DataArrayIntIterator()
9249 DataArrayIntTuple *DataArrayIntIterator::nextt()
9251 if(_tuple_id<_nb_tuple)
9254 DataArrayIntTuple *ret=new DataArrayIntTuple(_pt,_nb_comp);
9262 DataArrayIntTuple::DataArrayIntTuple(int *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
9266 std::string DataArrayIntTuple::repr() const
9268 std::ostringstream oss; oss << "(";
9269 for(int i=0;i<_nb_of_compo-1;i++)
9270 oss << _pt[i] << ", ";
9271 oss << _pt[_nb_of_compo-1] << ")";
9275 int DataArrayIntTuple::intValue() const
9279 throw INTERP_KERNEL::Exception("DataArrayIntTuple::intValue : DataArrayIntTuple instance has not exactly 1 component -> Not possible to convert it into an integer !");
9283 * This method returns a newly allocated instance the caller should dealed with by a MEDCoupling::DataArrayInt::decrRef.
9284 * This method performs \b no copy of data. The content is only referenced using MEDCoupling::DataArrayInt::useArray with ownership set to \b false.
9285 * 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
9286 * \b nbOfCompo=1 and \bnbOfTuples==this->_nb_of_elem.
9288 DataArrayInt *DataArrayIntTuple::buildDAInt(int nbOfTuples, int nbOfCompo) const
9290 if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
9292 DataArrayInt *ret=DataArrayInt::New();
9293 ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
9298 std::ostringstream oss; oss << "DataArrayIntTuple::buildDAInt : unable to build a requested DataArrayInt instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
9299 oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
9300 throw INTERP_KERNEL::Exception(oss.str().c_str());