1
1
// Package stats provides aggregate functions for statistics.
2
2
//
3
3
// Provided functions:
4
- // - stddev_pop: population standard deviation
5
- // - stddev_samp: sample standard deviation
6
4
// - var_pop: population variance
7
5
// - var_samp: sample variance
6
+ // - stddev_pop: population standard deviation
7
+ // - stddev_samp: sample standard deviation
8
+ // - skewness_pop: Pearson population skewness
9
+ // - skewness_samp: Pearson sample skewness
10
+ // - kurtosis_pop: Fisher population excess kurtosis
11
+ // - kurtosis_samp: Fisher sample excess kurtosis
8
12
// - covar_pop: population covariance
9
13
// - covar_samp: sample covariance
10
- // - corr: correlation coefficient
14
+ // - corr: Pearson correlation coefficient
11
15
// - regr_r2: correlation coefficient squared
12
16
// - regr_avgx: average of the independent variable
13
17
// - regr_avgy: average of the dependent variable
@@ -61,6 +65,10 @@ func Register(db *sqlite3.Conn) error {
61
65
db .CreateWindowFunction ("var_samp" , 1 , flags , newVariance (var_samp )),
62
66
db .CreateWindowFunction ("stddev_pop" , 1 , flags , newVariance (stddev_pop )),
63
67
db .CreateWindowFunction ("stddev_samp" , 1 , flags , newVariance (stddev_samp )),
68
+ db .CreateWindowFunction ("skewness_pop" , 1 , flags , newMoments (skewness_pop )),
69
+ db .CreateWindowFunction ("skewness_samp" , 1 , flags , newMoments (skewness_samp )),
70
+ db .CreateWindowFunction ("kurtosis_pop" , 1 , flags , newMoments (kurtosis_pop )),
71
+ db .CreateWindowFunction ("kurtosis_samp" , 1 , flags , newMoments (kurtosis_samp )),
64
72
db .CreateWindowFunction ("covar_pop" , 2 , flags , newCovariance (var_pop )),
65
73
db .CreateWindowFunction ("covar_samp" , 2 , flags , newCovariance (var_samp )),
66
74
db .CreateWindowFunction ("corr" , 2 , flags , newCovariance (corr )),
@@ -88,6 +96,10 @@ const (
88
96
var_samp
89
97
stddev_pop
90
98
stddev_samp
99
+ skewness_pop
100
+ skewness_samp
101
+ kurtosis_pop
102
+ kurtosis_samp
91
103
corr
92
104
regr_r2
93
105
regr_sxx
@@ -101,6 +113,23 @@ const (
101
113
regr_json
102
114
)
103
115
116
+ func special (kind int , n int64 ) (null , zero bool ) {
117
+ switch kind {
118
+ case var_pop , stddev_pop , regr_sxx , regr_syy , regr_sxy :
119
+ return n <= 0 , n == 1
120
+ case regr_avgx , regr_avgy :
121
+ return n <= 0 , false
122
+ case kurtosis_samp :
123
+ return n <= 3 , false
124
+ case skewness_samp :
125
+ return n <= 2 , false
126
+ case skewness_pop :
127
+ return n <= 1 , n == 2
128
+ default :
129
+ return n <= 1 , false
130
+ }
131
+ }
132
+
104
133
func newVariance (kind int ) func () sqlite3.AggregateFunction {
105
134
return func () sqlite3.AggregateFunction { return & variance {kind : kind } }
106
135
}
@@ -111,14 +140,11 @@ type variance struct {
111
140
}
112
141
113
142
func (fn * variance ) Value (ctx sqlite3.Context ) {
114
- switch fn .n {
115
- case 1 :
116
- switch fn .kind {
117
- case var_pop , stddev_pop :
118
- ctx .ResultFloat (0 )
119
- }
143
+ switch null , zero := special (fn .kind , fn .n ); {
144
+ case zero :
145
+ ctx .ResultFloat (0 )
120
146
return
121
- case 0 :
147
+ case null :
122
148
return
123
149
}
124
150
@@ -166,18 +192,11 @@ func (fn *covariance) Value(ctx sqlite3.Context) {
166
192
ctx .ResultInt64 (fn .regr_count ())
167
193
return
168
194
}
169
- switch fn .n {
170
- case 1 :
171
- switch fn .kind {
172
- case var_pop , stddev_pop , regr_sxx , regr_syy , regr_sxy :
173
- ctx .ResultFloat (0 )
174
- return
175
- case regr_avgx , regr_avgy :
176
- break
177
- default :
178
- return
179
- }
180
- case 0 :
195
+ switch null , zero := special (fn .kind , fn .n ); {
196
+ case zero :
197
+ ctx .ResultFloat (0 )
198
+ return
199
+ case null :
181
200
return
182
201
}
183
202
@@ -234,3 +253,51 @@ func (fn *covariance) Inverse(ctx sqlite3.Context, arg ...sqlite3.Value) {
234
253
fn .dequeue (fa , fb )
235
254
}
236
255
}
256
+
257
+ func newMoments (kind int ) func () sqlite3.AggregateFunction {
258
+ return func () sqlite3.AggregateFunction { return & momentfn {kind : kind } }
259
+ }
260
+
261
+ type momentfn struct {
262
+ kind int
263
+ moments
264
+ }
265
+
266
+ func (fn * momentfn ) Value (ctx sqlite3.Context ) {
267
+ switch null , zero := special (fn .kind , fn .n ); {
268
+ case zero :
269
+ ctx .ResultFloat (0 )
270
+ return
271
+ case null :
272
+ return
273
+ }
274
+
275
+ var r float64
276
+ switch fn .kind {
277
+ case skewness_pop :
278
+ r = fn .skewness_pop ()
279
+ case skewness_samp :
280
+ r = fn .skewness_samp ()
281
+ case kurtosis_pop :
282
+ r = fn .kurtosis_pop ()
283
+ case kurtosis_samp :
284
+ r = fn .kurtosis_samp ()
285
+ }
286
+ ctx .ResultFloat (r )
287
+ }
288
+
289
+ func (fn * momentfn ) Step (ctx sqlite3.Context , arg ... sqlite3.Value ) {
290
+ a := arg [0 ]
291
+ f := a .Float ()
292
+ if f != 0.0 || a .NumericType () != sqlite3 .NULL {
293
+ fn .enqueue (f )
294
+ }
295
+ }
296
+
297
+ func (fn * momentfn ) Inverse (ctx sqlite3.Context , arg ... sqlite3.Value ) {
298
+ a := arg [0 ]
299
+ f := a .Float ()
300
+ if f != 0.0 || a .NumericType () != sqlite3 .NULL {
301
+ fn .dequeue (f )
302
+ }
303
+ }
0 commit comments