From 4717f61d67ec4d7f115f343d033823ba2d34a109 Mon Sep 17 00:00:00 2001
From: Christophe Palmann <christophe.palmann@c-s.fr>
Date: Fri, 28 Nov 2014 10:02:16 +0100
Subject: [PATCH] ENH: bandmathx, operators

---
 Code/Common/otbParserX.cxx        |   3 +-
 Code/Common/otbParserXPlugins.cxx | 131 +++++++++++-------------------
 Code/Common/otbParserXPlugins.h   |  38 ++++++---
 3 files changed, 77 insertions(+), 95 deletions(-)

diff --git a/Code/Common/otbParserX.cxx b/Code/Common/otbParserX.cxx
index ceb423f626..f06b32f193 100644
--- a/Code/Common/otbParserX.cxx
+++ b/Code/Common/otbParserX.cxx
@@ -58,7 +58,7 @@ public:
   virtual void InitFun()
   {
     m_MuParserX.DefineFun(new ndvi);
-    m_MuParserX.DefineFun(new conv);
+    m_MuParserX.DefineFun(new dotpr);
     m_MuParserX.DefineFun(new bands);
     m_MuParserX.DefineFun(new cat);
     m_MuParserX.DefineFun(new mean);
@@ -74,6 +74,7 @@ public:
     m_MuParserX.DefineOprt(new MultiplicationByScalar);
     m_MuParserX.DefineOprt(new PowerByScalar);
 
+    m_MuParserX.DefineFun(new vnorm);
     m_MuParserX.DefineFun(new vmin);
     m_MuParserX.DefineFun(new vmax);
     m_MuParserX.DefineFun(new vcos);
diff --git a/Code/Common/otbParserXPlugins.cxx b/Code/Common/otbParserXPlugins.cxx
index 9f5d5b007a..c2af7313ee 100644
--- a/Code/Common/otbParserXPlugins.cxx
+++ b/Code/Common/otbParserXPlugins.cxx
@@ -55,7 +55,7 @@ void bands::Eval(mup::ptr_val_type &ret, const mup::ptr_val_type *a_pArg, int a_
     }
 
 
-void conv::Eval(mup::ptr_val_type &ret, const mup::ptr_val_type *a_pArg, int a_iArgc)
+void dotpr::Eval(mup::ptr_val_type &ret, const mup::ptr_val_type *a_pArg, int a_iArgc)
     {
       assert(a_pArg[0]->GetType()=='m');
 
@@ -92,7 +92,6 @@ void conv::Eval(mup::ptr_val_type &ret, const mup::ptr_val_type *a_pArg, int a_i
       *ret = res;
     }
 
-
 void ElementWiseDivision::Eval(mup::ptr_val_type &ret, const mup::ptr_val_type *a_pArg, int)
     {
 
@@ -653,63 +652,59 @@ void maj::Eval(mup::ptr_val_type &ret, const mup::ptr_val_type *a_pArg, int a_iA
     }
 
 
-void vmin::Eval(mup::ptr_val_type &ret, const mup::ptr_val_type *a_pArg, int a_iArgc)
+//--------------------------------------------------------------------------------------------------------//
+void vnorm::Eval(mup::ptr_val_type &ret, const mup::ptr_val_type *a_pArg, int a_iArgc)
     {
-  
-      std::vector<double> vect;
-      double min;
 
       int nbrows,nbcols;
       mup::matrix_type m1;
+      double sum=0.0;
 
-      for (int k=0; k<a_iArgc; ++k)
-      {
+      assert( a_iArgc==1 );
+      assert(a_pArg[0]->GetType()=='m');
 
-        // Get the argument from the argument input vector
-        switch (a_pArg[k]->GetType())
-        {
-          case 'm':
+      m1 = a_pArg[0]->GetArray();
 
-            min = itk::NumericTraits<double>::max();
+      nbrows = m1.GetRows();
+      nbcols = m1.GetCols();
 
-            m1 = a_pArg[k]->GetArray();
+      for (int i=0; i<nbrows; i++)
+        for (int j=0; j<nbcols; j++)
+          sum += vcl_pow(m1.At(i,j).GetFloat(),2.0);
 
-            nbrows = m1.GetRows();
-            nbcols = m1.GetCols();
 
-            for (int i=0; i<nbrows; i++)
-              for (int j=0; j<nbcols; j++)
-                if (m1.At(i,j).GetFloat() < min )
-                  min = m1.At(i,j).GetFloat();
+      // The return value is passed by writing it to the reference ret
+      mup::matrix_type res(1,1,vcl_sqrt(sum));
+      *ret = res;
+  }
 
-            vect.push_back(min);
 
-          break;
-    
-          case 'i':
-            min = itk::NumericTraits<double>::max();
+void vmin::Eval(mup::ptr_val_type &ret, const mup::ptr_val_type *a_pArg, int a_iArgc)
+    {
+  
+      std::vector<double> vect;
+      double min;
 
-            if ( (double) a_pArg[k]->GetInteger() < min)
-              min = (double) a_pArg[k]->GetInteger();
+      int nbrows,nbcols;
+      mup::matrix_type m1;
 
-            vect.push_back(min);
-          break;
-        
-          case 'f':
-            min = itk::NumericTraits<double>::max();
+      assert( a_iArgc==1 );
+      assert(a_pArg[0]->GetType()=='m');
 
-            if ( a_pArg[k]->GetFloat() < min)
-              min = a_pArg[k]->GetFloat();
+      min = itk::NumericTraits<double>::max();
 
-            vect.push_back(min);
-          break;
-        }
-      }
+      m1 = a_pArg[0]->GetArray();
+
+      nbrows = m1.GetRows();
+      nbcols = m1.GetCols();
+
+      for (int i=0; i<nbrows; i++)
+        for (int j=0; j<nbcols; j++)
+          if (m1.At(i,j).GetFloat() < min )
+            min = m1.At(i,j).GetFloat();
 
       // The return value is passed by writing it to the reference ret
-      mup::matrix_type res(1,vect.size(),0);
-      for (int j=0; j<vect.size(); j++)
-            res.At(0,j) = vect[j];
+      mup::matrix_type res(1,1,min);
       *ret = res;
     }
 
@@ -723,59 +718,27 @@ void vmax::Eval(mup::ptr_val_type &ret, const mup::ptr_val_type *a_pArg, int a_i
       int nbrows,nbcols;
       mup::matrix_type m1;
 
-      for (int k=0; k<a_iArgc; ++k)
-      {
-
-        // Get the argument from the argument input vector
-        switch (a_pArg[k]->GetType())
-        {
-          case 'm':
-
-            max = itk::NumericTraits<double>::min();
-
-            m1 = a_pArg[k]->GetArray();
-
-            nbrows = m1.GetRows();
-            nbcols = m1.GetCols();
-
-            for (int i=0; i<nbrows; i++)
-              for (int j=0; j<nbcols; j++)
-                if (m1.At(i,j).GetFloat() > max )
-                  max = m1.At(i,j).GetFloat();
-
-            vect.push_back(max);
-
-          break;
-    
-          case 'i':
-            max = itk::NumericTraits<double>::min();
+      assert( a_iArgc==1 );
+      assert(a_pArg[0]->GetType()=='m');
 
-            if ( (double) a_pArg[k]->GetInteger() > max)
-              max = (double) a_pArg[k]->GetInteger();
+      max = itk::NumericTraits<double>::min();
 
-            vect.push_back(max);
-          break;
-        
-          case 'f':
-            max = itk::NumericTraits<double>::min();
+      m1 = a_pArg[0]->GetArray();
 
-            if ( a_pArg[k]->GetFloat() > max)
-              max = a_pArg[k]->GetFloat();
+      nbrows = m1.GetRows();
+      nbcols = m1.GetCols();
 
-            vect.push_back(max);
-          break;
-        }
-      }
+      for (int i=0; i<nbrows; i++)
+        for (int j=0; j<nbcols; j++)
+          if (m1.At(i,j).GetFloat() > max )
+            max = m1.At(i,j).GetFloat();
 
       // The return value is passed by writing it to the reference ret
-      mup::matrix_type res(1,vect.size(),0);
-      for (int j=0; j<vect.size(); j++)
-            res.At(0,j) = vect[j];
+      mup::matrix_type res(1,1,max);
       *ret = res;
     }
 
 
-//--------------------------------------------------------------------------------------------------------//
 void vcos::Eval(mup::ptr_val_type &ret, const mup::ptr_val_type *a_pArg, int a_iArgc)
     {
       assert(a_iArgc==1);
diff --git a/Code/Common/otbParserXPlugins.h b/Code/Common/otbParserXPlugins.h
index 29de448a32..0ef1048d41 100644
--- a/Code/Common/otbParserXPlugins.h
+++ b/Code/Common/otbParserXPlugins.h
@@ -47,26 +47,25 @@ public:
   };
 
 
-class conv : public mup::ICallback
+class dotpr : public mup::ICallback
   {
 public:
-    conv():ICallback(mup::cmFUNC, "conv", -1)
+    dotpr():ICallback(mup::cmFUNC, "dotpr", -1)
     {}
 
     virtual void Eval(mup::ptr_val_type &ret, const mup::ptr_val_type *a_pArg, int a_iArgc);
 
     const mup::char_type* GetDesc() const
     {
-      return "conv(m1,m2) - A matrix convolution";
+      return "dotpr(m1,m2) - A vector/matrix dot product";
     }
 
     mup::IToken* Clone() const
     {
-      return new conv(*this);
+      return new dotpr(*this);
     }
   };
 
-
 class ElementWiseDivision : public mup::IOprtBin
   {
   public:
@@ -326,18 +325,37 @@ public:
     }
   };
 
+//--------------------------------------------------------------------------------------------------------//
+class vnorm : public mup::ICallback
+  {
+public:
+    vnorm():ICallback(mup::cmFUNC, "vnorm", 1)
+    {}
+
+    virtual void Eval(mup::ptr_val_type &ret, const mup::ptr_val_type *a_pArg, int a_iArgc);
+
+    const mup::char_type* GetDesc() const
+    {
+      return "vnorm(v1) - Norm for a vector : sqrt(sum of squared elements); works also with matrices";
+    }
+
+    mup::IToken* Clone() const
+    {
+      return new vnorm(*this);
+    }
+  };
 
 class vmin : public mup::ICallback
   {
 public:
-    vmin():ICallback(mup::cmFUNC, "vmin", -1)
+    vmin():ICallback(mup::cmFUNC, "vmin", 1)
     {}
 
     virtual void Eval(mup::ptr_val_type &ret, const mup::ptr_val_type *a_pArg, int a_iArgc);
 
     const mup::char_type* GetDesc() const
     {
-      return "vmin(m1,m2,..) - overall minimun";
+      return "vmin(m1) - overall minimun";
     }
 
     mup::IToken* Clone() const
@@ -350,14 +368,14 @@ public:
 class vmax : public mup::ICallback
   {
 public:
-    vmax():ICallback(mup::cmFUNC, "vmax", -1)
+    vmax():ICallback(mup::cmFUNC, "vmax", 1)
     {}
 
     virtual void Eval(mup::ptr_val_type &ret, const mup::ptr_val_type *a_pArg, int a_iArgc);
 
     const mup::char_type* GetDesc() const
     {
-      return "vmax(m1,m2,..) - overall maximun";
+      return "vmax(m1) - overall maximun";
     }
 
     mup::IToken* Clone() const
@@ -366,7 +384,7 @@ public:
     }
   };
 
-//--------------------------------------------------------------------------------------------------------//
+
 class vcos : public mup::ICallback
   {
 public:
-- 
GitLab