spreadsheet
typeScript/javascript spreadsheet parser, with formulas.
git clone https://git.vogt.world/spreadsheet.git
Log | Files | README.md
← Commit log
commit
message
Added Formulas.ERFC
author
Ben Vogt <[email protected]>
date
2017-02-19 18:28:36
stats
2 file(s) changed, 65 insertions(+), 38 deletions(-)
files
src/RawFormulas/RawFormulas.ts
tests/FormulasTest.ts
  1diff --git a/src/RawFormulas/RawFormulas.ts b/src/RawFormulas/RawFormulas.ts
  2index 3e0c3a2..653e7ec 100644
  3--- a/src/RawFormulas/RawFormulas.ts
  4+++ b/src/RawFormulas/RawFormulas.ts
  5@@ -119,7 +119,6 @@ var EOMONTH = function (start_date, months) {
  6   var edate = moment(start_date).add(months, 'months');
  7   return new Date(edate.year(), edate.month(), edate.daysInMonth());
  8 };
  9-var ERFC = Formula["ERFC"];
 10 var EXPONDIST = Formula["EXPONDIST"];
 11 var __COMPLEX = {
 12   "F.DIST": Formula["FDIST"],
 13@@ -128,6 +127,20 @@ var __COMPLEX = {
 14 var YEARFRAC = Formula["YEARFRAC"];
 15 
 16 
 17+/**
 18+ * Returns the complementary Gauss error function of a value.
 19+ * @param values[0] The number for which to calculate the complementary Gauss error function.
 20+ * @returns {number} complementary Gauss error function of a value
 21+ * @constructor
 22+ */
 23+var ERFC = function (...values) {
 24+  ArgsChecker.checkLength(values, 1);
 25+  var v = TypeCaster.firstValueAsNumber(values[0]);
 26+  return v === 0 ? 1 : 1 - erf(v);
 27+};
 28+
 29+
 30+
 31 /**
 32  * Returns the error function integrated between lower_limit and upper_limit.
 33  * @param values[0] lower_limit - The lower bound for integrating ERF.
 34@@ -140,46 +153,44 @@ var ERF = function (...values) : number {
 35   ArgsChecker.checkLengthWithin(values, 1, 2);
 36   var lower = TypeCaster.firstValueAsNumber(values[0]);
 37   var upper = values.length === 2 ? TypeCaster.firstValueAsNumber(values[1]) : 0;
 38+  return values.length === 1 ? erf(lower) : erf(upper) - erf(lower);
 39+};
 40 
 41-  // erf function from jStat [http://www.jstat.org/]
 42-  function erf(x) {
 43-    var cof = [-1.3026537197817094, 6.4196979235649026e-1, 1.9476473204185836e-2,
 44-      -9.561514786808631e-3, -9.46595344482036e-4, 3.66839497852761e-4,
 45-      4.2523324806907e-5, -2.0278578112534e-5, -1.624290004647e-6,
 46-      1.303655835580e-6, 1.5626441722e-8, -8.5238095915e-8,
 47-      6.529054439e-9, 5.059343495e-9, -9.91364156e-10,
 48-      -2.27365122e-10, 9.6467911e-11, 2.394038e-12,
 49-      -6.886027e-12, 8.94487e-13, 3.13092e-13,
 50-      -1.12708e-13, 3.81e-16, 7.106e-15,
 51-      -1.523e-15, -9.4e-17, 1.21e-16,
 52-      -2.8e-17];
 53-    var j = cof.length - 1;
 54-    var isneg = false;
 55-    var d = 0;
 56-    var dd = 0;
 57-    var t, ty, tmp, res;
 58-
 59-    if (x < 0) {
 60-      x = -x;
 61-      isneg = true;
 62-    }
 63-
 64-    t = 2 / (2 + x);
 65-    ty = 4 * t - 2;
 66+// erf function from jStat [http://www.jstat.org/]
 67+function erf(x) {
 68+  var cof = [-1.3026537197817094, 6.4196979235649026e-1, 1.9476473204185836e-2,
 69+    -9.561514786808631e-3, -9.46595344482036e-4, 3.66839497852761e-4,
 70+    4.2523324806907e-5, -2.0278578112534e-5, -1.624290004647e-6,
 71+    1.303655835580e-6, 1.5626441722e-8, -8.5238095915e-8,
 72+    6.529054439e-9, 5.059343495e-9, -9.91364156e-10,
 73+    -2.27365122e-10, 9.6467911e-11, 2.394038e-12,
 74+    -6.886027e-12, 8.94487e-13, 3.13092e-13,
 75+    -1.12708e-13, 3.81e-16, 7.106e-15,
 76+    -1.523e-15, -9.4e-17, 1.21e-16,
 77+    -2.8e-17];
 78+  var j = cof.length - 1;
 79+  var isneg = false;
 80+  var d = 0;
 81+  var dd = 0;
 82+  var t, ty, tmp, res;
 83+
 84+  if (x < 0) {
 85+    x = -x;
 86+    isneg = true;
 87+  }
 88 
 89-    for(; j > 0; j--) {
 90-      tmp = d;
 91-      d = ty * d - dd + cof[j];
 92-      dd = tmp;
 93-    }
 94+  t = 2 / (2 + x);
 95+  ty = 4 * t - 2;
 96 
 97-    res = t * Math.exp(-x * x + 0.5 * (cof[0] + ty * d) - dd);
 98-    return isneg ? res - 1 : 1 - res;
 99+  for(; j > 0; j--) {
100+    tmp = d;
101+    d = ty * d - dd + cof[j];
102+    dd = tmp;
103   }
104 
105-  return values.length === 1 ? erf(lower) : erf(upper) - erf(lower);
106-
107-};
108+  res = t * Math.exp(-x * x + 0.5 * (cof[0] + ty * d) - dd);
109+  return isneg ? res - 1 : 1 - res;
110+}
111 
112 
113 
114diff --git a/tests/FormulasTest.ts b/tests/FormulasTest.ts
115index 3fd8931..37c05e1 100644
116--- a/tests/FormulasTest.ts
117+++ b/tests/FormulasTest.ts
118@@ -902,9 +902,21 @@ assertEquals(ERF(1, 2), 0.15262147206923782);
119 assertEquals(ERF(2, 1), -0.15262147206923782);
120 
121 
122+// Test ERFC
123+assertEquals(ERFC(2), 0.004677734981047288);
124+assertEquals(ERFC("2"), 0.004677734981047288);
125+assertEquals(ERFC(0), 1);
126+assertEquals(ERFC(1), 0.1572992070502851);
127+assertEquals(ERFC(-1), 1.842700792949715);
128+assertEquals(ERFC(-10), 2);
129+catchAndAssertEquals(function() {
130+  ERFC();
131+}, ERRORS.NA_ERROR);
132+catchAndAssertEquals(function() {
133+  ERFC([]);
134+}, ERRORS.REF_ERROR);
135 
136 
137-assertEquals(ERFC(2), 0.004677734981047288);
138 
139 // Test EVEN
140 assertEquals(EVEN(3), 4);