spreadsheet
typeScript/javascript spreadsheet parser, with formulas.
git clone https://git.vogt.world/spreadsheet.git
Log | Files | README.md
← Commit log
commit
message
[MULTINOMIAL] formula added and tested
author
Ben Vogt <[email protected]>
date
2017-07-08 02:48:35
stats
8 file(s) changed, 101 insertions(+), 6 deletions(-)
files
DOCS.md
TODO.md
dist/Formulas/AllFormulas.js
dist/Formulas/Math.js
src/Formulas/AllFormulas.ts
src/Formulas/Math.ts
tests/Formulas/MathTest.ts
tests/SheetFormulaTest.ts
  1diff --git a/DOCS.md b/DOCS.md
  2index 99857f8..f27f203 100644
  3--- a/DOCS.md
  4+++ b/DOCS.md
  5@@ -1374,6 +1374,15 @@
  6 @returns {number} 
  7 @constructor
  8 ```
  9+
 10+### LTINOMIAL 
 11+
 12+```
 13+  Returns the factorial of the sum of the arguments divided by the product of the factorials of the arguments. 
 14+@param values - Range of numbers. 
 15+@returns {number} 
 16+@constructor
 17+```
 18 ## Range
 19 
 20 
 21diff --git a/TODO.md b/TODO.md
 22index ff4a55a..1b60759 100644
 23--- a/TODO.md
 24+++ b/TODO.md
 25@@ -48,7 +48,6 @@ For example 64 tbs to a qt.
 26 * ROWS - Requires changes to parser.js
 27 * VLOOKUP - Requires changes to parser.js
 28 * COUNTBLANK - Requires changes to parser.js
 29-* MULTINOMIAL
 30 * SERIESSUM
 31 * SUBTOTAL
 32 * TO_DATE - Contingent upon cells having display formats derived from type-hierarchy
 33diff --git a/dist/Formulas/AllFormulas.js b/dist/Formulas/AllFormulas.js
 34index a115e5b..379513a 100644
 35--- a/dist/Formulas/AllFormulas.js
 36+++ b/dist/Formulas/AllFormulas.js
 37@@ -74,6 +74,7 @@ exports.UMINUS = Math_1.UMINUS;
 38 exports.MROUND = Math_1.MROUND;
 39 exports.FACTDOUBLE = Math_1.FACTDOUBLE;
 40 exports.UNARY_PERCENT = Math_1.UNARY_PERCENT;
 41+exports.MULTINOMIAL = Math_1.MULTINOMIAL;
 42 var Range_1 = require("./Range");
 43 exports.FREQUENCY = Range_1.FREQUENCY;
 44 exports.GROWTH = Range_1.GROWTH;
 45diff --git a/dist/Formulas/Math.js b/dist/Formulas/Math.js
 46index 228f8ac..95be5ab 100644
 47--- a/dist/Formulas/Math.js
 48+++ b/dist/Formulas/Math.js
 49@@ -1342,3 +1342,39 @@ var UNARY_PERCENT = function (value) {
 50     return TypeConverter_1.TypeConverter.firstValueAsNumber(value) / 100;
 51 };
 52 exports.UNARY_PERCENT = UNARY_PERCENT;
 53+/**
 54+ * Returns the factorial of the sum of the arguments divided by the product of the factorials of the arguments.
 55+ * @param values - Range of numbers.
 56+ * @returns {number}
 57+ * @constructor
 58+ */
 59+var MULTINOMIAL = function () {
 60+    var values = [];
 61+    for (var _i = 0; _i < arguments.length; _i++) {
 62+        values[_i] = arguments[_i];
 63+    }
 64+    ArgsChecker_1.ArgsChecker.checkAtLeastLength(values, 1, "MULTINOMIAL");
 65+    values = Filter_1.Filter.flattenAndThrow(values).map(TypeConverter_1.TypeConverter.valueToNumber);
 66+    var memoizeFact = [];
 67+    function _fact(value) {
 68+        var n = Math.floor(value);
 69+        if (n === 0 || n === 1) {
 70+            return 1;
 71+        }
 72+        else if (memoizeFact[n] > 0) {
 73+            return memoizeFact[n];
 74+        }
 75+        else {
 76+            memoizeFact[n] = _fact(n - 1) * n;
 77+            return memoizeFact[n];
 78+        }
 79+    }
 80+    var sum = 0;
 81+    var divisor = 1;
 82+    for (var i = 0; i < values.length; i++) {
 83+        sum += arguments[i];
 84+        divisor *= _fact(values[i]);
 85+    }
 86+    return _fact(sum) / divisor;
 87+};
 88+exports.MULTINOMIAL = MULTINOMIAL;
 89diff --git a/src/Formulas/AllFormulas.ts b/src/Formulas/AllFormulas.ts
 90index 6749708..13960c6 100644
 91--- a/src/Formulas/AllFormulas.ts
 92+++ b/src/Formulas/AllFormulas.ts
 93@@ -71,7 +71,8 @@ import {
 94   UMINUS,
 95   MROUND,
 96   FACTDOUBLE,
 97-  UNARY_PERCENT
 98+  UNARY_PERCENT,
 99+  MULTINOMIAL
100 } from "./Math";
101 import {
102   FREQUENCY,
103@@ -418,5 +419,6 @@ export {
104   HARMEAN,
105   CONFIDENCE,
106   N,
107-  UNARY_PERCENT
108+  UNARY_PERCENT,
109+  MULTINOMIAL
110 }
111\ No newline at end of file
112diff --git a/src/Formulas/Math.ts b/src/Formulas/Math.ts
113index f9590af..6b77ebf 100644
114--- a/src/Formulas/Math.ts
115+++ b/src/Formulas/Math.ts
116@@ -1352,6 +1352,37 @@ var UNARY_PERCENT = function (value) {
117   return TypeConverter.firstValueAsNumber(value) / 100;
118 };
119 
120+
121+/**
122+ * Returns the factorial of the sum of the arguments divided by the product of the factorials of the arguments.
123+ * @param values - Range of numbers.
124+ * @returns {number}
125+ * @constructor
126+ */
127+var MULTINOMIAL = function (...values) {
128+  ArgsChecker.checkAtLeastLength(values, 1, "MULTINOMIAL");
129+  values = Filter.flattenAndThrow(values).map(TypeConverter.valueToNumber);
130+  var memoizeFact = [];
131+  function _fact(value) {
132+    var n = Math.floor(value);
133+    if (n === 0 || n === 1) {
134+      return 1;
135+    } else if (memoizeFact[n] > 0) {
136+      return memoizeFact[n];
137+    } else {
138+      memoizeFact[n] = _fact(n - 1) * n;
139+      return memoizeFact[n];
140+    }
141+  }
142+  var sum = 0;
143+  var divisor = 1;
144+  for (var i = 0; i < values.length; i++) {
145+    sum += arguments[i];
146+    divisor *= _fact(values[i]);
147+  }
148+  return _fact(sum) / divisor;
149+};
150+
151 export {
152   ABS,
153   ACOS,
154@@ -1425,5 +1456,6 @@ export {
155   UMINUS,
156   MROUND,
157   FACTDOUBLE,
158-  UNARY_PERCENT
159+  UNARY_PERCENT,
160+  MULTINOMIAL
161 }
162\ No newline at end of file
163diff --git a/tests/Formulas/MathTest.ts b/tests/Formulas/MathTest.ts
164index 74f4eb4..b28e3bc 100644
165--- a/tests/Formulas/MathTest.ts
166+++ b/tests/Formulas/MathTest.ts
167@@ -71,7 +71,8 @@ import {
168   UMINUS,
169   MROUND,
170   FACTDOUBLE,
171-  UNARY_PERCENT
172+  UNARY_PERCENT,
173+  MULTINOMIAL
174 } from "../../src/Formulas/Math";
175 import * as ERRORS from "../../src/Errors";
176 import {
177@@ -1501,4 +1502,15 @@ test("UNARY_PERCENT", function(){
178   catchAndAssertEquals(function() {
179     UNARY_PERCENT.apply(this, []);
180   }, ERRORS.NA_ERROR);
181+});
182+
183+
184+test("MULTINOMIAL", function(){
185+  assertEquals(MULTINOMIAL(1, 2, 3), 60);
186+  assertEquals(MULTINOMIAL(1, 33, 100), 2.4592658588587683e+33);
187+  assertEquals(MULTINOMIAL(2, 22), 276);
188+  assertEquals(MULTINOMIAL(3), 1);
189+  catchAndAssertEquals(function() {
190+    MULTINOMIAL.apply(this, []);
191+  }, ERRORS.NA_ERROR);
192 });
193\ No newline at end of file
194diff --git a/tests/SheetFormulaTest.ts b/tests/SheetFormulaTest.ts
195index c249510..5bd5766 100644
196--- a/tests/SheetFormulaTest.ts
197+++ b/tests/SheetFormulaTest.ts
198@@ -817,6 +817,10 @@ test("Sheet UNARY_PERCENT", function(){
199   assertFormulaEquals('=UNARY_PERCENT(10)', 0.1);
200 });
201 
202+test("Sheet MULTINOMIAL", function(){
203+  assertFormulaEquals('=MULTINOMIAL(2, 22)', 276);
204+});
205+
206 test("Sheet *", function(){
207   assertFormulaEquals('= 10 * 10', 100);
208   assertFormulaEquals('= 10 * 0', 0);