-
Notifications
You must be signed in to change notification settings - Fork 0
/
stddev.h
107 lines (93 loc) · 2.01 KB
/
stddev.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
#ifndef _STDDEV_H
#define _STDDEV_H
/*
* Basic statistics module: standard deviation routines.
#include <stdint.h>
#include <stdlib.h>
#include <math.h>
*/
struct stddev
{
int min;
int64_t sum;
uint64_t sum_sq;
uint64_t count;
};
static inline struct stddev *stddev_init(struct stddev *sd)
{
sd->min = INT_MAX;
sd->sum = 0;
sd->sum_sq = 0;
sd->count = 0;
return sd;
}
static inline struct stddev *stddev_new()
{
struct stddev *sd = malloc(sizeof(struct stddev));
return stddev_init(sd);
}
static inline void stddev_free(struct stddev *sd) { free(sd); }
static inline void stddev_add(struct stddev *sd, int value)
{
sd->count++;
sd->sum += value;
sd->sum_sq += value * value;
if (value < sd->min) {
sd->min = value;
}
}
static inline void stddev_remove(struct stddev *sd, int old_value)
{
sd->count--;
sd->sum -= old_value;
sd->sum_sq -= old_value * old_value;
}
static inline void stddev_modify(struct stddev *sd, int old_value,
int new_value)
{
stddev_remove(sd, old_value);
stddev_add(sd, new_value);
}
static inline void stddev_get(struct stddev *sd, uint64_t *counter_ptr,
double *avg_ptr, double *stddev_ptr)
{
double avg = 0.0, dev = 0.0;
double sum = (double)sd->sum, sum_sq = (double)sd->sum_sq,
count = (double)sd->count;
if (avg_ptr) {
if (sd->count != 0) {
avg = sum / count;
}
}
if (stddev_ptr) {
if (sd->count > 2) {
double variance =
(sum_sq - (sum * (sum / count))) / count;
dev = sqrt(fabs(variance));
}
}
if (counter_ptr) {
*counter_ptr = sd->count;
}
if (avg_ptr) {
*avg_ptr = avg;
}
if (stddev_ptr) {
*stddev_ptr = dev;
}
}
static inline void stddev_merge(struct stddev *dst, struct stddev *a,
struct stddev *b)
{
dst->count = a->count + b->count;
dst->sum = a->sum + b->sum;
dst->sum_sq = a->sum_sq + b->sum_sq;
}
static inline void stddev_split(struct stddev *dst, struct stddev *a,
struct stddev *b)
{
dst->count = a->count - b->count;
dst->sum = a->sum - b->sum;
dst->sum_sq = a->sum_sq - b->sum_sq;
}
#endif // _STDDEV_H