diff --git a/stat/stat.go b/stat/stat.go index b76907da..9bf24969 100644 --- a/stat/stat.go +++ b/stat/stat.go @@ -217,11 +217,14 @@ func Correlation(x, y, weights []float64) float64 { return (sxy - xcompensation*ycompensation/sumWeights) / math.Sqrt(sxx*syy) } -// KendallCorrelation returns the weighted Tau-a Kendall correlation between the -// samples of x and y. +// Kendall returns the weighted Tau-a Kendall correlation between the +// samples of x and y. The Kendall correlation measures the quantity of +// concordant and discordant pairs of numbers. If weights are specified then +// each pair is weighted by weights[i] * weights[j] and the final sum is +// normalized to stay between -1 and 1. // The lengths of x and y must be equal. If weights is nil then all of the // weights are 1. If weights is not nil, then len(x) must equal len(weights). -func KendallCorrelation(x, y, weights []float64) float64 { +func Kendall(x, y, weights []float64) float64 { if len(x) != len(y) { panic("stat: slice length mismatch") } @@ -250,15 +253,12 @@ func KendallCorrelation(x, y, weights []float64) float64 { var sumWeights float64 - var c int - for i := 0; i < n; i++ { for j := i; j < n; j++ { if i == j { continue } - c++ - var weight = weights[i] * weights[j] + weight := weights[i] * weights[j] if math.Signbit(x[j]-x[i]) == math.Signbit(y[j]-y[i]) { cc += weight } else { diff --git a/stat/stat_test.go b/stat/stat_test.go index e262c14c..bc5e3aee 100644 --- a/stat/stat_test.go +++ b/stat/stat_test.go @@ -136,7 +136,7 @@ func TestCorrelation(t *testing.T) { } } -func ExampleKendallCorrelation() { +func ExampleKendall() { x := []float64{8, -3, 7, 8, -4} y := []float64{10, 5, 6, 3, -1} w := []float64{2, 1.5, 3, 3, 2} @@ -144,7 +144,7 @@ func ExampleKendallCorrelation() { fmt.Println("Kendall correlation computes the number of ordered pairs") fmt.Println("between two datasets.") - c := KendallCorrelation(x, y, w) + c := Kendall(x, y, w) fmt.Printf("Kendall correlation is %.5f\n", c) // Output: @@ -153,7 +153,7 @@ func ExampleKendallCorrelation() { // Kendall correlation is 0.25000 } -func TestKendallCorrelation(t *testing.T) { +func TestKendall(t *testing.T) { for i, test := range []struct { x []float64 y []float64 @@ -197,19 +197,19 @@ func TestKendallCorrelation(t *testing.T) { ans: 1, }, } { - c := KendallCorrelation(test.x, test.y, test.weights) + c := Kendall(test.x, test.y, test.weights) if math.Abs(test.ans-c) > 1e-14 { t.Errorf("Correlation mismatch case %d. Expected %v, Found %v", i, test.ans, c) } } - if !panics(func() { KendallCorrelation(make([]float64, 2), make([]float64, 3), make([]float64, 3)) }) { - t.Errorf("KendallCorrelation did not panic with length mismatch") + if !panics(func() { Kendall(make([]float64, 2), make([]float64, 3), make([]float64, 3)) }) { + t.Errorf("Kendall did not panic with length mismatch") } - if !panics(func() { KendallCorrelation(make([]float64, 2), make([]float64, 3), nil) }) { - t.Errorf("KendallCorrelation did not panic with length mismatch") + if !panics(func() { Kendall(make([]float64, 2), make([]float64, 3), nil) }) { + t.Errorf("Kendall did not panic with length mismatch") } - if !panics(func() { KendallCorrelation(make([]float64, 3), make([]float64, 3), make([]float64, 2)) }) { - t.Errorf("KendallCorrelation did not panic with weights length mismatch") + if !panics(func() { Kendall(make([]float64, 3), make([]float64, 3), make([]float64, 2)) }) { + t.Errorf("Kendall did not panic with weights length mismatch") } }