spreadsheet
typeScript/javascript spreadsheet parser, with formulas.
git clone https://git.vogt.world/spreadsheet.git
Log | Files | README.md
← Commit log
commit
message
[Statistical.HYPGEOMDIST] formula added and tested
author
Ben Vogt <[email protected]>
date
2017-10-07 16:24:45
stats
7 file(s) changed, 116 insertions(+), 6 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 1449b3d..74b9b78 100644
  3--- a/DOCS.md
  4+++ b/DOCS.md
  5@@ -2260,6 +2260,18 @@
  6 @returns {number} 
  7 @constructor
  8 ```
  9+
 10+### HYPGEOMDIST 
 11+
 12+```
 13+  Returns the hypergeometric distribution. X is the number of results achieved in the random sample. 
 14+@param numberOfSuccesses - The number of results achieved in the random sample. 
 15+@param numberOfDraws - The size of the random sample. 
 16+@param successesInPop - The number of possible results in the total population. 
 17+@param populationSize - The size of the total population. 
 18+@returns {number} 
 19+@constructor
 20+```
 21 ## Text
 22 
 23 
 24diff --git a/TODO.md b/TODO.md
 25index 40c27a9..9c074d5 100644
 26--- a/TODO.md
 27+++ b/TODO.md
 28@@ -39,7 +39,6 @@ Many of these formulas can be written by allowing the Sheet and Parser to return
 29 
 30 
 31 ### Easy formulas to write
 32-* HYPGEOMDIST
 33 * CRITBINOM
 34 * ZTEST
 35 * CLEAN
 36diff --git a/dist/Formulas/AllFormulas.js b/dist/Formulas/AllFormulas.js
 37index 4122490..9cdf260 100644
 38--- a/dist/Formulas/AllFormulas.js
 39+++ b/dist/Formulas/AllFormulas.js
 40@@ -212,6 +212,7 @@ exports.RANK$AVG = Statistical_1.RANK$AVG;
 41 exports.RANK$EQ = Statistical_1.RANK$EQ;
 42 exports.LOGNORMDIST = Statistical_1.LOGNORMDIST;
 43 exports.TDIST = Statistical_1.TDIST;
 44+exports.HYPGEOMDIST = Statistical_1.HYPGEOMDIST;
 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 a24f626..b0b05c0 100644
 50--- a/dist/Formulas/Statistical.js
 51+++ b/dist/Formulas/Statistical.js
 52@@ -2060,3 +2060,35 @@ var TDIST = function (x, degreesOfFreedom, tails) {
 53     return tails * (1 - _studenttCDF(x, degreesOfFreedom));
 54 };
 55 exports.TDIST = TDIST;
 56+/**
 57+ * Returns the hypergeometric distribution. X is the number of results achieved in the random sample.
 58+ * @param numberOfSuccesses - The number of results achieved in the random sample.
 59+ * @param numberOfDraws - The size of the random sample.
 60+ * @param successesInPop - The number of possible results in the total population.
 61+ * @param populationSize - The size of the total population.
 62+ * @returns {number}
 63+ * @constructor
 64+ */
 65+var HYPGEOMDIST = function (numberOfSuccesses, numberOfDraws, successesInPop, populationSize) {
 66+    ArgsChecker_1.ArgsChecker.checkLength(arguments, 4, "HYPGEOMDIST");
 67+    numberOfSuccesses = TypeConverter_1.TypeConverter.firstValueAsNumber(numberOfSuccesses);
 68+    numberOfDraws = TypeConverter_1.TypeConverter.firstValueAsNumber(numberOfDraws);
 69+    if (numberOfSuccesses > numberOfDraws) {
 70+        throw new Errors_1.NumError("HYPGEOMDIST parameter 1 value is " + numberOfSuccesses
 71+            + ", but should be less than or equal to parameter 2 with " + numberOfDraws + ".");
 72+    }
 73+    if (numberOfSuccesses < 0) {
 74+        throw new Errors_1.NumError("HYPGEOMDIST parameter 1 value is " + numberOfSuccesses
 75+            + ", but should be greater than or equal to 0.");
 76+    }
 77+    if (numberOfSuccesses < (numberOfDraws + successesInPop - populationSize)) {
 78+        throw new Errors_1.NumError("HYPGEOMDIST parameter 1 value is " + numberOfSuccesses
 79+            + ", but should be greater than or equal to " + (numberOfDraws + successesInPop - populationSize) + ".");
 80+    }
 81+    successesInPop = TypeConverter_1.TypeConverter.firstValueAsNumber(successesInPop);
 82+    populationSize = TypeConverter_1.TypeConverter.firstValueAsNumber(populationSize);
 83+    return Math_1.COMBIN(successesInPop, numberOfSuccesses) *
 84+        Math_1.COMBIN(populationSize - successesInPop, numberOfDraws - numberOfSuccesses) /
 85+        Math_1.COMBIN(populationSize, numberOfDraws);
 86+};
 87+exports.HYPGEOMDIST = HYPGEOMDIST;
 88diff --git a/src/Formulas/AllFormulas.ts b/src/Formulas/AllFormulas.ts
 89index 12aff04..a7b7337 100644
 90--- a/src/Formulas/AllFormulas.ts
 91+++ b/src/Formulas/AllFormulas.ts
 92@@ -218,7 +218,8 @@ import {
 93   RANK$AVG,
 94   RANK$EQ,
 95   LOGNORMDIST,
 96-  TDIST
 97+  TDIST,
 98+  HYPGEOMDIST
 99 } from "./Statistical";
100 import {
101   ARABIC,
102@@ -525,5 +526,6 @@ export {
103   FVSCHEDULE,
104   PV,
105   RATE,
106-  SUBTOTAL
107+  SUBTOTAL,
108+  HYPGEOMDIST
109 }
110\ No newline at end of file
111diff --git a/src/Formulas/Statistical.ts b/src/Formulas/Statistical.ts
112index 41776e1..a0bd6f6 100644
113--- a/src/Formulas/Statistical.ts
114+++ b/src/Formulas/Statistical.ts
115@@ -16,7 +16,8 @@ import {
116 import {
117   SUM,
118   ABS,
119-  FLOOR
120+  FLOOR,
121+  COMBIN
122 } from "./Math";
123 import {
124   cdf,
125@@ -2048,6 +2049,38 @@ let TDIST = function (x, degreesOfFreedom, tails) {
126   return tails * (1 - _studenttCDF(x, degreesOfFreedom));
127 };
128 
129+/**
130+ * Returns the hypergeometric distribution. X is the number of results achieved in the random sample.
131+ * @param numberOfSuccesses - The number of results achieved in the random sample.
132+ * @param numberOfDraws - The size of the random sample.
133+ * @param successesInPop - The number of possible results in the total population.
134+ * @param populationSize - The size of the total population.
135+ * @returns {number}
136+ * @constructor
137+ */
138+let HYPGEOMDIST = function (numberOfSuccesses, numberOfDraws, successesInPop, populationSize) {
139+  ArgsChecker.checkLength(arguments, 4, "HYPGEOMDIST");
140+  numberOfSuccesses = TypeConverter.firstValueAsNumber(numberOfSuccesses);
141+  numberOfDraws = TypeConverter.firstValueAsNumber(numberOfDraws);
142+  if (numberOfSuccesses > numberOfDraws) {
143+    throw new NumError("HYPGEOMDIST parameter 1 value is " + numberOfSuccesses
144+        + ", but should be less than or equal to parameter 2 with " + numberOfDraws + ".");
145+  }
146+  if (numberOfSuccesses < 0) {
147+    throw new NumError("HYPGEOMDIST parameter 1 value is " + numberOfSuccesses
148+        + ", but should be greater than or equal to 0.");
149+  }
150+  if (numberOfSuccesses < (numberOfDraws + successesInPop - populationSize)) {
151+    throw new NumError("HYPGEOMDIST parameter 1 value is " + numberOfSuccesses
152+        + ", but should be greater than or equal to " + (numberOfDraws + successesInPop - populationSize) + ".");
153+  }
154+  successesInPop = TypeConverter.firstValueAsNumber(successesInPop);
155+  populationSize = TypeConverter.firstValueAsNumber(populationSize);
156+  return COMBIN(successesInPop, numberOfSuccesses) *
157+      COMBIN(populationSize - successesInPop, numberOfDraws - numberOfSuccesses) /
158+      COMBIN(populationSize, numberOfDraws);
159+};
160+
161 
162 export {
163   AVERAGE,
164@@ -2111,5 +2144,6 @@ export {
165   RANK$AVG,
166   RANK$EQ,
167   LOGNORMDIST,
168-  TDIST
169+  TDIST,
170+  HYPGEOMDIST
171 }
172\ No newline at end of file
173diff --git a/tests/Formulas/StatisticalTest.ts b/tests/Formulas/StatisticalTest.ts
174index 26b6b9b..4064684 100644
175--- a/tests/Formulas/StatisticalTest.ts
176+++ b/tests/Formulas/StatisticalTest.ts
177@@ -60,7 +60,8 @@ import {
178   RANK$AVG,
179   RANK$EQ,
180   LOGNORMDIST,
181-  TDIST
182+  TDIST,
183+  HYPGEOMDIST
184 } from "../../src/Formulas/Statistical";
185 import * as ERRORS from "../../src/Errors";
186 import {
187@@ -1239,4 +1240,31 @@ test("TDIST", function() {
188   catchAndAssertEquals(function() {
189     TDIST.apply(this, []);
190   }, ERRORS.NA_ERROR);
191+});
192+
193+test("HYPGEOMDIST", function() {
194+  assertEquals(HYPGEOMDIST(4, 12, 20, 44), 0.16895408557348432);
195+  assertEquals(HYPGEOMDIST(5, 12, 20, 40), 0.21512468231044427);
196+  assertEquals(HYPGEOMDIST(1, 12, 29, 40), 5.190757213128131e-9);
197+  catchAndAssertEquals(function() {
198+    HYPGEOMDIST(1, 12, 30, 40);
199+  }, ERRORS.NUM_ERROR);
200+  catchAndAssertEquals(function() {
201+    HYPGEOMDIST(1, 12, 35, 40);
202+  }, ERRORS.NUM_ERROR);
203+  catchAndAssertEquals(function() {
204+    HYPGEOMDIST(1, 12, 35, 40);
205+  }, ERRORS.NUM_ERROR);
206+  catchAndAssertEquals(function() {
207+    HYPGEOMDIST(-1, 12, 20, 44);
208+  }, ERRORS.NUM_ERROR);
209+  catchAndAssertEquals(function() {
210+    HYPGEOMDIST(13, 12, 20, 44);
211+  }, ERRORS.NUM_ERROR);
212+  catchAndAssertEquals(function() {
213+    HYPGEOMDIST.apply(this, [5, 12, 20]);
214+  }, ERRORS.NA_ERROR);
215+  catchAndAssertEquals(function() {
216+    HYPGEOMDIST.apply(this, [5, 12, 20, 40, 44]);
217+  }, ERRORS.NA_ERROR);
218 });
219\ No newline at end of file