From ebe114cf3c5c12b1fe09605583a8da7404fbb8ad Mon Sep 17 00:00:00 2001 From: Anthony Geay Date: Wed, 3 May 2017 08:13:46 +0200 Subject: [PATCH] Factorization is on ! --- src/MEDCoupling/MEDCouplingMemArray.cxx | 825 +----------------- src/MEDCoupling/MEDCouplingMemArray.hxx | 21 +- src/MEDCoupling/MEDCouplingMemArray.txx | 375 ++++++++ .../MEDCouplingBasicsTest5.py | 2 +- .../MEDCouplingDataArrayTypemaps.i | 1 - src/MEDCoupling_Swig/MEDCouplingRemapper.i | 3 + src/MEDLoader/Swig/MEDLoader.i | 3 + src/RENUMBER_Swig/MEDRenumber.i | 3 + 8 files changed, 428 insertions(+), 805 deletions(-) diff --git a/src/MEDCoupling/MEDCouplingMemArray.cxx b/src/MEDCoupling/MEDCouplingMemArray.cxx index 31c26f45d..a2eaa57e3 100644 --- a/src/MEDCoupling/MEDCouplingMemArray.cxx +++ b/src/MEDCoupling/MEDCouplingMemArray.cxx @@ -2771,46 +2771,6 @@ DataArrayDouble *DataArrayDouble::computeAbs() const return newArr; } -/*! - * Apply a linear function to a given component of \a this array, so that - * an array element (x) becomes \f$ a * x + b \f$. - * \param [in] a - the first coefficient of the function. - * \param [in] b - the second coefficient of the function. - * \param [in] compoId - the index of component to modify. - * \throw If \a this is not allocated, or \a compoId is not in [0,\c this->getNumberOfComponents() ). - */ -void DataArrayDouble::applyLin(double a, double b, int compoId) -{ - checkAllocated(); - double *ptr(getPointer()+compoId); - int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples()); - if(compoId<0 || compoId>=nbOfComp) - { - std::ostringstream oss; oss << "DataArrayDouble::applyLin : The compoId requested (" << compoId << ") is not valid ! Must be in [0," << nbOfComp << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - for(int i=0;ialloc(nbOfTuples,nbOfComp); - const double *cptr=getConstPointer(); - std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate()); - newArr->copyStringInfoFrom(*this); - return newArr; -} - /*! * Modify all elements of \a this array, so that * an element _x_ becomes val ^ x . Contrary to DataArrayInt::applyPow @@ -3839,86 +3778,6 @@ void DataArrayDouble::addEqual(const DataArrayDouble *other) declareAsNew(); } -/*! - * Returns a new DataArrayDouble that is a subtraction of two given arrays. There are 3 - * valid cases. - * 1. The arrays have same number of tuples and components. Then each value of - * the result array (_a_) is a subtraction of the corresponding values of \a a1 and - * \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ]. - * 2. The arrays have same number of tuples and one array, say _a2_, has one - * component. Then - * _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ]. - * 3. The arrays have same number of components and one array, say _a2_, has one - * tuple. Then - * _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ]. - * - * Info on components is copied either from the first array (in the first case) or from - * the array with maximal number of elements (getNbOfElems()). - * \param [in] a1 - an array to subtract from. - * \param [in] a2 - an array to subtract. - * \return DataArrayDouble * - the new instance of DataArrayDouble. - * The caller is to delete this result array using decrRef() as it is no more - * needed. - * \throw If either \a a1 or \a a2 is NULL. - * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and - * \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and - * none of them has number of tuples or components equal to 1. - */ -DataArrayDouble *DataArrayDouble::Substract(const DataArrayDouble *a1, const DataArrayDouble *a2) -{ - if(!a1 || !a2) - throw INTERP_KERNEL::Exception("DataArrayDouble::Substract : input DataArrayDouble instance is NULL !"); - int nbOfTuple1=a1->getNumberOfTuples(); - int nbOfTuple2=a2->getNumberOfTuples(); - int nbOfComp1=a1->getNumberOfComponents(); - int nbOfComp2=a2->getNumberOfComponents(); - if(nbOfTuple2==nbOfTuple1) - { - if(nbOfComp1==nbOfComp2) - { - MCAuto ret=DataArrayDouble::New(); - ret->alloc(nbOfTuple2,nbOfComp1); - std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus()); - ret->copyStringInfoFrom(*a1); - return ret.retn(); - } - else if(nbOfComp2==1) - { - MCAuto ret=DataArrayDouble::New(); - ret->alloc(nbOfTuple1,nbOfComp1); - const double *a2Ptr=a2->getConstPointer(); - const double *a1Ptr=a1->getConstPointer(); - double *res=ret->getPointer(); - for(int i=0;i(),a2Ptr[i])); - ret->copyStringInfoFrom(*a1); - return ret.retn(); - } - else - { - a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !"); - return 0; - } - } - else if(nbOfTuple2==1) - { - a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !"); - MCAuto ret=DataArrayDouble::New(); - ret->alloc(nbOfTuple1,nbOfComp1); - const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer(); - double *pt=ret->getPointer(); - for(int i=0;i()); - ret->copyStringInfoFrom(*a1); - return ret.retn(); - } - else - { - a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception - return 0; - } -} - /*! * Subtract values of another DataArrayDouble from values of \a this one. There are 3 * valid cases. @@ -3981,122 +3840,28 @@ void DataArrayDouble::substractEqual(const DataArrayDouble *other) } /*! - * Returns a new DataArrayDouble that is a product of two given arrays. There are 3 - * valid cases. - * 1. The arrays have same number of tuples and components. Then each value of - * the result array (_a_) is a product of the corresponding values of \a a1 and - * \a a2, i.e. _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ]. - * 2. The arrays have same number of tuples and one array, say _a2_, has one - * component. Then - * _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ]. - * 3. The arrays have same number of components and one array, say _a2_, has one - * tuple. Then - * _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ]. - * - * Info on components is copied either from the first array (in the first case) or from - * the array with maximal number of elements (getNbOfElems()). - * \param [in] a1 - a factor array. - * \param [in] a2 - another factor array. - * \return DataArrayDouble * - the new instance of DataArrayDouble. - * The caller is to delete this result array using decrRef() as it is no more - * needed. - * \throw If either \a a1 or \a a2 is NULL. - * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and - * \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and - * none of them has number of tuples or components equal to 1. - */ -DataArrayDouble *DataArrayDouble::Multiply(const DataArrayDouble *a1, const DataArrayDouble *a2) -{ - if(!a1 || !a2) - throw INTERP_KERNEL::Exception("DataArrayDouble::Multiply : input DataArrayDouble instance is NULL !"); - int nbOfTuple=a1->getNumberOfTuples(); - int nbOfTuple2=a2->getNumberOfTuples(); - int nbOfComp=a1->getNumberOfComponents(); - int nbOfComp2=a2->getNumberOfComponents(); - MCAuto ret=0; - if(nbOfTuple==nbOfTuple2) - { - if(nbOfComp==nbOfComp2) - { - ret=DataArrayDouble::New(); - ret->alloc(nbOfTuple,nbOfComp); - std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies()); - ret->copyStringInfoFrom(*a1); - } - else - { - int nbOfCompMin,nbOfCompMax; - const DataArrayDouble *aMin, *aMax; - if(nbOfComp>nbOfComp2) - { - nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp; - aMin=a2; aMax=a1; - } - else - { - nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2; - aMin=a1; aMax=a2; - } - if(nbOfCompMin==1) - { - ret=DataArrayDouble::New(); - ret->alloc(nbOfTuple,nbOfCompMax); - const double *aMinPtr=aMin->getConstPointer(); - const double *aMaxPtr=aMax->getConstPointer(); - double *res=ret->getPointer(); - for(int i=0;i(),aMinPtr[i])); - ret->copyStringInfoFrom(*aMax); - } - else - throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !"); - } - } - else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1)) - { - if(nbOfComp==nbOfComp2) - { - int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2); - const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1; - const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2; - const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer(); - ret=DataArrayDouble::New(); - ret->alloc(nbOfTupleMax,nbOfComp); - double *res=ret->getPointer(); - for(int i=0;i()); - ret->copyStringInfoFrom(*aMax); - } - else - throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !"); - } - else - throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !"); - return ret.retn(); -} - -/*! - * Multiply values of another DataArrayDouble to values of \a this one. There are 3 + * Divide values of \a this array by values of another DataArrayDouble. There are 3 * valid cases. * 1. The arrays have same number of tuples and components. Then each value of - * \a other array is multiplied to the corresponding value of \a this array, i.e. - * _this_ [ i, j ] *= _other_ [ i, j ]. + * \a this array is divided by the corresponding value of \a other one, i.e.: + * _a_ [ i, j ] /= _other_ [ i, j ]. * 2. The arrays have same number of tuples and \a other array has one component. Then - * _this_ [ i, j ] *= _other_ [ i, 0 ]. + * _a_ [ i, j ] /= _other_ [ i, 0 ]. * 3. The arrays have same number of components and \a other array has one tuple. Then - * _this_ [ i, j ] *= _a2_ [ 0, j ]. + * _a_ [ i, j ] /= _a2_ [ 0, j ]. * - * \param [in] other - an array to multiply to \a this one. + * \warning No check of division by zero is performed! + * \param [in] other - an array to divide \a this one by. * \throw If \a other is NULL. * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and * \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and * \a other has number of both tuples and components not equal to 1. */ -void DataArrayDouble::multiplyEqual(const DataArrayDouble *other) +void DataArrayDouble::divideEqual(const DataArrayDouble *other) { if(!other) - throw INTERP_KERNEL::Exception("DataArrayDouble::multiplyEqual : input DataArrayDouble instance is NULL !"); - const char *msg="Nb of tuples mismatch for DataArrayDouble::multiplyEqual !"; + throw INTERP_KERNEL::Exception("DataArrayDouble::divideEqual : input DataArrayDouble instance is NULL !"); + const char *msg="Nb of tuples mismatch for DataArrayDouble::divideEqual !"; checkAllocated(); other->checkAllocated(); int nbOfTuple=getNumberOfTuples(); @@ -4107,14 +3872,14 @@ void DataArrayDouble::multiplyEqual(const DataArrayDouble *other) { if(nbOfComp==nbOfComp2) { - std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies()); + std::transform(begin(),end(),other->begin(),getPointer(),std::divides()); } else if(nbOfComp2==1) { double *ptr=getPointer(); const double *ptrc=other->getConstPointer(); for(int i=0;i(),*ptrc++)); + std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides(),*ptrc++)); } else throw INTERP_KERNEL::Exception(msg); @@ -4126,7 +3891,7 @@ void DataArrayDouble::multiplyEqual(const DataArrayDouble *other) double *ptr=getPointer(); const double *ptrc=other->getConstPointer(); for(int i=0;i()); + std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides()); } else throw INTERP_KERNEL::Exception(msg); @@ -4137,190 +3902,47 @@ void DataArrayDouble::multiplyEqual(const DataArrayDouble *other) } /*! - * Returns a new DataArrayDouble that is a division of two given arrays. There are 3 + * Returns a new DataArrayDouble that is the result of pow of two given arrays. There are 3 * valid cases. - * 1. The arrays have same number of tuples and components. Then each value of - * the result array (_a_) is a division of the corresponding values of \a a1 and - * \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ]. - * 2. The arrays have same number of tuples and one array, say _a2_, has one - * component. Then - * _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ]. - * 3. The arrays have same number of components and one array, say _a2_, has one - * tuple. Then - * _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ]. * - * Info on components is copied either from the first array (in the first case) or from - * the array with maximal number of elements (getNbOfElems()). - * \warning No check of division by zero is performed! - * \param [in] a1 - a numerator array. - * \param [in] a2 - a denominator array. + * \param [in] a1 - an array to pow up. + * \param [in] a2 - another array to sum up. * \return DataArrayDouble * - the new instance of DataArrayDouble. * The caller is to delete this result array using decrRef() as it is no more * needed. * \throw If either \a a1 or \a a2 is NULL. - * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and - * \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and - * none of them has number of tuples or components equal to 1. + * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() + * \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1. + * \throw If there is a negative value in \a a1. */ -DataArrayDouble *DataArrayDouble::Divide(const DataArrayDouble *a1, const DataArrayDouble *a2) +DataArrayDouble *DataArrayDouble::Pow(const DataArrayDouble *a1, const DataArrayDouble *a2) { if(!a1 || !a2) - throw INTERP_KERNEL::Exception("DataArrayDouble::Divide : input DataArrayDouble instance is NULL !"); - int nbOfTuple1=a1->getNumberOfTuples(); + throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : at least one of input instances is null !"); + int nbOfTuple=a1->getNumberOfTuples(); int nbOfTuple2=a2->getNumberOfTuples(); - int nbOfComp1=a1->getNumberOfComponents(); + int nbOfComp=a1->getNumberOfComponents(); int nbOfComp2=a2->getNumberOfComponents(); - if(nbOfTuple2==nbOfTuple1) + if(nbOfTuple!=nbOfTuple2) + throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of tuples mismatches !"); + if(nbOfComp!=1 || nbOfComp2!=1) + throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of components of both arrays must be equal to 1 !"); + MCAuto ret=DataArrayDouble::New(); ret->alloc(nbOfTuple,1); + const double *ptr1(a1->begin()),*ptr2(a2->begin()); + double *ptr=ret->getPointer(); + for(int i=0;i ret=DataArrayDouble::New(); - ret->alloc(nbOfTuple2,nbOfComp1); - std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides()); - ret->copyStringInfoFrom(*a1); - return ret.retn(); - } - else if(nbOfComp2==1) + if(*ptr1>=0) { - MCAuto ret=DataArrayDouble::New(); - ret->alloc(nbOfTuple1,nbOfComp1); - const double *a2Ptr=a2->getConstPointer(); - const double *a1Ptr=a1->getConstPointer(); - double *res=ret->getPointer(); - for(int i=0;i(),a2Ptr[i])); - ret->copyStringInfoFrom(*a1); - return ret.retn(); + *ptr=pow(*ptr1,*ptr2); } else { - a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !"); - return 0; + std::ostringstream oss; oss << "DataArrayDouble::Pow : on tuple #" << i << " of a1 value is < 0 (" << *ptr1 << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); } } - else if(nbOfTuple2==1) - { - a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !"); - MCAuto ret=DataArrayDouble::New(); - ret->alloc(nbOfTuple1,nbOfComp1); - const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer(); - double *pt=ret->getPointer(); - for(int i=0;i()); - ret->copyStringInfoFrom(*a1); - return ret.retn(); - } - else - { - a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception - return 0; - } -} - -/*! - * Divide values of \a this array by values of another DataArrayDouble. There are 3 - * valid cases. - * 1. The arrays have same number of tuples and components. Then each value of - * \a this array is divided by the corresponding value of \a other one, i.e.: - * _a_ [ i, j ] /= _other_ [ i, j ]. - * 2. The arrays have same number of tuples and \a other array has one component. Then - * _a_ [ i, j ] /= _other_ [ i, 0 ]. - * 3. The arrays have same number of components and \a other array has one tuple. Then - * _a_ [ i, j ] /= _a2_ [ 0, j ]. - * - * \warning No check of division by zero is performed! - * \param [in] other - an array to divide \a this one by. - * \throw If \a other is NULL. - * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and - * \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and - * \a other has number of both tuples and components not equal to 1. - */ -void DataArrayDouble::divideEqual(const DataArrayDouble *other) -{ - if(!other) - throw INTERP_KERNEL::Exception("DataArrayDouble::divideEqual : input DataArrayDouble instance is NULL !"); - const char *msg="Nb of tuples mismatch for DataArrayDouble::divideEqual !"; - checkAllocated(); - other->checkAllocated(); - int nbOfTuple=getNumberOfTuples(); - int nbOfTuple2=other->getNumberOfTuples(); - int nbOfComp=getNumberOfComponents(); - int nbOfComp2=other->getNumberOfComponents(); - if(nbOfTuple==nbOfTuple2) - { - if(nbOfComp==nbOfComp2) - { - std::transform(begin(),end(),other->begin(),getPointer(),std::divides()); - } - else if(nbOfComp2==1) - { - double *ptr=getPointer(); - const double *ptrc=other->getConstPointer(); - for(int i=0;i(),*ptrc++)); - } - else - throw INTERP_KERNEL::Exception(msg); - } - else if(nbOfTuple2==1) - { - if(nbOfComp2==nbOfComp) - { - double *ptr=getPointer(); - const double *ptrc=other->getConstPointer(); - for(int i=0;i()); - } - else - throw INTERP_KERNEL::Exception(msg); - } - else - throw INTERP_KERNEL::Exception(msg); - declareAsNew(); -} - -/*! - * Returns a new DataArrayDouble that is the result of pow of two given arrays. There are 3 - * valid cases. - * - * \param [in] a1 - an array to pow up. - * \param [in] a2 - another array to sum up. - * \return DataArrayDouble * - the new instance of DataArrayDouble. - * The caller is to delete this result array using decrRef() as it is no more - * needed. - * \throw If either \a a1 or \a a2 is NULL. - * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() - * \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1. - * \throw If there is a negative value in \a a1. - */ -DataArrayDouble *DataArrayDouble::Pow(const DataArrayDouble *a1, const DataArrayDouble *a2) -{ - if(!a1 || !a2) - throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : at least one of input instances is null !"); - int nbOfTuple=a1->getNumberOfTuples(); - int nbOfTuple2=a2->getNumberOfTuples(); - int nbOfComp=a1->getNumberOfComponents(); - int nbOfComp2=a2->getNumberOfComponents(); - if(nbOfTuple!=nbOfTuple2) - throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of tuples mismatches !"); - if(nbOfComp!=1 || nbOfComp2!=1) - throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of components of both arrays must be equal to 1 !"); - MCAuto ret=DataArrayDouble::New(); ret->alloc(nbOfTuple,1); - const double *ptr1(a1->begin()),*ptr2(a2->begin()); - double *ptr=ret->getPointer(); - for(int i=0;i=0) - { - *ptr=pow(*ptr1,*ptr2); - } - else - { - std::ostringstream oss; oss << "DataArrayDouble::Pow : on tuple #" << i << " of a1 value is < 0 (" << *ptr1 << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - return ret.retn(); + return ret.retn(); } /*! @@ -6670,63 +6292,6 @@ DataArrayInt *DataArrayInt::computeAbs() const return newArr; } -/*! - * Apply a liner function to a given component of \a this array, so that - * an array element (x) becomes \f$ a * x + b \f$. - * \param [in] a - the first coefficient of the function. - * \param [in] b - the second coefficient of the function. - * \param [in] compoId - the index of component to modify. - * \throw If \a this is not allocated. - */ -void DataArrayInt::applyLin(int a, int b, int compoId) -{ - checkAllocated(); - int *ptr=getPointer()+compoId; - int nbOfComp=getNumberOfComponents(); - int nbOfTuple=getNumberOfTuples(); - for(int i=0;ialloc(nbOfTuples,nbOfComp); - const int *cptr=getConstPointer(); - std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate()); - newArr->copyStringInfoFrom(*this); - return newArr; -} - /*! * Modify all elements of \a this array, so that * an element _x_ becomes \f$ numerator / x \f$. @@ -8293,86 +7858,6 @@ void DataArrayInt::addEqual(const DataArrayInt *other) declareAsNew(); } -/*! - * Returns a new DataArrayInt that is a subtraction of two given arrays. There are 3 - * valid cases. - * 1. The arrays have same number of tuples and components. Then each value of - * the result array (_a_) is a subtraction of the corresponding values of \a a1 and - * \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ]. - * 2. The arrays have same number of tuples and one array, say _a2_, has one - * component. Then - * _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ]. - * 3. The arrays have same number of components and one array, say _a2_, has one - * tuple. Then - * _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ]. - * - * Info on components is copied either from the first array (in the first case) or from - * the array with maximal number of elements (getNbOfElems()). - * \param [in] a1 - an array to subtract from. - * \param [in] a2 - an array to subtract. - * \return DataArrayInt * - the new instance of DataArrayInt. - * The caller is to delete this result array using decrRef() as it is no more - * needed. - * \throw If either \a a1 or \a a2 is NULL. - * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and - * \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and - * none of them has number of tuples or components equal to 1. - */ -DataArrayInt *DataArrayInt::Substract(const DataArrayInt *a1, const DataArrayInt *a2) -{ - if(!a1 || !a2) - throw INTERP_KERNEL::Exception("DataArrayInt::Substract : input DataArrayInt instance is NULL !"); - int nbOfTuple1=a1->getNumberOfTuples(); - int nbOfTuple2=a2->getNumberOfTuples(); - int nbOfComp1=a1->getNumberOfComponents(); - int nbOfComp2=a2->getNumberOfComponents(); - if(nbOfTuple2==nbOfTuple1) - { - if(nbOfComp1==nbOfComp2) - { - MCAuto ret=DataArrayInt::New(); - ret->alloc(nbOfTuple2,nbOfComp1); - std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus()); - ret->copyStringInfoFrom(*a1); - return ret.retn(); - } - else if(nbOfComp2==1) - { - MCAuto ret=DataArrayInt::New(); - ret->alloc(nbOfTuple1,nbOfComp1); - const int *a2Ptr=a2->getConstPointer(); - const int *a1Ptr=a1->getConstPointer(); - int *res=ret->getPointer(); - for(int i=0;i(),a2Ptr[i])); - ret->copyStringInfoFrom(*a1); - return ret.retn(); - } - else - { - a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !"); - return 0; - } - } - else if(nbOfTuple2==1) - { - a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !"); - MCAuto ret=DataArrayInt::New(); - ret->alloc(nbOfTuple1,nbOfComp1); - const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer(); - int *pt=ret->getPointer(); - for(int i=0;i()); - ret->copyStringInfoFrom(*a1); - return ret.retn(); - } - else - { - a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception - return 0; - } -} - /*! * Subtract values of another DataArrayInt from values of \a this one. There are 3 * valid cases. @@ -8428,244 +7913,6 @@ void DataArrayInt::substractEqual(const DataArrayInt *other) declareAsNew(); } -/*! - * Returns a new DataArrayInt that is a product of two given arrays. There are 3 - * valid cases. - * 1. The arrays have same number of tuples and components. Then each value of - * the result array (_a_) is a product of the corresponding values of \a a1 and - * \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ]. - * 2. The arrays have same number of tuples and one array, say _a2_, has one - * component. Then - * _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ]. - * 3. The arrays have same number of components and one array, say _a2_, has one - * tuple. Then - * _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ]. - * - * Info on components is copied either from the first array (in the first case) or from - * the array with maximal number of elements (getNbOfElems()). - * \param [in] a1 - a factor array. - * \param [in] a2 - another factor array. - * \return DataArrayInt * - the new instance of DataArrayInt. - * The caller is to delete this result array using decrRef() as it is no more - * needed. - * \throw If either \a a1 or \a a2 is NULL. - * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and - * \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and - * none of them has number of tuples or components equal to 1. - */ -DataArrayInt *DataArrayInt::Multiply(const DataArrayInt *a1, const DataArrayInt *a2) -{ - if(!a1 || !a2) - throw INTERP_KERNEL::Exception("DataArrayInt::Multiply : input DataArrayInt instance is NULL !"); - int nbOfTuple=a1->getNumberOfTuples(); - int nbOfTuple2=a2->getNumberOfTuples(); - int nbOfComp=a1->getNumberOfComponents(); - int nbOfComp2=a2->getNumberOfComponents(); - MCAuto ret=0; - if(nbOfTuple==nbOfTuple2) - { - if(nbOfComp==nbOfComp2) - { - ret=DataArrayInt::New(); - ret->alloc(nbOfTuple,nbOfComp); - std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies()); - ret->copyStringInfoFrom(*a1); - } - else - { - int nbOfCompMin,nbOfCompMax; - const DataArrayInt *aMin, *aMax; - if(nbOfComp>nbOfComp2) - { - nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp; - aMin=a2; aMax=a1; - } - else - { - nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2; - aMin=a1; aMax=a2; - } - if(nbOfCompMin==1) - { - ret=DataArrayInt::New(); - ret->alloc(nbOfTuple,nbOfCompMax); - const int *aMinPtr=aMin->getConstPointer(); - const int *aMaxPtr=aMax->getConstPointer(); - int *res=ret->getPointer(); - for(int i=0;i(),aMinPtr[i])); - ret->copyStringInfoFrom(*aMax); - } - else - throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !"); - } - } - else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1)) - { - if(nbOfComp==nbOfComp2) - { - int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2); - const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1; - const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2; - const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer(); - ret=DataArrayInt::New(); - ret->alloc(nbOfTupleMax,nbOfComp); - int *res=ret->getPointer(); - for(int i=0;i()); - ret->copyStringInfoFrom(*aMax); - } - else - throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !"); - } - else - throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !"); - return ret.retn(); -} - - -/*! - * Multiply values of another DataArrayInt to values of \a this one. There are 3 - * valid cases. - * 1. The arrays have same number of tuples and components. Then each value of - * \a other array is multiplied to the corresponding value of \a this array, i.e.: - * _a_ [ i, j ] *= _other_ [ i, j ]. - * 2. The arrays have same number of tuples and \a other array has one component. Then - * _a_ [ i, j ] *= _other_ [ i, 0 ]. - * 3. The arrays have same number of components and \a other array has one tuple. Then - * _a_ [ i, j ] *= _a2_ [ 0, j ]. - * - * \param [in] other - an array to multiply to \a this one. - * \throw If \a other is NULL. - * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and - * \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and - * \a other has number of both tuples and components not equal to 1. - */ -void DataArrayInt::multiplyEqual(const DataArrayInt *other) -{ - if(!other) - throw INTERP_KERNEL::Exception("DataArrayInt::multiplyEqual : input DataArrayInt instance is NULL !"); - const char *msg="Nb of tuples mismatch for DataArrayInt::multiplyEqual !"; - checkAllocated(); other->checkAllocated(); - int nbOfTuple=getNumberOfTuples(); - int nbOfTuple2=other->getNumberOfTuples(); - int nbOfComp=getNumberOfComponents(); - int nbOfComp2=other->getNumberOfComponents(); - if(nbOfTuple==nbOfTuple2) - { - if(nbOfComp==nbOfComp2) - { - std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies()); - } - else if(nbOfComp2==1) - { - int *ptr=getPointer(); - const int *ptrc=other->getConstPointer(); - for(int i=0;i(),*ptrc++)); - } - else - throw INTERP_KERNEL::Exception(msg); - } - else if(nbOfTuple2==1) - { - if(nbOfComp2==nbOfComp) - { - int *ptr=getPointer(); - const int *ptrc=other->getConstPointer(); - for(int i=0;i()); - } - else - throw INTERP_KERNEL::Exception(msg); - } - else - throw INTERP_KERNEL::Exception(msg); - declareAsNew(); -} - - -/*! - * Returns a new DataArrayInt that is a division of two given arrays. There are 3 - * valid cases. - * 1. The arrays have same number of tuples and components. Then each value of - * the result array (_a_) is a division of the corresponding values of \a a1 and - * \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ]. - * 2. The arrays have same number of tuples and one array, say _a2_, has one - * component. Then - * _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ]. - * 3. The arrays have same number of components and one array, say _a2_, has one - * tuple. Then - * _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ]. - * - * Info on components is copied either from the first array (in the first case) or from - * the array with maximal number of elements (getNbOfElems()). - * \warning No check of division by zero is performed! - * \param [in] a1 - a numerator array. - * \param [in] a2 - a denominator array. - * \return DataArrayInt * - the new instance of DataArrayInt. - * The caller is to delete this result array using decrRef() as it is no more - * needed. - * \throw If either \a a1 or \a a2 is NULL. - * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and - * \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and - * none of them has number of tuples or components equal to 1. - */ -DataArrayInt *DataArrayInt::Divide(const DataArrayInt *a1, const DataArrayInt *a2) -{ - if(!a1 || !a2) - throw INTERP_KERNEL::Exception("DataArrayInt::Divide : input DataArrayInt instance is NULL !"); - int nbOfTuple1=a1->getNumberOfTuples(); - int nbOfTuple2=a2->getNumberOfTuples(); - int nbOfComp1=a1->getNumberOfComponents(); - int nbOfComp2=a2->getNumberOfComponents(); - if(nbOfTuple2==nbOfTuple1) - { - if(nbOfComp1==nbOfComp2) - { - MCAuto ret=DataArrayInt::New(); - ret->alloc(nbOfTuple2,nbOfComp1); - std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides()); - ret->copyStringInfoFrom(*a1); - return ret.retn(); - } - else if(nbOfComp2==1) - { - MCAuto ret=DataArrayInt::New(); - ret->alloc(nbOfTuple1,nbOfComp1); - const int *a2Ptr=a2->getConstPointer(); - const int *a1Ptr=a1->getConstPointer(); - int *res=ret->getPointer(); - for(int i=0;i(),a2Ptr[i])); - ret->copyStringInfoFrom(*a1); - return ret.retn(); - } - else - { - a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !"); - return 0; - } - } - else if(nbOfTuple2==1) - { - a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !"); - MCAuto ret=DataArrayInt::New(); - ret->alloc(nbOfTuple1,nbOfComp1); - const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer(); - int *pt=ret->getPointer(); - for(int i=0;i()); - ret->copyStringInfoFrom(*a1); - return ret.retn(); - } - else - { - a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception - return 0; - } -} - /*! * Divide values of \a this array by values of another DataArrayInt. There are 3 * valid cases. diff --git a/src/MEDCoupling/MEDCouplingMemArray.hxx b/src/MEDCoupling/MEDCouplingMemArray.hxx index 343859c42..a3aac9bfc 100644 --- a/src/MEDCoupling/MEDCouplingMemArray.hxx +++ b/src/MEDCoupling/MEDCouplingMemArray.hxx @@ -304,6 +304,13 @@ namespace MEDCoupling MEDCOUPLING_EXPORT MCAuto convertToDblArr() const; MEDCOUPLING_EXPORT MCAuto convertToIntArr() const; MEDCOUPLING_EXPORT MCAuto convertToFloatArr() const; + MEDCOUPLING_EXPORT void applyLin(T a, T b, int compoId); + MEDCOUPLING_EXPORT void applyLin(T a, T b); + MEDCOUPLING_EXPORT typename Traits::ArrayType *negate() const; + MEDCOUPLING_EXPORT void multiplyEqual(const typename Traits::ArrayType *other); + MEDCOUPLING_EXPORT static typename Traits::ArrayType *Substract(const typename Traits::ArrayType *a1, const typename Traits::ArrayType *a2); + MEDCOUPLING_EXPORT static typename Traits::ArrayType *Divide(const typename Traits::ArrayType *a1, const typename Traits::ArrayType *a2); + MEDCOUPLING_EXPORT static typename Traits::ArrayType *Multiply(const typename Traits::ArrayType *a1, const typename Traits::ArrayType *a2); protected: static typename Traits::ArrayType *PerformCopyOrIncrRef(bool dCpy, const typename Traits::ArrayType& self); private: @@ -452,12 +459,9 @@ namespace MEDCoupling MEDCOUPLING_EXPORT void sortPerTuple(bool asc); MEDCOUPLING_EXPORT void abs(); MEDCOUPLING_EXPORT DataArrayDouble *computeAbs() const; - MEDCOUPLING_EXPORT void applyLin(double a, double b, int compoId); - MEDCOUPLING_EXPORT void applyLin(double a, double b); MEDCOUPLING_EXPORT void applyInv(double numerator); MEDCOUPLING_EXPORT void applyPow(double val); MEDCOUPLING_EXPORT void applyRPow(double val); - MEDCOUPLING_EXPORT DataArrayDouble *negate() const; MEDCOUPLING_EXPORT DataArrayDouble *applyFunc(int nbOfComp, FunctionToEvaluate func) const; MEDCOUPLING_EXPORT DataArrayDouble *applyFunc(int nbOfComp, const std::string& func, bool isSafe=true) const; MEDCOUPLING_EXPORT DataArrayDouble *applyFunc(const std::string& func, bool isSafe=true) const; @@ -479,11 +483,7 @@ namespace MEDCoupling MEDCOUPLING_EXPORT static DataArrayDouble *Min(const DataArrayDouble *a1, const DataArrayDouble *a2); MEDCOUPLING_EXPORT static DataArrayDouble *Add(const DataArrayDouble *a1, const DataArrayDouble *a2); MEDCOUPLING_EXPORT void addEqual(const DataArrayDouble *other); - MEDCOUPLING_EXPORT static DataArrayDouble *Substract(const DataArrayDouble *a1, const DataArrayDouble *a2); MEDCOUPLING_EXPORT void substractEqual(const DataArrayDouble *other); - MEDCOUPLING_EXPORT static DataArrayDouble *Multiply(const DataArrayDouble *a1, const DataArrayDouble *a2); - MEDCOUPLING_EXPORT void multiplyEqual(const DataArrayDouble *other); - MEDCOUPLING_EXPORT static DataArrayDouble *Divide(const DataArrayDouble *a1, const DataArrayDouble *a2); MEDCOUPLING_EXPORT void divideEqual(const DataArrayDouble *other); MEDCOUPLING_EXPORT static DataArrayDouble *Pow(const DataArrayDouble *a1, const DataArrayDouble *a2); MEDCOUPLING_EXPORT void powEqual(const DataArrayDouble *other); @@ -599,10 +599,7 @@ namespace MEDCoupling MEDCOUPLING_EXPORT void getMinMaxValues(int& minValue, int& maxValue) const; MEDCOUPLING_EXPORT void abs(); MEDCOUPLING_EXPORT DataArrayInt *computeAbs() const; - MEDCOUPLING_EXPORT void applyLin(int a, int b, int compoId); - MEDCOUPLING_EXPORT void applyLin(int a, int b); MEDCOUPLING_EXPORT void applyInv(int numerator); - MEDCOUPLING_EXPORT DataArrayInt *negate() const; MEDCOUPLING_EXPORT void applyDivideBy(int val); MEDCOUPLING_EXPORT void applyModulus(int val); MEDCOUPLING_EXPORT void applyRModulus(int val); @@ -654,11 +651,7 @@ namespace MEDCoupling MEDCOUPLING_EXPORT void writeOnPlace(std::size_t id, int element0, const int *others, int sizeOfOthers) { _mem.writeOnPlace(id,element0,others,sizeOfOthers); } MEDCOUPLING_EXPORT static DataArrayInt *Add(const DataArrayInt *a1, const DataArrayInt *a2); MEDCOUPLING_EXPORT void addEqual(const DataArrayInt *other); - MEDCOUPLING_EXPORT static DataArrayInt *Substract(const DataArrayInt *a1, const DataArrayInt *a2); MEDCOUPLING_EXPORT void substractEqual(const DataArrayInt *other); - MEDCOUPLING_EXPORT static DataArrayInt *Multiply(const DataArrayInt *a1, const DataArrayInt *a2); - MEDCOUPLING_EXPORT void multiplyEqual(const DataArrayInt *other); - MEDCOUPLING_EXPORT static DataArrayInt *Divide(const DataArrayInt *a1, const DataArrayInt *a2); MEDCOUPLING_EXPORT void divideEqual(const DataArrayInt *other); MEDCOUPLING_EXPORT static DataArrayInt *Modulus(const DataArrayInt *a1, const DataArrayInt *a2); MEDCOUPLING_EXPORT void modulusEqual(const DataArrayInt *other); diff --git a/src/MEDCoupling/MEDCouplingMemArray.txx b/src/MEDCoupling/MEDCouplingMemArray.txx index 9e804bc6a..fdde67307 100644 --- a/src/MEDCoupling/MEDCouplingMemArray.txx +++ b/src/MEDCoupling/MEDCouplingMemArray.txx @@ -2373,6 +2373,381 @@ namespace MEDCoupling { return convertToOtherTypeOfArr(); } + + /*! + * Apply a linear function to a given component of \a this array, so that + * an array element (x) becomes \f$ a * x + b \f$. + * \param [in] a - the first coefficient of the function. + * \param [in] b - the second coefficient of the function. + * \param [in] compoId - the index of component to modify. + * \throw If \a this is not allocated, or \a compoId is not in [0,\c this->getNumberOfComponents() ). + */ + template + void DataArrayTemplateClassic::applyLin(T a, T b, int compoId) + { + this->checkAllocated(); + T *ptr(this->getPointer()+compoId); + int nbOfComp(this->getNumberOfComponents()),nbOfTuple(this->getNumberOfTuples()); + if(compoId<0 || compoId>=nbOfComp) + { + std::ostringstream oss; oss << "DataArrayDouble::applyLin : The compoId requested (" << compoId << ") is not valid ! Must be in [0," << nbOfComp << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + for(int i=0;ideclareAsNew(); + } + + /*! + * Apply a linear function to all elements of \a this array, so that + * an element _x_ becomes \f$ a * x + b \f$. + * \param [in] a - the first coefficient of the function. + * \param [in] b - the second coefficient of the function. + * \throw If \a this is not allocated. + */ + template + void DataArrayTemplateClassic::applyLin(T a, T b) + { + this->checkAllocated(); + T *ptr(this->getPointer()); + std::size_t nbOfElems(this->getNbOfElems()); + for(std::size_t i=0;ideclareAsNew(); + } + + /*! + * Returns a full copy of \a this array except that sign of all elements is reversed. + * \return DataArrayDouble * - the new instance of DataArrayDouble containing the + * same number of tuples and component as \a this array. + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * \throw If \a this is not allocated. + */ + template + typename Traits::ArrayType *DataArrayTemplateClassic::negate() const + { + this->checkAllocated(); + MCAuto::ArrayType> newArr(Traits::ArrayType::New()); + int nbOfTuples(this->getNumberOfTuples()),nbOfComp(this->getNumberOfComponents()); + newArr->alloc(nbOfTuples,nbOfComp); + const T *cptr(this->begin()); + std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate()); + newArr->copyStringInfoFrom(*this); + return newArr.retn(); + } + + /*! + * Multiply values of another DataArrayDouble to values of \a this one. There are 3 + * valid cases. + * 1. The arrays have same number of tuples and components. Then each value of + * \a other array is multiplied to the corresponding value of \a this array, i.e. + * _this_ [ i, j ] *= _other_ [ i, j ]. + * 2. The arrays have same number of tuples and \a other array has one component. Then + * _this_ [ i, j ] *= _other_ [ i, 0 ]. + * 3. The arrays have same number of components and \a other array has one tuple. Then + * _this_ [ i, j ] *= _a2_ [ 0, j ]. + * + * \param [in] other - an array to multiply to \a this one. + * \throw If \a other is NULL. + * \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and + * \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and + * \a other has number of both tuples and components not equal to 1. + */ + template + void DataArrayTemplateClassic::multiplyEqual(const typename Traits::ArrayType *other) + { + if(!other) + throw INTERP_KERNEL::Exception("DataArrayDouble::multiplyEqual : input DataArrayDouble instance is NULL !"); + const char *msg="Nb of tuples mismatch for DataArrayDouble::multiplyEqual !"; + this->checkAllocated(); + other->checkAllocated(); + int nbOfTuple(this->getNumberOfTuples()),nbOfTuple2(other->getNumberOfTuples()); + int nbOfComp(this->getNumberOfComponents()),nbOfComp2(other->getNumberOfComponents()); + if(nbOfTuple==nbOfTuple2) + { + if(nbOfComp==nbOfComp2) + { + std::transform(this->begin(),this->end(),other->begin(),this->getPointer(),std::multiplies()); + } + else if(nbOfComp2==1) + { + T *ptr(this->getPointer()); + const T *ptrc(other->begin()); + for(int i=0;i(),*ptrc++)); + } + else + throw INTERP_KERNEL::Exception(msg); + } + else if(nbOfTuple2==1) + { + if(nbOfComp2==nbOfComp) + { + T *ptr(this->getPointer()); + const T *ptrc(other->begin()); + for(int i=0;i()); + } + else + throw INTERP_KERNEL::Exception(msg); + } + else + throw INTERP_KERNEL::Exception(msg); + this->declareAsNew(); + } + + /*! + * Returns a new DataArrayDouble that is a subtraction of two given arrays. There are 3 + * valid cases. + * 1. The arrays have same number of tuples and components. Then each value of + * the result array (_a_) is a subtraction of the corresponding values of \a a1 and + * \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ]. + * 2. The arrays have same number of tuples and one array, say _a2_, has one + * component. Then + * _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ]. + * 3. The arrays have same number of components and one array, say _a2_, has one + * tuple. Then + * _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ]. + * + * Info on components is copied either from the first array (in the first case) or from + * the array with maximal number of elements (getNbOfElems()). + * \param [in] a1 - an array to subtract from. + * \param [in] a2 - an array to subtract. + * \return DataArrayDouble * - the new instance of DataArrayDouble. + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * \throw If either \a a1 or \a a2 is NULL. + * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and + * \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and + * none of them has number of tuples or components equal to 1. + */ + template + typename Traits::ArrayType *DataArrayTemplateClassic::Substract(const typename Traits::ArrayType *a1, const typename Traits::ArrayType *a2) + { + if(!a1 || !a2) + throw INTERP_KERNEL::Exception("DataArrayDouble::Substract : input DataArrayDouble instance is NULL !"); + int nbOfTuple1(a1->getNumberOfTuples()),nbOfTuple2(a2->getNumberOfTuples()); + int nbOfComp1(a1->getNumberOfComponents()),nbOfComp2(a2->getNumberOfComponents()); + if(nbOfTuple2==nbOfTuple1) + { + if(nbOfComp1==nbOfComp2) + { + MCAuto::ArrayType> ret(Traits::ArrayType::New()); + ret->alloc(nbOfTuple2,nbOfComp1); + std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus()); + ret->copyStringInfoFrom(*a1); + return ret.retn(); + } + else if(nbOfComp2==1) + { + MCAuto::ArrayType> ret(Traits::ArrayType::New()); + ret->alloc(nbOfTuple1,nbOfComp1); + const T *a2Ptr(a2->begin()); + const T *a1Ptr(a1->begin()); + T *res(ret->getPointer()); + for(int i=0;i(),a2Ptr[i])); + ret->copyStringInfoFrom(*a1); + return ret.retn(); + } + else + { + a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !"); + return 0; + } + } + else if(nbOfTuple2==1) + { + a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !"); + MCAuto::ArrayType> ret(Traits::ArrayType::New()); + ret->alloc(nbOfTuple1,nbOfComp1); + const T *a1ptr(a1->begin()),*a2ptr(a2->begin()); + T *pt(ret->getPointer()); + for(int i=0;i()); + ret->copyStringInfoFrom(*a1); + return ret.retn(); + } + else + { + a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception + return 0; + } + } + + /*! + * Returns a new DataArrayDouble that is a division of two given arrays. There are 3 + * valid cases. + * 1. The arrays have same number of tuples and components. Then each value of + * the result array (_a_) is a division of the corresponding values of \a a1 and + * \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ]. + * 2. The arrays have same number of tuples and one array, say _a2_, has one + * component. Then + * _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ]. + * 3. The arrays have same number of components and one array, say _a2_, has one + * tuple. Then + * _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ]. + * + * Info on components is copied either from the first array (in the first case) or from + * the array with maximal number of elements (getNbOfElems()). + * \warning No check of division by zero is performed! + * \param [in] a1 - a numerator array. + * \param [in] a2 - a denominator array. + * \return DataArrayDouble * - the new instance of DataArrayDouble. + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * \throw If either \a a1 or \a a2 is NULL. + * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and + * \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and + * none of them has number of tuples or components equal to 1. + */ + template + typename Traits::ArrayType *DataArrayTemplateClassic::Divide(const typename Traits::ArrayType *a1, const typename Traits::ArrayType *a2) + { + if(!a1 || !a2) + throw INTERP_KERNEL::Exception("DataArrayDouble::Divide : input DataArrayDouble instance is NULL !"); + int nbOfTuple1(a1->getNumberOfTuples()),nbOfTuple2(a2->getNumberOfTuples()); + int nbOfComp1(a1->getNumberOfComponents()),nbOfComp2(a2->getNumberOfComponents()); + if(nbOfTuple2==nbOfTuple1) + { + if(nbOfComp1==nbOfComp2) + { + MCAuto::ArrayType> ret(Traits::ArrayType::New()); + ret->alloc(nbOfTuple2,nbOfComp1); + std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides()); + ret->copyStringInfoFrom(*a1); + return ret.retn(); + } + else if(nbOfComp2==1) + { + MCAuto::ArrayType> ret(Traits::ArrayType::New()); + ret->alloc(nbOfTuple1,nbOfComp1); + const T *a2Ptr(a2->begin()),*a1Ptr(a1->begin()); + T *res(ret->getPointer()); + for(int i=0;i(),a2Ptr[i])); + ret->copyStringInfoFrom(*a1); + return ret.retn(); + } + else + { + a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !"); + return 0; + } + } + else if(nbOfTuple2==1) + { + a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !"); + MCAuto::ArrayType> ret(Traits::ArrayType::New()); + ret->alloc(nbOfTuple1,nbOfComp1); + const T *a1ptr=a1->begin(),*a2ptr(a2->begin()); + T *pt(ret->getPointer()); + for(int i=0;i()); + ret->copyStringInfoFrom(*a1); + return ret.retn(); + } + else + { + a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception + return 0; + } + } + + /*! + * Returns a new DataArrayDouble that is a product of two given arrays. There are 3 + * valid cases. + * 1. The arrays have same number of tuples and components. Then each value of + * the result array (_a_) is a product of the corresponding values of \a a1 and + * \a a2, i.e. _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ]. + * 2. The arrays have same number of tuples and one array, say _a2_, has one + * component. Then + * _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ]. + * 3. The arrays have same number of components and one array, say _a2_, has one + * tuple. Then + * _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ]. + * + * Info on components is copied either from the first array (in the first case) or from + * the array with maximal number of elements (getNbOfElems()). + * \param [in] a1 - a factor array. + * \param [in] a2 - another factor array. + * \return DataArrayDouble * - the new instance of DataArrayDouble. + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * \throw If either \a a1 or \a a2 is NULL. + * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and + * \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and + * none of them has number of tuples or components equal to 1. + */ + template + typename Traits::ArrayType *DataArrayTemplateClassic::Multiply(const typename Traits::ArrayType *a1, const typename Traits::ArrayType *a2) + { + if(!a1 || !a2) + throw INTERP_KERNEL::Exception("DataArrayDouble::Multiply : input DataArrayDouble instance is NULL !"); + int nbOfTuple(a1->getNumberOfTuples()),nbOfTuple2(a2->getNumberOfTuples()); + int nbOfComp(a1->getNumberOfComponents()),nbOfComp2(a2->getNumberOfComponents()); + MCAuto::ArrayType> ret=0; + if(nbOfTuple==nbOfTuple2) + { + if(nbOfComp==nbOfComp2) + { + ret=Traits::ArrayType::New(); + ret->alloc(nbOfTuple,nbOfComp); + std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies()); + ret->copyStringInfoFrom(*a1); + } + else + { + int nbOfCompMin,nbOfCompMax; + const typename Traits::ArrayType *aMin, *aMax; + if(nbOfComp>nbOfComp2) + { + nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp; + aMin=a2; aMax=a1; + } + else + { + nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2; + aMin=a1; aMax=a2; + } + if(nbOfCompMin==1) + { + ret=Traits::ArrayType::New(); + ret->alloc(nbOfTuple,nbOfCompMax); + const T *aMinPtr(aMin->begin()); + const T *aMaxPtr(aMax->begin()); + T *res=ret->getPointer(); + for(int i=0;i(),aMinPtr[i])); + ret->copyStringInfoFrom(*aMax); + } + else + throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !"); + } + } + else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1)) + { + if(nbOfComp==nbOfComp2) + { + int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2); + const typename Traits::ArrayType *aMin(nbOfTuple>nbOfTuple2?a2:a1); + const typename Traits::ArrayType *aMax(nbOfTuple>nbOfTuple2?a1:a2); + const T *aMinPtr(aMin->begin()),*aMaxPtr(aMax->begin()); + ret=Traits::ArrayType::New(); + ret->alloc(nbOfTupleMax,nbOfComp); + T *res(ret->getPointer()); + for(int i=0;i()); + ret->copyStringInfoFrom(*aMax); + } + else + throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !"); + } + else + throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !"); + return ret.retn(); + } /*! * Returns either a \a deep or \a shallow copy of this array. For more info see diff --git a/src/MEDCoupling_Swig/MEDCouplingBasicsTest5.py b/src/MEDCoupling_Swig/MEDCouplingBasicsTest5.py index f2a7c8649..0dafaef97 100644 --- a/src/MEDCoupling_Swig/MEDCouplingBasicsTest5.py +++ b/src/MEDCoupling_Swig/MEDCouplingBasicsTest5.py @@ -4565,7 +4565,6 @@ class MEDCouplingBasicsTest5(unittest.TestCase): m_1=m[[0,2,4]] ; m_1.zipCoords() self.assertTrue(f_1.getMesh().isEqual(m_1,1e-12)) pass -class MEDCouplingBasicsTest5(unittest.TestCase): def testFieldFloatIsOnStage1(self): """ My first test with field int.""" @@ -4588,6 +4587,7 @@ class MEDCouplingBasicsTest5(unittest.TestCase): self.assertEqual(a,3.2,12) pass +class MEDCouplingBasicsTest6:#5(unittest.TestCase): def testFieldFloatIsOnStage2(self): """ Very important test to check that isEqual of MEDCouplingFieldFloat is OK !""" m1=MEDCouplingCMesh() ; m1.setCoords(DataArrayDouble([0,1,2,3]),DataArrayDouble([0,1,2,3,4])) diff --git a/src/MEDCoupling_Swig/MEDCouplingDataArrayTypemaps.i b/src/MEDCoupling_Swig/MEDCouplingDataArrayTypemaps.i index 0d1783231..e9c066880 100644 --- a/src/MEDCoupling_Swig/MEDCouplingDataArrayTypemaps.i +++ b/src/MEDCoupling_Swig/MEDCouplingDataArrayTypemaps.i @@ -3005,7 +3005,6 @@ PyObject *DataArrayT_imul__internal(PyObject *trueSelf, PyObject *obj, typename typename MEDCoupling::Traits::ArrayTuple *aa; std::vector bb; int sw; - convertDoubleStarLikePyObjToCpp_2(obj,sw,val,a,aa,bb); convertFPStarLikePyObjToCpp_2(obj,sw,val,a,aa,bb,ti_da,ti_tuple); switch(sw) { diff --git a/src/MEDCoupling_Swig/MEDCouplingRemapper.i b/src/MEDCoupling_Swig/MEDCouplingRemapper.i index d170e1469..642aeb43c 100644 --- a/src/MEDCoupling_Swig/MEDCouplingRemapper.i +++ b/src/MEDCoupling_Swig/MEDCouplingRemapper.i @@ -142,6 +142,9 @@ def MEDCouplingFieldDoubleIpow(self,*args): def MEDCouplingDataArrayBytenew(cls,*args): import _MEDCouplingRemapper return _MEDCouplingRemapper.DataArrayByte____new___(cls,args) +def MEDCouplingDataArrayFloatImul(self,*args): + import _MEDCouplingRemapper + return _MEDCouplingRemapper.DataArrayFloat____imul___(self, self, *args) def MEDCouplingDataArrayIntnew(cls,*args): import _MEDCouplingRemapper return _MEDCouplingRemapper.DataArrayInt____new___(cls,args) diff --git a/src/MEDLoader/Swig/MEDLoader.i b/src/MEDLoader/Swig/MEDLoader.i index 7add2d533..e14a804f0 100644 --- a/src/MEDLoader/Swig/MEDLoader.i +++ b/src/MEDLoader/Swig/MEDLoader.i @@ -60,6 +60,9 @@ def MEDCouplingFieldDoubleIpow(self,*args): def MEDCouplingDataArrayBytenew(cls,*args): import _MEDLoader return _MEDLoader.DataArrayByte____new___(cls,args) +def MEDCouplingDataArrayFloatImul(self,*args): + import _MEDLoader + return _MEDLoader.DataArrayFloat____imul___(self, self, *args) def MEDCouplingDataArrayIntnew(cls,*args): import _MEDLoader return _MEDLoader.DataArrayInt____new___(cls,args) diff --git a/src/RENUMBER_Swig/MEDRenumber.i b/src/RENUMBER_Swig/MEDRenumber.i index 7839e5276..8cac841ce 100644 --- a/src/RENUMBER_Swig/MEDRenumber.i +++ b/src/RENUMBER_Swig/MEDRenumber.i @@ -62,6 +62,9 @@ def MEDCouplingDataArrayIntIpow(self,*args): def MEDCouplingDataArrayBytenew(cls,*args): import _MEDRenumber return _MEDRenumber.DataArrayByte____new___(cls,args) +def MEDCouplingDataArrayFloatImul(self,*args): + import _MEDRenumber + return _MEDRenumber.DataArrayFloat____imul___(self, self, *args) def MEDCouplingDataArrayDoubleTupleIadd(self,*args): import _MEDRenumber return _MEDRenumber.DataArrayDoubleTuple____iadd___(self, self, *args) -- 2.39.2