Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(85)

Side by Side Diff: tracing/tracing/value/histogram.html

Issue 2771723003: [tracing] Move math utilities from base into their own subdirectory (attempt 2) (Closed)
Patch Set: rebase Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « tracing/tracing/ui/tracks/track.html ('k') | tracing/tracing/value/histogram_set_test.html » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 <!DOCTYPE html> 1 <!DOCTYPE html>
2 <!-- 2 <!--
3 Copyright 2016 The Chromium Authors. All rights reserved. 3 Copyright 2016 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/iteration_helpers.html"> 8 <link rel="import" href="/tracing/base/iteration_helpers.html">
9 <link rel="import" href="/tracing/base/range.html"> 9 <link rel="import" href="/tracing/base/math/range.html">
10 <link rel="import" href="/tracing/base/running_statistics.html"> 10 <link rel="import" href="/tracing/base/math/running_statistics.html">
11 <link rel="import" href="/tracing/base/math/sorted_array_utils.html">
12 <link rel="import" href="/tracing/base/math/statistics.html">
11 <link rel="import" href="/tracing/base/scalar.html"> 13 <link rel="import" href="/tracing/base/scalar.html">
12 <link rel="import" href="/tracing/base/sorted_array_utils.html">
13 <link rel="import" href="/tracing/base/statistics.html">
14 <link rel="import" href="/tracing/base/unit.html"> 14 <link rel="import" href="/tracing/base/unit.html">
15 <link rel="import" href="/tracing/value/diagnostics/diagnostic_map.html"> 15 <link rel="import" href="/tracing/value/diagnostics/diagnostic_map.html">
16 16
17 <script> 17 <script>
18 'use strict'; 18 'use strict';
19 19
20 tr.exportTo('tr.v', function() { 20 tr.exportTo('tr.v', function() {
21 const MAX_DIAGNOSTIC_MAPS = 16; 21 const MAX_DIAGNOSTIC_MAPS = 16;
22 22
23 const DEFAULT_SAMPLE_VALUES_PER_BIN = 10; 23 const DEFAULT_SAMPLE_VALUES_PER_BIN = 10;
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
56 * Converts the given string to a percent between 0 and 1. 56 * Converts the given string to a percent between 0 and 1.
57 * @param {string} 57 * @param {string}
58 * @return {number} 58 * @return {number}
59 */ 59 */
60 function percentFromString(s) { 60 function percentFromString(s) {
61 return parseFloat(s[0] + '.' + s.substr(1).replace(/_/g, '')); 61 return parseFloat(s[0] + '.' + s.substr(1).replace(/_/g, ''));
62 } 62 }
63 63
64 class HistogramBin { 64 class HistogramBin {
65 /** 65 /**
66 * @param {!tr.b.Range} range 66 * @param {!tr.b.math.Range} range
67 */ 67 */
68 constructor(range) { 68 constructor(range) {
69 this.range = range; 69 this.range = range;
70 this.count = 0; 70 this.count = 0;
71 this.diagnosticMaps = []; 71 this.diagnosticMaps = [];
72 } 72 }
73 73
74 /** 74 /**
75 * @param {*} value 75 * @param {*} value
76 */ 76 */
77 addSample(value) { 77 addSample(value) {
78 this.count += 1; 78 this.count += 1;
79 } 79 }
80 80
81 /** 81 /**
82 * @param {!tr.v.d.DiagnosticMap} diagnostics 82 * @param {!tr.v.d.DiagnosticMap} diagnostics
83 */ 83 */
84 addDiagnosticMap(diagnostics) { 84 addDiagnosticMap(diagnostics) {
85 tr.b.Statistics.uniformlySampleStream( 85 tr.b.math.Statistics.uniformlySampleStream(
86 this.diagnosticMaps, this.count, diagnostics, MAX_DIAGNOSTIC_MAPS); 86 this.diagnosticMaps, this.count, diagnostics, MAX_DIAGNOSTIC_MAPS);
87 } 87 }
88 88
89 addBin(other) { 89 addBin(other) {
90 if (!this.range.equals(other.range)) { 90 if (!this.range.equals(other.range)) {
91 throw new Error('Merging incompatible Histogram bins.'); 91 throw new Error('Merging incompatible Histogram bins.');
92 } 92 }
93 tr.b.Statistics.mergeSampledStreams(this.diagnosticMaps, this.count, 93 tr.b.math.Statistics.mergeSampledStreams(this.diagnosticMaps, this.count,
94 other.diagnosticMaps, other.count, MAX_DIAGNOSTIC_MAPS); 94 other.diagnosticMaps, other.count, MAX_DIAGNOSTIC_MAPS);
95 this.count += other.count; 95 this.count += other.count;
96 } 96 }
97 97
98 fromDict(dict) { 98 fromDict(dict) {
99 this.count = dict[0]; 99 this.count = dict[0];
100 if (dict.length > 1) { 100 if (dict.length > 1) {
101 for (let map of dict[1]) { 101 for (let map of dict[1]) {
102 this.diagnosticMaps.push(tr.v.d.DiagnosticMap.fromDict(map)); 102 this.diagnosticMaps.push(tr.v.d.DiagnosticMap.fromDict(map));
103 } 103 }
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
186 get running() { 186 get running() {
187 return this.running_; 187 return this.running_;
188 } 188 }
189 189
190 get maxNumSampleValues() { 190 get maxNumSampleValues() {
191 return this.maxNumSampleValues_; 191 return this.maxNumSampleValues_;
192 } 192 }
193 193
194 set maxNumSampleValues(n) { 194 set maxNumSampleValues(n) {
195 this.maxNumSampleValues_ = n; 195 this.maxNumSampleValues_ = n;
196 tr.b.Statistics.uniformlySampleArray( 196 tr.b.math.Statistics.uniformlySampleArray(
197 this.sampleValues_, this.maxNumSampleValues_); 197 this.sampleValues_, this.maxNumSampleValues_);
198 } 198 }
199 199
200 get name() { 200 get name() {
201 return this.name_; 201 return this.name_;
202 } 202 }
203 203
204 get guid() { 204 get guid() {
205 if (this.guid_ === undefined) { 205 if (this.guid_ === undefined) {
206 this.guid_ = tr.b.GUID.allocateUUID4(); 206 this.guid_ = tr.b.GUID.allocateUUID4();
(...skipping 28 matching lines...) Expand all
235 for (let i = 0; i < dict.allBins.length; ++i) { 235 for (let i = 0; i < dict.allBins.length; ++i) {
236 hist.allBins[i].fromDict(dict.allBins[i]); 236 hist.allBins[i].fromDict(dict.allBins[i]);
237 } 237 }
238 } else { 238 } else {
239 for (var [i, binDict] of Object.entries(dict.allBins)) { 239 for (var [i, binDict] of Object.entries(dict.allBins)) {
240 hist.allBins[i].fromDict(binDict); 240 hist.allBins[i].fromDict(binDict);
241 } 241 }
242 } 242 }
243 } 243 }
244 if (dict.running) { 244 if (dict.running) {
245 hist.running_ = tr.b.RunningStatistics.fromDict(dict.running); 245 hist.running_ = tr.b.math.RunningStatistics.fromDict(dict.running);
246 } 246 }
247 if (dict.summaryOptions) { 247 if (dict.summaryOptions) {
248 hist.customizeSummaryOptions(dict.summaryOptions); 248 hist.customizeSummaryOptions(dict.summaryOptions);
249 } 249 }
250 if (dict.maxNumSampleValues !== undefined) { 250 if (dict.maxNumSampleValues !== undefined) {
251 hist.maxNumSampleValues = dict.maxNumSampleValues; 251 hist.maxNumSampleValues = dict.maxNumSampleValues;
252 } 252 }
253 if (dict.sampleValues) { 253 if (dict.sampleValues) {
254 hist.sampleValues_ = dict.sampleValues; 254 hist.sampleValues_ = dict.sampleValues;
255 } 255 }
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
294 294
295 /** 295 /**
296 * Requires that units agree. 296 * Requires that units agree.
297 * Returns DONT_CARE if that is the units' improvementDirection. 297 * Returns DONT_CARE if that is the units' improvementDirection.
298 * Returns SIGNIFICANT if the Mann-Whitney U test returns a 298 * Returns SIGNIFICANT if the Mann-Whitney U test returns a
299 * p-value less than opt_alpha or DEFAULT_ALPHA. Returns INSIGNIFICANT if 299 * p-value less than opt_alpha or DEFAULT_ALPHA. Returns INSIGNIFICANT if
300 * the p-value is greater than alpha. 300 * the p-value is greater than alpha.
301 * 301 *
302 * @param {!tr.v.Histogram} other 302 * @param {!tr.v.Histogram} other
303 * @param {number=} opt_alpha 303 * @param {number=} opt_alpha
304 * @return {!tr.b.Statistics.Significance} 304 * @return {!tr.b.math.Statistics.Significance}
305 */ 305 */
306 getDifferenceSignificance(other, opt_alpha) { 306 getDifferenceSignificance(other, opt_alpha) {
307 if (this.unit !== other.unit) { 307 if (this.unit !== other.unit) {
308 throw new Error('Cannot compare Histograms with different units'); 308 throw new Error('Cannot compare Histograms with different units');
309 } 309 }
310 310
311 if (this.unit.improvementDirection === 311 if (this.unit.improvementDirection ===
312 tr.b.ImprovementDirection.DONT_CARE) { 312 tr.b.ImprovementDirection.DONT_CARE) {
313 return tr.b.Statistics.Significance.DONT_CARE; 313 return tr.b.math.Statistics.Significance.DONT_CARE;
314 } 314 }
315 315
316 if (!(other instanceof Histogram)) { 316 if (!(other instanceof Histogram)) {
317 throw new Error('Unable to compute a p-value'); 317 throw new Error('Unable to compute a p-value');
318 } 318 }
319 319
320 let testResult = tr.b.Statistics.mwu( 320 let testResult = tr.b.math.Statistics.mwu(
321 this.sampleValues, other.sampleValues, opt_alpha); 321 this.sampleValues, other.sampleValues, opt_alpha);
322 return testResult.significance; 322 return testResult.significance;
323 } 323 }
324 324
325 /* 325 /*
326 * Compute an approximation of percentile based on the counts in the bins. 326 * Compute an approximation of percentile based on the counts in the bins.
327 * If the real percentile lies within |this.range| then the result of 327 * If the real percentile lies within |this.range| then the result of
328 * the function will deviate from the real percentile by at most 328 * the function will deviate from the real percentile by at most
329 * the maximum width of the bin(s) within which the point(s) 329 * the maximum width of the bin(s) within which the point(s)
330 * from which the real percentile would be calculated lie. 330 * from which the real percentile would be calculated lie.
(...skipping 25 matching lines...) Expand all
356 return bin.range.max; 356 return bin.range.max;
357 if (bin.range.max === Number.MAX_VALUE) 357 if (bin.range.max === Number.MAX_VALUE)
358 return bin.range.min; 358 return bin.range.min;
359 return bin.range.center; 359 return bin.range.center;
360 } 360 }
361 return this.allBins[this.allBins.length - 1].range.min; 361 return this.allBins[this.allBins.length - 1].range.min;
362 } 362 }
363 363
364 getBinForValue(value) { 364 getBinForValue(value) {
365 // Don't use subtraction to avoid arithmetic overflow. 365 // Don't use subtraction to avoid arithmetic overflow.
366 let binIndex = tr.b.findHighIndexInSortedArray( 366 let binIndex = tr.b.math.findHighIndexInSortedArray(
367 this.allBins, b => ((value < b.range.max) ? -1 : 1)); 367 this.allBins, b => ((value < b.range.max) ? -1 : 1));
368 return this.allBins[binIndex] || this.allBins[this.allBins.length - 1]; 368 return this.allBins[binIndex] || this.allBins[this.allBins.length - 1];
369 } 369 }
370 370
371 /** 371 /**
372 * @param {number|*} value 372 * @param {number|*} value
373 * @param {(!Object|!tr.v.d.DiagnosticMap)=} opt_diagnostics 373 * @param {(!Object|!tr.v.d.DiagnosticMap)=} opt_diagnostics
374 */ 374 */
375 addSample(value, opt_diagnostics) { 375 addSample(value, opt_diagnostics) {
376 if (opt_diagnostics && 376 if (opt_diagnostics &&
377 !(opt_diagnostics instanceof tr.v.d.DiagnosticMap)) { 377 !(opt_diagnostics instanceof tr.v.d.DiagnosticMap)) {
378 opt_diagnostics = tr.v.d.DiagnosticMap.fromObject(opt_diagnostics); 378 opt_diagnostics = tr.v.d.DiagnosticMap.fromObject(opt_diagnostics);
379 } 379 }
380 380
381 if (typeof(value) !== 'number' || isNaN(value)) { 381 if (typeof(value) !== 'number' || isNaN(value)) {
382 this.numNans++; 382 this.numNans++;
383 if (opt_diagnostics) { 383 if (opt_diagnostics) {
384 tr.b.Statistics.uniformlySampleStream(this.nanDiagnosticMaps, 384 tr.b.math.Statistics.uniformlySampleStream(this.nanDiagnosticMaps,
385 this.numNans, opt_diagnostics, MAX_DIAGNOSTIC_MAPS); 385 this.numNans, opt_diagnostics, MAX_DIAGNOSTIC_MAPS);
386 } 386 }
387 } else { 387 } else {
388 if (this.running_ === undefined) { 388 if (this.running_ === undefined) {
389 this.running_ = new tr.b.RunningStatistics(); 389 this.running_ = new tr.b.math.RunningStatistics();
390 } 390 }
391 this.running_.add(value); 391 this.running_.add(value);
392 392
393 let bin = this.getBinForValue(value); 393 let bin = this.getBinForValue(value);
394 bin.addSample(value); 394 bin.addSample(value);
395 if (opt_diagnostics) { 395 if (opt_diagnostics) {
396 bin.addDiagnosticMap(opt_diagnostics); 396 bin.addDiagnosticMap(opt_diagnostics);
397 } 397 }
398 } 398 }
399 399
400 tr.b.Statistics.uniformlySampleStream(this.sampleValues_, 400 tr.b.math.Statistics.uniformlySampleStream(this.sampleValues_,
401 this.numValues + this.numNans, value, this.maxNumSampleValues); 401 this.numValues + this.numNans, value, this.maxNumSampleValues);
402 } 402 }
403 403
404 sampleValuesInto(samples) { 404 sampleValuesInto(samples) {
405 for (let sampleValue of this.sampleValues) { 405 for (let sampleValue of this.sampleValues) {
406 samples.push(sampleValue); 406 samples.push(sampleValue);
407 } 407 }
408 } 408 }
409 409
410 /** 410 /**
(...skipping 14 matching lines...) Expand all
425 return false; 425 return false;
426 } 426 }
427 for (let i = 0; i < this.binBoundariesDict_.length; ++i) { 427 for (let i = 0; i < this.binBoundariesDict_.length; ++i) {
428 let slice = this.binBoundariesDict_[i]; 428 let slice = this.binBoundariesDict_[i];
429 let otherSlice = other.binBoundariesDict_[i]; 429 let otherSlice = other.binBoundariesDict_[i];
430 if (slice instanceof Array) { 430 if (slice instanceof Array) {
431 if (!(otherSlice instanceof Array)) { 431 if (!(otherSlice instanceof Array)) {
432 return false; 432 return false;
433 } 433 }
434 if (slice[0] !== otherSlice[0] || 434 if (slice[0] !== otherSlice[0] ||
435 !tr.b.approximately(slice[1], otherSlice[1]) || 435 !tr.b.math.approximately(slice[1], otherSlice[1]) ||
436 slice[2] !== otherSlice[2]) { 436 slice[2] !== otherSlice[2]) {
437 return false; 437 return false;
438 } 438 }
439 } else { 439 } else {
440 if (otherSlice instanceof Array) { 440 if (otherSlice instanceof Array) {
441 return false; 441 return false;
442 } 442 }
443 if (!tr.b.approximately(slice, otherSlice)) { 443 if (!tr.b.math.approximately(slice, otherSlice)) {
444 return false; 444 return false;
445 } 445 }
446 } 446 }
447 } 447 }
448 return true; 448 return true;
449 } 449 }
450 450
451 /** 451 /**
452 * Add |other| to this Histogram in-place if they can be added. 452 * Add |other| to this Histogram in-place if they can be added.
453 * 453 *
454 * @param {!tr.v.Histogram} other 454 * @param {!tr.v.Histogram} other
455 */ 455 */
456 addHistogram(other) { 456 addHistogram(other) {
457 if (!this.canAddHistogram(other)) { 457 if (!this.canAddHistogram(other)) {
458 throw new Error('Merging incompatible Histograms'); 458 throw new Error('Merging incompatible Histograms');
459 } 459 }
460 460
461 tr.b.Statistics.mergeSampledStreams(this.nanDiagnosticMaps, this.numNans, 461 tr.b.math.Statistics.mergeSampledStreams(this.nanDiagnosticMaps,
462 other.nanDiagnosticMaps, other.numNans, MAX_DIAGNOSTIC_MAPS); 462 this.numNans, other.nanDiagnosticMaps, other.numNans,
463 tr.b.Statistics.mergeSampledStreams( 463 MAX_DIAGNOSTIC_MAPS);
464 tr.b.math.Statistics.mergeSampledStreams(
464 this.sampleValues, this.numValues + this.numNans, 465 this.sampleValues, this.numValues + this.numNans,
465 other.sampleValues, other.numValues + other.numNans, 466 other.sampleValues, other.numValues + other.numNans,
466 (this.maxNumSampleValues + other.maxNumSampleValues) / 2); 467 (this.maxNumSampleValues + other.maxNumSampleValues) / 2);
467 this.numNans += other.numNans; 468 this.numNans += other.numNans;
468 469
469 if (other.running_ !== undefined) { 470 if (other.running_ !== undefined) {
470 if (this.running_ === undefined) { 471 if (this.running_ === undefined) {
471 this.running_ = new tr.b.RunningStatistics(); 472 this.running_ = new tr.b.math.RunningStatistics();
472 } 473 }
473 this.running_ = this.running_.merge(other.running_); 474 this.running_ = this.running_.merge(other.running_);
474 } 475 }
475 476
476 for (let i = 0; i < this.allBins.length; ++i) { 477 for (let i = 0; i < this.allBins.length; ++i) {
477 this.allBins[i].addBin(other.allBins[i]); 478 this.allBins[i].addBin(other.allBins[i]);
478 } 479 }
479 480
480 let mergedFrom = this.diagnostics.get(tr.v.d.MERGED_FROM_DIAGNOSTIC_KEY); 481 let mergedFrom = this.diagnostics.get(tr.v.d.MERGED_FROM_DIAGNOSTIC_KEY);
481 if (!mergedFrom) { 482 if (!mergedFrom) {
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
543 } 544 }
544 if (statName === 'std') { 545 if (statName === 'std') {
545 if (this.standardDeviation === undefined) return undefined; 546 if (this.standardDeviation === undefined) return undefined;
546 return new tr.b.Scalar(this.unit, this.standardDeviation); 547 return new tr.b.Scalar(this.unit, this.standardDeviation);
547 } 548 }
548 if (statName === 'geometricMean') { 549 if (statName === 'geometricMean') {
549 return new tr.b.Scalar(this.unit, this.geometricMean); 550 return new tr.b.Scalar(this.unit, this.geometricMean);
550 } 551 }
551 if (statName === 'min' || statName === 'max' || statName === 'sum') { 552 if (statName === 'min' || statName === 'max' || statName === 'sum') {
552 if (this.running_ === undefined) { 553 if (this.running_ === undefined) {
553 this.running_ = new tr.b.RunningStatistics(); 554 this.running_ = new tr.b.math.RunningStatistics();
554 } 555 }
555 return new tr.b.Scalar(this.unit, this.running_[statName]); 556 return new tr.b.Scalar(this.unit, this.running_[statName]);
556 } 557 }
557 if (statName === 'nans') { 558 if (statName === 'nans') {
558 return new tr.b.Scalar( 559 return new tr.b.Scalar(
559 tr.b.Unit.byName.count_smallerIsBetter, this.numNans); 560 tr.b.Unit.byName.count_smallerIsBetter, this.numNans);
560 } 561 }
561 if (statName === 'count') { 562 if (statName === 'count') {
562 return new tr.b.Scalar( 563 return new tr.b.Scalar(
563 tr.b.Unit.byName.count_smallerIsBetter, this.numValues); 564 tr.b.Unit.byName.count_smallerIsBetter, this.numValues);
(...skipping 30 matching lines...) Expand all
594 thisStat.unit.correspondingDeltaUnit, deltaValue); 595 thisStat.unit.correspondingDeltaUnit, deltaValue);
595 } 596 }
596 597
597 if (statName === Z_SCORE_NAME) { 598 if (statName === Z_SCORE_NAME) {
598 return new tr.b.Scalar( 599 return new tr.b.Scalar(
599 tr.b.Unit.byName['sigmaDelta' + suffix], 600 tr.b.Unit.byName['sigmaDelta' + suffix],
600 (this.average - opt_referenceHistogram.average) / 601 (this.average - opt_referenceHistogram.average) /
601 opt_referenceHistogram.standardDeviation); 602 opt_referenceHistogram.standardDeviation);
602 } 603 }
603 604
604 let mwu = opt_mwu || tr.b.Statistics.mwu( 605 let mwu = opt_mwu || tr.b.math.Statistics.mwu(
605 this.sampleValues, opt_referenceHistogram.sampleValues); 606 this.sampleValues, opt_referenceHistogram.sampleValues);
606 if (statName === P_VALUE_NAME) { 607 if (statName === P_VALUE_NAME) {
607 return new tr.b.Scalar(tr.b.Unit.byName.unitlessNumber, mwu.p); 608 return new tr.b.Scalar(tr.b.Unit.byName.unitlessNumber, mwu.p);
608 } 609 }
609 if (statName === U_STATISTIC_NAME) { 610 if (statName === U_STATISTIC_NAME) {
610 return new tr.b.Scalar(tr.b.Unit.byName.unitlessNumber, mwu.U); 611 return new tr.b.Scalar(tr.b.Unit.byName.unitlessNumber, mwu.U);
611 } 612 }
612 613
613 throw new Error('Unrecognized statistic name: ' + statName); 614 throw new Error('Unrecognized statistic name: ' + statName);
614 } 615 }
(...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after
945 * If no other bin boundaries are added, then |minBinBoundary| will be the 946 * If no other bin boundaries are added, then |minBinBoundary| will be the
946 * boundary between the underflow bin and the overflow bin. 947 * boundary between the underflow bin and the overflow bin.
947 * If no other bin boundaries are added and |minBinBoundary| is either 948 * If no other bin boundaries are added and |minBinBoundary| is either
948 * -Number.MAX_VALUE or +Number.MAX_VALUE, then only a single binRange will 949 * -Number.MAX_VALUE or +Number.MAX_VALUE, then only a single binRange will
949 * be built. 950 * be built.
950 * 951 *
951 * @param {number} minBinBoundary The minimum boundary between bins. 952 * @param {number} minBinBoundary The minimum boundary between bins.
952 */ 953 */
953 constructor(minBinBoundary) { 954 constructor(minBinBoundary) {
954 this.builder_ = [minBinBoundary]; 955 this.builder_ = [minBinBoundary];
955 this.range_ = new tr.b.Range(); 956 this.range_ = new tr.b.math.Range();
956 this.range_.addValue(minBinBoundary); 957 this.range_.addValue(minBinBoundary);
957 this.binRanges_ = undefined; 958 this.binRanges_ = undefined;
958 } 959 }
959 960
960 get range() { 961 get range() {
961 return this.range_; 962 return this.range_;
962 } 963 }
963 964
964 asDict() { 965 asDict() {
965 if (this.builder_.length === 1 && this.builder_[0] === Number.MAX_VALUE) { 966 if (this.builder_.length === 1 && this.builder_[0] === Number.MAX_VALUE) {
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
1009 1010
1010 default: 1011 default:
1011 throw new Error('Unrecognized HistogramBinBoundaries slice type'); 1012 throw new Error('Unrecognized HistogramBinBoundaries slice type');
1012 } 1013 }
1013 } 1014 }
1014 HISTOGRAM_BIN_BOUNDARIES_CACHE.set(cacheKey, binBoundaries); 1015 HISTOGRAM_BIN_BOUNDARIES_CACHE.set(cacheKey, binBoundaries);
1015 return binBoundaries; 1016 return binBoundaries;
1016 } 1017 }
1017 1018
1018 /** 1019 /**
1019 * @return {!Array.<!tr.b.Range>} 1020 * @return {!Array.<!tr.b.math.Range>}
1020 */ 1021 */
1021 get binRanges() { 1022 get binRanges() {
1022 if (this.binRanges_ === undefined) { 1023 if (this.binRanges_ === undefined) {
1023 this.build_(); 1024 this.build_();
1024 } 1025 }
1025 return this.binRanges_; 1026 return this.binRanges_;
1026 } 1027 }
1027 1028
1028 build_() { 1029 build_() {
1029 if (typeof this.builder_[0] !== 'number') { 1030 if (typeof this.builder_[0] !== 'number') {
1030 throw new Error('Invalid start of builder_'); 1031 throw new Error('Invalid start of builder_');
1031 } 1032 }
1032 this.binRanges_ = []; 1033 this.binRanges_ = [];
1033 let prevBoundary = this.builder_[0]; 1034 let prevBoundary = this.builder_[0];
1034 1035
1035 if (prevBoundary > -Number.MAX_VALUE) { 1036 if (prevBoundary > -Number.MAX_VALUE) {
1036 // underflow bin 1037 // underflow bin
1037 this.binRanges_.push(tr.b.Range.fromExplicitRange(-Number.MAX_VALUE, 1038 this.binRanges_.push(tr.b.math.Range.fromExplicitRange(
1038 prevBoundary)); 1039 -Number.MAX_VALUE, prevBoundary));
1039 } 1040 }
1040 1041
1041 for (let slice of this.builder_.slice(1)) { 1042 for (let slice of this.builder_.slice(1)) {
1042 if (!(slice instanceof Array)) { 1043 if (!(slice instanceof Array)) {
1043 this.binRanges_.push( 1044 this.binRanges_.push(
1044 tr.b.Range.fromExplicitRange(prevBoundary, slice)); 1045 tr.b.math.Range.fromExplicitRange(prevBoundary, slice));
1045 prevBoundary = slice; 1046 prevBoundary = slice;
1046 continue; 1047 continue;
1047 } 1048 }
1048 let nextMaxBinBoundary = slice[1]; 1049 let nextMaxBinBoundary = slice[1];
1049 let binCount = slice[2]; 1050 let binCount = slice[2];
1050 let sliceMinBinBoundary = prevBoundary; 1051 let sliceMinBinBoundary = prevBoundary;
1051 1052
1052 switch (slice[0]) { 1053 switch (slice[0]) {
1053 case HistogramBinBoundaries.SLICE_TYPE.LINEAR: 1054 case HistogramBinBoundaries.SLICE_TYPE.LINEAR:
1054 { 1055 {
1055 let binWidth = (nextMaxBinBoundary - prevBoundary) / binCount; 1056 let binWidth = (nextMaxBinBoundary - prevBoundary) / binCount;
1056 for (let i = 1; i < binCount; i++) { 1057 for (let i = 1; i < binCount; i++) {
1057 let boundary = sliceMinBinBoundary + i * binWidth; 1058 let boundary = sliceMinBinBoundary + i * binWidth;
1058 this.binRanges_.push(tr.b.Range.fromExplicitRange( 1059 this.binRanges_.push(tr.b.math.Range.fromExplicitRange(
1059 prevBoundary, boundary)); 1060 prevBoundary, boundary));
1060 prevBoundary = boundary; 1061 prevBoundary = boundary;
1061 } 1062 }
1062 break; 1063 break;
1063 } 1064 }
1064 1065
1065 case HistogramBinBoundaries.SLICE_TYPE.EXPONENTIAL: 1066 case HistogramBinBoundaries.SLICE_TYPE.EXPONENTIAL:
1066 { 1067 {
1067 let binExponentWidth = 1068 let binExponentWidth =
1068 Math.log(nextMaxBinBoundary / prevBoundary) / binCount; 1069 Math.log(nextMaxBinBoundary / prevBoundary) / binCount;
1069 for (let i = 1; i < binCount; i++) { 1070 for (let i = 1; i < binCount; i++) {
1070 let boundary = sliceMinBinBoundary * Math.exp( 1071 let boundary = sliceMinBinBoundary * Math.exp(
1071 i * binExponentWidth); 1072 i * binExponentWidth);
1072 this.binRanges_.push(tr.b.Range.fromExplicitRange( 1073 this.binRanges_.push(tr.b.math.Range.fromExplicitRange(
1073 prevBoundary, boundary)); 1074 prevBoundary, boundary));
1074 prevBoundary = boundary; 1075 prevBoundary = boundary;
1075 } 1076 }
1076 break; 1077 break;
1077 } 1078 }
1078 1079
1079 default: 1080 default:
1080 throw new Error('Unrecognized HistogramBinBoundaries slice type'); 1081 throw new Error('Unrecognized HistogramBinBoundaries slice type');
1081 } 1082 }
1082 this.binRanges_.push(tr.b.Range.fromExplicitRange( 1083 this.binRanges_.push(tr.b.math.Range.fromExplicitRange(
1083 prevBoundary, nextMaxBinBoundary)); 1084 prevBoundary, nextMaxBinBoundary));
1084 prevBoundary = nextMaxBinBoundary; 1085 prevBoundary = nextMaxBinBoundary;
1085 } 1086 }
1086 if (prevBoundary < Number.MAX_VALUE) { 1087 if (prevBoundary < Number.MAX_VALUE) {
1087 // overflow bin 1088 // overflow bin
1088 this.binRanges_.push(tr.b.Range.fromExplicitRange( 1089 this.binRanges_.push(tr.b.math.Range.fromExplicitRange(
1089 prevBoundary, Number.MAX_VALUE)); 1090 prevBoundary, Number.MAX_VALUE));
1090 } 1091 }
1091 } 1092 }
1092 1093
1093 /** 1094 /**
1094 * Add a bin boundary |nextMaxBinBoundary| to the builder. 1095 * Add a bin boundary |nextMaxBinBoundary| to the builder.
1095 * 1096 *
1096 * This operation effectively corresponds to appending a new central bin 1097 * This operation effectively corresponds to appending a new central bin
1097 * with the range [this.range.max, nextMaxBinBoundary]. 1098 * with the range [this.range.max, nextMaxBinBoundary].
1098 * 1099 *
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
1259 Histogram, 1260 Histogram,
1260 HistogramBinBoundaries, 1261 HistogramBinBoundaries,
1261 P_VALUE_NAME, 1262 P_VALUE_NAME,
1262 U_STATISTIC_NAME, 1263 U_STATISTIC_NAME,
1263 Z_SCORE_NAME, 1264 Z_SCORE_NAME,
1264 percentFromString, 1265 percentFromString,
1265 percentToString, 1266 percentToString,
1266 }; 1267 };
1267 }); 1268 });
1268 </script> 1269 </script>
OLDNEW
« no previous file with comments | « tracing/tracing/ui/tracks/track.html ('k') | tracing/tracing/value/histogram_set_test.html » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698