| OLD | NEW |
| (Empty) |
| 1 # Copyright 2013 The Chromium Authors. All rights reserved. | |
| 2 # Use of this source code is governed by a BSD-style license that can be | |
| 3 # found in the LICENSE file. | |
| 4 | |
| 5 import unittest | |
| 6 import random | |
| 7 | |
| 8 from metrics import statistics | |
| 9 | |
| 10 | |
| 11 def Relax(samples, iterations=10): | |
| 12 """Lloyd relaxation in 1D. | |
| 13 | |
| 14 Keeps the position of the first and last sample. | |
| 15 """ | |
| 16 for _ in xrange(0, iterations): | |
| 17 voronoi_boundaries = [] | |
| 18 for i in xrange(1, len(samples)): | |
| 19 voronoi_boundaries.append((samples[i] + samples[i-1]) * 0.5) | |
| 20 | |
| 21 relaxed_samples = [] | |
| 22 relaxed_samples.append(samples[0]) | |
| 23 for i in xrange(1, len(samples)-1): | |
| 24 relaxed_samples.append( | |
| 25 (voronoi_boundaries[i-1] + voronoi_boundaries[i]) * 0.5) | |
| 26 relaxed_samples.append(samples[-1]) | |
| 27 samples = relaxed_samples | |
| 28 return samples | |
| 29 | |
| 30 | |
| 31 class StatisticsUnitTest(unittest.TestCase): | |
| 32 | |
| 33 def testNormalizeSamples(self): | |
| 34 samples = [] | |
| 35 normalized_samples, scale = statistics.NormalizeSamples(samples) | |
| 36 self.assertEquals(normalized_samples, samples) | |
| 37 self.assertEquals(scale, 1.0) | |
| 38 | |
| 39 samples = [0.0, 0.0] | |
| 40 normalized_samples, scale = statistics.NormalizeSamples(samples) | |
| 41 self.assertEquals(normalized_samples, samples) | |
| 42 self.assertEquals(scale, 1.0) | |
| 43 | |
| 44 samples = [0.0, 1.0/3.0, 2.0/3.0, 1.0] | |
| 45 normalized_samples, scale = statistics.NormalizeSamples(samples) | |
| 46 self.assertEquals(normalized_samples, [1.0/8.0, 3.0/8.0, 5.0/8.0, 7.0/8.0]) | |
| 47 self.assertEquals(scale, 0.75) | |
| 48 | |
| 49 samples = [1.0/8.0, 3.0/8.0, 5.0/8.0, 7.0/8.0] | |
| 50 normalized_samples, scale = statistics.NormalizeSamples(samples) | |
| 51 self.assertEquals(normalized_samples, samples) | |
| 52 self.assertEquals(scale, 1.0) | |
| 53 | |
| 54 def testDiscrepancyRandom(self): | |
| 55 """Tests NormalizeSamples and Discrepancy with random samples. | |
| 56 | |
| 57 Generates 10 sets of 10 random samples, computes the discrepancy, | |
| 58 relaxes the samples using Llloyd's algorithm in 1D, and computes the | |
| 59 discrepancy of the relaxed samples. Discrepancy of the relaxed samples | |
| 60 must be less than or equal to the discrepancy of the original samples. | |
| 61 """ | |
| 62 random.seed(1234567) | |
| 63 for _ in xrange(0, 10): | |
| 64 samples = [] | |
| 65 num_samples = 10 | |
| 66 clock = 0.0 | |
| 67 samples.append(clock) | |
| 68 for _ in xrange(1, num_samples): | |
| 69 clock += random.random() | |
| 70 samples.append(clock) | |
| 71 samples = statistics.NormalizeSamples(samples)[0] | |
| 72 d = statistics.Discrepancy(samples) | |
| 73 | |
| 74 relaxed_samples = Relax(samples) | |
| 75 d_relaxed = statistics.Discrepancy(relaxed_samples) | |
| 76 | |
| 77 self.assertTrue(d_relaxed <= d) | |
| 78 | |
| 79 def testDiscrepancyAnalytic(self): | |
| 80 """Computes discrepancy for sample sets with known statistics.""" | |
| 81 interval_multiplier = 100000 | |
| 82 | |
| 83 samples = [] | |
| 84 d = statistics.Discrepancy(samples, interval_multiplier) | |
| 85 self.assertEquals(d, 1.0) | |
| 86 | |
| 87 samples = [0.5] | |
| 88 d = statistics.Discrepancy(samples, interval_multiplier) | |
| 89 self.assertEquals(round(d), 1.0) | |
| 90 | |
| 91 samples = [0.0, 1.0] | |
| 92 d = statistics.Discrepancy(samples, interval_multiplier) | |
| 93 self.assertAlmostEquals(round(d, 2), 1.0) | |
| 94 | |
| 95 samples = [0.5, 0.5, 0.5] | |
| 96 d = statistics.Discrepancy(samples, interval_multiplier) | |
| 97 self.assertAlmostEquals(d, 1.0) | |
| 98 | |
| 99 samples = [1.0/8.0, 3.0/8.0, 5.0/8.0, 7.0/8.0] | |
| 100 d = statistics.Discrepancy(samples, interval_multiplier) | |
| 101 self.assertAlmostEquals(round(d, 2), 0.25) | |
| 102 | |
| 103 samples = [0.0, 1.0/3.0, 2.0/3.0, 1.0] | |
| 104 d = statistics.Discrepancy(samples, interval_multiplier) | |
| 105 self.assertAlmostEquals(round(d, 2), 0.5) | |
| 106 | |
| 107 samples = statistics.NormalizeSamples(samples)[0] | |
| 108 d = statistics.Discrepancy(samples, interval_multiplier) | |
| 109 self.assertAlmostEquals(round(d, 2), 0.25) | |
| 110 | |
| 111 time_stamps_a = [0, 1, 2, 3, 5, 6] | |
| 112 time_stamps_b = [0, 1, 2, 3, 5, 7] | |
| 113 time_stamps_c = [0, 2, 3, 4] | |
| 114 time_stamps_d = [0, 2, 3, 4, 5] | |
| 115 d_abs_a = statistics.TimestampsDiscrepancy(time_stamps_a, True, | |
| 116 interval_multiplier) | |
| 117 d_abs_b = statistics.TimestampsDiscrepancy(time_stamps_b, True, | |
| 118 interval_multiplier) | |
| 119 d_abs_c = statistics.TimestampsDiscrepancy(time_stamps_c, True, | |
| 120 interval_multiplier) | |
| 121 d_abs_d = statistics.TimestampsDiscrepancy(time_stamps_d, True, | |
| 122 interval_multiplier) | |
| 123 d_rel_a = statistics.TimestampsDiscrepancy(time_stamps_a, False, | |
| 124 interval_multiplier) | |
| 125 d_rel_b = statistics.TimestampsDiscrepancy(time_stamps_b, False, | |
| 126 interval_multiplier) | |
| 127 d_rel_c = statistics.TimestampsDiscrepancy(time_stamps_c, False, | |
| 128 interval_multiplier) | |
| 129 d_rel_d = statistics.TimestampsDiscrepancy(time_stamps_d, False, | |
| 130 interval_multiplier) | |
| 131 | |
| 132 self.assertTrue(d_abs_a < d_abs_b) | |
| 133 self.assertTrue(d_rel_a < d_rel_b) | |
| 134 self.assertTrue(d_rel_d < d_rel_c) | |
| 135 self.assertEquals(round(d_abs_d, 2), round(d_abs_c, 2)) | |
| 136 | |
| 137 def testDiscrepancyMultipleRanges(self): | |
| 138 samples = [[0.0, 1.2, 2.3, 3.3], [6.3, 7.5, 8.4], [4.2, 5.4, 5.9]] | |
| 139 d_0 = statistics.Discrepancy(samples[0]) | |
| 140 d_1 = statistics.Discrepancy(samples[1]) | |
| 141 d_2 = statistics.Discrepancy(samples[2]) | |
| 142 d = statistics.Discrepancy(samples) | |
| 143 self.assertEquals(d, max(d_0, d_1, d_2)) | |
| 144 | |
| 145 def testPercentile(self): | |
| 146 # The 50th percentile is the median value. | |
| 147 self.assertEquals(3, statistics.Percentile([4, 5, 1, 3, 2], 50)) | |
| 148 self.assertEquals(2.5, statistics.Percentile([5, 1, 3, 2], 50)) | |
| 149 # When the list of values is empty, 0 is returned. | |
| 150 self.assertEquals(0, statistics.Percentile([], 50)) | |
| 151 # When the given percentage is very low, the lowest value is given. | |
| 152 self.assertEquals(1, statistics.Percentile([2, 1, 5, 4, 3], 5)) | |
| 153 # When the given percentage is very high, the highest value is given. | |
| 154 self.assertEquals(5, statistics.Percentile([5, 2, 4, 1, 3], 95)) | |
| 155 # Linear interpolation between closest ranks is used. Using the example | |
| 156 # from <http://en.wikipedia.org/wiki/Percentile>: | |
| 157 self.assertEquals(27.5, statistics.Percentile([15, 20, 35, 40, 50], 40)) | |
| 158 | |
| 159 def testArithmeticMean(self): | |
| 160 # The ArithmeticMean function computes the simple average. | |
| 161 self.assertAlmostEquals(40/3.0, statistics.ArithmeticMean([10, 10, 20], 3)) | |
| 162 self.assertAlmostEquals(15.0, statistics.ArithmeticMean([10, 20], 2)) | |
| 163 # Both lists of values or single values can be given for either argument. | |
| 164 self.assertAlmostEquals(40/3.0, statistics.ArithmeticMean(40, [1, 1, 1])) | |
| 165 # If the 'count' is zero, then zero is returned. | |
| 166 self.assertEquals(0, statistics.ArithmeticMean(4.0, 0)) | |
| 167 self.assertEquals(0, statistics.ArithmeticMean(4.0, [])) | |
| 168 | |
| 169 def testDurationsDiscrepancy(self): | |
| 170 durations = [] | |
| 171 d = statistics.DurationsDiscrepancy(durations) | |
| 172 self.assertEquals(d, 1.0) | |
| 173 | |
| 174 durations = [4] | |
| 175 d = statistics.DurationsDiscrepancy(durations) | |
| 176 self.assertEquals(d, 1.0) | |
| 177 | |
| 178 durations_a = [1, 1, 1, 1, 1] | |
| 179 durations_b = [1, 1, 2, 1, 1] | |
| 180 durations_c = [1, 2, 1, 2, 1] | |
| 181 | |
| 182 d_a = statistics.DurationsDiscrepancy(durations_a) | |
| 183 d_b = statistics.DurationsDiscrepancy(durations_b) | |
| 184 d_c = statistics.DurationsDiscrepancy(durations_c) | |
| 185 | |
| 186 self.assertTrue(d_a < d_b < d_c) | |
| OLD | NEW |