Merge pull request #2354 from neonstalwart/stddev

make stddev work
pull/2443/merge
Paul Dix 2015-04-29 15:27:26 -07:00
commit 8d91b75a5a
2 changed files with 44 additions and 11 deletions

View File

@ -581,14 +581,41 @@ func runTestsData(t *testing.T, testName string, nodes Cluster, database, retent
// Aggregations // Aggregations
{ {
reset: true, reset: true,
name: "large mean", name: "stddev with just one point",
write: `{"database" : "%DB%", "retentionPolicy" : "%RP%", "points": [
{"name": "cpu", "timestamp": "2015-04-20T14:27:41Z", "fields": {"value": 45}}
]}`,
query: `SELECT stddev(value) FROM cpu`,
queryDb: "%DB%",
expected: `{"results":[{"series":[{"name":"cpu","columns":["time","stddev"],"values":[["1970-01-01T00:00:00Z",null]]}]}]}`,
},
{
reset: true,
name: "large mean and stddev",
write: `{"database" : "%DB%", "retentionPolicy" : "%RP%", "points": [ write: `{"database" : "%DB%", "retentionPolicy" : "%RP%", "points": [
{"name": "cpu", "timestamp": "2015-04-20T14:27:40Z", "fields": {"value": ` + string(maxFloat64) + `}}, {"name": "cpu", "timestamp": "2015-04-20T14:27:40Z", "fields": {"value": ` + string(maxFloat64) + `}},
{"name": "cpu", "timestamp": "2015-04-20T14:27:41Z", "fields": {"value": ` + string(maxFloat64) + `}} {"name": "cpu", "timestamp": "2015-04-20T14:27:41Z", "fields": {"value": ` + string(maxFloat64) + `}}
]}`, ]}`,
query: `SELECT mean(value) FROM cpu`, query: `SELECT mean(value), stddev(value) FROM cpu`,
queryDb: "%DB%", queryDb: "%DB%",
expected: `{"results":[{"series":[{"name":"cpu","columns":["time","mean"],"values":[["1970-01-01T00:00:00Z",` + string(maxFloat64) + `]]}]}]}`, expected: `{"results":[{"series":[{"name":"cpu","columns":["time","mean","stddev"],"values":[["1970-01-01T00:00:00Z",` + string(maxFloat64) + `,0]]}]}]}`,
},
{
reset: true,
name: "mean and stddev",
write: `{"database" : "%DB%", "retentionPolicy" : "%RP%", "points": [
{"name": "cpu", "timestamp": "2000-01-01T00:00:00Z", "fields": {"value": 2}},
{"name": "cpu", "timestamp": "2000-01-01T00:00:10Z", "fields": {"value": 4}},
{"name": "cpu", "timestamp": "2000-01-01T00:00:20Z", "fields": {"value": 4}},
{"name": "cpu", "timestamp": "2000-01-01T00:00:30Z", "fields": {"value": 4}},
{"name": "cpu", "timestamp": "2000-01-01T00:00:40Z", "fields": {"value": 5}},
{"name": "cpu", "timestamp": "2000-01-01T00:00:50Z", "fields": {"value": 5}},
{"name": "cpu", "timestamp": "2000-01-01T00:01:00Z", "fields": {"value": 7}},
{"name": "cpu", "timestamp": "2000-01-01T00:01:10Z", "fields": {"value": 9}}
]}`,
query: `SELECT mean(value), stddev(value) FROM cpu WHERE time >= '2000-01-01' AND time < '2000-01-01T00:02:00Z' GROUP BY time(10m)`,
queryDb: "%DB%",
expected: `{"results":[{"series":[{"name":"cpu","columns":["time","mean","stddev"],"values":[["2000-01-01T00:00:00Z",5,2.138089935299395]]}]}]}`,
}, },
{ {
reset: true, reset: true,

View File

@ -157,6 +157,12 @@ func InitializeUnmarshaller(c *Call) (UnmarshalFunc, error) {
err := json.Unmarshal(b, &o) err := json.Unmarshal(b, &o)
return &o, err return &o, err
}, nil }, nil
case "stddev":
return func(b []byte) (interface{}, error) {
val := make([]float64, 0)
err := json.Unmarshal(b, &val)
return val, err
}, nil
default: default:
return func(b []byte) (interface{}, error) { return func(b []byte) (interface{}, error) {
var val interface{} var val interface{}
@ -395,7 +401,7 @@ func MapStddev(itr Iterator) interface{} {
values = append(values, v.(float64)) values = append(values, v.(float64))
} }
return nil return values
} }
// ReduceStddev computes the stddev of values. // ReduceStddev computes the stddev of values.
@ -414,13 +420,13 @@ func ReduceStddev(values []interface{}) interface{} {
return nil return nil
} }
// Get the sum
var sum float64
for _, v := range data {
sum += v
}
// Get the mean // Get the mean
mean := sum / float64(len(data)) var mean float64
var count int
for _, v := range data {
count++
mean += (v - mean) / float64(count)
}
// Get the variance // Get the variance
var variance float64 var variance float64
for _, v := range data { for _, v := range data {
@ -428,7 +434,7 @@ func ReduceStddev(values []interface{}) interface{} {
sq := math.Pow(dif, 2) sq := math.Pow(dif, 2)
variance += sq variance += sq
} }
variance = variance / float64(len(data)-1) variance = variance / float64(count-1)
stddev := math.Sqrt(variance) stddev := math.Sqrt(variance)
return stddev return stddev