From 74edba005fa6aa728ff1ca8df94000495658bdb0 Mon Sep 17 00:00:00 2001
From: ctraizet <cedric.traizet@c-s.fr>
Date: Mon, 18 Mar 2019 15:21:49 +0100
Subject: [PATCH] REFAC: replace UnConstrainedLeastSquareImageFilter by a
 functorImageFilter

---
 .../app/otbHyperspectralUnmixing.cxx          |   2 +-
 .../otbUnConstrainedLeastSquareImageFilter.h  | 121 +++---------------
 ...otbUnConstrainedLeastSquareImageFilter.hxx |  49 +++++--
 ...otbUnConstrainedLeastSquareImageFilter.cxx |   2 +-
 4 files changed, 56 insertions(+), 118 deletions(-)

diff --git a/Modules/Applications/AppHyperspectral/app/otbHyperspectralUnmixing.cxx b/Modules/Applications/AppHyperspectral/app/otbHyperspectralUnmixing.cxx
index 3a1f53eff3..a7353577a9 100644
--- a/Modules/Applications/AppHyperspectral/app/otbHyperspectralUnmixing.cxx
+++ b/Modules/Applications/AppHyperspectral/app/otbHyperspectralUnmixing.cxx
@@ -196,7 +196,7 @@ private:
           UCLSUnmixingFilterType::New();
 
       unmixer->SetInput(inputImage);
-      unmixer->SetMatrix(endMembersMatrix);
+      unmixer->GetModifiableFunctor().SetMatrix(endMembersMatrix);
       unmixer->SetNumberOfThreads(1); // FIXME : currently buggy
 
       abundanceMap = unmixer->GetOutput();
diff --git a/Modules/Hyperspectral/Unmixing/include/otbUnConstrainedLeastSquareImageFilter.h b/Modules/Hyperspectral/Unmixing/include/otbUnConstrainedLeastSquareImageFilter.h
index 68a52ea5ba..82d541808c 100644
--- a/Modules/Hyperspectral/Unmixing/include/otbUnConstrainedLeastSquareImageFilter.h
+++ b/Modules/Hyperspectral/Unmixing/include/otbUnConstrainedLeastSquareImageFilter.h
@@ -22,7 +22,7 @@
 #define otbUnConstrainedLeastSquareImageFilter_h
 
 #include "itkMacro.h"
-#include "otbUnaryFunctorImageFilter.h"
+#include "otbFunctorImageFilter.h"
 #include "vnl/algo/vnl_svd.h"
 #include <boost/shared_ptr.hpp>
 
@@ -33,8 +33,9 @@ namespace Functor {
 
 /** \class UnConstrainedLeastSquareFunctor
  *
- * \brief TODO
+ * \brief Solves a least square system on a pixel
  *
+ * \sa UnConstrainedLeastSquareImageFilter
  *
  * \ingroup OTBUnmixing
  */
@@ -49,51 +50,14 @@ public:
   typedef vnl_vector<PrecisionType> VectorType;
   typedef vnl_matrix<PrecisionType> MatrixType;
 
-  UnConstrainedLeastSquareFunctor() : m_OutputSize(0) {}
-  virtual ~UnConstrainedLeastSquareFunctor() {}
-
-  unsigned int GetOutputSize() const
-  {
-    return m_OutputSize;
-  }
-
-  bool operator != (const UnConstrainedLeastSquareFunctor& itkNotUsed(other)) const
-  {
-    return true;
-  }
-
-  bool operator == (const UnConstrainedLeastSquareFunctor& other) const
-  {
-    return !(*this != other);
-  }
-
-  void SetMatrix(const MatrixType& m)
-  {
-    //std::cout << "m : " << m.rows() << " " << m.cols() << std::endl;
-    m_Svd.reset( new SVDType(m) );
-    m_Inv = m_Svd->inverse();
-    m_OutputSize = m.cols();
-  }
-
-  OutputType operator ()(const InputType& in) const
-  {
-    // TODO : support different types between input and output ?
-    VectorType inVector(in.Size());
-    for (unsigned int i = 0; i < in.GetSize(); ++i )
-      {
-      inVector[i] = in[i];
-      }
-
-    VectorType outVector = m_Inv * inVector;
-
-    OutputType out(outVector.size());
-    for (unsigned int i = 0; i < out.GetSize(); ++i )
-      {
-      out[i] = outVector[i];
-      }
-
-    return out;
-  }
+  UnConstrainedLeastSquareFunctor() : m_OutputSize(0) {};
+  virtual ~UnConstrainedLeastSquareFunctor() = default;
+
+  size_t OutputSize(const std::array<size_t,1> & nbBands) const;
+
+  void SetMatrix(const MatrixType& m);
+
+  OutputType operator ()(const InputType& in) const;
 
 private:
 
@@ -106,7 +70,7 @@ private:
 };
 }
 
-/** \class UnConstrainedLeastSquareImageFilter
+/** \typedef UnConstrainedLeastSquareImageFilter
  *
  * \brief Solves a least square system for each pixel
  *
@@ -127,63 +91,10 @@ private:
  *
  * \ingroup OTBUnmixing
  */
