spreadsheet
typeScript/javascript spreadsheet parser, with formulas.
git clone https://git.vogt.world/spreadsheet.git
Log | Files | README.md
← Commit log
commit
message
[POISSON] formula added and tested
author
Ben Vogt <[email protected]>
date
2017-07-03 01:05:15
stats
8 file(s) changed, 133 insertions(+), 9 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
tests/SheetFormulaTest.ts
  1diff --git a/DOCS.md b/DOCS.md
  2index 4ccd508..86d963c 100644
  3--- a/DOCS.md
  4+++ b/DOCS.md
  5@@ -1707,6 +1707,17 @@
  6 @returns {number} 
  7 @constructor TODO: This formula will fail to parse since the first argument is followed by an argument that is an array. TODO (continued) This is a known issue.
  8 ```
  9+
 10+### POISSON 
 11+
 12+```
 13+  Returns the Poisson distribution for the given number. 
 14+@param x - Number to use. 
 15+@param meanValue - The middle value for the Poisson distribution. 
 16+@param cumulative - [OPTIONAL] - 0 calculates the density function, 1 calculates the distribution. Defaults to 0. 
 17+@returns {number} 
 18+@constructor
 19+```
 20 ## Text
 21 
 22 
 23diff --git a/TODO.md b/TODO.md
 24index 4c3340b..0f59ee1 100644
 25--- a/TODO.md
 26+++ b/TODO.md
 27@@ -77,7 +77,6 @@ For example 64 tbs to a qt.
 28 * PERCENTRANK.EXC
 29 * PERCENTRANK.INC
 30 * PERMUT
 31-* POISSON
 32 * PROB
 33 * RANK
 34 * RANK.AVG
 35diff --git a/dist/Formulas/AllFormulas.js b/dist/Formulas/AllFormulas.js
 36index 2b7c47a..1caa9d5 100644
 37--- a/dist/Formulas/AllFormulas.js
 38+++ b/dist/Formulas/AllFormulas.js
 39@@ -155,6 +155,7 @@ exports.LARGE = Statistical_1.LARGE;
 40 exports.KURT = Statistical_1.KURT;
 41 exports.INTERCEPT = Statistical_1.INTERCEPT;
 42 exports.FORECAST = Statistical_1.FORECAST;
 43+exports.POISSON = Statistical_1.POISSON;
 44 var Text_1 = require("./Text");
 45 exports.ARABIC = Text_1.ARABIC;
 46 exports.CHAR = Text_1.CHAR;
 47@@ -194,6 +195,7 @@ exports.WORKDAY$INTL = Date_1.WORKDAY$INTL;
 48 var __COMPLEX = {
 49     "F.DIST": Statistical_1.FDIST$LEFTTAILED,
 50     "NETWORKDAYS.INTL": Date_1.NETWORKDAYS$INTL,
 51-    "WORKDAY.INTL": Date_1.WORKDAY$INTL
 52+    "WORKDAY.INTL": Date_1.WORKDAY$INTL,
 53+    "POISSON.DIST": Statistical_1.POISSON
 54 };
 55 exports.__COMPLEX = __COMPLEX;
 56diff --git a/dist/Formulas/Statistical.js b/dist/Formulas/Statistical.js
 57index e74fa2b..3c2d373 100644
 58--- a/dist/Formulas/Statistical.js
 59+++ b/dist/Formulas/Statistical.js
 60@@ -932,3 +932,41 @@ var FORECAST = function (x, rangeY, rangeX) {
 61     return a + b * x;
 62 };
 63 exports.FORECAST = FORECAST;
 64+/**
 65+ * Returns the Poisson distribution for the given number.
 66+ * @param x - Number to use.
 67+ * @param meanValue - The middle value for the Poisson distribution.
 68+ * @param cumulative - [OPTIONAL] - 0 calculates the density function, 1 calculates the distribution. Defaults to 0.
 69+ * @returns {number}
 70+ * @constructor
 71+ */
 72+var POISSON = function (x, meanValue, cumulative) {
 73+    ArgsChecker_1.ArgsChecker.checkLengthWithin(arguments, 2, 3, "POISSON");
 74+    x = TypeConverter_1.TypeConverter.firstValueAsNumber(x);
 75+    meanValue = TypeConverter_1.TypeConverter.firstValueAsNumber(meanValue);
 76+    cumulative = (cumulative === undefined) ? 0 : TypeConverter_1.TypeConverter.firstValueAsNumber(cumulative);
 77+    if (x < 0) {
 78+        throw new Errors_1.NumError("Function POISSON parameter 1 value is " + x + ". It should be greater than or equal to 0.");
 79+    }
 80+    if (meanValue < 0) {
 81+        throw new Errors_1.NumError("Function POISSON parameter 2 value is " + x + ". It should be greater than or equal to 0.");
 82+    }
 83+    function factorial(n) {
 84+        return n < 0 ? NaN : MathHelpers_1.gammafn(n + 1);
 85+    }
 86+    function poissonPDF(k, l) {
 87+        return Math.pow(l, k) * Math.exp(-l) / factorial(k);
 88+    }
 89+    function poissonCDF(x, l) {
 90+        var sumarr = [], k = 0;
 91+        if (x < 0)
 92+            return 0;
 93+        for (; k <= x; k++) {
 94+            sumarr.push(poissonPDF(k, l));
 95+        }
 96+        return MathHelpers_1.sum(sumarr);
 97+    }
 98+    ;
 99+    return (cumulative) ? poissonCDF(x, meanValue) : poissonPDF(x, meanValue);
100+};
101+exports.POISSON = POISSON;
102diff --git a/src/Formulas/AllFormulas.ts b/src/Formulas/AllFormulas.ts
103index 2aadb28..f50780a 100644
104--- a/src/Formulas/AllFormulas.ts
105+++ b/src/Formulas/AllFormulas.ts
106@@ -160,7 +160,8 @@ import {
107   LARGE,
108   KURT,
109   INTERCEPT,
110-  FORECAST
111+  FORECAST,
112+  POISSON
113 } from "./Statistical";
114 import {
115   ARABIC,
116@@ -204,7 +205,8 @@ import {
117 var __COMPLEX = {
118   "F.DIST": FDIST$LEFTTAILED,
119   "NETWORKDAYS.INTL": NETWORKDAYS$INTL,
120-  "WORKDAY.INTL": WORKDAY$INTL
121+  "WORKDAY.INTL": WORKDAY$INTL,
122+  "POISSON.DIST": POISSON
123 };
124 
125 export {
126@@ -389,5 +391,6 @@ export {
127   FV,
128   ISEMAIL,
129   ISURL,
130-  LINEST
131+  LINEST,
132+  POISSON
133 }
134\ No newline at end of file
135diff --git a/src/Formulas/Statistical.ts b/src/Formulas/Statistical.ts
136index c93c961..c813c6a 100644
137--- a/src/Formulas/Statistical.ts
138+++ b/src/Formulas/Statistical.ts
139@@ -25,7 +25,9 @@ import {
140   pdf,
141   stdev,
142   cleanFloat,
143-  mean
144+  mean,
145+  gammafn,
146+  sum
147 } from "../Utilities/MathHelpers";
148 
149 
150@@ -919,6 +921,47 @@ var FORECAST = function (x, rangeY, rangeX) {
151 };
152 
153 
154+/**
155+ * Returns the Poisson distribution for the given number.
156+ * @param x - Number to use.
157+ * @param meanValue - The middle value for the Poisson distribution.
158+ * @param cumulative - [OPTIONAL] - 0 calculates the density function, 1 calculates the distribution. Defaults to 0.
159+ * @returns {number}
160+ * @constructor
161+ */
162+var POISSON = function (x, meanValue, cumulative?) {
163+  ArgsChecker.checkLengthWithin(arguments, 2, 3, "POISSON");
164+  x = TypeConverter.firstValueAsNumber(x);
165+  meanValue = TypeConverter.firstValueAsNumber(meanValue);
166+  cumulative = (cumulative === undefined) ? 0 : TypeConverter.firstValueAsNumber(cumulative);
167+
168+  if (x < 0) {
169+    throw new NumError("Function POISSON parameter 1 value is " + x + ". It should be greater than or equal to 0.");
170+  }
171+  if (meanValue < 0) {
172+    throw new NumError("Function POISSON parameter 2 value is " + x + ". It should be greater than or equal to 0.");
173+  }
174+
175+  function factorial(n) {
176+    return n < 0 ? NaN : gammafn(n + 1);
177+  }
178+  function poissonPDF(k, l) {
179+    return Math.pow(l, k) * Math.exp(-l) / factorial(k);
180+  }
181+  function poissonCDF(x, l) {
182+    var sumarr = [],
183+      k = 0;
184+    if (x < 0) return 0;
185+    for (; k <= x; k++) {
186+      sumarr.push(poissonPDF(k, l));
187+    }
188+    return sum(sumarr);
189+  };
190+
191+  return (cumulative) ? poissonCDF(x, meanValue) : poissonPDF(x, meanValue);
192+};
193+
194+
195 export {
196   AVERAGE,
197   AVERAGEA,
198@@ -952,5 +995,6 @@ export {
199   LARGE,
200   KURT,
201   INTERCEPT,
202-  FORECAST
203+  FORECAST,
204+  POISSON
205 }
206\ No newline at end of file
207diff --git a/tests/Formulas/StatisticalTest.ts b/tests/Formulas/StatisticalTest.ts
208index 98a65ba..19beb83 100644
209--- a/tests/Formulas/StatisticalTest.ts
210+++ b/tests/Formulas/StatisticalTest.ts
211@@ -31,7 +31,8 @@ import {
212   LARGE,
213   KURT,
214   INTERCEPT,
215-  FORECAST
216+  FORECAST,
217+  POISSON
218 } from "../../src/Formulas/Statistical";
219 import * as ERRORS from "../../src/Errors";
220 import {
221@@ -694,3 +695,24 @@ test("FORCAST", function() {
222     FORECAST.apply(this, [0, [1, 2, 3], [1, 2, 3], [1, 2, 3]]);
223   }, ERRORS.NA_ERROR);
224 });
225+
226+
227+test("POISSON", function() {
228+  assertEquals(POISSON(3, 500, true), 1.4932281660406229e-210);
229+  assertEquals(POISSON(30, 500, true), 2.660801877634559e-169);
230+  assertEquals(POISSON(3, 5, true), 0.26502591529736175);
231+  assertEquals(POISSON(3, 5, false), 0.14037389581428059);
232+  assertEquals(POISSON(3, 5), 0.14037389581428059);
233+  catchAndAssertEquals(function() {
234+    POISSON(-3, 5);
235+  }, ERRORS.NUM_ERROR);
236+  catchAndAssertEquals(function() {
237+    POISSON(3, -5);
238+  }, ERRORS.NUM_ERROR);
239+  catchAndAssertEquals(function() {
240+    POISSON.apply(this, [1, 2, 3, 4]);
241+  }, ERRORS.NA_ERROR);
242+  catchAndAssertEquals(function() {
243+    POISSON.apply(this, [1]);
244+  }, ERRORS.NA_ERROR);
245+});
246diff --git a/tests/SheetFormulaTest.ts b/tests/SheetFormulaTest.ts
247index bf28619..cfa25d8 100644
248--- a/tests/SheetFormulaTest.ts
249+++ b/tests/SheetFormulaTest.ts
250@@ -767,6 +767,11 @@ test("Sheet LINEST", function(){
251   assertFormulaEqualsArray('=LINEST([15.53, 19.99, 20.43, 21.18, 25.93, 30], [1, 2, 3, 4, 5, 6])', [2.5977142857142863,	13.08466666666666]);
252 });
253 
254+test("Sheet POISSON, POISSON.DIST", function(){
255+  assertFormulaEquals('=POISSON(3, 5, true)', 0.26502591529736175);
256+  assertFormulaEquals('=POISSON.DIST(3, 5, true)', 0.26502591529736175);
257+});
258+
259 test("Sheet *", function(){
260   assertFormulaEquals('= 10 * 10', 100);
261   assertFormulaEquals('= 10 * 0', 0);