d91042212a1bf19a1db7d16b5ec7a301ab63bddd
[WebKit-https.git] / Websites / perf.webkit.org / unit-tests / statistics-tests.js
1 "use strict";
2
3 var assert = require('assert');
4 var Statistics = require('../public/shared/statistics.js');
5 if (!assert.almostEqual)
6     assert.almostEqual = require('./resources/almost-equal.js');
7
8
9 describe('assert.almostEqual', function () {
10     it('should not throw when values are identical', function () {
11         assert.doesNotThrow(function () { assert.almostEqual(1, 1); });
12     });
13
14     it('should not throw when values are close', function () {
15         assert.doesNotThrow(function () { assert.almostEqual(1.10, 1.107, 2); });
16         assert.doesNotThrow(function () { assert.almostEqual(1256.7, 1256.72, 4); });
17     });
18
19     it('should throw when values are not close', function () {
20         assert.throws(function () { assert.almostEqual(1.10, 1.27, 2); });
21         assert.throws(function () { assert.almostEqual(735.4, 735.6, 4); });
22     });
23 });
24
25 describe('Statistics', function () {
26     describe('min', function () {
27         it('should find the mininum value', function () {
28             assert.equal(Statistics.min([1, 2, 3, 4]), 1);
29             assert.equal(Statistics.min([4, 3, 2, 1]), 1);
30             assert.equal(Statistics.min([2000, 20, 200]), 20);
31             assert.equal(Statistics.min([0.3, 0.06, 0.5]), 0.06);
32             assert.equal(Statistics.min([-0.3, 0.06, 0.5]), -0.3);
33             assert.equal(Statistics.min([-0.3, 0.06, 0.5, Infinity]), -0.3);
34             assert.equal(Statistics.min([-0.3, 0.06, 0.5, -Infinity]), -Infinity);
35             assert.equal(Statistics.min([]), Infinity);
36         });
37     });
38
39     describe('max', function () {
40         it('should find the mininum value', function () {
41             assert.equal(Statistics.max([1, 2, 3, 4]), 4);
42             assert.equal(Statistics.max([4, 3, 2, 1]), 4);
43             assert.equal(Statistics.max([2000, 20, 200]), 2000);
44             assert.equal(Statistics.max([0.3, 0.06, 0.5]), 0.5);
45             assert.equal(Statistics.max([-0.3, 0.06, 0.5]), 0.5);
46             assert.equal(Statistics.max([-0.3, 0.06, 0.5, Infinity]), Infinity);
47             assert.equal(Statistics.max([-0.3, 0.06, 0.5, -Infinity]), 0.5);
48             assert.equal(Statistics.max([]), -Infinity);
49         });
50     });
51
52     describe('sum', function () {
53         it('should find the sum of values', function () {
54             assert.equal(Statistics.sum([1, 2, 3, 4]), 10);
55             assert.equal(Statistics.sum([4, 3, 2, 1]), 10);
56             assert.equal(Statistics.sum([2000, 20, 200]), 2220);
57             assert.equal(Statistics.sum([0.3, 0.06, 0.5]), 0.86);
58             assert.equal(Statistics.sum([-0.3, 0.06, 0.5]), 0.26);
59             assert.equal(Statistics.sum([-0.3, 0.06, 0.5, Infinity]), Infinity);
60             assert.equal(Statistics.sum([-0.3, 0.06, 0.5, -Infinity]), -Infinity);
61             assert.equal(Statistics.sum([]), 0);
62         });
63     });
64
65     describe('squareSum', function () {
66         it('should find the square sum of values', function () {
67             assert.equal(Statistics.squareSum([1, 2, 3, 4]), 30);
68             assert.equal(Statistics.squareSum([4, 3, 2, 1]), 30);
69             assert.equal(Statistics.squareSum([2000, 20, 200]), 2000 * 2000 + 20 * 20 + 200* 200);
70             assert.equal(Statistics.squareSum([0.3, 0.06, 0.5]), 0.09 + 0.0036 + 0.25);
71             assert.equal(Statistics.squareSum([-0.3, 0.06, 0.5]), 0.09 + 0.0036 + 0.25);
72             assert.equal(Statistics.squareSum([-0.3, 0.06, 0.5, Infinity]), Infinity);
73             assert.equal(Statistics.squareSum([-0.3, 0.06, 0.5, -Infinity]), Infinity);
74             assert.equal(Statistics.squareSum([]), 0);
75         });
76     });
77
78     describe('sampleStandardDeviation', function () {
79         function stdev(values) {
80             return Statistics.sampleStandardDeviation(values.length,
81                 Statistics.sum(values), Statistics.squareSum(values));
82         }
83
84         it('should find the standard deviation of values', function () {
85             assert.almostEqual(stdev([1, 2, 3, 4]), 1.2909944);
86             assert.almostEqual(stdev([4, 3, 2, 1]), 1.2909944);
87             assert.almostEqual(stdev([2000, 20, 200]), 1094.89726);
88             assert.almostEqual(stdev([0.3, 0.06, 0.5]), 0.220302822);
89             assert.almostEqual(stdev([-0.3, 0.06, 0.5]), 0.40066611203);
90             assert.almostEqual(stdev([-0.3, 0.06, 0.5, Infinity]), NaN);
91             assert.almostEqual(stdev([-0.3, 0.06, 0.5, -Infinity]), NaN);
92             assert.almostEqual(stdev([]), 0);
93         });
94     });
95
96     describe('confidenceIntervalDelta', function () {
97         it('should find the p-value of values using Student\'s t distribution', function () {
98             function delta(values, probabilty) {
99                 return Statistics.confidenceIntervalDelta(probabilty, values.length,
100                     Statistics.sum(values), Statistics.squareSum(values));
101             }
102
103             // https://onlinecourses.science.psu.edu/stat414/node/199
104             var values = [118, 115, 125, 110, 112, 130, 117, 112, 115, 120, 113, 118, 119, 122, 123, 126];
105             assert.almostEqual(delta(values, 0.95), 3.015, 3);
106
107             // Following values are computed using Excel Online's STDEV and CONFIDENCE.T
108             assert.almostEqual(delta([1, 2, 3, 4], 0.8), 1.057159);
109             assert.almostEqual(delta([1, 2, 3, 4], 0.9), 1.519090);
110             assert.almostEqual(delta([1, 2, 3, 4], 0.95), 2.054260);
111
112             assert.almostEqual(delta([0.3, 0.06, 0.5], 0.8), 0.2398353);
113             assert.almostEqual(delta([0.3, 0.06, 0.5], 0.9), 0.3713985);
114             assert.almostEqual(delta([0.3, 0.06, 0.5], 0.95), 0.5472625);
115
116             assert.almostEqual(delta([-0.3, 0.06, 0.5], 0.8), 0.4361900);
117             assert.almostEqual(delta([-0.3, 0.06, 0.5], 0.9), 0.6754647);
118             assert.almostEqual(delta([-0.3, 0.06, 0.5], 0.95), 0.9953098);
119
120             assert.almostEqual(delta([123, 107, 109, 104, 111], 0.8), 5.001167);
121             assert.almostEqual(delta([123, 107, 109, 104, 111], 0.9), 6.953874);
122             assert.almostEqual(delta([123, 107, 109, 104, 111], 0.95), 9.056490);
123
124             assert.almostEqual(delta([6785, 7812, 6904, 7503, 6943, 7207, 6812], 0.8), 212.6155);
125             assert.almostEqual(delta([6785, 7812, 6904, 7503, 6943, 7207, 6812], 0.9), 286.9585);
126             assert.almostEqual(delta([6785, 7812, 6904, 7503, 6943, 7207, 6812], 0.95), 361.3469);
127
128         });
129     });
130
131     // https://en.wikipedia.org/wiki/Welch%27s_t_test
132
133     var example1 = {
134         A1: [27.5, 21.0, 19.0, 23.6, 17.0, 17.9, 16.9, 20.1, 21.9, 22.6, 23.1, 19.6, 19.0, 21.7, 21.4],
135         A2: [27.1, 22.0, 20.8, 23.4, 23.4, 23.5, 25.8, 22.0, 24.8, 20.2, 21.9, 22.1, 22.9, 20.5, 24.4],
136         expectedT: 2.46,
137         expectedDegreesOfFreedom: 25.0,
138         expectedRange: [0.95, 0.98] // P = 0.021 so 1 - P = 0.979 is between 0.95 and 0.98
139     };
140
141     var example2 = {
142         A1: [17.2, 20.9, 22.6, 18.1, 21.7, 21.4, 23.5, 24.2, 14.7, 21.8],
143         A2: [21.5, 22.8, 21.0, 23.0, 21.6, 23.6, 22.5, 20.7, 23.4, 21.8, 20.7, 21.7, 21.5, 22.5, 23.6, 21.5, 22.5, 23.5, 21.5, 21.8],
144         expectedT: 1.57,
145         expectedDegreesOfFreedom: 9.9,
146         expectedRange: [0.8, 0.9] // P = 0.149 so 1 - P = 0.851 is between 0.8 and 0.9
147     };
148
149     var example3 = {
150         A1: [19.8, 20.4, 19.6, 17.8, 18.5, 18.9, 18.3, 18.9, 19.5, 22.0],
151         A2: [28.2, 26.6, 20.1, 23.3, 25.2, 22.1, 17.7, 27.6, 20.6, 13.7, 23.2, 17.5, 20.6, 18.0, 23.9, 21.6, 24.3, 20.4, 24.0, 13.2],
152         expectedT: 2.22,
153         expectedDegreesOfFreedom: 24.5,
154         expectedRange: [0.95, 0.98] // P = 0.036 so 1 - P = 0.964 is beteween 0.95 and 0.98
155     };
156
157     describe('computeWelchsT', function () {
158         function computeWelchsT(values1, values2, probability) {
159             return Statistics.computeWelchsT(values1, 0, values1.length, values2, 0, values2.length, probability);
160         }
161
162         it('should detect the statistically significant difference using Welch\'s t-test', function () {
163             assert.equal(computeWelchsT(example1.A1, example1.A2, 0.8).significantlyDifferent, true);
164             assert.equal(computeWelchsT(example1.A1, example1.A2, 0.9).significantlyDifferent, true);
165             assert.equal(computeWelchsT(example1.A1, example1.A2, 0.95).significantlyDifferent, true);
166             assert.equal(computeWelchsT(example1.A1, example1.A2, 0.98).significantlyDifferent, false);
167
168             assert.equal(computeWelchsT(example2.A1, example2.A2, 0.8).significantlyDifferent, true);
169             assert.equal(computeWelchsT(example2.A1, example2.A2, 0.9).significantlyDifferent, false);
170             assert.equal(computeWelchsT(example2.A1, example2.A2, 0.95).significantlyDifferent, false);
171             assert.equal(computeWelchsT(example2.A1, example2.A2, 0.98).significantlyDifferent, false);
172
173             assert.equal(computeWelchsT(example3.A1, example3.A2, 0.8).significantlyDifferent, true);
174             assert.equal(computeWelchsT(example3.A1, example3.A2, 0.9).significantlyDifferent, true);
175             assert.equal(computeWelchsT(example3.A1, example3.A2, 0.95).significantlyDifferent, true);
176             assert.equal(computeWelchsT(example3.A1, example3.A2, 0.98).significantlyDifferent, false);
177         });
178
179         it('should find the t-value of values using Welch\'s t-test', function () {
180             assert.almostEqual(computeWelchsT(example1.A1, example1.A2).t, example1.expectedT, 2);
181             assert.almostEqual(computeWelchsT(example2.A1, example2.A2).t, example2.expectedT, 2);
182             assert.almostEqual(computeWelchsT(example3.A1, example3.A2).t, example3.expectedT, 2);
183         });
184
185         it('should find the degreees of freedom using Welch–Satterthwaite equation', function () {
186             assert.almostEqual(computeWelchsT(example1.A1, example1.A2).degreesOfFreedom, example1.expectedDegreesOfFreedom, 2);
187             assert.almostEqual(computeWelchsT(example2.A1, example2.A2).degreesOfFreedom, example2.expectedDegreesOfFreedom, 2);
188             assert.almostEqual(computeWelchsT(example3.A1, example3.A2).degreesOfFreedom, example3.expectedDegreesOfFreedom, 2);
189         });
190
191         it('should respect the start and the end indices', function () {
192             var A1 = example2.A1.slice();
193             var A2 = example2.A2.slice();
194
195             var expectedT = Statistics.computeWelchsT(A1, 0, A1.length, A2, 0, A2.length).t;
196
197             A1.unshift(21);
198             A1.push(15);
199             A1.push(24);
200             assert.almostEqual(Statistics.computeWelchsT(A1, 1, A1.length - 3, A2, 0, A2.length).t, expectedT);
201
202             A2.unshift(24.3);
203             A2.unshift(25.8);
204             A2.push(23);
205             A2.push(24);
206             A2 = A2.reverse();
207             assert.almostEqual(Statistics.computeWelchsT(A1, 1, A1.length - 3, A2, 2, A2.length - 4).t, expectedT);
208         });
209     });
210
211     describe('probabilityRangeForWelchsT', function () {
212         it('should find the t-value of values using Welch\'s t-test', function () {
213             assert.almostEqual(Statistics.probabilityRangeForWelchsT(example1.A1, example1.A2).t, example1.expectedT, 2);
214             assert.almostEqual(Statistics.probabilityRangeForWelchsT(example2.A1, example2.A2).t, example2.expectedT, 2);
215             assert.almostEqual(Statistics.probabilityRangeForWelchsT(example3.A1, example3.A2).t, example3.expectedT, 2);
216         });
217
218         it('should find the degreees of freedom using Welch–Satterthwaite equation', function () {
219             assert.almostEqual(Statistics.probabilityRangeForWelchsT(example1.A1, example1.A2).degreesOfFreedom,
220                 example1.expectedDegreesOfFreedom, 2);
221             assert.almostEqual(Statistics.probabilityRangeForWelchsT(example2.A1, example2.A2).degreesOfFreedom,
222                 example2.expectedDegreesOfFreedom, 2);
223             assert.almostEqual(Statistics.probabilityRangeForWelchsT(example3.A1, example3.A2).degreesOfFreedom,
224                 example3.expectedDegreesOfFreedom, 2);
225         });
226
227         it('should compute the range of probabilites using the p-value of Welch\'s t-test', function () {
228             assert.almostEqual(Statistics.probabilityRangeForWelchsT(example1.A1, example1.A2).range[0], example1.expectedRange[0]);
229             assert.almostEqual(Statistics.probabilityRangeForWelchsT(example1.A1, example1.A2).range[1], example1.expectedRange[1]);
230
231             assert.almostEqual(Statistics.probabilityRangeForWelchsT(example2.A1, example2.A2).range[0], example2.expectedRange[0]);
232             assert.almostEqual(Statistics.probabilityRangeForWelchsT(example2.A1, example2.A2).range[1], example2.expectedRange[1]);
233
234             assert.almostEqual(Statistics.probabilityRangeForWelchsT(example3.A1, example3.A2).range[0], example3.expectedRange[0]);
235             assert.almostEqual(Statistics.probabilityRangeForWelchsT(example3.A1, example3.A2).range[1], example3.expectedRange[1]);
236         });
237     });
238
239     describe('movingAverage', function () {
240         it('should return the origian values when both forward and backward window size is 0', function () {
241             assert.deepEqual(Statistics.movingAverage([1, 2, 3, 4, 5], 0, 0), [1, 2, 3, 4, 5]);
242         });
243
244         it('should find the moving average with a positive backward window', function () {
245             assert.deepEqual(Statistics.movingAverage([1, 2, 3, 4, 5], 1, 0),
246                 [1, (1 + 2) / 2, (2 + 3) / 2, (3 + 4) / 2, (4 + 5) / 2]);
247
248             assert.deepEqual(Statistics.movingAverage([1, 2, 3, 4, 5], 2, 0),
249                 [1, (1 + 2) / 2, (1 + 2 + 3) / 3, (2 + 3 + 4) / 3, (3 + 4 + 5) / 3]);
250
251             assert.deepEqual(Statistics.movingAverage([1, 2, 3, 4, 5], 3, 0),
252                 [1, (1 + 2) / 2, (1 + 2 + 3) / 3, (1 + 2 + 3 + 4) / 4, (2 + 3 + 4 + 5) / 4]);
253
254             assert.deepEqual(Statistics.movingAverage([1, 2, 3, 4, 5], 4, 0),
255                 [1, (1 + 2) / 2, (1 + 2 + 3) / 3, (1 + 2 + 3 + 4) / 4, (1 + 2 + 3 + 4 + 5) / 5]);
256
257             assert.deepEqual(Statistics.movingAverage([1, 2, 3, 4, 5], 5, 0),
258                 [1, (1 + 2) / 2, (1 + 2 + 3) / 3, (1 + 2 + 3 + 4) / 4, (1 + 2 + 3 + 4 + 5) / 5]);
259         });
260
261         it('should find the moving average with a positive forward window', function () {
262             assert.deepEqual(Statistics.movingAverage([1, 2, 3, 4, 5], 0, 1),
263                 [(1 + 2) / 2, (2 + 3) / 2, (3 + 4) / 2, (4 + 5) / 2, 5]);
264
265             assert.deepEqual(Statistics.movingAverage([1, 2, 3, 4, 5], 0, 2),
266                 [(1 + 2 + 3) / 3, (2 + 3 + 4) / 3, (3 + 4 + 5) / 3, (4 + 5) / 2, 5]);
267
268             assert.deepEqual(Statistics.movingAverage([1, 2, 3, 4, 5], 0, 3),
269                 [(1 + 2 + 3 + 4) / 4, (2 + 3 + 4 + 5) / 4, (3 + 4 + 5) / 3, (4 + 5) / 2, 5]);
270
271             assert.deepEqual(Statistics.movingAverage([1, 2, 3, 4, 5], 0, 4),
272                 [(1 + 2 + 3 + 4 + 5) / 5, (2 + 3 + 4 + 5) / 4, (3 + 4 + 5) / 3, (4 + 5) / 2, 5]);
273
274             assert.deepEqual(Statistics.movingAverage([1, 2, 3, 4, 5], 0, 5),
275                 [(1 + 2 + 3 + 4 + 5) / 5, (2 + 3 + 4 + 5) / 4, (3 + 4 + 5) / 3, (4 + 5) / 2, 5]);
276         });
277
278         it('should find the moving average when both backward and forward window sizes are specified', function () {
279             assert.deepEqual(Statistics.movingAverage([1, 2, 3, 4, 5], 1, 1),
280                 [(1 + 2) / 2, (1 + 2 + 3) / 3, (2 + 3 + 4) / 3, (3 + 4 + 5) / 3, (4 + 5) / 2]);
281
282             assert.deepEqual(Statistics.movingAverage([1, 2, 3, 4, 5], 1, 2),
283                 [(1 + 2 + 3) / 3, (1 + 2 + 3 + 4) / 4, (2 + 3 + 4 + 5) / 4, (3 + 4 + 5) / 3, (4 + 5) / 2]);
284
285             assert.deepEqual(Statistics.movingAverage([1, 2, 3, 4, 5], 2, 1),
286                 [(1 + 2) / 2, (1 + 2 + 3) / 3, (1 + 2 + 3 + 4) / 4, (2 + 3 + 4 + 5) / 4, (3 + 4 + 5) / 3]);
287
288             assert.deepEqual(Statistics.movingAverage([1, 2, 3, 4, 5], 2, 2),
289                 [(1 + 2 + 3) / 3, (1 + 2 + 3 + 4) / 4, (1 + 2 + 3 + 4 + 5) / 5, (2 + 3 + 4 + 5) / 4, (3 + 4 + 5) / 3]);
290
291             assert.deepEqual(Statistics.movingAverage([1, 2, 3, 4, 5], 2, 3),
292                 [(1 + 2 + 3 + 4) / 4, (1 + 2 + 3 + 4 + 5) / 5, (1 + 2 + 3 + 4 + 5) / 5, (2 + 3 + 4 + 5) / 4, (3 + 4 + 5) / 3]);
293
294             assert.deepEqual(Statistics.movingAverage([1, 2, 3, 4, 5], 3, 2),
295                 [(1 + 2 + 3) / 3, (1 + 2 + 3 + 4) / 4, (1 + 2 + 3 + 4 + 5) / 5, (1 + 2 + 3 + 4 + 5) / 5, (2 + 3 + 4 + 5) / 4]);
296
297             assert.deepEqual(Statistics.movingAverage([1, 2, 3, 4, 5], 3, 3),
298                 [(1 + 2 + 3 + 4) / 4, (1 + 2 + 3 + 4 + 5) / 5, (1 + 2 + 3 + 4 + 5) / 5, (1 + 2 + 3 + 4 + 5) / 5, (2 + 3 + 4 + 5) / 4]);
299         });
300     });
301
302     describe('cumulativeMovingAverage', function () {
303         it('should find the cumulative moving average', function () {
304             assert.deepEqual(Statistics.cumulativeMovingAverage([1, 2, 3, 4, 5]),
305                 [1, (1 + 2) / 2, (1 + 2 + 3) / 3, (1 + 2 + 3 + 4) / 4, (1 + 2 + 3 + 4 + 5) / 5]);
306
307             assert.deepEqual(Statistics.cumulativeMovingAverage([-1, 7, 0, 8.5, 2]),
308                 [-1, (-1 + 7) / 2, (-1 + 7 + 0) / 3, (-1 + 7 + 0 + 8.5) / 4, (-1 + 7 + 0 + 8.5 + 2) / 5]);
309         });
310     });
311
312     describe('exponentialMovingAverage', function () {
313         it('should find the exponential moving average', function () {
314             var averages = Statistics.exponentialMovingAverage([1, 2, 3, 4, 5], 0.2);
315             assert.equal(averages[0], 1);
316             assert.almostEqual(averages[1], 0.2 * 2 + 0.8 * averages[0]);
317             assert.almostEqual(averages[2], 0.2 * 3 + 0.8 * averages[1]);
318             assert.almostEqual(averages[3], 0.2 * 4 + 0.8 * averages[2]);
319             assert.almostEqual(averages[4], 0.2 * 5 + 0.8 * averages[3]);
320
321             averages = Statistics.exponentialMovingAverage([0.8, -0.2, 0.4, -0.3, 0.5], 0.1);
322             assert.almostEqual(averages[0], 0.8);
323             assert.almostEqual(averages[1], 0.1 * -0.2 + 0.9 * averages[0]);
324             assert.almostEqual(averages[2], 0.1 * 0.4 + 0.9 * averages[1]);
325             assert.almostEqual(averages[3], 0.1 * -0.3 + 0.9 * averages[2]);
326             assert.almostEqual(averages[4], 0.1 * 0.5 + 0.9 * averages[3]);
327         });
328     });
329
330     describe('segmentTimeSeriesGreedyWithStudentsTTest', function () {
331         it('should segment time series', function () {
332             assert.deepEqual(Statistics.segmentTimeSeriesGreedyWithStudentsTTest([1, 1, 1, 3, 3, 3], 1), [0, 2, 6]);
333             assert.deepEqual(Statistics.segmentTimeSeriesGreedyWithStudentsTTest([1, 1.2, 0.9, 1.1, 1.5, 1.7, 1.8], 1), [0, 4, 7]);
334         });
335     });
336
337     describe('segmentTimeSeriesByMaximizingSchwarzCriterion', function () {
338         it('should segment time series of length 0 into a single segment', function () {
339             var values = [];
340             assert.deepEqual(Statistics.segmentTimeSeriesByMaximizingSchwarzCriterion(values), [0, 0]);
341         });
342
343         it('should not segment time series of length two into two pieces', function () {
344             var values = [1, 2];
345             assert.deepEqual(Statistics.segmentTimeSeriesByMaximizingSchwarzCriterion(values), [0, 2]);
346         });
347
348         it('should segment time series [1, 2, 3] into three pieces', function () {
349             var values = [1, 2, 3];
350             assert.deepEqual(Statistics.segmentTimeSeriesByMaximizingSchwarzCriterion(values), [0, 1, 3]);
351         });
352
353         it('should segment time series for platform=47 metric=4875 between 1453938553772 and 1454630903100 into two parts', function () {
354             var values = [
355                 1546.5603, 1548.1536, 1563.5452, 1539.7823, 1546.4184, 1548.9299, 1532.5444, 1546.2800, 1547.1760, 1551.3507,
356                 1548.3277, 1544.7673, 1542.7157, 1538.1700, 1538.0948, 1543.0364, 1537.9737, 1542.2611, 1543.9685, 1546.4901,
357                 1544.4080, 1540.8671, 1537.3353, 1549.4331, 1541.4436, 1544.1299, 1550.1770, 1553.1872, 1549.3417, 1542.3788,
358                 1543.5094, 1541.7905, 1537.6625, 1547.3840, 1538.5185, 1549.6764, 1556.6138, 1552.0476, 1541.7629, 1544.7006,
359                 /* segments changes here */
360                 1587.1390, 1594.5451, 1586.2430, 1596.7310, 1548.1423];
361             assert.deepEqual(Statistics.segmentTimeSeriesByMaximizingSchwarzCriterion(values), [0, 39, values.length]);
362         });
363
364         it('should segment time series for platform=51 metric=4565 betweeen 1452191332230 and 1454628206453 into two parts', function () {
365             var values = [
366                 147243216, 147736350, 146670090, 146629723, 142749220, 148234161, 147303822, 145112097, 145852468, 147094741,
367                 147568897, 145160531, 148028242, 141272279, 144323236, 147492567, 146219156, 144895726, 144418925, 145455873,
368                 141924694, 141025833, 142082139, 144154698, 145312939, 148282554, 151852126, 149303740, 149431703, 150300257,
369                 148752468, 150449779, 150030118, 150553542, 151775421, 146666762, 149492535, 147143284, 150356837, 147799616,
370                 149889520,
371                 258634751, 147397840, 256106147, 261100534, 255903392, 259658019, 259501433, 257685682, 258460322, 255563633,
372                 259050663, 255567490, 253274911];
373             assert.deepEqual(Statistics.segmentTimeSeriesByMaximizingSchwarzCriterion(values), [0, 40, values.length]);
374         });
375
376         it('should not segment time series for platform=51 metric=4817 betweeen 1453926047749 and 1454635479052 into multiple parts', function () {
377             var values = [
378                 5761.3, 5729.4, 5733.49, 5727.4, 5726.56, 5727.48, 5716.79, 5721.23, 5682.5, 5735.71,
379                 5750.99, 5755.51, 5756.02, 5725.76, 5710.14, 5776.17, 5774.29, 5769.99, 5739.65, 5756.05,
380                 5722.87, 5726.8, 5779.23, 5772.2, 5763.1, 5807.05];
381             assert.deepEqual(Statistics.segmentTimeSeriesByMaximizingSchwarzCriterion(values), [0, values.length]);
382         });
383
384         it('should not segment time series for platform=51 metric=4817 betweeen 1453926047749 and 1454635479052 into multiple parts', function () {
385             var values = new Array(37);
386             for (let i = 0; i < 37; i++)
387                 values[i] = 1;
388             assert.deepEqual(Statistics.segmentTimeSeriesByMaximizingSchwarzCriterion(values), [ 0, 6, 16, 26, 37 ]);
389         });
390     });
391
392     describe('findRangesForChangeDetectionsWithWelchsTTest', () => {
393         it('should return an empty array if the value is empty list', () => {
394             assert.deepEqual(Statistics.findRangesForChangeDetectionsWithWelchsTTest([], [], 0.975), []);
395         });
396
397         it('should return an empty array if segmentation is empty list', () => {
398             assert.deepEqual(Statistics.findRangesForChangeDetectionsWithWelchsTTest([1,2,3], [], 0.975), []);
399         });
400
401         it('should return the range if computeWelchsT shows a significant change', () => {
402             const values = [
403                 747.30337423744,
404                 731.47392585276,
405                 743.66763513161,
406                 738.02055323487,
407                 738.25426340842,
408                 742.38680046471,
409                 733.13921703284,
410                 739.22069966147,
411                 735.69295749633,
412                 743.01705472504,
413                 745.45778145306,
414                 731.04841157169,
415                 729.4372674973,
416                 735.4497416527,
417                 739.0230668644,
418                 730.91782989909,
419                 722.18725411279,
420                 731.96223451728,
421                 730.04119216192,
422                 730.78087646284,
423                 729.63155210365,
424                 730.17585200878,
425                 733.93766054706,
426                 740.74920717197,
427                 752.14718023647,
428                 764.49990164847,
429                 766.36100828473,
430                 756.2291883252,
431                 750.14522451097,
432                 749.57595092266,
433                 748.03624881866,
434                 769.41522176386,
435                 744.04660430456,
436                 751.17927808265,
437                 753.29996854062,
438                 757.01813756936,
439                 746.62413820741,
440                 742.64420062736,
441                 758.12726352772,
442                 778.2278439089,
443                 775.11818554541,
444                 775.11818554541];
445             const segmentation = [{
446                     seriesIndex: 0,
447                     time: 1505176030671,
448                     value: 736.5366704896555,
449                     x: 370.4571789404566,
450                     y: 185.52613334520248,
451                 },
452                 {
453                     seriesIndex: 18,
454                     time: 1515074391534,
455                     value: 736.5366704896555,
456                     x: 919.4183852714947,
457                     y: 185.52613334520248
458                 },
459                 {
460                     seriesIndex: 18,
461                     time: 1515074391534,
462                     value: 750.3483428383142,
463                     x: 919.4183852714947,
464                     y: 177.9710953409673,
465                 },
466                 {
467                     seriesIndex: 41,
468                     time: 1553851695869,
469                     value: 750.3483428383142,
470                     x: 3070.000290764446,
471                     y: 177.9710953409673,
472                 }];
473             assert.deepEqual(Statistics.findRangesForChangeDetectionsWithWelchsTTest(values, segmentation, 0.975), [
474                 {
475                   "endIndex": 29,
476                   "segmentationEndValue": 750.3483428383142,
477                   "segmentationStartValue": 736.5366704896555,
478                   "startIndex": 6
479                 }
480             ]);
481         })
482     });
483 });