1
1
/*
2
- * Copyright (C) 2015-2017 Apple Inc. All rights reserved.
2
+ * Copyright (C) 2015-2024 Apple Inc. All rights reserved.
3
3
*
4
4
* Redistribution and use in source and binary forms, with or without
5
5
* modification, are permitted provided that the following conditions
22
22
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23
23
* THE POSSIBILITY OF SUCH DAMAGE.
24
24
*/
25
- Pseudo =
26
- {
27
- initialRandomSeed : 49734321 ,
28
- randomSeed : 49734321 ,
29
25
30
- resetRandomSeed : function ( )
26
+ class Pseudo {
27
+ static initialRandomSeed = 49734321 ;
28
+ static randomSeed = 49734321 ;
29
+
30
+ static resetRandomSeed ( )
31
31
{
32
32
Pseudo . randomSeed = Pseudo . initialRandomSeed ;
33
- } ,
33
+ }
34
34
35
- random : function ( )
35
+ static random ( )
36
36
{
37
37
var randomSeed = Pseudo . randomSeed ;
38
38
randomSeed = ( ( randomSeed + 0x7ed55d16 ) + ( randomSeed << 12 ) ) & 0xffffffff ;
@@ -44,42 +44,41 @@ Pseudo =
44
44
Pseudo . randomSeed = randomSeed ;
45
45
return ( randomSeed & 0xfffffff ) / 0x10000000 ;
46
46
}
47
- } ;
47
+ }
48
48
49
- Statistics =
50
- {
51
- sampleMean : function ( numberOfSamples , sum )
49
+ class Statistics {
50
+ static sampleMean ( numberOfSamples , sum )
52
51
{
53
52
if ( numberOfSamples < 1 )
54
53
return 0 ;
55
54
return sum / numberOfSamples ;
56
- } ,
55
+ }
57
56
58
57
// With sum and sum of squares, we can compute the sample standard deviation in O(1).
59
58
// See https://rniwa.com/2012-11-10/sample-standard-deviation-in-terms-of-sum-and-square-sum-of-samples/
60
- unbiasedSampleStandardDeviation : function ( numberOfSamples , sum , squareSum )
59
+ static unbiasedSampleStandardDeviation ( numberOfSamples , sum , squareSum )
61
60
{
62
61
if ( numberOfSamples < 2 )
63
62
return 0 ;
64
63
return Math . sqrt ( ( squareSum - sum * sum / numberOfSamples ) / ( numberOfSamples - 1 ) ) ;
65
- } ,
64
+ }
66
65
67
- geometricMean : function ( values )
66
+ static geometricMean ( values )
68
67
{
69
68
if ( ! values . length )
70
69
return 0 ;
71
70
var roots = values . map ( function ( value ) { return Math . pow ( value , 1 / values . length ) ; } )
72
71
return roots . reduce ( function ( a , b ) { return a * b ; } ) ;
73
- } ,
72
+ }
74
73
75
74
// Cumulative distribution function
76
- cdf : function ( value , mean , standardDeviation )
75
+ static cdf ( value , mean , standardDeviation )
77
76
{
78
77
return 0.5 * ( 1 + Statistics . erf ( ( value - mean ) / ( Math . sqrt ( 2 * standardDeviation * standardDeviation ) ) ) ) ;
79
- } ,
78
+ }
80
79
81
80
// Approximation of Gauss error function, Abramowitz and Stegun 7.1.26
82
- erf : function ( value )
81
+ static erf ( value )
83
82
{
84
83
var sign = ( value >= 0 ) ? 1 : - 1 ;
85
84
value = Math . abs ( value ) ;
@@ -94,92 +93,89 @@ Statistics =
94
93
var t = 1.0 / ( 1.0 + p * value ) ;
95
94
var y = 1.0 - ( ( ( ( ( a5 * t + a4 ) * t ) + a3 ) * t + a2 ) * t + a1 ) * t * Math . exp ( - value * value ) ;
96
95
return sign * y ;
97
- } ,
96
+ }
98
97
99
- largestDeviationPercentage : function ( low , mean , high )
98
+ static largestDeviationPercentage ( low , mean , high )
100
99
{
101
100
return Math . max ( Math . abs ( low / mean - 1 ) , ( high / mean - 1 ) ) ;
102
101
}
103
- } ;
102
+ }
103
+
104
+ class Experiment {
105
+ static DEFAULT_CONCERN = 5 ;
106
+ static DEFAULT_CONCERN_SIZE = 100 ;
104
107
105
- Experiment = Utilities . createClass (
106
- function ( includeConcern )
108
+ constructor ( includeConcern )
107
109
{
108
110
if ( includeConcern )
109
- this . _maxHeap = Heap . createMaxHeap ( Experiment . defaults . CONCERN_SIZE ) ;
111
+ this . _maxHeap = Heap . createMaxHeap ( Experiment . DEFAULT_CONCERN_SIZE ) ;
110
112
this . reset ( ) ;
111
- } , {
113
+ }
112
114
113
- reset : function ( )
115
+ reset ( )
114
116
{
115
117
this . _sum = 0 ;
116
118
this . _squareSum = 0 ;
117
119
this . _numberOfSamples = 0 ;
118
120
if ( this . _maxHeap )
119
121
this . _maxHeap . init ( ) ;
120
- } ,
122
+ }
121
123
122
124
get sampleCount ( )
123
125
{
124
126
return this . _numberOfSamples ;
125
- } ,
127
+ }
126
128
127
- sample : function ( value )
129
+ sample ( value )
128
130
{
129
131
this . _sum += value ;
130
132
this . _squareSum += value * value ;
131
133
if ( this . _maxHeap )
132
134
this . _maxHeap . push ( value ) ;
133
135
++ this . _numberOfSamples ;
134
- } ,
136
+ }
135
137
136
- mean : function ( )
138
+ mean ( )
137
139
{
138
140
return Statistics . sampleMean ( this . _numberOfSamples , this . _sum ) ;
139
- } ,
141
+ }
140
142
141
- standardDeviation : function ( )
143
+ standardDeviation ( )
142
144
{
143
145
return Statistics . unbiasedSampleStandardDeviation ( this . _numberOfSamples , this . _sum , this . _squareSum ) ;
144
- } ,
146
+ }
145
147
146
- cdf : function ( value )
148
+ cdf ( value )
147
149
{
148
150
return Statistics . cdf ( value , this . mean ( ) , this . standardDeviation ( ) ) ;
149
- } ,
151
+ }
150
152
151
- percentage : function ( )
153
+ percentage ( )
152
154
{
153
155
var mean = this . mean ( ) ;
154
156
return mean ? this . standardDeviation ( ) * 100 / mean : 0 ;
155
- } ,
157
+ }
156
158
157
- concern : function ( percentage )
159
+ concern ( percentage )
158
160
{
159
161
if ( ! this . _maxHeap )
160
162
return this . mean ( ) ;
161
163
162
164
var size = Math . ceil ( this . _numberOfSamples * percentage / 100 ) ;
163
165
var values = this . _maxHeap . values ( size ) ;
164
166
return values . length ? values . reduce ( function ( a , b ) { return a + b ; } ) / values . length : 0 ;
165
- } ,
167
+ }
166
168
167
- score : function ( percentage )
169
+ score ( percentage )
168
170
{
169
171
return Statistics . geometricMean ( [ this . mean ( ) , Math . max ( this . concern ( percentage ) , 1 ) ] ) ;
170
172
}
171
- } ) ;
172
-
173
- Experiment . defaults =
174
- {
175
- CONCERN : 5 ,
176
- CONCERN_SIZE : 100 ,
177
- } ;
173
+ }
178
174
179
- Regression = Utilities . createClass (
175
+ class Regression {
180
176
// `samples` is [ [ complexity, frameLength ], [ complexity, frameLength ], ... ]
181
177
// All samples are analyzed. startIndex, endIndex are just stored for use by the caller.
182
- function ( samples , startIndex , endIndex , options )
178
+ constructor ( samples , startIndex , endIndex , options )
183
179
{
184
180
const desiredFrameLength = options . desiredFrameLength ;
185
181
var profile ;
@@ -214,14 +210,14 @@ Regression = Utilities.createClass(
214
210
this . n1 = profile . n1 ;
215
211
this . n2 = profile . n2 ;
216
212
this . error = profile . error ;
217
- } , {
213
+ }
218
214
219
- valueAt : function ( complexity )
215
+ valueAt ( complexity )
220
216
{
221
217
if ( this . n1 == 1 || complexity > this . complexity )
222
218
return this . s2 + this . t2 * complexity ;
223
219
return this . s1 + this . t1 * complexity ;
224
- } ,
220
+ }
225
221
226
222
// A generic two-segment piecewise regression calculator. Based on Kundu/Ubhaya
227
223
//
@@ -234,7 +230,7 @@ Regression = Utilities.createClass(
234
230
//
235
231
// x is assumed to be complexity, y is frame length. Can be used for pure complexity-FPS
236
232
// analysis or for ramp controllers since complexity monotonically decreases with time.
237
- _calculateRegression : function ( samples , options )
233
+ _calculateRegression ( samples , options )
238
234
{
239
235
const complexityIndex = 0 ;
240
236
const frameLengthIndex = 1 ;
@@ -387,10 +383,8 @@ Regression = Utilities.createClass(
387
383
n2 : n2_best
388
384
} ;
389
385
}
390
- } ) ;
391
386
392
- Utilities . extendObject ( Regression , {
393
- bootstrap : function ( samples , iterationCount , processResample , confidencePercentage )
387
+ static bootstrap ( samples , iterationCount , processResample , confidencePercentage )
394
388
{
395
389
var sampleLength = samples . length ;
396
390
var resample = new Array ( sampleLength ) ;
@@ -418,4 +412,4 @@ Utilities.extendObject(Regression, {
418
412
confidencePercentage : confidencePercentage
419
413
} ;
420
414
}
421
- } ) ;
415
+ }
0 commit comments