| <!DOCTYPE html> |
| <html> |
| <head> |
| <script src="../../../resources/js-test-pre.js"></script> |
| <script src="../../../../PerformanceTests/resources/runner.js"></script> |
| <script type="text/javascript"> |
| var alternateComputeStatistics = { |
| min: function(array) { |
| return Math.min.apply(Math, array); |
| }, |
| max: function(array) { |
| return Math.max.apply(Math, array); |
| }, |
| median: function(originalData) { |
| // don't want side effects on the input array, so... |
| var array = originalData.slice(0); |
| array.sort(function(a,b) { return a - b; }); |
| var mid = Math.floor(array.length / 2); |
| if (array.length % 2) |
| return array[mid]; |
| else |
| return (array[mid-1] + array[mid]) / 2; |
| }, |
| mean: function(array) { |
| return alternateComputeStatistics.sum(array)/array.length; |
| }, |
| sum: function(array) { |
| var total = 0; |
| for (var index in array) |
| total += array[index]; |
| return total; |
| }, |
| variance: function(array) { |
| var mean = alternateComputeStatistics.mean(array); |
| var sumOfSquaredDiffs = 0; |
| for (var index in array) { |
| var squaredDiff = array[index] - mean; |
| sumOfSquaredDiffs += squaredDiff * squaredDiff; |
| }; |
| return sumOfSquaredDiffs / (array.length - 1); |
| }, |
| stdev: function(array) { |
| return Math.sqrt(alternateComputeStatistics.variance(array)); |
| } |
| }; |
| </script> |
| </head> |
| <body> |
| |
| <div id="description"></div> |
| |
| <script type="text/javascript"> |
| description("This test verifies PerfTestRunner.computeStatistics(), " + |
| "including: min, max, median, mean, variance, and stdev."); |
| </script> |
| |
| <div id="console"></div> |
| |
| <script type="text/javascript"> |
| var data = []; |
| var stats = []; |
| |
| data = [0, 0, 0, 0, 0]; |
| debug("Ensure no latent divide by 0's for an odd number of elements."); |
| debug("data = " + JSON.stringify(data)); |
| stats = PerfTestRunner.computeStatistics(data); |
| shouldEvaluateTo("stats.min", 0); |
| shouldEvaluateTo("stats.max", 0); |
| shouldEvaluateTo("stats.median", 0); |
| shouldEvaluateTo("stats.mean", 0); |
| shouldEvaluateTo("stats.variance", 0); |
| shouldEvaluateTo("stats.stdev", 0); |
| debug(""); |
| |
| data = [1, 10, 2, 20, 5]; |
| debug("This test will catch if any order dependencies in the data, such as"); |
| debug("needing to be numerically sorted, are not resolved by the algorithm."); |
| debug("This variant covers an odd number of elements."); |
| debug("data = " + JSON.stringify(data)); |
| stats = PerfTestRunner.computeStatistics(data); |
| // hand calculated |
| shouldEvaluateTo("stats.min", 1); |
| shouldEvaluateTo("stats.max", 20); |
| shouldEvaluateTo("stats.median", 5); |
| shouldEvaluateTo("stats.mean", (38/5)); |
| // using alternate implementation |
| shouldEvaluateTo("stats.min", alternateComputeStatistics.min(data)); |
| shouldEvaluateTo("stats.max", alternateComputeStatistics.max(data)); |
| shouldEvaluateTo("stats.median", alternateComputeStatistics.median(data)); |
| shouldEvaluateTo("stats.mean", alternateComputeStatistics.mean(data)); |
| shouldBeCloseTo("stats.variance", alternateComputeStatistics.variance(data), 0.0001); |
| shouldBeCloseTo("stats.stdev", alternateComputeStatistics.stdev(data), 0.0001); |
| debug(""); |
| |
| data = [-1, -10, -2, -20, -5]; |
| debug("This test will catch if any order dependencies in the data, such as"); |
| debug("needing to be numerically sorted, are not resolved by the algorithm."); |
| debug("This variant covers an odd number of elements, and negative values."); |
| debug("data = " + JSON.stringify(data)); |
| stats = PerfTestRunner.computeStatistics(data); |
| // hand calculated |
| shouldEvaluateTo("stats.min", -20); |
| shouldEvaluateTo("stats.max", -1); |
| shouldEvaluateTo("stats.median", -5); |
| shouldEvaluateTo("stats.mean", (-38/5)); |
| // using alternate implementation |
| shouldEvaluateTo("stats.min", alternateComputeStatistics.min(data)); |
| shouldEvaluateTo("stats.max", alternateComputeStatistics.max(data)); |
| shouldEvaluateTo("stats.median", alternateComputeStatistics.median(data)); |
| shouldEvaluateTo("stats.mean", alternateComputeStatistics.mean(data)); |
| shouldBeCloseTo("stats.variance", alternateComputeStatistics.variance(data), 0.0001); |
| shouldBeCloseTo("stats.stdev", alternateComputeStatistics.stdev(data), 0.0001); |
| debug(""); |
| |
| data = [0, 0, 0, 0]; |
| debug("Ensure no latent divide by 0's for an even number of elements."); |
| debug("data = " + JSON.stringify(data)); |
| stats = PerfTestRunner.computeStatistics(data); |
| shouldEvaluateTo("stats.median", 0); |
| debug(""); |
| |
| data = [1, 10, 2, 20, 5, 6]; |
| debug("This test verifies that median is handled correctly for"); |
| debug("an even number of elements."); |
| debug("data = " + JSON.stringify(data)); |
| stats = PerfTestRunner.computeStatistics(data); |
| shouldEvaluateTo("stats.median", 5.5); |
| shouldEvaluateTo("stats.median", alternateComputeStatistics.median(data)); |
| debug(""); |
| |
| data = [-1, -10, -2, -20, -5, -6]; |
| debug("This test verifies that median is handled correctly for"); |
| debug("an even number of elements, including negative numbers."); |
| debug("data = " + JSON.stringify(data)); |
| stats = PerfTestRunner.computeStatistics(data); |
| shouldEvaluateTo("stats.median", -5.5); |
| shouldEvaluateTo("stats.median", alternateComputeStatistics.median(data)); |
| debug(""); |
| |
| // runner.js marks this as an async test so we need to call notifyDone. |
| if (window.testRunner) |
| testRunner.notifyDone(); |
| </script> |
| |
| <script src="../../../resources/js-test-post.js"></script> |
| </body> |
| </html> |