Module: check_mk
Branch: master
Commit: 7fadec11c731a571f8bb0d336a118d2cdeaf9d85
URL:
http://git.mathias-kettner.de/git/?p=check_mk.git;a=commit;h=7fadec11c731a5…
Author: Sven Panne <sp(a)mathias-kettner.de>
Date: Fri Nov 24 11:02:54 2017 +0100
5465 FIX Fixed calculation of standard deviation.
Note: This fixes only a slightly esoteric feature, namely "Stats: std ..."
headers. Normal users are not affected, only those using this header via
self-written scripts.
Livestatus incorrectly used a bias correction when calculating the standard
deviation. For more mathematical background see:
https://en.wikipedia.org/wiki/Bessel%27s_correction
http://mathworld.wolfram.com/StandardDeviation.html
Change-Id: I54ee4adb94dd1bda2afb4b558c647484b768ea0c
---
.werks/5465 | 18 ++++++++++++++++++
livestatus/src/DoubleAggregator.cc | 6 ++++--
livestatus/src/IntAggregator.cc | 6 ++++--
livestatus/src/PerfdataAggregator.cc | 19 ++++++++-----------
livestatus/src/TimeAggregator.cc | 6 ++++--
5 files changed, 38 insertions(+), 17 deletions(-)
diff --git a/.werks/5465 b/.werks/5465
new file mode 100644
index 0000000..2cb94e8
--- /dev/null
+++ b/.werks/5465
@@ -0,0 +1,18 @@
+Title: Fixed calculation of standard deviation.
+Level: 1
+Component: livestatus
+Compatible: compat
+Edition: cre
+Version: 1.5.0i2
+Date: 1511517478
+Class: fix
+
+Note: This fixes only a slightly esoteric feature, namely "Stats: std ..."
+headers. Normal users are not affected, only those using this header via
+self-written scripts.
+
+Livestatus incorrectly used a bias correction when calculating the standard
+deviation. For more mathematical background see:
+
+
https://en.wikipedia.org/wiki/Bessel%27s_correction
+
http://mathworld.wolfram.com/StandardDeviation.html
diff --git a/livestatus/src/DoubleAggregator.cc b/livestatus/src/DoubleAggregator.cc
index 5ed83a0..b0c6c2c 100644
--- a/livestatus/src/DoubleAggregator.cc
+++ b/livestatus/src/DoubleAggregator.cc
@@ -87,9 +87,11 @@ void DoubleAggregator::output(RowRenderer& r) const {
r.output(_aggr / _count);
break;
- case StatsOperation::std:
- r.output(sqrt((_sumq - _aggr * _aggr / _count) / (_count - 1)));
+ case StatsOperation::std: {
+ auto mean = _aggr / _count;
+ r.output(sqrt(_sumq / _count - mean * mean));
break;
+ }
case StatsOperation::suminv:
r.output(_aggr);
diff --git a/livestatus/src/IntAggregator.cc b/livestatus/src/IntAggregator.cc
index b130f30..ef97737 100644
--- a/livestatus/src/IntAggregator.cc
+++ b/livestatus/src/IntAggregator.cc
@@ -87,9 +87,11 @@ void IntAggregator::output(RowRenderer &r) const {
r.output(_aggr / _count);
break;
- case StatsOperation::std:
- r.output(sqrt((_sumq - _aggr * _aggr / _count) / (_count - 1)));
+ case StatsOperation::std: {
+ auto mean = _aggr / _count;
+ r.output(sqrt(_sumq / _count - mean * mean));
break;
+ }
case StatsOperation::suminv:
r.output(_aggr);
diff --git a/livestatus/src/PerfdataAggregator.cc b/livestatus/src/PerfdataAggregator.cc
index 3653477..d007da5 100644
--- a/livestatus/src/PerfdataAggregator.cc
+++ b/livestatus/src/PerfdataAggregator.cc
@@ -53,11 +53,7 @@ void PerfdataAggregator::consumeVariable(const std::string
&varname,
double value) {
auto it = _aggr.find(varname);
if (it == _aggr.end()) { // first entry
- perf_aggr new_entry;
- new_entry._count = 1;
- new_entry._aggr = value;
- new_entry._sumq = value * value;
- _aggr.emplace(varname, new_entry);
+ _aggr.emplace(varname, perf_aggr{1, value, value * value});
} else {
it->second._count++;
switch (_operation) {
@@ -122,12 +118,13 @@ void PerfdataAggregator::output(RowRenderer &r) const {
break;
case StatsOperation::std:
- value = entry.second._count <= 1
- ? 0.0
- : sqrt((entry.second._sumq -
- (entry.second._aggr * entry.second._aggr) /
- entry.second._count) /
- (entry.second._count - 1));
+ if (entry.second._count == 0) {
+ value = 0.0;
+ } else {
+ auto mean = entry.second._aggr / entry.second._count;
+ value = sqrt(entry.second._sumq / entry.second._count -
+ mean * mean);
+ }
break;
case StatsOperation::suminv:
diff --git a/livestatus/src/TimeAggregator.cc b/livestatus/src/TimeAggregator.cc
index 461b400..8baa6b5 100644
--- a/livestatus/src/TimeAggregator.cc
+++ b/livestatus/src/TimeAggregator.cc
@@ -88,9 +88,11 @@ void TimeAggregator::output(RowRenderer &r) const {
r.output(_aggr / _count);
break;
- case StatsOperation::std:
- r.output(sqrt((_sumq - _aggr * _aggr / _count) / (_count - 1)));
+ case StatsOperation::std: {
+ auto mean = _aggr / _count;
+ r.output(sqrt(_sumq / _count - mean * mean));
break;
+ }
case StatsOperation::suminv:
r.output(_aggr);