Пример #1
0
func TestSortWeighted(t *testing.T) {
	for i, test := range []struct {
		x    []float64
		w    []float64
		ansx []float64
		answ []float64
	}{
		{
			x:    []float64{8, 3, 7, 8, 4},
			ansx: []float64{3, 4, 7, 8, 8},
		},
		{
			x:    []float64{8, 3, 7, 8, 4},
			w:    []float64{.5, 1, 1, .5, 1},
			ansx: []float64{3, 4, 7, 8, 8},
			answ: []float64{1, 1, 1, .5, .5},
		},
	} {
		SortWeighted(test.x, test.w)
		if !floats.Same(test.x, test.ansx) {
			t.Errorf("SortWeighted mismatch case %d. Expected x %v, Found x %v", i, test.ansx, test.x)
		}
		if !(test.w == nil) && !floats.Same(test.w, test.answ) {
			t.Errorf("SortWeighted mismatch case %d. Expected w %v, Found w %v", i, test.answ, test.w)
		}
	}
	if !Panics(func() { SortWeighted(make([]float64, 3), make([]float64, 2)) }) {
		t.Errorf("SortWeighted did not panic with x, weights length mismatch")
	}
}
Пример #2
0
func TestSortWeightedLabeled(t *testing.T) {
	for i, test := range []struct {
		x    []float64
		l    []bool
		w    []float64
		ansx []float64
		ansl []bool
		answ []float64
	}{
		{
			x:    []float64{8, 3, 7, 8, 4},
			ansx: []float64{3, 4, 7, 8, 8},
		},
		{
			x:    []float64{8, 3, 7, 8, 4},
			w:    []float64{.5, 1, 1, .5, 1},
			ansx: []float64{3, 4, 7, 8, 8},
			answ: []float64{1, 1, 1, .5, .5},
		},
		{
			x:    []float64{8, 3, 7, 8, 4},
			l:    []bool{false, false, true, false, true},
			ansx: []float64{3, 4, 7, 8, 8},
			ansl: []bool{false, true, true, false, false},
		},
		{
			x:    []float64{8, 3, 7, 8, 4},
			l:    []bool{false, false, true, false, true},
			w:    []float64{.5, 1, 1, .5, 1},
			ansx: []float64{3, 4, 7, 8, 8},
			ansl: []bool{false, true, true, false, false},
			answ: []float64{1, 1, 1, .5, .5},
		},
	} {
		SortWeightedLabeled(test.x, test.l, test.w)
		if !floats.Same(test.x, test.ansx) {
			t.Errorf("SortWeightedLabelled mismatch case %d. Expected x %v, Found x %v", i, test.ansx, test.x)
		}
		if (test.l != nil) && !reflect.DeepEqual(test.l, test.ansl) {
			t.Errorf("SortWeightedLabelled mismatch case %d. Expected l %v, Found l %v", i, test.ansl, test.l)
		}
		if (test.w != nil) && !floats.Same(test.w, test.answ) {
			t.Errorf("SortWeightedLabelled mismatch case %d. Expected w %v, Found w %v", i, test.answ, test.w)
		}
	}
	if !Panics(func() { SortWeightedLabeled(make([]float64, 3), make([]bool, 2), make([]float64, 3)) }) {
		t.Errorf("SortWeighted did not panic with x, labels length mismatch")
	}
	if !Panics(func() { SortWeightedLabeled(make([]float64, 3), make([]bool, 2), nil) }) {
		t.Errorf("SortWeighted did not panic with x, labels length mismatch")
	}
	if !Panics(func() { SortWeightedLabeled(make([]float64, 3), make([]bool, 3), make([]float64, 2)) }) {
		t.Errorf("SortWeighted did not panic with x, weights length mismatch")
	}
	if !Panics(func() { SortWeightedLabeled(make([]float64, 3), nil, make([]float64, 2)) }) {
		t.Errorf("SortWeighted did not panic with x, weights length mismatch")
	}
}
Пример #3
0
func sameAnswerF64SliceOfSlice(a, b interface{}) bool {
	for i, v := range a.([][]float64) {
		if same := floats.Same(v, b.([][]float64)[i]); !same {
			return false
		}
	}
	return true
}
Пример #4
0
// Test cases where calculated manually.
func TestROC(t *testing.T) {
	cases := []struct {
		y       []float64
		c       []bool
		w       []float64
		n       int
		wantTPR []float64
		wantFPR []float64
	}{
		{
			y:       []float64{0, 3, 5, 6, 7.5, 8},
			c:       []bool{true, false, true, false, false, false},
			wantTPR: []float64{0, 0.5, 0.5, 1, 1, 1, 1},
			wantFPR: []float64{0, 0, 0.25, 0.25, 0.5, 0.75, 1},
		},
		{
			y:       []float64{0, 3, 5, 6, 7.5, 8},
			c:       []bool{true, false, true, false, false, false},
			w:       []float64{4, 1, 6, 3, 2, 2},
			wantTPR: []float64{0, 0.4, 0.4, 1, 1, 1, 1},
			wantFPR: []float64{0, 0, 0.125, 0.125, 0.5, 0.75, 1},
		},
		{
			y:       []float64{0, 3, 5, 6, 7.5, 8},
			c:       []bool{true, false, true, false, false, false},
			n:       int(5),
			wantTPR: []float64{0, 0.5, 0.5, 1, 1},
			wantFPR: []float64{0, 0, 0.25, 0.5, 1},
		},
		{
			y:       []float64{0, 3, 5, 6, 7.5, 8},
			c:       []bool{true, false, true, false, false, false},
			n:       int(9),
			wantTPR: []float64{0, 0.5, 0.5, 0.5, 0.5, 1, 1, 1, 1},
			wantFPR: []float64{0, 0, 0, 0.25, 0.25, 0.25, 0.5, 0.5, 1},
		},
		{
			y:       []float64{0, 3, 5, 6, 7.5, 8},
			c:       []bool{true, false, true, false, false, false},
			w:       []float64{4, 1, 6, 3, 2, 2},
			n:       int(5),
			wantTPR: []float64{0, 0.4, 0.4, 1, 1},
			wantFPR: []float64{0, 0, 0.125, 0.5, 1},
		},
		{
			y:       []float64{0, 3, 5, 6, 7.5, 8},
			c:       []bool{true, false, true, false, false, false},
			w:       []float64{4, 1, 6, 3, 2, 2},
			n:       int(9),
			wantTPR: []float64{0, 0.4, 0.4, 0.4, 0.4, 1, 1, 1, 1},
			wantFPR: []float64{0, 0, 0, 0.125, 0.125, 0.125, 0.5, 0.5, 1},
		},
		{
			y:       []float64{0, 3, 6, 6, 6, 8},
			c:       []bool{true, false, true, false, false, false},
			wantTPR: []float64{0, 0.5, 0.5, 1, 1},
			wantFPR: []float64{0, 0, 0.25, 0.75, 1},
		},
		{
			y:       []float64{0, 3, 6, 6, 6, 8},
			c:       []bool{true, false, true, false, false, false},
			w:       []float64{4, 1, 6, 3, 2, 2},
			wantTPR: []float64{0, 0.4, 0.4, 1, 1},
			wantFPR: []float64{0, 0, 0.125, 0.75, 1},
		},
		{
			y:       []float64{0, 3, 6, 6, 6, 8},
			c:       []bool{true, false, true, false, false, false},
			n:       int(5),
			wantTPR: []float64{0, 0.5, 0.5, 1, 1},
			wantFPR: []float64{0, 0, 0.25, 0.75, 1},
		},
		{
			y:       []float64{0, 3, 6, 6, 6, 8},
			c:       []bool{true, false, true, false, false, false},
			n:       int(9),
			wantTPR: []float64{0, 0.5, 0.5, 0.5, 0.5, 0.5, 1, 1, 1},
			wantFPR: []float64{0, 0, 0, 0.25, 0.25, 0.25, 0.75, 0.75, 1},
		},
		{
			y:       []float64{0, 3, 6, 6, 6, 8},
			c:       []bool{true, false, true, false, false, false},
			w:       []float64{4, 1, 6, 3, 2, 2},
			n:       int(5),
			wantTPR: []float64{0, 0.4, 0.4, 1, 1},
			wantFPR: []float64{0, 0, 0.125, 0.75, 1},
		},
		{
			y:       []float64{0, 3, 6, 6, 6, 8},
			c:       []bool{true, false, true, false, false, false},
			w:       []float64{4, 1, 6, 3, 2, 2},
			n:       int(9),
			wantTPR: []float64{0, 0.4, 0.4, 0.4, 0.4, 0.4, 1, 1, 1},
			wantFPR: []float64{0, 0, 0, 0.125, 0.125, 0.125, 0.75, 0.75, 1},
		},
		{
			y:       []float64{1, 2},
			c:       []bool{true, true},
			wantTPR: []float64{0, 0.5, 1},
			wantFPR: []float64{0, 0, 1},
		},
		{
			y:       []float64{1, 2},
			c:       []bool{true, true},
			n:       int(2),
			wantTPR: []float64{0, 1},
			wantFPR: []float64{0, 1},
		},
		{
			y:       []float64{1, 2},
			c:       []bool{true, true},
			n:       int(7),
			wantTPR: []float64{0, 0.5, 0.5, 0.5, 0.5, 0.5, 1},
			wantFPR: []float64{0, 0, 0, 0, 0, 0, 1},
		},
		{
			y:       []float64{1},
			c:       []bool{true},
			wantTPR: []float64{0, 1},
			wantFPR: []float64{0, 1},
		},
		{
			y:       []float64{1},
			c:       []bool{true},
			n:       int(2),
			wantTPR: []float64{0, 1},
			wantFPR: []float64{0, 1},
		},
		{
			y:       []float64{1},
			c:       []bool{false},
			wantTPR: []float64{0, 1},
			wantFPR: []float64{0, 1},
		},
		{
			y:       []float64{0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 10},
			c:       []bool{true, false, true, true, false, false, true},
			n:       int(5),
			wantTPR: []float64{0, 0.75, 0.75, 0.75, 1},
			wantFPR: []float64{0, 1, 1, 1, 1},
		},
		{
			y:       []float64{},
			c:       []bool{},
			wantTPR: nil,
			wantFPR: nil,
		},
		{
			y:       []float64{},
			c:       []bool{},
			n:       int(5),
			wantTPR: nil,
			wantFPR: nil,
		},
	}
	for i, test := range cases {
		gotTPR, gotFPR := ROC(test.n, test.y, test.c, test.w)
		if !floats.Same(gotTPR, test.wantTPR) {
			t.Errorf("%d: unexpected TPR got:%v want:%v", i, gotTPR, test.wantTPR)
		}
		if !floats.Same(gotFPR, test.wantFPR) {
			t.Errorf("%d: unexpected FPR got:%v want:%v", i, gotFPR, test.wantFPR)
		}
	}
}
Пример #5
0
func TestFlattenBanded(t *testing.T) {
	for i, test := range []struct {
		dense     [][]float64
		ku        int
		kl        int
		condensed [][]float64
	}{
		{
			dense:     [][]float64{{3}},
			ku:        0,
			kl:        0,
			condensed: [][]float64{{3}},
		},
		{
			dense: [][]float64{
				{3, 4, 0},
			},
			ku: 1,
			kl: 0,
			condensed: [][]float64{
				{3, 4},
			},
		},
		{
			dense: [][]float64{
				{3, 4, 0, 0, 0},
			},
			ku: 1,
			kl: 0,
			condensed: [][]float64{
				{3, 4},
			},
		},
		{
			dense: [][]float64{
				{3, 4, 0},
				{0, 5, 8},
				{0, 0, 2},
				{0, 0, 0},
				{0, 0, 0},
			},
			ku: 1,
			kl: 0,
			condensed: [][]float64{
				{3, 4},
				{5, 8},
				{2, math.NaN()},
				{math.NaN(), math.NaN()},
				{math.NaN(), math.NaN()},
			},
		},
		{
			dense: [][]float64{
				{3, 4, 6},
				{0, 5, 8},
				{0, 0, 2},
				{0, 0, 0},
				{0, 0, 0},
			},
			ku: 2,
			kl: 0,
			condensed: [][]float64{
				{3, 4, 6},
				{5, 8, math.NaN()},
				{2, math.NaN(), math.NaN()},
				{math.NaN(), math.NaN(), math.NaN()},
				{math.NaN(), math.NaN(), math.NaN()},
			},
		},
		{
			dense: [][]float64{
				{3, 4, 6},
				{1, 5, 8},
				{0, 6, 2},
				{0, 0, 7},
				{0, 0, 0},
			},
			ku: 2,
			kl: 1,
			condensed: [][]float64{
				{math.NaN(), 3, 4, 6},
				{1, 5, 8, math.NaN()},
				{6, 2, math.NaN(), math.NaN()},
				{7, math.NaN(), math.NaN(), math.NaN()},
				{math.NaN(), math.NaN(), math.NaN(), math.NaN()},
			},
		},
		{
			dense: [][]float64{
				{1, 2, 0},
				{3, 4, 5},
				{6, 7, 8},
				{0, 9, 10},
				{0, 0, 11},
			},
			ku: 1,
			kl: 2,
			condensed: [][]float64{
				{math.NaN(), math.NaN(), 1, 2},
				{math.NaN(), 3, 4, 5},
				{6, 7, 8, math.NaN()},
				{9, 10, math.NaN(), math.NaN()},
				{11, math.NaN(), math.NaN(), math.NaN()},
			},
		},
		{
			dense: [][]float64{
				{1, 0, 0},
				{3, 4, 0},
				{6, 7, 8},
				{0, 9, 10},
				{0, 0, 11},
			},
			ku: 0,
			kl: 2,
			condensed: [][]float64{
				{math.NaN(), math.NaN(), 1},
				{math.NaN(), 3, 4},
				{6, 7, 8},
				{9, 10, math.NaN()},
				{11, math.NaN(), math.NaN()},
			},
		},
		{
			dense: [][]float64{
				{1, 0, 0, 0, 0},
				{3, 4, 0, 0, 0},
				{1, 3, 5, 0, 0},
			},
			ku: 0,
			kl: 2,
			condensed: [][]float64{
				{math.NaN(), math.NaN(), 1},
				{math.NaN(), 3, 4},
				{1, 3, 5},
			},
		},
	} {
		condensed := flattenBanded(test.dense, test.ku, test.kl)
		correct := flatten(test.condensed)
		if !floats.Same(condensed, correct) {
			t.Errorf("Case %v mismatch. Want %v, got %v.", i, correct, condensed)
		}
	}
}
Пример #6
0
func SameF64S(str string, c, native []float64) {
	if !floats.Same(c, native) {
		panic(fmt.Sprintf("Case %s: []float64 mismatch. c = %v, native = %v.", str, c, native))
	}
}
Пример #7
0
func TestQuantile(t *testing.T) {
	cumulantKinds := []CumulantKind{Empirical}
	for i, test := range []struct {
		p   []float64
		x   []float64
		w   []float64
		ans [][]float64
	}{
		{
			p:   []float64{0, 0.05, 0.1, 0.15, 0.45, 0.5, 0.55, 0.85, 0.9, 0.95, 1},
			x:   []float64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10},
			w:   nil,
			ans: [][]float64{{1, 1, 1, 2, 5, 5, 6, 9, 9, 10, 10}},
		},
		{
			p:   []float64{0, 0.05, 0.1, 0.15, 0.45, 0.5, 0.55, 0.85, 0.9, 0.95, 1},
			x:   []float64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10},
			w:   []float64{3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
			ans: [][]float64{{1, 1, 1, 2, 5, 5, 6, 9, 9, 10, 10}},
		},
		{
			p:   []float64{0.5},
			x:   []float64{1, 2, 3, 4, 5, 6, 7, 8, math.NaN(), 10},
			ans: [][]float64{{math.NaN()}},
		},
	} {
		copyX := make([]float64, len(test.x))
		copy(copyX, test.x)
		var copyW []float64
		if test.w != nil {
			copyW = make([]float64, len(test.w))
			copy(copyW, test.w)
		}
		for j, p := range test.p {
			for k, kind := range cumulantKinds {
				v := Quantile(p, kind, test.x, test.w)
				if !floats.Same(copyX, test.x) {
					t.Errorf("x changed for case %d kind %d percentile %v", i, k, p)
				}
				if !floats.Same(copyW, test.w) {
					t.Errorf("x changed for case %d kind %d percentile %v", i, k, p)
				}
				if v != test.ans[k][j] && !(math.IsNaN(v) && math.IsNaN(test.ans[k][j])) {
					t.Errorf("mismatch case %d kind %d percentile %v. Expected: %v, found: %v", i, k, p, test.ans[k][j], v)
				}
			}
		}
	}
	// panic cases
	for _, test := range []struct {
		name string
		p    float64
		c    CumulantKind
		x    []float64
		w    []float64
	}{
		{
			name: "p < 0",
			c:    Empirical,
			p:    -1,
		},
		{
			name: "p > 1",
			c:    Empirical,
			p:    2,
		},
		{
			name: "p is NaN",
			c:    Empirical,
			p:    math.NaN(),
		},
		{
			name: "len(x) != len(weights)",
			c:    Empirical,
			p:    .5,
			x:    make([]float64, 4),
			w:    make([]float64, 2),
		},
		{
			name: "x not sorted",
			c:    Empirical,
			p:    .5,
			x:    []float64{3, 2, 1},
		},
		{
			name: "CumulantKind is unknown",
			c:    CumulantKind(1000),
			p:    .5,
			x:    []float64{1, 2, 3},
		},
	} {
		if !Panics(func() { Quantile(test.p, test.c, test.x, test.w) }) {
			t.Errorf("Quantile did not panic when %s", test.name)
		}
	}
}