Salome HOME
Merge branch 'abn/norm_max'
authorAnthony Geay <anthony.geay@edf.fr>
Mon, 27 Aug 2018 11:54:46 +0000 (13:54 +0200)
committerAnthony Geay <anthony.geay@edf.fr>
Mon, 27 Aug 2018 11:54:46 +0000 (13:54 +0200)
src/MEDCoupling/MEDCouplingFieldDouble.cxx
src/MEDCoupling/MEDCouplingFieldDouble.hxx
src/MEDCoupling/MEDCouplingMemArray.cxx
src/MEDCoupling/MEDCouplingMemArray.hxx
src/MEDCoupling/Test/MEDCouplingBasicsTest4.cxx
src/MEDCoupling_Swig/MEDCouplingBasicsTest3.py
src/MEDCoupling_Swig/MEDCouplingCommon.i
src/MEDCoupling_Swig/MEDCouplingMemArray.i

index a1966c945c061da55408876043e39f40a3531f70..6e6d5dc21c5c55c1b0e7802e9846071fa86940a4 100644 (file)
@@ -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<double> 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().
index 322d66dd7bcd8c67478bd00ff1c460e94579c4d5..757df6ae72a3ec4dae16c244673cdab27cebdeeb 100644 (file)
@@ -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;
index b96febeff68774d2aea7815440d5586daa468df7..0343614a83d4f0325d914e15de2f74bd6b8b4e67 100644 (file)
@@ -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;i<nbOfTuples;i++)
+    for (int j=0; j<nbOfCompos; j++, pt++)
+      {
+        double val(std::abs(*pt));
+        if(val>res[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.
index edb12b5660997df50e562739b3363a0c6c745267..825b9c8979e66d2717ad964c2994b084b700668b 100644 (file)
@@ -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;
index 9a9361fd85238f2b790f0bf9d686320d60677ecc..1a9eded7a3ba9b70601f712f1542f1327114a44e 100644 (file)
@@ -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();
 }
 
index 80f5f6bb0b3382240dc2d78d50013cbb20b8dba9..2675891380db52d27c60d11d3899eaeb41e086d9 100644 (file)
@@ -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):
index 40dcdafcdd7f7c56899067e8f3fac6ee1e910ce8..45d2fc793d050c861baecd579ea948b183d8a62e 100644 (file)
@@ -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<double>(tmp,sz);
       }
+      PyObject *normMax() const throw(INTERP_KERNEL::Exception)
+      {
+        int sz=self->getNumberOfComponents();
+        INTERP_KERNEL::AutoPtr<double> tmp=new double[sz];
+        self->normMax(tmp);
+        return convertDblArrToPyList<double>(tmp,sz);
+      }
       void renumberCells(PyObject *li, bool check=true) throw(INTERP_KERNEL::Exception)
       {
         int szArr,sw,iTypppArr;
index ce219c7749ecc698cdec2ba48a863a2a0eed7a90..8637c98fd93d8c776cd6b18e4b4597d2e4739d16 100644 (file)
@@ -1341,6 +1341,14 @@ namespace MEDCoupling
         PyObject *ret=convertDblArrToPyListOfTuple<double>(tmp,2,nbOfCompo);
         return ret;
       }
+      
+      PyObject *normMaxPerComponent() const throw(INTERP_KERNEL::Exception)
+      {
+        int nbOfCompo(self->getNumberOfComponents());
+        INTERP_KERNEL::AutoPtr<double> tmp(new double[nbOfCompo]);
+        self->normMaxPerComponent(tmp);
+        return convertDblArrToPyList<double>(tmp,nbOfCompo);
+      }
 
       PyObject *accumulate() const throw(INTERP_KERNEL::Exception)
       {