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);