-
Notifications
You must be signed in to change notification settings - Fork 0
/
percentiles.js
executable file
·73 lines (72 loc) · 1.62 KB
/
percentiles.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
function createPercentile(targetLen) {
var serie = [];
var slen = 0;
return {
push: push,
lastFold: lastFold,
getCurrent: getCurrent
};
function push(x) {
for (var i = 0; i < slen; i++) {
if (x < serie[i][0]) break;
}
serie.splice(i, 0, [x, 1]);
slen++;
if (slen == (targetLen * 2)) {
var sbefore = serie.slice();
fold();
console.log({before: sbefore, after: serie.slice(), current: serie});
};
}
function fold() {
debugger;
var fserie = [];
var last = slen - 2;
for (var i = 0; i <= last; i += 2) {
var fb = 2 * i / last;
var fa = 2 - fb;
var a = serie[i], b = serie[i+1];
fserie.push([
((a[0] * a[1] * fa) + (b[0] * b[1] * fb)) / (a[1] + b[1]),
a[1] + b[1]
]);
}
serie = fserie;
slen = fserie.length;
}
function lastFold() {
var total = 0;
for (var i = 0; i < slen; i++) {
total += serie[i][1];
}
var fserie = [];
var ftarget = total / targetLen;
var fremain = ftarget;
var fcurrent = [0, 0];
for (i = 0; i < slen; i++) {
var fitem = serie[i];
var part1 = fcurrent[0] + fitem[0];
var part2 = fcurrent[1] + fitem[1];
while (part2 > fremain) {
var diff = part2 - fremain;
var fpush1 = part1 * fremain / part2;
var fpush2 = part2 - diff;
fserie.push([fpush1, fpush2]);
part1 -= fpush1;
part2 -= fpush2;
fremain = ftarget;
}
fcurrent[0] = part1;
fcurrent[1] = part2;
}
if (fserie.length == (targetLen - 1)) {
fserie.push(fcurrent);
fcurrent[0] = 0;
fcurrent[1] = 0;
}
return fserie;
}
function getCurrent() {
return serie;
}
}