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  }