-template <class TInputImage, class TOutputImage, class TPrecision>
-class ITK_EXPORT UnConstrainedLeastSquareImageFilter :
-  public otb::UnaryFunctorImageFilter<TInputImage, TOutputImage,
-      Functor::UnConstrainedLeastSquareFunctor<typename TInputImage::PixelType,
-          typename TOutputImage::PixelType, TPrecision> >
-{
-public:
-  /** Standard class typedefs. */
-  typedef UnConstrainedLeastSquareImageFilter Self;
-  typedef otb::UnaryFunctorImageFilter
-     <TInputImage,
-      TOutputImage,
-      Functor::UnConstrainedLeastSquareFunctor<
-          typename TInputImage::PixelType,
-          typename TOutputImage::PixelType,
-          TPrecision>
-     >                                 Superclass;
-
-  typedef itk::SmartPointer<Self>       Pointer;
-  typedef itk::SmartPointer<const Self> ConstPointer;
-
-  typedef Functor::UnConstrainedLeastSquareFunctor<
-      typename TInputImage::PixelType,
-      typename TOutputImage::PixelType,
-      TPrecision> FunctorType;
-
-  typedef typename FunctorType::MatrixType MatrixType;
-
-  /** Method for creation through the object factory. */
-  itkNewMacro(Self);
-
-  /** Run-time type information (and related methods). */
-  itkTypeMacro(UnConstrainedLeastSquareImageFilter, otb::UnaryFunctorImageFilter);
-
-  /** Pixel types. */
-  typedef typename TInputImage::PixelType  InputPixelType;
-  typedef typename TOutputImage::PixelType OutputPixelType;
-
-  void SetMatrix(const MatrixType& m)
-  {
-    this->GetFunctor().SetMatrix(m);
-    this->Modified();
-  }
-
-protected:
-  UnConstrainedLeastSquareImageFilter();
-
-  ~UnConstrainedLeastSquareImageFilter() override {}
-
-  void PrintSelf(std::ostream& os, itk::Indent indent) const override;
-
-private:
-  UnConstrainedLeastSquareImageFilter(const Self &) = delete;
-
-  void operator =(const Self&) = delete;
-
-};
+template <typename TInputImage, typename TOutputImage, typename TPrecision>
+using UnConstrainedLeastSquareImageFilter = FunctorImageFilter<
+        Functor::UnConstrainedLeastSquareFunctor<typename TInputImage::PixelType,
+          typename TOutputImage::PixelType, TPrecision> >;
 
 } // end namespace otb
 
diff --git a/Modules/Hyperspectral/Unmixing/include/otbUnConstrainedLeastSquareImageFilter.hxx b/Modules/Hyperspectral/Unmixing/include/otbUnConstrainedLeastSquareImageFilter.hxx
index 151b927bff..4d939d2569 100644
--- a/Modules/Hyperspectral/Unmixing/include/otbUnConstrainedLeastSquareImageFilter.hxx
+++ b/Modules/Hyperspectral/Unmixing/include/otbUnConstrainedLeastSquareImageFilter.hxx
@@ -25,24 +25,51 @@
 
 namespace otb
 {
+namespace Functor
+{
 
-/**
- *
- */
-template <class TInputImage, class TOutputImage, class TPrecision>
-UnConstrainedLeastSquareImageFilter<TInputImage, TOutputImage, TPrecision>
-::UnConstrainedLeastSquareImageFilter()
+template <class TInput, class TOutput, class TPrecision>
+size_t
+UnConstrainedLeastSquareFunctor<TInput, TOutput, TPrecision>
+::OutputSize(const std::array<size_t,1> & itkNotUsed(nbBands)) const
 {
+  return m_OutputSize;
 }
 
-template <class TInputImage, class TOutputImage, class TPrecision>
+template <class TInput, class TOutput, class TPrecision>
 void
-UnConstrainedLeastSquareImageFilter<TInputImage, TOutputImage, TPrecision>
-::PrintSelf(std::ostream& os, itk::Indent indent) const
+UnConstrainedLeastSquareFunctor<TInput, TOutput, TPrecision>
+::SetMatrix(const MatrixType& m)
 {
-  Superclass::PrintSelf(os, indent);
+  m_Svd.reset( new SVDType(m) );
+  m_Inv = m_Svd->inverse();
+  m_OutputSize = m.cols();
 }
 
-} // end namespace
+template <class TInput, class TOutput, class TPrecision>
+typename UnConstrainedLeastSquareFunctor<TInput, TOutput, TPrecision>::OutputType 
+UnConstrainedLeastSquareFunctor<TInput, TOutput, TPrecision>
+::operator ()(const InputType& in) const
+{
+  VectorType inVector(in.Size());
+  for (unsigned int i = 0; i < in.GetSize(); ++i )
+  {
+    inVector[i] = in[i];
+  }
+
+  VectorType outVector = m_Inv * inVector;
+
+  OutputType out(outVector.size());
+  for (unsigned int i = 0; i < out.GetSize(); ++i )
+  {
+    out[i] = outVector[i];
+  }
+
+  return out;
+  }
+
+
+} // end namespace Functor
+} // end namespace otb
 
 #endif
diff --git a/Modules/Hyperspectral/Unmixing/test/otbUnConstrainedLeastSquareImageFilter.cxx b/Modules/Hyperspectral/Unmixing/test/otbUnConstrainedLeastSquareImageFilter.cxx
index 3a031bdd08..1ab8e00bae 100644
--- a/Modules/Hyperspectral/Unmixing/test/otbUnConstrainedLeastSquareImageFilter.cxx
+++ b/Modules/Hyperspectral/Unmixing/test/otbUnConstrainedLeastSquareImageFilter.cxx
@@ -57,7 +57,7 @@ int otbUnConstrainedLeastSquareImageFilterTest(int itkNotUsed(argc), char * argv
       UnConstrainedLeastSquareSolverType::New();
 
   unmixer->SetInput(readerImage->GetOutput());
-  unmixer->SetMatrix(endMember2Matrix->GetMatrix());
+  unmixer->GetModifiableFunctor().SetMatrix(endMember2Matrix->GetMatrix());
 
   WriterType::Pointer writer = WriterType::New();
   writer->SetFileName(outputImage);
-- 
GitLab