diff --git a/Modules/Applications/AppHyperspectral/app/otbSpectralAngleClassification.cxx b/Modules/Applications/AppHyperspectral/app/otbSpectralAngleClassification.cxx
index 98aeb935cb94b9dc4ba8fdef5c830ae5d883899a..5e4eec3dd663715220450f7e0eb3e8679e34d9d6 100644
--- a/Modules/Applications/AppHyperspectral/app/otbSpectralAngleClassification.cxx
+++ b/Modules/Applications/AppHyperspectral/app/otbSpectralAngleClassification.cxx
@@ -192,21 +192,11 @@ private:
                                               : std::numeric_limits<ValueType>::max();
       auto bv = GetParameterInt("bv");
       
-      // This lambda return the index of the minimum value in a pixel, values above threshold are not classified.
+      // This lambda return the index of the minimum value in a pixel, values above threshold are classified as background values.
       auto minIndexLambda = [threshold, bv](PixelType const & pixel)
       {
-        auto min = threshold;
-        int res = bv;
-        
-        for (unsigned int i = 0; i < pixel.Size(); i++)
-        {
-          if (pixel[i] < min)
-          {
-            min = pixel[i];
-            res = i+1;
-          }
-        }
-        return res;
+        auto minElem = std::min_element(&pixel[0], &pixel[pixel.Size()]);
+        return static_cast<int>(*minElem < threshold ? std::distance(&pixel[0], minElem) + 1 : bv);
       };
       
       auto classificationFilter = NewFunctorFilter(minIndexLambda);
diff --git a/Modules/Filtering/ImageManipulation/include/otbBinarySpectralAngleFunctor.h b/Modules/Filtering/ImageManipulation/include/otbBinarySpectralAngleFunctor.h
index 59d0bf2f3c965bc9469c3d09e3e8e7a393db88e3..34a476efea28d092a5f64815593a0756c0879321 100644
--- a/Modules/Filtering/ImageManipulation/include/otbBinarySpectralAngleFunctor.h
+++ b/Modules/Filtering/ImageManipulation/include/otbBinarySpectralAngleFunctor.h
@@ -49,12 +49,13 @@ public:
   virtual ~BinarySpectralAngleFunctor() = default;
 
   // Binary operator
-  inline TOutputValue operator()(const TInput1& in1, const TInput2& in2) const
+  TOutputValue operator()(const TInput1& in1, const TInput2& in2) const
   {
     // Compute norms.
     auto in1Norm = 0;
     auto in2Norm = 0;
-    for (unsigned int i = 0; i < std::min(in1.Size(), in2.Size()); ++i)
+    auto nbIter = std::min(in1.Size(), in2.Size());
+    for (unsigned int i = 0; i < nbIter; ++i)
     {
       in1Norm += in1[i] * in1[i];
       in2Norm += in2[i] * in2[i];
diff --git a/Modules/Filtering/ImageManipulation/include/otbSpectralAngleFunctor.h b/Modules/Filtering/ImageManipulation/include/otbSpectralAngleFunctor.h
index 3670a8c84040df812a34278b490043b9f3f1a960..8b6c1ab13264aaa6621c335aaea50cc183276da4 100644
--- a/Modules/Filtering/ImageManipulation/include/otbSpectralAngleFunctor.h
+++ b/Modules/Filtering/ImageManipulation/include/otbSpectralAngleFunctor.h
@@ -41,12 +41,7 @@ template <class TInput, class TReference, class TOutput>
 TOutput ComputeSpectralAngle(TInput const & input, typename TInput ::ValueType const & inputNorm, 
                               TReference const & reference, typename TReference::ValueType refNorm)
 {
-  // Compute scalar product.
-  double scalarProduct   = 0.0;
-  for (unsigned int i = 0; i < std::min(input.Size(), reference.Size()); ++i)
-  {
-    scalarProduct += input[i] * reference[i];
-  }
+  double scalarProduct = std::inner_product(&input[0], &input[input.Size()], &reference[0], 0. );
   auto normProd = inputNorm * refNorm;
   if ((normProd == 0.0) || (scalarProduct / normProd > 1))
   {
@@ -75,7 +70,7 @@ public:
     m_ReferencePixel.Fill(1);
   }
 
-  virtual ~SpectralAngleFunctor() = default;
+  ~SpectralAngleFunctor() = default;
 
   // Binary operator
   inline TOutputValue operator()(TInput const & inPix) const
@@ -114,8 +109,7 @@ public:
   // Binary operator
   inline TOutput operator()(const TInput& inPix) const
   {
-    TOutput res;
-    res.SetSize(m_ReferencePixels.size());
+    TOutput res(m_ReferencePixels.size());
     
     auto inputNorm = inPix.GetNorm();
     
@@ -133,18 +127,18 @@ public:
     return m_ReferencePixels.size();
   }
 
-  void SetReferencePixels(std::vector<TReference> const & ref)
+  void SetReferencePixels(std::vector<TReference> ref)
   {
-    m_ReferencePixels = ref;
+    m_ReferencePixels = std::move(ref);
     m_ReferenceNorm.clear();
     // Precompute the norm of reference pixels
-    for (auto const & pix : ref)
+    for (auto const & pixel : m_ReferencePixels)
     {
-      m_ReferenceNorm.push_back(pix.GetNorm());
+      m_ReferenceNorm.push_back(pixel.GetNorm());
     }
   }
   
-  std::vector<TReference> GetReferencePixels() const
+  std::vector<TReference> const & GetReferencePixels() const
   {
     return m_ReferencePixels;
   }
diff --git a/Modules/Filtering/ImageManipulation/include/otbSpectralInformationDivergenceFunctor.h b/Modules/Filtering/ImageManipulation/include/otbSpectralInformationDivergenceFunctor.h
index 6236a0adeda3dbb720468dd847c6444a7bcca5f2..b89f84a8e59b3eb9fe9462f63c7435a31be6d90c 100644
--- a/Modules/Filtering/ImageManipulation/include/otbSpectralInformationDivergenceFunctor.h
+++ b/Modules/Filtering/ImageManipulation/include/otbSpectralInformationDivergenceFunctor.h
@@ -89,7 +89,7 @@ private:
       // Input pixel should be non negative (e.g. reflectance, radiance)
       if (input[i] <= 0) 
       {
-        throw std::domain_error("Input pixel of the spectral information divergence algorithm should be strictly positive.");
+        throw std::runtime_error("Input pixels of the spectral information divergence algorithm should be strictly positive.");
       }
       sum += input[i];
     }
@@ -107,7 +107,8 @@ private:
     OutputValueType sid = 0.0;
     for (unsigned int i = 0; i < p.Size(); i++)
     {
-      sid += p[i] * std::log(p[i]/q[i]) + q[i] * std::log(q[i]/p[i]);
+      // Compute SID : p[i] * std::log(p[i]/q[i]) + q[i] * std::log(q[i]/p[i]);
+      sid += (p[i] - q[i]) * std::log(p[i]/q[i]);
     }
     return sid;
   }