From a9cd22271d445cf8f0c14d5d779b0058396c5d20 Mon Sep 17 00:00:00 2001 From: Said Abou-Hallawa Date: Thu, 29 Aug 2024 17:49:00 -0700 Subject: [PATCH] Fix the two piecewise-linear regression calculation https://github.com/WebKit/MotionMark/issues/66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The current implementation of the regression calculation has these flaws: When processing (x[0], y[0]), L1 must be any line through (x[0], y[0]) which meets L2 at a point (x’, y’) where x[0] < x' < x[1]. L1 has no error. When processing (x[n - 2], y[n - 2]), L2 must be any line through (x[n - 1], y[n - 1]) which meets L1 at a point (x’, y’) where x[n - 2] < x' < x[n - 1]. L2 has no error. The lambda calculation is incorrect. It includes a term called H which is equal to C - I. Looking at the algorithm of Kundu/Ubhaya, this should be just C. lambda should to be used with calculating L1 and (1 - lambda) should to be used with calculating L2. Currently (1 - lambda) is used in calculating L1 and L2. The current calculation has this condition if (t1 != t2) continue; This condition is almost always true even if t1 and t2 are essentiallyEqual. --- MotionMark/resources/statistics.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/MotionMark/resources/statistics.js b/MotionMark/resources/statistics.js index 30fa89d..9139599 100644 --- a/MotionMark/resources/statistics.js +++ b/MotionMark/resources/statistics.js @@ -244,11 +244,11 @@ Regression = Utilities.createClass( }, _areEssentiallyEqual: function(n1, n2) { - const epsilon = 0.001; + const epsilon = 0.0001; return Math.abs(n1 - n2) < epsilon; }, - _setOptimal: function(segment1, segment2, xp, x, options) { + _setOptimal: function(segment1, segment2, x, xn, options) { if (segment1.e + segment2.e > this.segment1.e + this.segment2.e) return false; @@ -256,7 +256,7 @@ Regression = Utilities.createClass( if (!this._areEssentiallyEqual(this.segment1.t, this.segment2.t)) { // If segment1 and segment2 are not parallel, then they have to meet // at complexity such that xp < complexity < x. - if (!(complexity >= xp && complexity <= x)) + if (!(complexity >= x && complexity <= xn)) return false; } else { // If segment1 and segment2 are parallel, then they have to form one @@ -395,7 +395,7 @@ Regression = Utilities.createClass( }; } - if (this._setOptimal(segment1, segment2, xp, x, options)) + if (this._setOptimal(segment1, segment2, x, sortedSamples[j + 1][complexityIndex], options)) continue // These values remove the influence of this sample @@ -426,7 +426,7 @@ Regression = Utilities.createClass( e: (k2 + a2 * s2 * s2 + c2 * t2 * t2 - 2 * d2 * s2 - 2 * h2 * t2 + 2 * b2 * s2 * t2) + lambda1 * Math.pow(y - (s2 + t2 * x), 2) }; - this._setOptimal(segment1, segment2, xp, x, options); + this._setOptimal(segment1, segment2, x, sortedSamples[j + 1][complexityIndex], options); } } });