-
Notifications
You must be signed in to change notification settings - Fork 0
/
stats.js
129 lines (99 loc) · 3.48 KB
/
stats.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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
export const stats = {
spareRandom: null,
// This function generates random numbers along a Normal or Log-normal distribution
// using the Marsaglia polar method. the mean is 0 and the deviation is 1
// the function generates two values at each invocation - that is why we have the spare
normalRandom: ()=> {
let val, u, v, s, mul;
if(stats.spareRandom !== null) {
val = stats.spareRandom;
stats.spareRandom = null;
}
else {
do {
u = Math.random()*2-1;
v = Math.random()*2-1;
s = u*u+v*v;
} while(s === 0 || s >= 1);
mul = Math.sqrt(-2 * Math.log(s) / s);
val = u * mul;
stats.spareRandom = v * mul;
}
return val;
},
cumulative: (points, distri) => {
// check
if (points.length != distri.length) return null
// copy but swap x and y
for (let i=0; i < points.length; i++) distri[i].x = points[i].y
// sort the array
distri.sort( (a, b) => a.x - b.x )
// get the size
let nPoints = distri.length
// change the y values
for (let i=0; i< nPoints; i++) distri[i].y = i/nPoints
return distri
},
histogram: (points, bins) => {
// the nr of buckets
let nB = bins.length
// th nr of points
let nP = points.length
// check
if (!nP || !nB) return [0,0]
// find the min and max
let xMin=points[0].y, xMax = points[0].y
for (let i=0; i<nP; i++) {
if (points[i].y < xMin) xMin = points[i].y
else if (points[i].y > xMax) xMax = points[i].y
}
// the bin size
let bSize = (1.1*xMax - 0.9*xMin)/nB
// check
if (bSize == 0) bSize = 1.0
// initialize the buckets
for (let i=0; i<nB;i++) {
bins[i].x = 0.9*xMin + i*bSize
bins[i].y = 0
}
// count the objects per bin
for (let i=0;i<nP;i++) bins[ Math.floor( (points[i].y - 0.9*xMin) / bSize) ].y++
// normalize the bins and find the max value
let yMin = bins[0].y/nP
let yMax = yMin
for (let i=0; i<nB; i++) {
bins[i].y /= nP
if (bins[i].y < yMin) yMin = bins[i].y
else if (bins[i].y > yMax) yMax = bins[i].y
}
// return the min and max value
return [xMin, xMax, yMin, yMax]
},
constValue: (points,xmin, xmax, value) => {
// check and swap if necessary
if (xmin > xmax) { let tmp = xmin; xmin = xmax; xmax = tmp}
// fill the array with the constant value
for (let i = 0; i <= xmax-xmin; i++) {
points[i].x = xmin + i
points[i].y = value
}
},
rndNormal: (points, xmin, xmax, mu, sigma) => {
// check and swap if necessary
if (xmin > xmax) { let tmp = xmin; xmin = xmax; xmax = tmp}
// calculate
for (let i = 0; i <= xmax-xmin; i++) {
points[i].x = xmin + i
points[i].y = normalRandom()*sigma + mu
}
},
rndUniform: ( points, xmin, xmax, a, b ) => {
// check and swap if necessary
if (xmin > xmax) { let tmp = xmin; xmin = xmax; xmax = tmp}
// generate the random numbers
for (let i = 0; i <= xmax-xmin; i++) {
points[i].x = xmin + i
points[i].y = (Math.random() * (b-a)) + a
}
},
}