19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project# Copyright 2014 The Chromium Authors. All rights reserved.
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project# Use of this source code is governed by a BSD-style license that can be
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project# found in the LICENSE file.
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport math
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport random
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport unittest
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectfrom telemetry.util import statistics
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectdef Relax(samples, iterations=10):
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  """Lloyd relaxation in 1D.
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  Keeps the position of the first and last sample.
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  """
171a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen  for _ in xrange(0, iterations):
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    voronoi_boundaries = []
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for i in xrange(1, len(samples)):
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      voronoi_boundaries.append((samples[i] + samples[i-1]) * 0.5)
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    relaxed_samples = []
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    relaxed_samples.append(samples[0])
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for i in xrange(1, len(samples)-1):
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      relaxed_samples.append(
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project          (voronoi_boundaries[i-1] + voronoi_boundaries[i]) * 0.5)
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    relaxed_samples.append(samples[-1])
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    samples = relaxed_samples
295ac72a29593ab9a20337a2225df52bdf4754be02Dianne Hackborn  return samples
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectdef CreateRandomSamples(num_samples):
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  samples = []
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  position = 0.0
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  samples.append(position)
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  for _ in xrange(1, num_samples):
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    position += random.random()
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    samples.append(position)
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  return samples
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
401a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyenclass StatisticsUnitTest(unittest.TestCase):
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
421a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen  def testNormalizeSamples(self):
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    samples = []
441a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen    normalized_samples, scale = statistics.NormalizeSamples(samples)
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    self.assertEquals(normalized_samples, [])
461a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen    self.assertEquals(scale, 1.0)
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
481a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen    samples = [0.0, 0.0]
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    normalized_samples, scale = statistics.NormalizeSamples(samples)
501a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen    self.assertEquals(normalized_samples, [0.5, 0.5])
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    self.assertEquals(scale, 1.0)
521a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    samples = [0.0, 1.0/3.0, 2.0/3.0, 1.0]
541a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen    normalized_samples, scale = statistics.NormalizeSamples(samples)
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    self.assertEquals(normalized_samples, [1.0/8.0, 3.0/8.0, 5.0/8.0, 7.0/8.0])
561a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen    self.assertEquals(scale, 0.75)
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
581a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen    samples = [1.0/8.0, 3.0/8.0, 5.0/8.0, 7.0/8.0]
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    normalized_samples, scale = statistics.NormalizeSamples(samples)
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    self.assertEquals(normalized_samples, samples)
611a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen    self.assertEquals(scale, 1.0)
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
631a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen  def testDiscrepancyRandom(self):
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    """Tests NormalizeSamples and Discrepancy with random samples.
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
661a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen    Generates 10 sets of 10 random samples, computes the discrepancy,
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    relaxes the samples using Llloyd's algorithm in 1D, and computes the
681a44d5dcabc18cd5ef111f732ccff91683a1a093Neal Nguyen    discrepancy of the relaxed samples. Discrepancy of the relaxed samples
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    must be less than or equal to the discrepancy of the original samples.
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    """
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    random.seed(1234567)
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for _ in xrange(0, 10):
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      samples = CreateRandomSamples(10)
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      samples = statistics.NormalizeSamples(samples)[0]
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      d = statistics.Discrepancy(samples)
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      relaxed_samples = Relax(samples)
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      d_relaxed = statistics.Discrepancy(relaxed_samples)
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      self.assertTrue(d_relaxed <= d)
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  def testDiscrepancyAnalytic(self):
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    """Computes discrepancy for sample sets with known statistics."""
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    samples = []
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    d = statistics.Discrepancy(samples)
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    self.assertEquals(d, 0.0)
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    samples = [0.5]
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    d = statistics.Discrepancy(samples)
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    self.assertEquals(d, 0.5)
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    samples = [0.0, 1.0]
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    d = statistics.Discrepancy(samples)
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    self.assertEquals(d, 1.0)
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    samples = [0.5, 0.5, 0.5]
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    d = statistics.Discrepancy(samples)
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    self.assertEquals(d, 1.0)
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    samples = [1.0/8.0, 3.0/8.0, 5.0/8.0, 7.0/8.0]
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    d = statistics.Discrepancy(samples)
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    self.assertEquals(d, 0.25)
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    samples = [1.0/8.0, 5.0/8.0, 5.0/8.0, 7.0/8.0]
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    d = statistics.Discrepancy(samples)
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    self.assertEquals(d, 0.5)
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    samples = [1.0/8.0, 3.0/8.0, 5.0/8.0, 5.0/8.0, 7.0/8.0]
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    d = statistics.Discrepancy(samples)
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    self.assertEquals(d, 0.4)
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    samples = [0.0, 1.0/3.0, 2.0/3.0, 1.0]
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    d = statistics.Discrepancy(samples)
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    self.assertEquals(d, 0.5)
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    samples = statistics.NormalizeSamples(samples)[0]
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    d = statistics.Discrepancy(samples)
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    self.assertEquals(d, 0.25)
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  def testTimestampsDiscrepancy(self):
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    time_stamps = []
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    d_abs = statistics.TimestampsDiscrepancy(time_stamps, True)
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    self.assertEquals(d_abs, 0.0)
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    time_stamps = [4]
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    d_abs = statistics.TimestampsDiscrepancy(time_stamps, True)
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    self.assertEquals(d_abs, 0.5)
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    time_stamps_a = [0, 1, 2, 3, 5, 6]
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    time_stamps_b = [0, 1, 2, 3, 5, 7]
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    time_stamps_c = [0, 2, 3, 4]
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    time_stamps_d = [0, 2, 3, 4, 5]
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    d_abs_a = statistics.TimestampsDiscrepancy(time_stamps_a, True)
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    d_abs_b = statistics.TimestampsDiscrepancy(time_stamps_b, True)
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    d_abs_c = statistics.TimestampsDiscrepancy(time_stamps_c, True)
1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    d_abs_d = statistics.TimestampsDiscrepancy(time_stamps_d, True)
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    d_rel_a = statistics.TimestampsDiscrepancy(time_stamps_a, False)
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    d_rel_b = statistics.TimestampsDiscrepancy(time_stamps_b, False)
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    d_rel_c = statistics.TimestampsDiscrepancy(time_stamps_c, False)
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    d_rel_d = statistics.TimestampsDiscrepancy(time_stamps_d, False)
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    self.assertTrue(d_abs_a < d_abs_b)
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    self.assertTrue(d_rel_a < d_rel_b)
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    self.assertTrue(d_rel_d < d_rel_c)
1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    self.assertAlmostEquals(d_abs_d, d_abs_c)
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  def testDiscrepancyMultipleRanges(self):
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    samples = [[0.0, 1.2, 2.3, 3.3], [6.3, 7.5, 8.4], [4.2, 5.4, 5.9]]
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    d_0 = statistics.TimestampsDiscrepancy(samples[0])
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    d_1 = statistics.TimestampsDiscrepancy(samples[1])
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    d_2 = statistics.TimestampsDiscrepancy(samples[2])
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    d = statistics.TimestampsDiscrepancy(samples)
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    self.assertEquals(d, max(d_0, d_1, d_2))
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  def testApproximateDiscrepancy(self):
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    """Tests approimate discrepancy implementation by comparing to exact
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    solution.
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    """
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    random.seed(1234567)
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for _ in xrange(0, 5):
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      samples = CreateRandomSamples(10)
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      samples = statistics.NormalizeSamples(samples)[0]
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      d = statistics.Discrepancy(samples)
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      d_approx = statistics.Discrepancy(samples, 500)
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project      self.assertEquals(round(d, 2), round(d_approx, 2))
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  def testPercentile(self):
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    # The 50th percentile is the median value.
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    self.assertEquals(3, statistics.Percentile([4, 5, 1, 3, 2], 50))
1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    self.assertEquals(2.5, statistics.Percentile([5, 1, 3, 2], 50))
1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    # When the list of values is empty, 0 is returned.
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    self.assertEquals(0, statistics.Percentile([], 50))
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    # When the given percentage is very low, the lowest value is given.
1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    self.assertEquals(1, statistics.Percentile([2, 1, 5, 4, 3], 5))
1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    # When the given percentage is very high, the highest value is given.
1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    self.assertEquals(5, statistics.Percentile([5, 2, 4, 1, 3], 95))
1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    # Linear interpolation between closest ranks is used. Using the example
1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    # from <http://en.wikipedia.org/wiki/Percentile>:
1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    self.assertEquals(27.5, statistics.Percentile([15, 20, 35, 40, 50], 40))
1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  def testArithmeticMean(self):
1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    # The ArithmeticMean function computes the simple average.
1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    self.assertAlmostEquals(40/3.0, statistics.ArithmeticMean([10, 10, 20]))
1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    self.assertAlmostEquals(15.0, statistics.ArithmeticMean([10, 20]))
1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    # If the 'count' is zero, then zero is returned.
1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    self.assertEquals(0, statistics.ArithmeticMean([]))
1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  def testDurationsDiscrepancy(self):
1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    durations = []
1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    d = statistics.DurationsDiscrepancy(durations)
1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    self.assertEquals(d, 0.0)
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    durations = [4]
1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    d = statistics.DurationsDiscrepancy(durations)
1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    self.assertEquals(d, 4.0)
1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    durations_a = [1, 1, 1, 1, 1]
1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    durations_b = [1, 1, 2, 1, 1]
1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    durations_c = [1, 2, 1, 2, 1]
1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    d_a = statistics.DurationsDiscrepancy(durations_a)
2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    d_b = statistics.DurationsDiscrepancy(durations_b)
2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    d_c = statistics.DurationsDiscrepancy(durations_c)
2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    self.assertTrue(d_a < d_b < d_c)
2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  def testStandardDeviation(self):
2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    self.assertAlmostEquals(math.sqrt(2/3.0),
2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            statistics.StandardDeviation([1, 2, 3]))
2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    self.assertEquals(0, statistics.StandardDeviation([1]))
2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    self.assertEquals(0, statistics.StandardDeviation([]))
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  def testTrapezoidalRule(self):
2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    self.assertEquals(4, statistics.TrapezoidalRule([1, 2, 3], 1))
2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    self.assertEquals(2, statistics.TrapezoidalRule([1, 2, 3], .5))
2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    self.assertEquals(0, statistics.TrapezoidalRule([1, 2, 3], 0))
2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    self.assertEquals(-4, statistics.TrapezoidalRule([1, 2, 3], -1))
2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    self.assertEquals(3, statistics.TrapezoidalRule([-1, 2, 3], 1))
2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    self.assertEquals(0, statistics.TrapezoidalRule([1], 1))
2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    self.assertEquals(0, statistics.TrapezoidalRule([0], 1))
2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project