OLD | NEW |
1 # Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 # Use of this source code is governed by a BSD-style license that can be |
3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
4 | 4 |
5 """A collection of statistical utility functions to be used by metrics.""" | 5 """A collection of statistical utility functions to be used by metrics.""" |
6 | 6 |
7 import bisect | 7 import bisect |
8 import math | 8 import math |
9 | 9 |
10 | 10 |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
152 | 152 |
153 Args: | 153 Args: |
154 durations: List of interval lengths in milliseconds. | 154 durations: List of interval lengths in milliseconds. |
155 absolute: See TimestampsDiscrepancy. | 155 absolute: See TimestampsDiscrepancy. |
156 interval_multiplier: See TimestampsDiscrepancy. | 156 interval_multiplier: See TimestampsDiscrepancy. |
157 """ | 157 """ |
158 timestamps = reduce(lambda x, y: x + [x[-1] + y], durations, [0])[1:] | 158 timestamps = reduce(lambda x, y: x + [x[-1] + y], durations, [0])[1:] |
159 return TimestampsDiscrepancy(timestamps, absolute, interval_multiplier) | 159 return TimestampsDiscrepancy(timestamps, absolute, interval_multiplier) |
160 | 160 |
161 | 161 |
162 def ArithmeticMean(numerator, denominator): | 162 def ArithmeticMean(data): |
163 """Calculates arithmetic mean. | 163 """Calculates arithmetic mean. |
164 | 164 |
165 Both numerator and denominator can be given as either individual | 165 Args: |
166 values or lists of values which will be summed. | 166 data: A list of samples. |
| 167 |
| 168 Returns: |
| 169 The arithmetic mean value, or 0 if the list is empty. |
| 170 """ |
| 171 numerator_total = Total(data) |
| 172 denominator_total = Total(len(data)) |
| 173 return DivideIfPossibleOrZero(numerator_total, denominator_total) |
| 174 |
| 175 |
| 176 def StandardDeviation(data): |
| 177 """Calculates the standard deviation. |
167 | 178 |
168 Args: | 179 Args: |
169 numerator: A quantity that represents a sum total value. | 180 data: A list of samples. |
170 denominator: A quantity that represents a count of the number of things. | |
171 | 181 |
172 Returns: | 182 Returns: |
173 The arithmetic mean value, or 0 if the denominator value was 0. | 183 The standard deviation of the samples provided. |
174 """ | 184 """ |
175 numerator_total = Total(numerator) | 185 if len(data) == 1: |
176 denominator_total = Total(denominator) | 186 return 0.0 |
177 return DivideIfPossibleOrZero(numerator_total, denominator_total) | |
178 | 187 |
| 188 mean = ArithmeticMean(data) |
| 189 variances = [float(x) - mean for x in data] |
| 190 variances = [x * x for x in variances] |
| 191 std_dev = math.sqrt(ArithmeticMean(variances)) |
| 192 |
| 193 return std_dev |
| 194 |
| 195 |
| 196 def TrapezoidalRule(data, dx): |
| 197 """ Calculate the integral according to the trapezoidal rule |
| 198 |
| 199 TrapezoidalRule approximates the definite integral of f from a to b by |
| 200 the composite trapezoidal rule, using n subintervals. |
| 201 http://en.wikipedia.org/wiki/Trapezoidal_rule#Uniform_grid |
| 202 |
| 203 Args: |
| 204 data: A list of samples |
| 205 dx: The uniform distance along the x axis between any two samples |
| 206 |
| 207 Returns: |
| 208 The area under the curve defined by the samples and the uniform distance |
| 209 according to the trapezoidal rule. |
| 210 """ |
| 211 |
| 212 n = len(data) - 1 |
| 213 s = data[0] + data[n] |
| 214 |
| 215 if n == 0: |
| 216 return 0.0 |
| 217 |
| 218 for i in range(1, n): |
| 219 s += 2 * data[i] |
| 220 |
| 221 return s * dx / 2.0 |
179 | 222 |
180 def Total(data): | 223 def Total(data): |
181 """Returns the float value of a number or the sum of a list.""" | 224 """Returns the float value of a number or the sum of a list.""" |
182 if type(data) == float: | 225 if type(data) == float: |
183 total = data | 226 total = data |
184 elif type(data) == int: | 227 elif type(data) == int: |
185 total = float(data) | 228 total = float(data) |
186 elif type(data) == list: | 229 elif type(data) == list: |
187 total = float(sum(data)) | 230 total = float(sum(data)) |
188 else: | 231 else: |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
256 new_values.append(value) | 299 new_values.append(value) |
257 else: | 300 else: |
258 new_values.append(0.001) | 301 new_values.append(0.001) |
259 # Compute the sum of the log of the values. | 302 # Compute the sum of the log of the values. |
260 log_sum = sum(map(math.log, new_values)) | 303 log_sum = sum(map(math.log, new_values)) |
261 # Raise e to that sum over the number of values. | 304 # Raise e to that sum over the number of values. |
262 mean = math.pow(math.e, (log_sum / len(new_values))) | 305 mean = math.pow(math.e, (log_sum / len(new_values))) |
263 # Return the rounded mean. | 306 # Return the rounded mean. |
264 return int(round(mean)) | 307 return int(round(mean)) |
265 | 308 |
OLD | NEW |