commit
message
[BINOMDIST] formula added and tested
author
Ben Vogt <[email protected]>
date
2017-07-08 14:13:27
stats
7 file(s) changed,
173 insertions(+),
8 deletions(-)
files
DOCS.md
TODO.md
dist/Formulas/AllFormulas.js
dist/Formulas/Statistical.js
src/Formulas/AllFormulas.ts
src/Formulas/Statistical.ts
tests/Formulas/StatisticalTest.ts
1diff --git a/DOCS.md b/DOCS.md
2index f27f203..88a439e 100644
3--- a/DOCS.md
4+++ b/DOCS.md
5@@ -1848,6 +1848,18 @@
6 @returns {number}
7 @constructor
8 ```
9+
10+### BINOMDIST
11+
12+```
13+ Returns the individual term binomial distribution probability.
14+@param successes - The number of successes in a set of trials.
15+@param trials - The number of independent trials.
16+@param probability - The probability of success on each trial.
17+@param cumulative - 0 calculates the probability of a single event, 1 calculates the cumulative probability.
18+@returns {number}
19+@constructor
20+```
21 ## Text
22
23
24diff --git a/TODO.md b/TODO.md
25index 1b60759..91e8cfb 100644
26--- a/TODO.md
27+++ b/TODO.md
28@@ -54,7 +54,6 @@ For example 64 tbs to a qt.
29 * TO_DOLLARS - Contingent upon cells having display formats derived from type-hierarchy
30 * TO_PERCENT - Contingent upon cells having display formats derived from type-hierarchy
31 * TO_TEXT - Contingent upon cells having display formats derived from type-hierarchy
32-* BINOMDIST
33 * COVAR
34 * CRITBINOM
35 * F.DIST.RT
36diff --git a/dist/Formulas/AllFormulas.js b/dist/Formulas/AllFormulas.js
37index 379513a..6a837e8 100644
38--- a/dist/Formulas/AllFormulas.js
39+++ b/dist/Formulas/AllFormulas.js
40@@ -169,6 +169,7 @@ exports.NEGBINOMDIST = Statistical_1.NEGBINOMDIST;
41 exports.GEOMEAN = Statistical_1.GEOMEAN;
42 exports.HARMEAN = Statistical_1.HARMEAN;
43 exports.CONFIDENCE = Statistical_1.CONFIDENCE;
44+exports.BINOMDIST = Statistical_1.BINOMDIST;
45 var Text_1 = require("./Text");
46 exports.ARABIC = Text_1.ARABIC;
47 exports.CHAR = Text_1.CHAR;
48diff --git a/dist/Formulas/Statistical.js b/dist/Formulas/Statistical.js
49index b1a0f8e..137bd06 100644
50--- a/dist/Formulas/Statistical.js
51+++ b/dist/Formulas/Statistical.js
52@@ -1342,10 +1342,10 @@ exports.HARMEAN = HARMEAN;
53 * @constructor
54 */
55 var CONFIDENCE = function (alpha, standDev, size) {
56+ ArgsChecker_1.ArgsChecker.checkLength(arguments, 3, "CONFIDENCE");
57 alpha = TypeConverter_1.TypeConverter.firstValueAsNumber(alpha);
58 standDev = TypeConverter_1.TypeConverter.firstValueAsNumber(standDev);
59 size = TypeConverter_1.TypeConverter.firstValueAsNumber(size);
60- ArgsChecker_1.ArgsChecker.checkLength(arguments, 3, "CONFIDENCE");
61 if (alpha <= 0 || alpha >= 1) {
62 throw new Errors_1.NumError("Function CONFIDENCE parameter 1 value is " + alpha
63 + ". Valid values are between 0 and 1 exclusively.");
64@@ -1415,3 +1415,65 @@ var CONFIDENCE = function (alpha, standDev, size) {
65 return _normalci(1, alpha, standDev, size)[1] - 1;
66 };
67 exports.CONFIDENCE = CONFIDENCE;
68+/**
69+ * Returns the individual term binomial distribution probability.
70+ * @param successes - The number of successes in a set of trials.
71+ * @param trials - The number of independent trials.
72+ * @param probability - The probability of success on each trial.
73+ * @param cumulative - 0 calculates the probability of a single event, 1 calculates the cumulative probability.
74+ * @returns {number}
75+ * @constructor
76+ */
77+var BINOMDIST = function (successes, trials, probability, cumulative) {
78+ ArgsChecker_1.ArgsChecker.checkLength(arguments, 4, "BINOMDIST");
79+ successes = TypeConverter_1.TypeConverter.firstValueAsNumber(successes);
80+ trials = TypeConverter_1.TypeConverter.firstValueAsNumber(trials);
81+ probability = TypeConverter_1.TypeConverter.firstValueAsNumber(probability);
82+ cumulative = TypeConverter_1.TypeConverter.firstValueAsNumber(cumulative);
83+ function _binomialCDF(x, n, p) {
84+ var binomarr = [], k = 0;
85+ if (x < 0) {
86+ return 0;
87+ }
88+ if (x < n) {
89+ for (; k <= x; k++) {
90+ binomarr[k] = _binomialPDF(k, n, p);
91+ }
92+ return MathHelpers_1.sum(binomarr);
93+ }
94+ return 1;
95+ }
96+ function _combination(n, m) {
97+ // make sure n or m don't exceed the upper limit of usable values
98+ return (n > 170 || m > 170)
99+ ? Math.exp(_combinationln(n, m))
100+ : (_factorial(n) / _factorial(m)) / _factorial(n - m);
101+ }
102+ function _factorial(n) {
103+ return n < 0 ? NaN : MathHelpers_1.gammafn(n + 1);
104+ }
105+ function _factorialln(n) {
106+ return n < 0 ? NaN : MathHelpers_1.gammaln(n + 1);
107+ }
108+ function _combinationln(n, m) {
109+ return _factorialln(n) - _factorialln(m) - _factorialln(n - m);
110+ }
111+ function _binomialPDF(k, n, p) {
112+ return (p === 0 || p === 1) ?
113+ ((n * p) === k ? 1 : 0) :
114+ _combination(n, k) * Math.pow(p, k) * Math.pow(1 - p, n - k);
115+ }
116+ if (trials < 0) {
117+ throw new Errors_1.NumError("Function BINOMDIST parameter 2 value is " + trials + ", but should be greater than 0.");
118+ }
119+ if (trials < successes) {
120+ throw new Errors_1.NumError("Function BINOMDIST parameter 1 value is " + trials
121+ + ". It should be less than or equal to value of Function BINOMDIST parameter 2 with " + successes + ".");
122+ }
123+ if (probability > 1 || probability < 0) {
124+ throw new Errors_1.NumError("Function BINOMDIST parameter 3 value is " + probability
125+ + ", but should be between 0 and 1 inclusive.");
126+ }
127+ return (cumulative) ? _binomialCDF(successes, trials, probability) : _binomialPDF(successes, trials, probability);
128+};
129+exports.BINOMDIST = BINOMDIST;
130diff --git a/src/Formulas/AllFormulas.ts b/src/Formulas/AllFormulas.ts
131index 13960c6..c30dc27 100644
132--- a/src/Formulas/AllFormulas.ts
133+++ b/src/Formulas/AllFormulas.ts
134@@ -174,7 +174,8 @@ import {
135 NEGBINOMDIST,
136 GEOMEAN,
137 HARMEAN,
138- CONFIDENCE
139+ CONFIDENCE,
140+ BINOMDIST
141 } from "./Statistical";
142 import {
143 ARABIC,
144@@ -420,5 +421,6 @@ export {
145 CONFIDENCE,
146 N,
147 UNARY_PERCENT,
148- MULTINOMIAL
149+ MULTINOMIAL,
150+ BINOMDIST
151 }
152\ No newline at end of file
153diff --git a/src/Formulas/Statistical.ts b/src/Formulas/Statistical.ts
154index c4adb45..24d1d79 100644
155--- a/src/Formulas/Statistical.ts
156+++ b/src/Formulas/Statistical.ts
157@@ -28,7 +28,8 @@ import {
158 mean,
159 gammafn,
160 sum,
161- erf
162+ erf,
163+ gammaln
164 } from "../Utilities/MathHelpers";
165
166
167@@ -1339,10 +1340,10 @@ var HARMEAN = function (...values) {
168 * @constructor
169 */
170 var CONFIDENCE = function (alpha, standDev, size) {
171+ ArgsChecker.checkLength(arguments, 3, "CONFIDENCE");
172 alpha = TypeConverter.firstValueAsNumber(alpha);
173 standDev = TypeConverter.firstValueAsNumber(standDev);
174 size = TypeConverter.firstValueAsNumber(size);
175- ArgsChecker.checkLength(arguments, 3, "CONFIDENCE");
176 if (alpha <= 0 || alpha >= 1) {
177 throw new NumError("Function CONFIDENCE parameter 1 value is " + alpha
178 + ". Valid values are between 0 and 1 exclusively.");
179@@ -1408,6 +1409,70 @@ var CONFIDENCE = function (alpha, standDev, size) {
180 };
181
182
183+/**
184+ * Returns the individual term binomial distribution probability.
185+ * @param successes - The number of successes in a set of trials.
186+ * @param trials - The number of independent trials.
187+ * @param probability - The probability of success on each trial.
188+ * @param cumulative - 0 calculates the probability of a single event, 1 calculates the cumulative probability.
189+ * @returns {number}
190+ * @constructor
191+ */
192+var BINOMDIST = function (successes, trials, probability, cumulative) {
193+ ArgsChecker.checkLength(arguments, 4, "BINOMDIST");
194+ successes = TypeConverter.firstValueAsNumber(successes);
195+ trials = TypeConverter.firstValueAsNumber(trials);
196+ probability = TypeConverter.firstValueAsNumber(probability);
197+ cumulative = TypeConverter.firstValueAsNumber(cumulative);
198+ function _binomialCDF(x, n, p) {
199+ var binomarr = [],
200+ k = 0;
201+ if (x < 0) {
202+ return 0;
203+ }
204+ if (x < n) {
205+ for (; k <= x; k++) {
206+ binomarr[ k ] = _binomialPDF(k, n, p);
207+ }
208+ return sum(binomarr);
209+ }
210+ return 1;
211+ }
212+ function _combination(n, m) {
213+ // make sure n or m don't exceed the upper limit of usable values
214+ return (n > 170 || m > 170)
215+ ? Math.exp(_combinationln(n, m))
216+ : (_factorial(n) / _factorial(m)) / _factorial(n - m);
217+ }
218+ function _factorial(n) {
219+ return n < 0 ? NaN : gammafn(n + 1);
220+ }
221+ function _factorialln(n) {
222+ return n < 0 ? NaN : gammaln(n + 1);
223+ }
224+ function _combinationln(n, m) {
225+ return _factorialln(n) - _factorialln(m) - _factorialln(n - m);
226+ }
227+ function _binomialPDF(k, n, p) {
228+ return (p === 0 || p === 1) ?
229+ ((n * p) === k ? 1 : 0) :
230+ _combination(n, k) * Math.pow(p, k) * Math.pow(1 - p, n - k);
231+ }
232+ if (trials < 0) {
233+ throw new NumError("Function BINOMDIST parameter 2 value is " + trials + ", but should be greater than 0.");
234+ }
235+ if (trials < successes) {
236+ throw new NumError("Function BINOMDIST parameter 1 value is " + trials
237+ + ". It should be less than or equal to value of Function BINOMDIST parameter 2 with " + successes + ".");
238+ }
239+ if (probability > 1 || probability < 0) {
240+ throw new NumError("Function BINOMDIST parameter 3 value is " + probability
241+ + ", but should be between 0 and 1 inclusive.");
242+ }
243+ return (cumulative) ? _binomialCDF(successes, trials, probability) : _binomialPDF(successes, trials, probability);
244+};
245+
246+
247 export {
248 AVERAGE,
249 AVERAGEA,
250@@ -1452,5 +1517,6 @@ export {
251 NEGBINOMDIST,
252 GEOMEAN,
253 HARMEAN,
254- CONFIDENCE
255+ CONFIDENCE,
256+ BINOMDIST
257 }
258\ No newline at end of file
259diff --git a/tests/Formulas/StatisticalTest.ts b/tests/Formulas/StatisticalTest.ts
260index 4dcf84a..b1ae495 100644
261--- a/tests/Formulas/StatisticalTest.ts
262+++ b/tests/Formulas/StatisticalTest.ts
263@@ -42,7 +42,8 @@ import {
264 NEGBINOMDIST,
265 GEOMEAN,
266 HARMEAN,
267- CONFIDENCE
268+ CONFIDENCE,
269+ BINOMDIST
270 } from "../../src/Formulas/Statistical";
271 import * as ERRORS from "../../src/Errors";
272 import {
273@@ -893,4 +894,25 @@ test("CONFIDENCE", function() {
274 catchAndAssertEquals(function() {
275 CONFIDENCE.apply(this, [0.8, 101.1, 24281, 22]);
276 }, ERRORS.NA_ERROR);
277+});
278+
279+test("BINOMDIST", function() {
280+ assertEquals(BINOMDIST(20, 22, 0.04, true), 0.9999999999999998);
281+ assertEquals(BINOMDIST(14, 22, 0.4, true), 0.9929516025629364);
282+ assertEquals(BINOMDIST(14, 22, 0.4, false), 0.014417421604478797);
283+ catchAndAssertEquals(function() {
284+ BINOMDIST(21, 20, 0.4, false);
285+ }, ERRORS.NUM_ERROR);
286+ catchAndAssertEquals(function() {
287+ BINOMDIST(20, 20, -1, false);
288+ }, ERRORS.NUM_ERROR);
289+ catchAndAssertEquals(function() {
290+ BINOMDIST(20, 0, -1, false);
291+ }, ERRORS.NUM_ERROR);
292+ catchAndAssertEquals(function() {
293+ BINOMDIST.apply(this, [20, 20, 1]);
294+ }, ERRORS.NA_ERROR);
295+ catchAndAssertEquals(function() {
296+ BINOMDIST.apply(this, [20, 20, 1, true, 10]);
297+ }, ERRORS.NA_ERROR);
298 });
299\ No newline at end of file