use kahan summation for aggregation functions

Signed-off-by: darshanime <deathbullet@gmail.com>
This commit is contained in:
darshanime 2021-10-30 19:41:36 +05:30
parent 694b872dee
commit 42d786f1ac
2 changed files with 16 additions and 12 deletions

View File

@ -471,28 +471,32 @@ func funcQuantileOverTime(vals []parser.Value, args parser.Expressions, enh *Eva
// === stddev_over_time(Matrix parser.ValueTypeMatrix) Vector ===
func funcStddevOverTime(vals []parser.Value, args parser.Expressions, enh *EvalNodeHelper) Vector {
return aggrOverTime(vals, enh, func(values []Point) float64 {
var aux, count, mean float64
var count float64
var mean, cMean float64
var aux, cAux float64
for _, v := range values {
count++
delta := v.V - mean
mean += delta / count
aux += delta * (v.V - mean)
delta := v.V - (mean + cMean)
mean, cMean = kahanSumInc(delta/count, mean, cMean)
aux, cAux = kahanSumInc(delta*(v.V-(mean+cMean)), aux, cAux)
}
return math.Sqrt(aux / count)
return math.Sqrt((aux + cAux) / count)
})
}
// === stdvar_over_time(Matrix parser.ValueTypeMatrix) Vector ===
func funcStdvarOverTime(vals []parser.Value, args parser.Expressions, enh *EvalNodeHelper) Vector {
return aggrOverTime(vals, enh, func(values []Point) float64 {
var aux, count, mean float64
var count float64
var mean, cMean float64
var aux, cAux float64
for _, v := range values {
count++
delta := v.V - mean
mean += delta / count
aux += delta * (v.V - mean)
delta := v.V - (mean + cMean)
mean, cMean = kahanSumInc(delta/count, mean, cMean)
aux, cAux = kahanSumInc(delta*(v.V-(mean+cMean)), aux, cAux)
}
return aux / count
return (aux + cAux) / count
})
}

View File

@ -73,8 +73,8 @@ func TestFunctionList(t *testing.T) {
}
}
func TestKahanSummation(t *testing.T) {
func TestKahanSum(t *testing.T) {
vals := []float64{1.0, math.Pow(10, 100), 1.0, -1 * math.Pow(10, 100)}
expected := 2.0
require.Equal(t, expected, kahanSummation(vals))
require.Equal(t, expected, kahanSum(vals))
}