diff OrthancStone/Sources/Toolbox/LinearAlgebra.cpp @ 1890:6ce81914f7e4

added classes BucketAccumulator1D/2D
author Sebastien Jodogne <s.jodogne@gmail.com>
date Tue, 18 Jan 2022 22:08:55 +0100
parents 7053b8a0aaec
children 187a261d7ae2
line wrap: on
line diff
--- a/OrthancStone/Sources/Toolbox/LinearAlgebra.cpp	Tue Jan 18 17:52:43 2022 +0100
+++ b/OrthancStone/Sources/Toolbox/LinearAlgebra.cpp	Tue Jan 18 22:08:55 2022 +0100
@@ -717,6 +717,49 @@
 
       return m;
     }
+
+
+    template <typename T>
+    static T ComputeMedianInternal(std::vector<T>& v)
+    {
+      if (v.size() == 0)
+      {
+        throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange, "Empty vector");
+      }
+      
+      const size_t middle = v.size() / 2;
+      nth_element(v.begin(), v.begin() + middle, v.end());
+
+      T median = v[middle];
+      
+      if (v.size() % 2 == 1)
+      {
+        return median;
+      }
+      else
+      {
+        /**
+         * Side-effect of "nth_element()": "All of the elements before
+         * this new nth element are less than or equal to the elements
+         * after the new nth element."
+         * https://en.cppreference.com/w/cpp/algorithm/nth_element
+         **/
+        
+        typename std::vector<T>::const_iterator m = std::max_element(v.begin(), v.begin() + middle);
+
+        return (*m + median) / static_cast<T>(2);
+      }
+    }
+
+    double ComputeMedian(std::vector<double>& v)
+    {
+      return ComputeMedianInternal<double>(v);
+    }
+
+    float ComputeMedian(std::vector<float>& v)
+    {
+      return ComputeMedianInternal<float>(v);
+    }
   }
 
   std::ostream& operator<<(std::ostream& s, const Vector& vec)