OLD | NEW |
1 <!DOCTYPE html> | 1 <!DOCTYPE html> |
2 <!-- | 2 <!-- |
3 Copyright (c) 2014 The Chromium Authors. All rights reserved. | 3 Copyright (c) 2014 The Chromium Authors. All rights reserved. |
4 Use of this source code is governed by a BSD-style license that can be | 4 Use of this source code is governed by a BSD-style license that can be |
5 found in the LICENSE file. | 5 found in the LICENSE file. |
6 --> | 6 --> |
7 | 7 |
8 <link rel="import" href="/tracing/base/math.html"> | 8 <link rel="import" href="/tracing/base/math.html"> |
9 <link rel="import" href="/tracing/base/range.html"> | 9 <link rel="import" href="/tracing/base/range.html"> |
| 10 <script src="/mannwhitneyu/mannwhitneyu.js"></script> |
10 | 11 |
11 <script> | 12 <script> |
12 'use strict'; | 13 'use strict'; |
| 14 // In node, the script-src for mannwhitneyu above brings in mannwhitneyui |
| 15 // into a module, instead of into the global scope. Whereas this file |
| 16 // assumes that mannwhitneyu is in the global scope. So, in Node only, we |
| 17 // require() it in, and then take all its exports and shove them into the |
| 18 // global scope by hand. |
| 19 (function(global) { |
| 20 if (tr.isNode) { |
| 21 var mwuAbsPath = HTMLImportsLoader.hrefToAbsolutePath( |
| 22 '/mannwhitneyu.js'); |
| 23 var mwuModule = require(mwuAbsPath); |
| 24 for (var exportName in mwuModule) { |
| 25 global[exportName] = mwuModule[exportName]; |
| 26 } |
| 27 } |
| 28 })(this); |
| 29 </script> |
| 30 |
| 31 <script> |
| 32 'use strict'; |
13 | 33 |
14 tr.exportTo('tr.b', function() { | 34 tr.exportTo('tr.b', function() { |
15 | 35 |
16 function identity(d) { | 36 function identity(d) { |
17 return d; | 37 return d; |
18 } | 38 } |
19 | 39 |
20 function Statistics() { | 40 function Statistics() { |
21 } | 41 } |
22 | 42 |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
124 var func = opt_func || identity; | 144 var func = opt_func || identity; |
125 var tmp = new Array(ary.length); | 145 var tmp = new Array(ary.length); |
126 var i = 0; | 146 var i = 0; |
127 for (var elt of ary) | 147 for (var elt of ary) |
128 tmp[i] = func.call(opt_this, elt, i++); | 148 tmp[i] = func.call(opt_this, elt, i++); |
129 tmp.sort((a, b) => a - b); | 149 tmp.sort((a, b) => a - b); |
130 var idx = Math.floor((ary.length - 1) * percent); | 150 var idx = Math.floor((ary.length - 1) * percent); |
131 return tmp[idx]; | 151 return tmp[idx]; |
132 }; | 152 }; |
133 | 153 |
134 /* Clamp a value between some low and high value. */ | |
135 Statistics.clamp = function(value, opt_low, opt_high) { | |
136 opt_low = opt_low || 0.0; | |
137 opt_high = opt_high || 1.0; | |
138 return Math.min(Math.max(value, opt_low), opt_high); | |
139 }; | |
140 | |
141 /** | 154 /** |
142 * Sorts the samples, and map them linearly to the range [0,1]. | 155 * Sorts the samples, and map them linearly to the range [0,1]. |
143 * | 156 * |
144 * They're mapped such that for the N samples, the first sample is 0.5/N and | 157 * They're mapped such that for the N samples, the first sample is 0.5/N and |
145 * the last sample is (N-0.5)/N. | 158 * the last sample is (N-0.5)/N. |
146 * | 159 * |
147 * Background: The discrepancy of the sample set i/(N-1); i=0, ..., N-1 is | 160 * Background: The discrepancy of the sample set i/(N-1); i=0, ..., N-1 is |
148 * 2/N, twice the discrepancy of the sample set (i+1/2)/N; i=0, ..., N-1. In | 161 * 2/N, twice the discrepancy of the sample set (i+1/2)/N; i=0, ..., N-1. In |
149 * our case we don't want to distinguish between these two cases, as our | 162 * our case we don't want to distinguish between these two cases, as our |
150 * original domain is not bounded (it is for Monte Carlo integration, where | 163 * original domain is not bounded (it is for Monte Carlo integration, where |
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
335 var s = Statistics.normalizeSamples(timestamps); | 348 var s = Statistics.normalizeSamples(timestamps); |
336 var samples = s.normalized_samples; | 349 var samples = s.normalized_samples; |
337 var sample_scale = s.scale; | 350 var sample_scale = s.scale; |
338 var discrepancy = Statistics.discrepancy(samples, opt_location_count); | 351 var discrepancy = Statistics.discrepancy(samples, opt_location_count); |
339 var inv_sample_count = 1.0 / samples.length; | 352 var inv_sample_count = 1.0 / samples.length; |
340 if (opt_absolute === true) { | 353 if (opt_absolute === true) { |
341 // Compute absolute discrepancy | 354 // Compute absolute discrepancy |
342 discrepancy /= sample_scale; | 355 discrepancy /= sample_scale; |
343 } else { | 356 } else { |
344 // Compute relative discrepancy | 357 // Compute relative discrepancy |
345 discrepancy = Statistics.clamp( | 358 discrepancy = tr.b.clamp( |
346 (discrepancy - inv_sample_count) / (1.0 - inv_sample_count)); | 359 (discrepancy - inv_sample_count) / (1.0 - inv_sample_count), 0.0, 1.0); |
347 } | 360 } |
348 return discrepancy; | 361 return discrepancy; |
349 }; | 362 }; |
350 | 363 |
351 /** | 364 /** |
352 * A discrepancy based metric for measuring duration jank. | 365 * A discrepancy based metric for measuring duration jank. |
353 * | 366 * |
354 * DurationsDiscrepancy computes a jank metric which measures how irregular a | 367 * DurationsDiscrepancy computes a jank metric which measures how irregular a |
355 * given sequence of intervals is. In order to minimize jank, each duration | 368 * given sequence of intervals is. In order to minimize jank, each duration |
356 * should be equally long. This is similar to how timestamp jank works, | 369 * should be equally long. This is similar to how timestamp jank works, |
(...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
732 */ | 745 */ |
733 Statistics.LogNormalDistribution.fromMedianAndDiminishingReturns = | 746 Statistics.LogNormalDistribution.fromMedianAndDiminishingReturns = |
734 function(median, diminishingReturns) { | 747 function(median, diminishingReturns) { |
735 diminishingReturns = Math.log(diminishingReturns / median); | 748 diminishingReturns = Math.log(diminishingReturns / median); |
736 var shape = Math.sqrt(1 - 3 * diminishingReturns - | 749 var shape = Math.sqrt(1 - 3 * diminishingReturns - |
737 Math.sqrt(Math.pow(diminishingReturns - 3, 2) - 8)) / 2; | 750 Math.sqrt(Math.pow(diminishingReturns - 3, 2) - 8)) / 2; |
738 var location = Math.log(median); | 751 var location = Math.log(median); |
739 return new Statistics.LogNormalDistribution(location, shape); | 752 return new Statistics.LogNormalDistribution(location, shape); |
740 }; | 753 }; |
741 | 754 |
| 755 Statistics.mwu = mannwhitneyu; |
| 756 |
742 return { | 757 return { |
743 Statistics: Statistics | 758 Statistics: Statistics |
744 }; | 759 }; |
745 }); | 760 }); |
746 </script> | 761 </script> |
OLD | NEW |