From b781e152c1a42a2cea9bf649ca5cca8af0c974d7 Mon Sep 17 00:00:00 2001
From: Rainer Kartmann <rainer.kartmann@student.kit.edu>
Date: Thu, 14 Mar 2019 16:02:44 +0100
Subject: [PATCH] Added statistics measures

---
 VirtualRobot/CMakeLists.txt               |   2 +
 VirtualRobot/math/statistics/measures.cpp | 110 ++++++++++++++++++++++
 VirtualRobot/math/statistics/measures.h   |  31 ++++++
 3 files changed, 143 insertions(+)
 create mode 100644 VirtualRobot/math/statistics/measures.cpp
 create mode 100644 VirtualRobot/math/statistics/measures.h

diff --git a/VirtualRobot/CMakeLists.txt b/VirtualRobot/CMakeLists.txt
index 1bf2d54b7..7af2f9508 100644
--- a/VirtualRobot/CMakeLists.txt
+++ b/VirtualRobot/CMakeLists.txt
@@ -334,6 +334,7 @@ math/Plane.cpp
 math/Primitive.cpp
 math/Triangle.cpp
 math/WeightedAverage.cpp
+math/statistics/measures.cpp
 Util/xml/tinyxml2.cpp
 Util/json/eigen_conversion.cpp
 )
@@ -507,6 +508,7 @@ math/TransformedFunctionR1R3.h
 math/TransformedFunctionR2R3.h
 math/Triangle.h
 math/WeightedAverage.h
+math/statistics/measures.h
 Util/xml/tinyxml2.h
 Util/json/json.hpp
 Util/json/eigen_conversion.h
diff --git a/VirtualRobot/math/statistics/measures.cpp b/VirtualRobot/math/statistics/measures.cpp
new file mode 100644
index 000000000..59fa4486d
--- /dev/null
+++ b/VirtualRobot/math/statistics/measures.cpp
@@ -0,0 +1,110 @@
+#include "measures.h"
+
+#include <algorithm>
+#include <cmath>
+#include <stdexcept>
+
+
+namespace math { namespace stat
+{
+
+void sort(std::vector<float>& values)
+{
+    std::sort(values.begin(), values.end());
+}
+
+std::vector<float> sorted(const std::vector<float>& values)
+{
+    std::vector<float> s = values;
+    std::sort(s.begin(), s.end());
+    return s;
+}
+
+float min(const std::vector<float>& values, bool isSorted)
+{
+    return isSorted ? values.front() : *std::min_element(values.begin(), values.end());
+}
+
+float max(const std::vector<float>& values, bool isSorted)
+{
+    return isSorted ? values.back() : *std::max_element(values.begin(), values.end());
+}
+
+float mean(const std::vector<float>& values)
+{
+    if (values.empty() == 0)
+        throw std::range_error("Given values are empty.");
+    
+    float sum = 0;
+    for (float v : values)
+    {
+        sum += v;
+    }
+    return sum / values.size();
+}
+
+float stddev(const std::vector<float>& values)
+{
+    return stddev(values, mean(values));
+}
+
+float stddev(const std::vector<float>& values, float mean)
+{
+    float sum = 0;
+    for (float v : values)
+    {
+        float diff = v - mean;
+        sum += diff * diff;
+    }
+    float variance = sum / (values.size() - 1);
+    return std::sqrt(variance);
+}
+
+float quantile(const std::vector<float>& _values, float p, bool isSorted)
+{
+    const std::vector<float>& values = isSorted ? _values : sorted(_values);
+    
+    float location = p * values.size();
+    
+    std::size_t floor = static_cast<std::size_t>(std::floor(location));
+    std::size_t ceil = static_cast<std::size_t>(std::ceil(location));
+    
+    if (floor == ceil)
+    {
+        return values.at(floor);
+    }
+    else
+    {
+        float t = location - floor;
+        return (1 - t) * values.at(floor) + t * values.at(ceil);
+    }
+}
+
+float lowerQuartile(const std::vector<float>& values, bool isSorted)
+{
+    return quantile(values, .25, isSorted);
+}
+
+float median(const std::vector<float>& values, bool isSorted)
+{
+    return quantile(values, .5, isSorted);
+}
+
+float upperQuartile(const std::vector<float>& values, bool isSorted)
+{
+    return quantile(values, .75, isSorted);
+}
+
+float interquartileRange(const std::vector<float>& _values, bool isSorted)
+{
+    const std::vector<float>& values = isSorted ? _values : sorted(_values);
+    return interquartileRange(lowerQuartile(values, true), upperQuartile(values, true));
+}
+
+float interquartileRange(float lowerQuartile, float upperQuartile)
+{
+    return upperQuartile - lowerQuartile;
+}
+
+
+}}
diff --git a/VirtualRobot/math/statistics/measures.h b/VirtualRobot/math/statistics/measures.h
new file mode 100644
index 000000000..dd18caa2b
--- /dev/null
+++ b/VirtualRobot/math/statistics/measures.h
@@ -0,0 +1,31 @@
+#pragma once
+
+#include <vector>
+
+
+namespace math { namespace stat
+{
+
+    void sort(std::vector<float>& values);
+    std::vector<float> sorted(const std::vector<float>& values);
+
+    
+    float min(const std::vector<float>& values, bool isSorted=false);
+    float max(const std::vector<float>& values, bool isSorted=false);
+    float mean(const std::vector<float>& values);
+    
+    float stddev(const std::vector<float>& values);
+    float stddev(const std::vector<float>& values, float mean);
+    
+    float quantile(const std::vector<float>& values, float p, bool isSorted=false);
+    
+    float lowerQuartile(const std::vector<float>& values, bool isSorted=false);
+    float median(const std::vector<float>& values, bool isSorted=false);
+    float upperQuartile(const std::vector<float>& values, bool isSorted=false);
+    
+    float interquartileRange(const std::vector<float>& values, bool isSorted=false);
+    float interquartileRange(float lowerQuartile, float upperQuartile);
+    
+
+
+}}
-- 
GitLab