From c12ef7d958422cf4178154d376b8c3177fcc2121 Mon Sep 17 00:00:00 2001 From: abn Date: Wed, 8 Aug 2018 17:04:49 +0200 Subject: [PATCH] API change: MEDCouplingFieldDouble::normMax is now aligned with normL1 and normL2 --- src/MEDCoupling/MEDCouplingFieldDouble.cxx | 55 ++++++++++++++----- src/MEDCoupling/MEDCouplingFieldDouble.hxx | 3 +- src/MEDCoupling/MEDCouplingMemArray.cxx | 24 ++++++++ src/MEDCoupling/MEDCouplingMemArray.hxx | 1 + .../Test/MEDCouplingBasicsTest4.cxx | 19 ++++++- .../MEDCouplingBasicsTest3.py | 18 +++++- src/MEDCoupling_Swig/MEDCouplingCommon.i | 9 ++- src/MEDCoupling_Swig/MEDCouplingMemArray.i | 8 +++ 8 files changed, 118 insertions(+), 19 deletions(-) diff --git a/src/MEDCoupling/MEDCouplingFieldDouble.cxx b/src/MEDCoupling/MEDCouplingFieldDouble.cxx index a1966c945..6e6d5dc21 100644 --- a/src/MEDCoupling/MEDCouplingFieldDouble.cxx +++ b/src/MEDCoupling/MEDCouplingFieldDouble.cxx @@ -683,19 +683,6 @@ double MEDCouplingFieldDouble::norm2() const return getArray()->norm2(); } -/*! - * This method returns the max norm of \a this field. - * \f[ - * \max_{0 \leq i < nbOfEntity}{abs(val[i])} - * \f] - * \throw If the data array is not set. - */ -double MEDCouplingFieldDouble::normMax() const -{ - if(getArray()==0) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::normMax : no default array defined !"); - return getArray()->normMax(); -} /*! * Computes the weighted average of values of each component of \a this field, the weights being the @@ -842,6 +829,48 @@ void MEDCouplingFieldDouble::normL2(double *res) const _type->normL2(_mesh,getArray(),res); } +/*! + * Returns the \c infinite norm of values of a given component of \a this field: +* \f[ + * \max_{0 \leq i < nbOfEntity}{abs(val[i])} + * \f] + * \param [in] compId - an index of the component of interest. + * \throw If \a compId is not valid. + A valid range is ( 0 <= \a compId < \a this->getNumberOfComponents() ). + * \throw If the data array is not set. + */ +double MEDCouplingFieldDouble::normMax(int compId) const +{ + if(getArray()==0) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::normMax : no default array defined !"); + int nbComps=getArray()->getNumberOfComponents(); + if(compId<0 || compId>=nbComps) + { + std::ostringstream oss; oss << "MEDCouplingFieldDouble::normMax : Invalid compId specified : No such nb of components ! Should be in [0," << nbComps << ") !"; + throw INTERP_KERNEL::Exception(oss.str()); + } + INTERP_KERNEL::AutoPtr res=new double[nbComps]; + getArray()->normMaxPerComponent(res); + return res[compId]; +} + +/*! + * Returns the \c infinite norm of values of each component of \a this field: + * \f[ + * \max_{0 \leq i < nbOfEntity}{abs(val[i])} + * \f] + * \param [out] res - pointer to an array of result values, of size at least \a + * this->getNumberOfComponents(), that is to be allocated by the caller. + * \throw If the data array is not set. + * + */ +void MEDCouplingFieldDouble::normMax(double *res) const +{ + if(getArray()==0) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::normMax : no default array defined !"); + getArray()->normMaxPerComponent(res); +} + /*! * Computes a sum of values of a given component of \a this field multiplied by * values returned by buildMeasureField(). diff --git a/src/MEDCoupling/MEDCouplingFieldDouble.hxx b/src/MEDCoupling/MEDCouplingFieldDouble.hxx index 322d66dd7..757df6ae7 100644 --- a/src/MEDCoupling/MEDCouplingFieldDouble.hxx +++ b/src/MEDCoupling/MEDCouplingFieldDouble.hxx @@ -60,13 +60,14 @@ namespace MEDCoupling MEDCOUPLING_EXPORT double getMinValue2(DataArrayInt*& tupleIds) const; MEDCOUPLING_EXPORT double getAverageValue() const; MEDCOUPLING_EXPORT double norm2() const; - MEDCOUPLING_EXPORT double normMax() const; MEDCOUPLING_EXPORT void getWeightedAverageValue(double *res, bool isWAbs=true) const; MEDCOUPLING_EXPORT double getWeightedAverageValue(int compId, bool isWAbs=true) const; MEDCOUPLING_EXPORT double normL1(int compId) const; MEDCOUPLING_EXPORT void normL1(double *res) const; MEDCOUPLING_EXPORT double normL2(int compId) const; MEDCOUPLING_EXPORT void normL2(double *res) const; + MEDCOUPLING_EXPORT double normMax(int compId) const; + MEDCOUPLING_EXPORT void normMax(double *res) const; MEDCOUPLING_EXPORT double integral(int compId, bool isWAbs) const; MEDCOUPLING_EXPORT void integral(bool isWAbs, double *res) const; MEDCOUPLING_EXPORT void getValueOnPos(int i, int j, int k, double *res) const; diff --git a/src/MEDCoupling/MEDCouplingMemArray.cxx b/src/MEDCoupling/MEDCouplingMemArray.cxx index b96febeff..0343614a8 100644 --- a/src/MEDCoupling/MEDCouplingMemArray.cxx +++ b/src/MEDCoupling/MEDCouplingMemArray.cxx @@ -1644,6 +1644,30 @@ double DataArrayDouble::normMax() const return ret; } +/*! + * Returns the maximum norm of for each component of \a this array. + * If the number of elements in \a this is 0, -1. is returned. +* \param [out] res - pointer to an array of result values, of size at least \a + * this->getNumberOfComponents(), that is to be allocated by the caller. + * \throw If \a this is not allocated. + */ +void DataArrayDouble::normMaxPerComponent(double * res) const +{ + checkAllocated(); + std::size_t nbOfTuples(getNumberOfTuples()); + int nbOfCompos(getNumberOfComponents()); + std::fill(res, res+nbOfCompos, -1.0); + const double *pt(getConstPointer()); + for(std::size_t i=0;ires[j]) + res[j]=val; + } +} + + /*! * Returns the minimum norm (absolute value) of the vector defined by \a this array. * This method works even if the number of components is different from one. diff --git a/src/MEDCoupling/MEDCouplingMemArray.hxx b/src/MEDCoupling/MEDCouplingMemArray.hxx index edb12b566..825b9c897 100644 --- a/src/MEDCoupling/MEDCouplingMemArray.hxx +++ b/src/MEDCoupling/MEDCouplingMemArray.hxx @@ -448,6 +448,7 @@ namespace MEDCoupling MEDCOUPLING_EXPORT double getAverageValue() const; MEDCOUPLING_EXPORT double norm2() const; MEDCOUPLING_EXPORT double normMax() const; + MEDCOUPLING_EXPORT void normMaxPerComponent(double * res) const; MEDCOUPLING_EXPORT double normMin() const; MEDCOUPLING_EXPORT void accumulate(double *res) const; MEDCOUPLING_EXPORT double accumulate(int compId) const; diff --git a/src/MEDCoupling/Test/MEDCouplingBasicsTest4.cxx b/src/MEDCoupling/Test/MEDCouplingBasicsTest4.cxx index 9a9361fd8..1a9eded7a 100644 --- a/src/MEDCoupling/Test/MEDCouplingBasicsTest4.cxx +++ b/src/MEDCoupling/Test/MEDCouplingBasicsTest4.cxx @@ -1560,16 +1560,31 @@ void MEDCouplingBasicsTest4::testNormMax1() f->setMesh(m); m->decrRef(); // - DataArrayDouble *d=DataArrayDouble::New(); + DataArrayDouble *d=DataArrayDouble::New(); d->alloc(0,2); + double res[2]; + d->normMaxPerComponent(res); + + CPPUNIT_ASSERT_DOUBLES_EQUAL(-1.0,res[0],1e-14); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-1.0,res[1],1e-14); + const double tab[10]={2.3,-1.2,6.3,-7.8,2.9,7.7,2.1,0.,3.6,-7.6}; d->alloc(5,2); std::copy(tab,tab+10,d->getPointer()); + + d->normMaxPerComponent(res); + CPPUNIT_ASSERT_DOUBLES_EQUAL(6.3,res[0],1e-14); + CPPUNIT_ASSERT_DOUBLES_EQUAL(7.8,res[1],1e-14); + f->setArray(d); d->decrRef(); f->checkConsistencyLight(); // - CPPUNIT_ASSERT_DOUBLES_EQUAL(7.8,f->normMax(),1e-14); + f->normMax(res); + CPPUNIT_ASSERT_DOUBLES_EQUAL(6.3,res[0],1e-14); + CPPUNIT_ASSERT_DOUBLES_EQUAL(7.8,res[1],1e-14); // + CPPUNIT_ASSERT_DOUBLES_EQUAL(6.3,f->normMax(0),1e-14); + CPPUNIT_ASSERT_DOUBLES_EQUAL(7.8,f->normMax(1),1e-14); f->decrRef(); } diff --git a/src/MEDCoupling_Swig/MEDCouplingBasicsTest3.py b/src/MEDCoupling_Swig/MEDCouplingBasicsTest3.py index 80f5f6bb0..267589138 100644 --- a/src/MEDCoupling_Swig/MEDCouplingBasicsTest3.py +++ b/src/MEDCoupling_Swig/MEDCouplingBasicsTest3.py @@ -1962,14 +1962,28 @@ class MEDCouplingBasicsTest3(unittest.TestCase): f=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); f.setMesh(m); # - d=DataArrayDouble.New(); + d=DataArrayDouble.New(); d.alloc(0,2) + res = d.normMaxPerComponent() + self.assertAlmostEqual(-1.0, res[0],14) + self.assertAlmostEqual(-1.0, res[1],14) + tab=[2.3,-1.2,6.3,-7.8,2.9,7.7,2.1,0.,3.6,-7.6] d.setValues(tab,5,2); + + res = d.normMaxPerComponent() + self.assertAlmostEqual(6.3, res[0],14) + self.assertAlmostEqual(7.8, res[1],14) + f.setArray(d); f.checkConsistencyLight(); # - self.assertAlmostEqual(7.8,f.normMax(),14); + res = f.normMax() + self.assertAlmostEqual(6.3,res[0],14); + self.assertAlmostEqual(7.8,res[1],14); # + self.assertAlmostEqual(6.3,f.normMax(0),14); + self.assertAlmostEqual(7.8,f.normMax(1),14); + pass def testFindAndCorrectBadOriented3DExtrudedCells1(self): diff --git a/src/MEDCoupling_Swig/MEDCouplingCommon.i b/src/MEDCoupling_Swig/MEDCouplingCommon.i index 40dcdafcd..45d2fc793 100644 --- a/src/MEDCoupling_Swig/MEDCouplingCommon.i +++ b/src/MEDCoupling_Swig/MEDCouplingCommon.i @@ -4094,12 +4094,12 @@ namespace MEDCoupling double getMinValue() const throw(INTERP_KERNEL::Exception); double getAverageValue() const throw(INTERP_KERNEL::Exception); double norm2() const throw(INTERP_KERNEL::Exception); - double normMax() const throw(INTERP_KERNEL::Exception); //do not put a default value to isWAbs because confusion in python with overloaded getWeightedAverageValue method double getWeightedAverageValue(int compId, bool isWAbs) const throw(INTERP_KERNEL::Exception); double integral(int compId, bool isWAbs) const throw(INTERP_KERNEL::Exception); double normL1(int compId) const throw(INTERP_KERNEL::Exception); double normL2(int compId) const throw(INTERP_KERNEL::Exception); + double normMax(int compId) const throw(INTERP_KERNEL::Exception); DataArrayInt *findIdsInRange(double vmin, double vmax) const throw(INTERP_KERNEL::Exception); MEDCouplingFieldDouble *buildSubPartRange(int begin, int end, int step) const throw(INTERP_KERNEL::Exception); static MEDCouplingFieldDouble *MergeFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception); @@ -4363,6 +4363,13 @@ namespace MEDCoupling self->normL2(tmp); return convertDblArrToPyList(tmp,sz); } + PyObject *normMax() const throw(INTERP_KERNEL::Exception) + { + int sz=self->getNumberOfComponents(); + INTERP_KERNEL::AutoPtr tmp=new double[sz]; + self->normMax(tmp); + return convertDblArrToPyList(tmp,sz); + } void renumberCells(PyObject *li, bool check=true) throw(INTERP_KERNEL::Exception) { int szArr,sw,iTypppArr; diff --git a/src/MEDCoupling_Swig/MEDCouplingMemArray.i b/src/MEDCoupling_Swig/MEDCouplingMemArray.i index ce219c774..8637c98fd 100644 --- a/src/MEDCoupling_Swig/MEDCouplingMemArray.i +++ b/src/MEDCoupling_Swig/MEDCouplingMemArray.i @@ -1341,6 +1341,14 @@ namespace MEDCoupling PyObject *ret=convertDblArrToPyListOfTuple(tmp,2,nbOfCompo); return ret; } + + PyObject *normMaxPerComponent() const throw(INTERP_KERNEL::Exception) + { + int nbOfCompo(self->getNumberOfComponents()); + INTERP_KERNEL::AutoPtr tmp(new double[nbOfCompo]); + self->normMaxPerComponent(tmp); + return convertDblArrToPyList(tmp,nbOfCompo); + } PyObject *accumulate() const throw(INTERP_KERNEL::Exception) { -- 2.39.2