github.com/biogo/store@v0.0.0-20201120204734-aad293a2328f/kdtree/medians_test.go (about) 1 // Copyright ©2012 The bíogo Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package kdtree 6 7 import ( 8 "math/rand" 9 "sort" 10 "testing" 11 12 "gopkg.in/check.v1" 13 ) 14 15 type Ints []int 16 17 func (a Ints) Len() int { return len(a) } 18 func (a Ints) Less(i, j int) bool { return a[i] < a[j] } 19 func (a Ints) Slice(s, e int) SortSlicer { return a[s:e] } 20 func (a Ints) Swap(i, j int) { a[i], a[j] = a[j], a[i] } 21 22 func (s *S) TestPartition(c *check.C) { 23 for p := 0; p < 100; p++ { 24 list := make(Ints, 1e5) 25 for i := range list { 26 list[i] = rand.Int() 27 } 28 pi := Partition(list, rand.Intn(list.Len())) 29 for i := 0; i < pi; i++ { 30 c.Check(list[i] <= list[pi], check.Equals, true) 31 } 32 for i := pi + 1; i < len(list); i++ { 33 c.Check(list[i] > list[pi], check.Equals, true) 34 } 35 } 36 } 37 38 func (s *S) TestPartitionCollision(c *check.C) { 39 for p := 0; p < 10; p++ { 40 list := make(Ints, 10) 41 for i := range list { 42 list[i] = rand.Intn(5) 43 } 44 pi := Partition(list, p) 45 for i := 0; i < pi; i++ { 46 c.Check(list[i] <= list[pi], check.Equals, true) 47 } 48 for i := pi + 1; i < len(list); i++ { 49 c.Check(list[i] > list[pi], check.Equals, true) 50 } 51 } 52 } 53 54 func sortSelection(list Ints, k int) int { 55 sort.Sort(list) 56 return list[k] 57 } 58 59 func (s *S) TestSelect(c *check.C) { 60 for k := 0; k < 2121; k++ { 61 list := make(Ints, 2121) 62 for i := range list { 63 list[i] = rand.Intn(1000) 64 } 65 Select(list, k) 66 sorted := append(Ints(nil), list...) 67 c.Check(list[k], check.Equals, sortSelection(sorted, k), check.Commentf("\n%d\n%v\n%v", k, list, sorted)) 68 } 69 } 70 71 func (s *S) TestMedianOfMedians(c *check.C) { 72 list := make(Ints, 1e4) 73 for i := range list { 74 list[i] = rand.Int() 75 } 76 p := MedianOfMedians(list) 77 med := list[p] 78 sort.Sort(list) 79 var found bool 80 for _, v := range list[len(list)*3/10 : len(list)*7/10+1] { 81 if v == med { 82 found = true 83 break 84 } 85 } 86 c.Check(found, check.Equals, true) 87 } 88 89 func (s *S) TestMedianOfRandoms(c *check.C) { 90 list := make(Ints, 1e4) 91 for i := range list { 92 list[i] = rand.Int() 93 } 94 p := MedianOfRandoms(list, Randoms) 95 med := list[p] 96 sort.Sort(list) 97 var found bool 98 for _, v := range list[len(list)*3/10 : len(list)*7/10+1] { 99 if v == med { 100 found = true 101 break 102 } 103 } 104 c.Check(found, check.Equals, true) 105 } 106 107 func BenchmarkMoM(b *testing.B) { 108 for i := 0; i < b.N; i++ { 109 b.StopTimer() 110 list := make(Ints, 1e4) 111 for i := range list { 112 list[i] = rand.Int() 113 } 114 b.StartTimer() 115 _ = MedianOfMedians(list) 116 } 117 } 118 119 func BenchmarkMoMPartition(b *testing.B) { 120 for i := 0; i < b.N; i++ { 121 b.StopTimer() 122 list := make(Ints, 1e4) 123 for i := range list { 124 list[i] = rand.Int() 125 } 126 b.StartTimer() 127 p := MedianOfMedians(list) 128 p = Partition(list, p) 129 } 130 } 131 132 func BenchmarkRM(b *testing.B) { 133 b.StopTimer() 134 list := make(Ints, 1e4) 135 for i := range list { 136 list[i] = rand.Int() 137 } 138 b.StartTimer() 139 for i := 0; i < b.N; i++ { 140 _ = MedianOfRandoms(list, list.Len()/1e3) 141 } 142 } 143 144 func BenchmarkRMPartition(b *testing.B) { 145 b.StopTimer() 146 list := make(Ints, 1e4) 147 for i := range list { 148 list[i] = rand.Int() 149 } 150 b.StartTimer() 151 for i := 0; i < b.N; i++ { 152 p := MedianOfRandoms(list, list.Len()/1e3) 153 p = Partition(list, p) 154 } 155 } 156 157 func BenchmarkSM(b *testing.B) { 158 for i := 0; i < b.N; i++ { 159 b.StopTimer() 160 list := make(Ints, 1e4) 161 for i := range list { 162 list[i] = rand.Int() 163 } 164 b.StartTimer() 165 sort.Sort(list) 166 } 167 }