Simplify Skew Sig

Simplify the Skew interface to remove dependence on mean and standard
deviation calculation.
This commit is contained in:
Jonathan J Lawlor
2014-11-07 18:23:43 -05:00
parent d310d7322a
commit 943fa00fdc
2 changed files with 11 additions and 10 deletions

15
stat.go
View File

@@ -768,24 +768,27 @@ func Quantile(p float64, c CumulantKind, x, weights []float64) float64 {
// Skew computes the skewness of the sample data. // Skew computes the skewness of the sample data.
// If weights is nil then all of the weights are 1. If weights is not nil, then // If weights is nil then all of the weights are 1. If weights is not nil, then
// len(x) must equal len(weights). // len(x) must equal len(weights).
func Skew(x []float64, mean, stdev float64, weights []float64) float64 { func Skew(x []float64, weights []float64) float64 {
// this is a three-pass approach. There are one pass approaches, but
// I don't know of a two-pass one, or the numerical stability of the
// one vs three pass version.
u, std := MeanStdDev(x, weights)
if weights == nil { if weights == nil {
var s float64 var s float64
for _, v := range x { for _, v := range x {
z := (v - mean) / stdev z := (v - u) / std
s += z * z * z s += z * z * z
} }
return s * skewCorrection(float64(len(x))) return s * skewCorrection(float64(len(x)))
} }
if len(x) != len(weights) {
panic("stat: slice length mismatch")
}
var ( var (
s float64 s float64
sumWeights float64 sumWeights float64
) )
for i, v := range x { for i, v := range x {
z := (v - mean) / stdev z := (v - u) / std
s += weights[i] * z * z * z s += weights[i] * z * z * z
sumWeights += weights[i] sumWeights += weights[i]
} }

View File

@@ -1171,14 +1171,12 @@ func TestSkew(t *testing.T) {
ans: -1.12066646837198, ans: -1.12066646837198,
}, },
} { } {
mean := Mean(test.x, test.weights) skew := Skew(test.x, test.weights)
std := StdDev(test.x, test.weights)
skew := Skew(test.x, mean, std, test.weights)
if math.Abs(skew-test.ans) > 1e-14 { if math.Abs(skew-test.ans) > 1e-14 {
t.Errorf("Skew mismatch case %d. Expected %v, Found %v", i, test.ans, skew) t.Errorf("Skew mismatch case %d. Expected %v, Found %v", i, test.ans, skew)
} }
} }
if !Panics(func() { Skew(make([]float64, 3), 0, 1, make([]float64, 2)) }) { if !Panics(func() { Skew(make([]float64, 3), make([]float64, 2)) }) {
t.Errorf("Skew did not panic with x, weights length mismatch") t.Errorf("Skew did not panic with x, weights length mismatch")
} }
} }