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 === // === stddev_over_time(Matrix parser.ValueTypeMatrix) Vector ===
func funcStddevOverTime(vals []parser.Value, args parser.Expressions, enh *EvalNodeHelper) Vector { func funcStddevOverTime(vals []parser.Value, args parser.Expressions, enh *EvalNodeHelper) Vector {
return aggrOverTime(vals, enh, func(values []Point) float64 { 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 { for _, v := range values {
count++ count++
delta := v.V - mean delta := v.V - (mean + cMean)
mean += delta / count mean, cMean = kahanSumInc(delta/count, mean, cMean)
aux += delta * (v.V - mean) 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 === // === stdvar_over_time(Matrix parser.ValueTypeMatrix) Vector ===
func funcStdvarOverTime(vals []parser.Value, args parser.Expressions, enh *EvalNodeHelper) Vector { func funcStdvarOverTime(vals []parser.Value, args parser.Expressions, enh *EvalNodeHelper) Vector {
return aggrOverTime(vals, enh, func(values []Point) float64 { 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 { for _, v := range values {
count++ count++
delta := v.V - mean delta := v.V - (mean + cMean)
mean += delta / count mean, cMean = kahanSumInc(delta/count, mean, cMean)
aux += delta * (v.V - mean) 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)} vals := []float64{1.0, math.Pow(10, 100), 1.0, -1 * math.Pow(10, 100)}
expected := 2.0 expected := 2.0
require.Equal(t, expected, kahanSummation(vals)) require.Equal(t, expected, kahanSum(vals))
} }