-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathgaussian.js
More file actions
113 lines (95 loc) · 3.3 KB
/
gaussian.js
File metadata and controls
113 lines (95 loc) · 3.3 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
(function(exports) {
// Complementary error function
// From Numerical Recipes in C 2e p221
var erfc = function(x) {
var z = Math.abs(x);
var t = 1 / (1 + z / 2);
var r = t * Math.exp(-z * z - 1.26551223 + t * (1.00002368 +
t * (0.37409196 + t * (0.09678418 + t * (-0.18628806 +
t * (0.27886807 + t * (-1.13520398 + t * (1.48851587 +
t * (-0.82215223 + t * 0.17087277)))))))))
return x >= 0 ? r : 2 - r;
};
// Inverse complementary error function
// From Numerical Recipes 3e p265
var ierfc = function(x) {
if (x >= 2) { return -100; }
if (x <= 0) { return 100; }
var xx = (x < 1) ? x : 2 - x;
var t = Math.sqrt(-2 * Math.log(xx / 2));
var r = -0.70711 * ((2.30753 + t * 0.27061) /
(1 + t * (0.99229 + t * 0.04481)) - t);
for (var j = 0; j < 2; j++) {
var err = erfc(r) - xx;
r += err / (1.12837916709551257 * Math.exp(-(r * r)) - r * err);
}
return (x < 1) ? r : -r;
};
// Models the normal distribution
var Gaussian = function(mean, variance) {
if (variance <= 0) {
throw new Error('Variance must be > 0 (but was ' + variance + ')');
}
this.mean = mean;
this.variance = variance;
this.standardDeviation = Math.sqrt(variance);
}
// Probability density function
Gaussian.prototype.pdf = function(x) {
var m = this.standardDeviation * Math.sqrt(2 * Math.PI);
var e = Math.exp(-Math.pow(x - this.mean, 2) / (2 * this.variance));
return e / m;
};
// Cumulative density function
Gaussian.prototype.cdf = function(x) {
return 0.5 * erfc(-(x - this.mean) / (this.standardDeviation * Math.sqrt(2)));
};
// Percent point function
Gaussian.prototype.ppf = function(x) {
return this.mean - this.standardDeviation * Math.sqrt(2) * ierfc(2 * x);
};
// Product distribution of this and d (scale for constant)
Gaussian.prototype.mul = function(d) {
if (typeof(d) === "number") {
return this.scale(d);
}
var precision = 1 / this.variance;
var dprecision = 1 / d.variance;
return fromPrecisionMean(
precision + dprecision,
precision * this.mean + dprecision * d.mean);
};
// Quotient distribution of this and d (scale for constant)
Gaussian.prototype.div = function(d) {
if (typeof(d) === "number") {
return this.scale(1 / d);
}
var precision = 1 / this.variance;
var dprecision = 1 / d.variance;
return fromPrecisionMean(
precision - dprecision,
precision * this.mean - dprecision * d.mean);
};
// Addition of this and d
Gaussian.prototype.add = function(d) {
return gaussian(this.mean + d.mean, this.variance + d.variance);
};
// Subtraction of this and d
Gaussian.prototype.sub = function(d) {
return gaussian(this.mean - d.mean, this.variance + d.variance);
};
// Scale this by constant c
Gaussian.prototype.scale = function(c) {
return gaussian(this.mean * c, this.variance * c * c);
};
var gaussian = function(mean, variance) {
return new Gaussian(mean, variance);
};
var fromPrecisionMean = function(precision, precisionmean) {
return gaussian(precisionmean / precision, 1 / precision);
};
exports(gaussian);
})
(typeof(exports) !== "undefined"
? function(e) { module.exports = e; }
: function(e) { this["gaussian"] = e; });