spreadsheet
typeScript/javascript spreadsheet parser, with formulas.
git clone https://git.vogt.world/spreadsheet.git
Log | Files | README.md
← Commit log
commit
message
[NORMSINV] formula added and tested
author
Ben Vogt <[email protected]>
date
2017-07-03 19:12:43
stats
8 file(s) changed, 117 insertions(+), 7 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 52495ae..4135a3f 100644
  3--- a/DOCS.md
  4+++ b/DOCS.md
  5@@ -1740,6 +1740,15 @@
  6 @returns {number} 
  7 @constructor
  8 ```
  9+
 10+### NORMSINV 
 11+
 12+```
 13+  Returns the inverse of the standard normal distribution for the given number. 
 14+@param probability - The probability value. 
 15+@returns {number} 
 16+@constructor
 17+```
 18 ## Text
 19 
 20 
 21diff --git a/TODO.md b/TODO.md
 22index 7ad7ef2..48dd3d5 100644
 23--- a/TODO.md
 24+++ b/TODO.md
 25@@ -72,7 +72,6 @@ For example 64 tbs to a qt.
 26 * NORMDIST
 27 * NORMINV
 28 * NORMSDIST
 29-* NORMSINV
 30 * PERMUT
 31 * PROB
 32 * RANK
 33diff --git a/dist/Formulas/AllFormulas.js b/dist/Formulas/AllFormulas.js
 34index 65d4a45..35f07c0 100644
 35--- a/dist/Formulas/AllFormulas.js
 36+++ b/dist/Formulas/AllFormulas.js
 37@@ -158,6 +158,7 @@ exports.FORECAST = Statistical_1.FORECAST;
 38 exports.POISSON = Statistical_1.POISSON;
 39 exports.PERCENTRANK = Statistical_1.PERCENTRANK;
 40 exports.PERCENTRANK$EXC = Statistical_1.PERCENTRANK$EXC;
 41+exports.NORMSINV = Statistical_1.NORMSINV;
 42 var Text_1 = require("./Text");
 43 exports.ARABIC = Text_1.ARABIC;
 44 exports.CHAR = Text_1.CHAR;
 45diff --git a/dist/Formulas/Statistical.js b/dist/Formulas/Statistical.js
 46index afd6bd5..761e5fc 100644
 47--- a/dist/Formulas/Statistical.js
 48+++ b/dist/Formulas/Statistical.js
 49@@ -1062,3 +1062,42 @@ var PERCENTRANK$EXC = function (data, x, significance) {
 50     return v;
 51 };
 52 exports.PERCENTRANK$EXC = PERCENTRANK$EXC;
 53+/**
 54+ * Returns the inverse of the standard normal distribution for the given number.
 55+ * @param probability - The probability value.
 56+ * @returns {number}
 57+ * @constructor
 58+ */
 59+var NORMSINV = function (probability) {
 60+    ArgsChecker_1.ArgsChecker.checkLength(arguments, 1, "NORMSINV");
 61+    probability = TypeConverter_1.TypeConverter.firstValueAsNumber(probability);
 62+    function erfc(x) {
 63+        return 1 - MathHelpers_1.erf(x);
 64+    }
 65+    function erfcinv(p) {
 66+        var j = 0;
 67+        var x, err, t, pp;
 68+        if (p >= 2)
 69+            return -100;
 70+        if (p <= 0)
 71+            return 100;
 72+        pp = (p < 1) ? p : 2 - p;
 73+        t = Math.sqrt(-2 * Math.log(pp / 2));
 74+        x = -0.70711 * ((2.30753 + t * 0.27061) /
 75+            (1 + t * (0.99229 + t * 0.04481)) - t);
 76+        for (; j < 2; j++) {
 77+            err = erfc(x) - pp;
 78+            x += err / (1.12837916709551257 * Math.exp(-x * x) - x * err);
 79+        }
 80+        return (p < 1) ? x : -x;
 81+    }
 82+    function inv(p, mean, std) {
 83+        return -1.41421356237309505 * std * erfcinv(2 * p) + mean;
 84+    }
 85+    if (probability <= 0 || probability >= 1) {
 86+        throw new Errors_1.NumError("Function NORMSINV parameter 1 value is " + probability +
 87+            ". Valid values are between 0 and 1 exclusive.");
 88+    }
 89+    return inv(probability, 0, 1);
 90+};
 91+exports.NORMSINV = NORMSINV;
 92diff --git a/src/Formulas/AllFormulas.ts b/src/Formulas/AllFormulas.ts
 93index 64e38a9..5268505 100644
 94--- a/src/Formulas/AllFormulas.ts
 95+++ b/src/Formulas/AllFormulas.ts
 96@@ -163,7 +163,8 @@ import {
 97   FORECAST,
 98   POISSON,
 99   PERCENTRANK,
100-  PERCENTRANK$EXC
101+  PERCENTRANK$EXC,
102+  NORMSINV
103 } from "./Statistical";
104 import {
105   ARABIC,
106@@ -398,5 +399,6 @@ export {
107   LINEST,
108   POISSON,
109   PERCENTRANK,
110-  PERCENTRANK$EXC
111+  PERCENTRANK$EXC,
112+  NORMSINV
113 }
114\ No newline at end of file
115diff --git a/src/Formulas/Statistical.ts b/src/Formulas/Statistical.ts
116index 5bc4d98..fdc811c 100644
117--- a/src/Formulas/Statistical.ts
118+++ b/src/Formulas/Statistical.ts
119@@ -27,7 +27,8 @@ import {
120   cleanFloat,
121   mean,
122   gammafn,
123-  sum
124+  sum,
125+  erf
126 } from "../Utilities/MathHelpers";
127 
128 
129@@ -1054,6 +1055,46 @@ var PERCENTRANK$EXC = function (data, x, significance?) {
130 };
131 
132 
133+/**
134+ * Returns the inverse of the standard normal distribution for the given number.
135+ * @param probability - The probability value.
136+ * @returns {number}
137+ * @constructor
138+ */
139+var NORMSINV = function (probability) {
140+  ArgsChecker.checkLength(arguments, 1, "NORMSINV");
141+  probability =  TypeConverter.firstValueAsNumber(probability);
142+  function erfc(x) {
143+    return 1 - erf(x);
144+  }
145+  function erfcinv(p) {
146+    var j = 0;
147+    var x, err, t, pp;
148+    if (p >= 2)
149+      return -100;
150+    if (p <= 0)
151+      return 100;
152+    pp = (p < 1) ? p : 2 - p;
153+    t = Math.sqrt(-2 * Math.log(pp / 2));
154+    x = -0.70711 * ((2.30753 + t * 0.27061) /
155+      (1 + t * (0.99229 + t * 0.04481)) - t);
156+    for (; j < 2; j++) {
157+      err = erfc(x) - pp;
158+      x += err / (1.12837916709551257 * Math.exp(-x * x) - x * err);
159+    }
160+    return (p < 1) ? x : -x;
161+  }
162+  function inv(p, mean, std) {
163+    return -1.41421356237309505 * std * erfcinv(2 * p) + mean;
164+  }
165+  if (probability <= 0 || probability >= 1) {
166+    throw new NumError("Function NORMSINV parameter 1 value is " + probability +
167+        ". Valid values are between 0 and 1 exclusive.");
168+  }
169+  return inv(probability, 0, 1);
170+};
171+
172+
173 export {
174   AVERAGE,
175   AVERAGEA,
176@@ -1090,5 +1131,6 @@ export {
177   FORECAST,
178   POISSON,
179   PERCENTRANK,
180-  PERCENTRANK$EXC
181+  PERCENTRANK$EXC,
182+  NORMSINV
183 }
184\ No newline at end of file
185diff --git a/tests/Formulas/StatisticalTest.ts b/tests/Formulas/StatisticalTest.ts
186index 539e959..f9bf91e 100644
187--- a/tests/Formulas/StatisticalTest.ts
188+++ b/tests/Formulas/StatisticalTest.ts
189@@ -34,7 +34,8 @@ import {
190   FORECAST,
191   POISSON,
192   PERCENTRANK,
193-  PERCENTRANK$EXC
194+  PERCENTRANK$EXC,
195+  NORMSINV
196 } from "../../src/Formulas/Statistical";
197 import * as ERRORS from "../../src/Errors";
198 import {
199@@ -748,4 +749,16 @@ test("PERCENTRANK$EXC", function() {
200   catchAndAssertEquals(function() {
201     PERCENTRANK$EXC([1, 5, 3, 7, 3, 2, 6, 8, 4, 9, 0, 3, 1], -1);
202   }, ERRORS.NA_ERROR);
203+});
204+
205+
206+test("NORMSINV", function() {
207+  assertEquals(NORMSINV(0.1), -1.2815515655446006);
208+  assertEquals(NORMSINV(0.4), -0.2533471031357999);
209+  catchAndAssertEquals(function() {
210+    NORMSINV(0);
211+  }, ERRORS.NUM_ERROR);
212+  catchAndAssertEquals(function() {
213+    NORMSINV(1);
214+  }, ERRORS.NUM_ERROR);
215 });
216\ No newline at end of file
217diff --git a/tests/SheetFormulaTest.ts b/tests/SheetFormulaTest.ts
218index 8b17052..910dd0c 100644
219--- a/tests/SheetFormulaTest.ts
220+++ b/tests/SheetFormulaTest.ts
221@@ -781,6 +781,10 @@ test("Sheet PERCENTRANK.EXC", function(){
222   assertFormulaEquals('=PERCENTRANK.EXC([1], 1)', 1);
223 });
224 
225+test("Sheet NORMSINV", function(){
226+  assertFormulaEquals('=NORMSINV(0.1)', -1.2815515655446006);
227+});
228+
229 test("Sheet *", function(){
230   assertFormulaEquals('= 10 * 10', 100);
231   assertFormulaEquals('= 10 * 0', 0);