forked from Khan/khan-exercises
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathstat.js
More file actions
114 lines (94 loc) · 3.14 KB
/
stat.js
File metadata and controls
114 lines (94 loc) · 3.14 KB
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
$.extend(KhanUtil, {
sum: function(values) {
var sum = 0;
$.each(values, function(index, value) {
sum += value;
});
return sum;
},
mean: function(values) {
return KhanUtil.sum(values) / values.length;
},
median: function(values) {
var sortedInts, median;
sortedInts = KhanUtil.sortNumbers(values);
if (values.length % 2 === 0) {
median = KhanUtil.roundTo(1,
(sortedInts[(values.length / 2) - 1] + sortedInts[values.length / 2]) / 2);
} else {
median = sortedInts[Math.floor(values.length / 2)];
}
return median;
},
mode: function(values) {
var numInstances = [];
var modeInstances = -1;
var mode;
for (var i = 0; i < values.length; i++) {
if (!numInstances[values[i]]) {
numInstances[values[i]] = 1;
} else {
numInstances[values[i]] += 1;
if (numInstances[values[i]] > modeInstances) {
modeInstances = numInstances[values[i]];
mode = values[i];
}
}
}
// iterate again to check for 'no mode'
for (var i = 0; i < numInstances.length; i++) {
if (numInstances[i]) {
if (i !== mode && numInstances[i] >= modeInstances) {
return false;
}
}
}
return mode;
},
variance: function(values) {
var xbar = KhanUtil.mean(values);
var n = values.length;
var sum = 0;
$.each(values, function(i, x_i) {
sum += (x_i - xbar) * (x_i - xbar);
});
return sum / (n - 1);
},
variancePop: function(values) {
var xbar = KhanUtil.mean(values);
var N = values.length;
var sum = 0;
$.each(values, function(i, x_i) {
sum += (x_i - xbar) * (x_i - xbar);
});
return sum / N;
},
stdDev: function(values) {
return Math.sqrt(KhanUtil.variance(values));
},
stdDevPop: function(values) {
return Math.sqrt(KhanUtil.variancePop(values));
},
// Gaussian distribution using Box-Muller transform
// defaults to standard normal unless target mean and stddev are passed
// Pass "count" to get an array of data
randGaussian: function(tgtMean, tgtStdDev, count) {
if (count == null) {
var x1, x2, rad, y1;
do {
x1 = 2 * KhanUtil.random() - 1;
x2 = 2 * KhanUtil.random() - 1;
rad = x1 * x1 + x2 * x2;
} while (rad >= 1 || rad == 0);
var c = Math.sqrt(-2 * Math.log(rad) / rad);
return x1 * c * (tgtStdDev || 1) + (tgtMean || 0);
} else {
return $.map(new Array(count), function() {
return KhanUtil.randGaussian(tgtMean, tgtStdDev);
});
}
},
gaussianPDF: function(mean, stddev, x) {
return (1 / Math.sqrt(2 * Math.PI * stddev * stddev)) * Math.exp(-((x - mean) * (x - mean)) / (2 * stddev * stddev));
}
});