@@ -177,21 +177,22 @@ Experiment.defaults =
177
177
} ;
178
178
179
179
Regression = Utilities . createClass (
180
- function ( samples , getComplexity , getFrameLength , startIndex , endIndex , options )
180
+ // `samples` is [ [ complexity, frameLength ], [ complexity, frameLength ], ... ]
181
+ // All samples are analyzed. startIndex, endIndex are just stored for use by the caller.
182
+ function ( samples , startIndex , endIndex , options )
181
183
{
182
184
const desiredFrameLength = options . desiredFrameLength ;
183
185
var profile ;
184
186
185
187
if ( ! options . preferredProfile || options . preferredProfile == Strings . json . profiles . slope ) {
186
- profile = this . _calculateRegression ( samples , getComplexity , getFrameLength , startIndex , endIndex , {
188
+ profile = this . _calculateRegression ( samples , {
187
189
shouldClip : true ,
188
190
s1 : desiredFrameLength ,
189
191
t1 : 0
190
192
} ) ;
191
193
this . profile = Strings . json . profiles . slope ;
192
- }
193
- else if ( options . preferredProfile == Strings . json . profiles . flat ) {
194
- profile = this . _calculateRegression ( samples , getComplexity , getFrameLength , startIndex , endIndex , {
194
+ } else if ( options . preferredProfile == Strings . json . profiles . flat ) {
195
+ profile = this . _calculateRegression ( samples , {
195
196
shouldClip : true ,
196
197
s1 : desiredFrameLength ,
197
198
t1 : 0 ,
@@ -233,11 +234,14 @@ Regression = Utilities.createClass(
233
234
//
234
235
// x is assumed to be complexity, y is frame length. Can be used for pure complexity-FPS
235
236
// analysis or for ramp controllers since complexity monotonically decreases with time.
236
- _calculateRegression : function ( samples , getComplexity , getFrameLength , startIndex , endIndex , options )
237
+ _calculateRegression : function ( samples , options )
237
238
{
238
- if ( startIndex == endIndex ) {
239
+ const complexityIndex = 0 ;
240
+ const frameLengthIndex = 1 ;
241
+
242
+ if ( samples . length == 1 ) {
239
243
// Only one sample point; we can't calculate any regression.
240
- var x = getComplexity ( samples , startIndex ) ;
244
+ var x = samples [ 0 ] [ complexityIndex ] ;
241
245
return {
242
246
complexity : x ,
243
247
s1 : x ,
@@ -249,17 +253,19 @@ Regression = Utilities.createClass(
249
253
} ;
250
254
}
251
255
256
+ // Sort by increasing complexity.
257
+ var sortedSamples = samples . slice ( ) . sort ( ( a , b ) => a [ complexityIndex ] - b [ complexityIndex ] ) ;
258
+
252
259
// x is expected to increase in complexity
253
- var iterationDirection = endIndex > startIndex ? 1 : - 1 ;
254
- var lowComplexity = getComplexity ( samples , startIndex ) ;
255
- var highComplexity = getComplexity ( samples , endIndex ) ;
260
+ var lowComplexity = sortedSamples [ 0 ] [ complexityIndex ] ;
261
+ var highComplexity = sortedSamples [ samples . length - 1 ] [ complexityIndex ] ;
262
+
256
263
var a1 = 0 , b1 = 0 , c1 = 0 , d1 = 0 , h1 = 0 , k1 = 0 ;
257
264
var a2 = 0 , b2 = 0 , c2 = 0 , d2 = 0 , h2 = 0 , k2 = 0 ;
258
265
259
- // Iterate from low to high complexity
260
- for ( var i = startIndex ; iterationDirection * ( endIndex - i ) > - 1 ; i += iterationDirection ) {
261
- var x = getComplexity ( samples , i ) ;
262
- var y = getFrameLength ( samples , i ) ;
266
+ for ( var i = 0 ; i < sortedSamples . length ; ++ i ) {
267
+ var x = sortedSamples [ i ] [ complexityIndex ] ;
268
+ var y = sortedSamples [ i ] [ frameLengthIndex ] ;
263
269
a2 += 1 ;
264
270
b2 += x ;
265
271
c2 += x * x ;
@@ -279,9 +285,9 @@ Regression = Utilities.createClass(
279
285
t2_best = t2 ;
280
286
error2_best = error2 ;
281
287
// Number of samples included in the first segment, inclusive of splitIndex
282
- n1_best = iterationDirection * ( splitIndex - startIndex ) + 1 ;
288
+ n1_best = splitIndex + 1 ;
283
289
// Number of samples included in the second segment
284
- n2_best = iterationDirection * ( endIndex - splitIndex ) ;
290
+ n2_best = samples . length - splitIndex - 1 ;
285
291
if ( ! options . shouldClip || ( x_prime >= lowComplexity && x_prime <= highComplexity ) )
286
292
x_best = x_prime ;
287
293
else {
@@ -290,21 +296,21 @@ Regression = Utilities.createClass(
290
296
}
291
297
}
292
298
293
- // Iterate from startIndex to endIndex - 1 , inclusive
294
- for ( var i = startIndex ; iterationDirection * ( endIndex - i ) > 0 ; i += iterationDirection ) {
295
- var x = getComplexity ( samples , i ) ;
296
- var y = getFrameLength ( samples , i ) ;
299
+ // Iterate from 0 to n - 2 , inclusive
300
+ for ( var i = 0 ; i < sortedSamples . length - 1 ; ++ i ) {
301
+ var x = sortedSamples [ i ] [ complexityIndex ] ;
302
+ var y = sortedSamples [ i ] [ frameLengthIndex ] ;
297
303
var xx = x * x ;
298
304
var yx = y * x ;
299
305
var yy = y * y ;
300
- // a1, b1, etc. is sum from startIndex to i, inclusive
306
+ // a1, b1, etc. is sum from 0 to i, inclusive
301
307
a1 += 1 ;
302
308
b1 += x ;
303
309
c1 += xx ;
304
310
d1 += y ;
305
311
h1 += yx ;
306
312
k1 += yy ;
307
- // a2, b2, etc. is sum from i+1 to endIndex , inclusive
313
+ // a2, b2, etc. is sum from i+1 to sortedSamples.length - 1 , inclusive
308
314
a2 -= 1 ;
309
315
b2 -= x ;
310
316
c2 -= xx ;
@@ -328,7 +334,7 @@ Regression = Utilities.createClass(
328
334
var error1 = ( k1 + a1 * s1 * s1 + c1 * t1 * t1 - 2 * d1 * s1 - 2 * h1 * t1 + 2 * b1 * s1 * t1 ) || Number . MAX_VALUE ;
329
335
var error2 = ( k2 + a2 * s2 * s2 + c2 * t2 * t2 - 2 * d2 * s2 - 2 * h2 * t2 + 2 * b2 * s2 * t2 ) || Number . MAX_VALUE ;
330
336
331
- if ( i == startIndex ) {
337
+ if ( i == 0 ) {
332
338
setBest ( s1 , t1 , error1 , s2 , t2 , error2 , i , x_prime , x ) ;
333
339
continue ;
334
340
}
@@ -337,7 +343,8 @@ Regression = Utilities.createClass(
337
343
continue ;
338
344
339
345
// Projected point is not between this and the next sample
340
- if ( x_prime > getComplexity ( samples , i + iterationDirection ) || x_prime < x ) {
346
+ var nextSampleComplexity = sortedSamples [ i + 1 ] [ complexityIndex ] ;
347
+ if ( x_prime > nextSampleComplexity || x_prime < x ) {
341
348
// Calculate lambda, which divides the weight of this sample between the two lines
342
349
343
350
// These values remove the influence of this sample
0 commit comments