/*!
* Sets information on all components. This method can change number of components
* at certain conditions; if the conditions are not respected, an exception is thrown.
- * The number of components can be changed provided that \a this is not allocated.
+ * The number of components can be changed in \a this only if \a this is not allocated.
+ * The condition of number of components must not be changed.
*
* To know more on format of the component information see
* \ref MEDCouplingArrayBasicsCompoName "DataArrays infos".
throw INTERP_KERNEL::Exception("DataArrayDouble::checkAllocated : Array is defined but not allocated ! Call alloc or setValues method first !");
}
+/*!
+ * This method desallocated \a this without modification of informations relative to the components.
+ * After call of this method, DataArrayDouble::isAllocated will return false.
+ * If \a this is already not allocated, \a this is let unchanged.
+ */
+void DataArrayDouble::desallocate() throw(INTERP_KERNEL::Exception)
+{
+ _mem.destroy();
+}
+
std::size_t DataArrayDouble::getHeapMemorySize() const
{
std::size_t sz=_mem.getNbOfElemAllocated();
* than the current number the array is truncated, otherwise the array is extended.
* \param [in] nbOfTuples - new number of tuples.
* \throw If \a this is not allocated.
+ * \throw If \a nbOfTuples is negative.
*/
void DataArrayDouble::reAlloc(int nbOfTuples) throw(INTERP_KERNEL::Exception)
{
+ if(nbOfTuples<0)
+ throw INTERP_KERNEL::Exception("DataArrayDouble::reAlloc : input new number of tuples should be >=0 !");
checkAllocated();
_mem.reAlloc(getNumberOfComponents()*(std::size_t)nbOfTuples);
declareAsNew();
double *tmp=new double[nbTuples*nbOfCompo];
const double *iptr=getConstPointer();
for(int i=0;i<nbTuples;i++)
- std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),tmp+nbOfCompo*old2New[i]);
+ {
+ int v=old2New[i];
+ if(v>=0 && v<nbTuples)
+ std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),tmp+nbOfCompo*v);
+ else
+ {
+ std::ostringstream oss; oss << "DataArrayDouble::renumberInPlace : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
+ throw INTERP_KERNEL::Exception(oss.str().c_str());
+ }
+ }
std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
delete [] tmp;
declareAsNew();
double *tmp=new double[nbTuples*nbOfCompo];
const double *iptr=getConstPointer();
for(int i=0;i<nbTuples;i++)
- std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),tmp+nbOfCompo*i);
+ {
+ int v=new2Old[i];
+ if(v>=0 && v<nbTuples)
+ std::copy(iptr+nbOfCompo*v,iptr+nbOfCompo*(v+1),tmp+nbOfCompo*i);
+ else
+ {
+ std::ostringstream oss; oss << "DataArrayDouble::renumberInPlaceR : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
+ throw INTERP_KERNEL::Exception(oss.str().c_str());
+ }
+ }
std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
delete [] tmp;
declareAsNew();
copyPartOfStringInfoFrom2(compIds,*other);
}
+/*!
+ * This method checks that all tuples in \a other are in \a this.
+ * If true, the output param \a tupleIds contains the tuples ids of \a this that correspond to tupes in \a this.
+ * 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.
+ *
+ * \param [in] other - the array having the same number of components than \a this.
+ * \param [out] tupleIds - the tuple ids containing the same number of tuples than \a other has.
+ * \sa DataArrayDouble::findCommonTuples
+ */
+bool DataArrayDouble::areIncludedInMe(const DataArrayDouble *other, double prec, DataArrayInt *&tupleIds) const throw(INTERP_KERNEL::Exception)
+{
+ if(!other)
+ throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : input array is NULL !");
+ checkAllocated(); other->checkAllocated();
+ if(getNumberOfComponents()!=other->getNumberOfComponents())
+ throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : the number of components does not match !");
+ MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> a=DataArrayDouble::Aggregate(this,other);
+ DataArrayInt *c=0,*ci=0;
+ a->findCommonTuples(prec,getNumberOfTuples(),c,ci);
+ MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cSafe(c),ciSafe(ci);
+ int newNbOfTuples=-1;
+ MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(a->getNumberOfTuples(),c->begin(),ci->begin(),ci->end(),newNbOfTuples);
+ MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=ids->selectByTupleId2(getNumberOfTuples(),a->getNumberOfTuples(),1);
+ tupleIds=ret1.retn();
+ return newNbOfTuples==getNumberOfTuples();
+}
+
/*!
* Searches for tuples coincident within \a prec tolerance. Each tuple is considered
* as coordinates of a point in getNumberOfComponents()-dimensional space. The
* \ref cpp_mcdataarraydouble_findcommontuples "Here is a C++ example".
*
* \ref py_mcdataarraydouble_findcommontuples "Here is a Python example".
- * \sa DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2().
+ * \sa DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(), DataArrayDouble::areIncludedInMe
*/
void DataArrayDouble::findCommonTuples(double prec, int limitTupleId, DataArrayInt *&comm, DataArrayInt *&commIndex) const throw(INTERP_KERNEL::Exception)
{
return _mem[tupleId*_info_on_compo.size()+compoId];
}
+/*!
+ * Returns the first value of \a this.
+ * \return double - the last value of \a this array.
+ * \throw If \a this is not allocated.
+ * \throw If \a this->getNumberOfComponents() != 1.
+ * \throw If \a this->getNumberOfTuples() < 1.
+ */
+double DataArrayDouble::front() const throw(INTERP_KERNEL::Exception)
+{
+ checkAllocated();
+ if(getNumberOfComponents()!=1)
+ throw INTERP_KERNEL::Exception("DataArrayDouble::front : number of components not equal to one !");
+ int nbOfTuples=getNumberOfTuples();
+ if(nbOfTuples<1)
+ throw INTERP_KERNEL::Exception("DataArrayDouble::front : number of tuples must be >= 1 !");
+ return *(getConstPointer());
+}
+
/*!
* Returns the last value of \a this.
* \return double - the last value of \a this array.
throw INTERP_KERNEL::Exception("DataArrayInt::checkAllocated : Array is defined but not allocated ! Call alloc or setValues method first !");
}
+/*!
+ * This method desallocated \a this without modification of informations relative to the components.
+ * After call of this method, DataArrayInt::isAllocated will return false.
+ * If \a this is already not allocated, \a this is let unchanged.
+ */
+void DataArrayInt::desallocate() throw(INTERP_KERNEL::Exception)
+{
+ _mem.destroy();
+}
+
std::size_t DataArrayInt::getHeapMemorySize() const
{
std::size_t sz=_mem.getNbOfElemAllocated();
*pt=indArrBg[*pt];
else
{
- std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn;
+ std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " of this value is " << *pt << ", should be in [0," << nbElemsIn << ") !";
throw INTERP_KERNEL::Exception(oss.str().c_str());
}
}
}
else
{
- std::ostringstream oss; oss << "DataArrayInt::splitByValueRange : At rank #" << i << " the value is " << work[i] << " whereas the last value is " << *bg;
+ std::ostringstream oss; oss << "DataArrayInt::splitByValueRange : At rank #" << i << " the value is " << work[i] << " should be in [0," << *bg << ") !";
throw INTERP_KERNEL::Exception(oss.str().c_str());
}
}
int *tmp=new int[nbTuples*nbOfCompo];
const int *iptr=getConstPointer();
for(int i=0;i<nbTuples;i++)
- std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),tmp+nbOfCompo*old2New[i]);
+ {
+ int v=old2New[i];
+ if(v>=0 && v<nbTuples)
+ std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),tmp+nbOfCompo*v);
+ else
+ {
+ std::ostringstream oss; oss << "DataArrayInt::renumberInPlace : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
+ throw INTERP_KERNEL::Exception(oss.str().c_str());
+ }
+ }
std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
delete [] tmp;
declareAsNew();
int *tmp=new int[nbTuples*nbOfCompo];
const int *iptr=getConstPointer();
for(int i=0;i<nbTuples;i++)
- std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),tmp+nbOfCompo*i);
+ {
+ int v=new2Old[i];
+ if(v>=0 && v<nbTuples)
+ std::copy(iptr+nbOfCompo*v,iptr+nbOfCompo*(v+1),tmp+nbOfCompo*i);
+ else
+ {
+ std::ostringstream oss; oss << "DataArrayInt::renumberInPlaceR : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !";
+ throw INTERP_KERNEL::Exception(oss.str().c_str());
+ }
+ }
std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer());
delete [] tmp;
declareAsNew();
* than the current number the array is truncated, otherwise the array is extended.
* \param [in] nbOfTuples - new number of tuples.
* \throw If \a this is not allocated.
+ * \throw If \a nbOfTuples is negative.
*/
void DataArrayInt::reAlloc(int nbOfTuples) throw(INTERP_KERNEL::Exception)
{
+ if(nbOfTuples<0)
+ throw INTERP_KERNEL::Exception("DataArrayInt::reAlloc : input new number of tuples should be >=0 !");
checkAllocated();
_mem.reAlloc(getNumberOfComponents()*(std::size_t)nbOfTuples);
declareAsNew();
return _mem[tupleId*_info_on_compo.size()+compoId];
}
+/*!
+ * Returns the first value of \a this.
+ * \return int - the last value of \a this array.
+ * \throw If \a this is not allocated.
+ * \throw If \a this->getNumberOfComponents() != 1.
+ * \throw If \a this->getNumberOfTuples() < 1.
+ */
+int DataArrayInt::front() const throw(INTERP_KERNEL::Exception)
+{
+ checkAllocated();
+ if(getNumberOfComponents()!=1)
+ throw INTERP_KERNEL::Exception("DataArrayInt::front : number of components not equal to one !");
+ int nbOfTuples=getNumberOfTuples();
+ if(nbOfTuples<1)
+ throw INTERP_KERNEL::Exception("DataArrayInt::front : number of tuples must be >= 1 !");
+ return *(getConstPointer());
+}
+
/*!
* Returns the last value of \a this.
- * \return double - the last value of \a this array.
+ * \return int - the last value of \a this array.
* \throw If \a this is not allocated.
* \throw If \a this->getNumberOfComponents() != 1.
* \throw If \a this->getNumberOfTuples() < 1.
return ret.retn();
}
+/*!
+ * This method takes as input a list of DataArrayInt instances \a arrs that represent each a packed index arrays.
+ * A packed index array is an allocated array with one component, and at least one tuple. The first element
+ * of each array in \a arrs must be 0. Each array in \a arrs is expected to be increasingly monotonic.
+ * 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.
+ *
+ * \return DataArrayInt * - a new object to be managed by the caller.
+ */
+DataArrayInt *DataArrayInt::AggregateIndexes(const std::vector<const DataArrayInt *>& arrs) throw(INTERP_KERNEL::Exception)
+{
+ int retSz=1;
+ for(std::vector<const DataArrayInt *>::const_iterator it4=arrs.begin();it4!=arrs.end();it4++)
+ {
+ if(*it4)
+ {
+ (*it4)->checkAllocated();
+ if((*it4)->getNumberOfComponents()!=1)
+ {
+ std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of compo != 1 at pos " << std::distance(arrs.begin(),it4) << " !";
+ throw INTERP_KERNEL::Exception(oss.str().c_str());
+ }
+ int nbTupl=(*it4)->getNumberOfTuples();
+ if(nbTupl<1)
+ {
+ std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of tuples < 1 at pos " << std::distance(arrs.begin(),it4) << " !";
+ throw INTERP_KERNEL::Exception(oss.str().c_str());
+ }
+ if((*it4)->front()!=0)
+ {
+ std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with front value != 0 at pos " << std::distance(arrs.begin(),it4) << " !";
+ throw INTERP_KERNEL::Exception(oss.str().c_str());
+ }
+ retSz+=nbTupl-1;
+ }
+ else
+ {
+ std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a null instance at pos " << std::distance(arrs.begin(),it4) << " !";
+ throw INTERP_KERNEL::Exception(oss.str().c_str());
+ }
+ }
+ if(arrs.empty())
+ throw INTERP_KERNEL::Exception("DataArrayInt::AggregateIndexes : input list must be NON EMPTY !");
+ MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
+ ret->alloc(retSz,1);
+ int *pt=ret->getPointer(); *pt++=0;
+ for(std::vector<const DataArrayInt *>::const_iterator it=arrs.begin();it!=arrs.end();it++)
+ pt=std::transform((*it)->begin()+1,(*it)->end(),pt,std::bind2nd(std::plus<int>(),pt[-1]));
+ ret->copyStringInfoFrom(*(arrs[0]));
+ return ret.retn();
+}
+
/*!
* Returns the maximal value and its location within \a this one-dimensional array.
* \param [out] tupleId - index of the tuple holding the maximal value.
* this[*id] in [\b vmin,\b vmax)
*
* \param [in] vmin begin of range. This value is included in range (included).
- * \param [out] vmax end of range. This value is \b not included in range (excluded).
+ * \param [in] vmax end of range. This value is \b not included in range (excluded).
* \return a newly allocated data array that the caller should deal with.
*/
DataArrayInt *DataArrayInt::getIdsInRange(int vmin, int vmax) const throw(INTERP_KERNEL::Exception)
return ret.retn();
}
+/*!
+ * This method works only on data array with one component.
+ * 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.
+ *
+ * \param [in] vmin begin of range. This value is included in range (included).
+ * \param [in] vmax end of range. This value is \b not included in range (excluded).
+ * \return if all ids in \a this are so that (*this)[i]==i for all i in [ 0, \c this->getNumberOfTuples() ).
+ */
+bool DataArrayInt::checkAllIdsInRange(int vmin, int vmax) const throw(INTERP_KERNEL::Exception)
+{
+ checkAllocated();
+ if(getNumberOfComponents()!=1)
+ throw INTERP_KERNEL::Exception("DataArrayInt::checkAllIdsInRange : this must have exactly one component !");
+ int nbOfTuples=getNumberOfTuples();
+ bool ret=true;
+ const int *cptr=getConstPointer();
+ for(int i=0;i<nbOfTuples;i++,cptr++)
+ {
+ if(*cptr>=vmin && *cptr<vmax)
+ { ret=ret && *cptr==i; }
+ else
+ {
+ std::ostringstream oss; oss << "DataArrayInt::checkAllIdsInRange : tuple #" << i << " has value " << *cptr << " should be in [" << vmin << "," << vmax << ") !";
+ throw INTERP_KERNEL::Exception(oss.str().c_str());
+ }
+ }
+ return ret;
+}
+
/*!
* Modify all elements of \a this array, so that
* an element _x_ becomes <em> val % x </em>.
* "MEDCouplingUMesh::buildDescendingConnectivity" and
* \ref ParaMEDMEM::MEDCouplingUMesh::getNodalConnectivityIndex
* "MEDCouplingUMesh::getNodalConnectivityIndex" etc.
+ * This method preforms the reverse operation of DataArrayInt::computeOffsets2.
* \return DataArrayInt * - a new instance of DataArrayInt, whose number of tuples
* equals to \a this->getNumberOfComponents() - 1, and number of components is 1.
* The caller is to delete this array using decrRef() as it is no more needed.
* - this contains [1,3,6,7,7,9,15]
* - result array contains [2,3,1,0,2,6],
* where 2 = 3 - 1, 3 = 6 - 3, 1 = 7 - 6 etc.
+ *
+ * \sa DataArrayInt::computeOffsets2
*/
DataArrayInt *DataArrayInt::deltaShiftIndex() const throw(INTERP_KERNEL::Exception)
{
* components remains the same and number of tuples is inceamented by one.<br>
* This method is useful for allToAllV in MPI with contiguous policy. This method
* differs from computeOffsets() in that the number of tuples is changed by this one.
+ * This method preforms the reverse operation of DataArrayInt::deltaShiftIndex.
* \throw If \a this is not allocated.
* \throw If \a this->getNumberOfComponents() != 1.
*
* \b Example: <br>
* - Before \a this contains [3,5,1,2,0,8]
* - After \a this contains [0,3,8,9,11,11,19]<br>
+ * \sa DataArrayInt::deltaShiftIndex
*/
void DataArrayInt::computeOffsets2() throw(INTERP_KERNEL::Exception)
{