commit
message
Added Formulas.ERF
author
Ben Vogt <[email protected]>
date
2017-02-19 18:20:15
stats
2 file(s) changed,
81 insertions(+),
2 deletions(-)
files
src/RawFormulas/RawFormulas.ts
tests/FormulasTest.ts
1diff --git a/src/RawFormulas/RawFormulas.ts b/src/RawFormulas/RawFormulas.ts
2index c45bcca..3e0c3a2 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 ERF = Formula["ERF"];
10 var ERFC = Formula["ERFC"];
11 var EXPONDIST = Formula["EXPONDIST"];
12 var __COMPLEX = {
13@@ -129,6 +128,61 @@ var __COMPLEX = {
14 var YEARFRAC = Formula["YEARFRAC"];
15
16
17+/**
18+ * Returns the error function integrated between lower_limit and upper_limit.
19+ * @param values[0] lower_limit - The lower bound for integrating ERF.
20+ * @param values[1] upper_limit - [Optional]. The upper bound for integrating ERF. If omitted, ERF integrates between
21+ * zero and lower_limit.
22+ * @returns {number} error function integrated between lower_limit and upper_limit
23+ * @constructor
24+ */
25+var ERF = function (...values) : number {
26+ ArgsChecker.checkLengthWithin(values, 1, 2);
27+ var lower = TypeCaster.firstValueAsNumber(values[0]);
28+ var upper = values.length === 2 ? TypeCaster.firstValueAsNumber(values[1]) : 0;
29+
30+ // erf function from jStat [http://www.jstat.org/]
31+ function erf(x) {
32+ var cof = [-1.3026537197817094, 6.4196979235649026e-1, 1.9476473204185836e-2,
33+ -9.561514786808631e-3, -9.46595344482036e-4, 3.66839497852761e-4,
34+ 4.2523324806907e-5, -2.0278578112534e-5, -1.624290004647e-6,
35+ 1.303655835580e-6, 1.5626441722e-8, -8.5238095915e-8,
36+ 6.529054439e-9, 5.059343495e-9, -9.91364156e-10,
37+ -2.27365122e-10, 9.6467911e-11, 2.394038e-12,
38+ -6.886027e-12, 8.94487e-13, 3.13092e-13,
39+ -1.12708e-13, 3.81e-16, 7.106e-15,
40+ -1.523e-15, -9.4e-17, 1.21e-16,
41+ -2.8e-17];
42+ var j = cof.length - 1;
43+ var isneg = false;
44+ var d = 0;
45+ var dd = 0;
46+ var t, ty, tmp, res;
47+
48+ if (x < 0) {
49+ x = -x;
50+ isneg = true;
51+ }
52+
53+ t = 2 / (2 + x);
54+ ty = 4 * t - 2;
55+
56+ for(; j > 0; j--) {
57+ tmp = d;
58+ d = ty * d - dd + cof[j];
59+ dd = tmp;
60+ }
61+
62+ res = t * Math.exp(-x * x + 0.5 * (cof[0] + ty * d) - dd);
63+ return isneg ? res - 1 : 1 - res;
64+ }
65+
66+ return values.length === 1 ? erf(lower) : erf(upper) - erf(lower);
67+
68+};
69+
70+
71+
72 /**
73 * Calculates the depreciation of an asset for a specified period using the double-declining balance method.
74 * @param values[0] cost - The initial cost of the asset.
75diff --git a/tests/FormulasTest.ts b/tests/FormulasTest.ts
76index e43a062..3fd8931 100644
77--- a/tests/FormulasTest.ts
78+++ b/tests/FormulasTest.ts
79@@ -884,7 +884,25 @@ assertEquals(EFFECT(0.99, 12), 1.5890167507927795);
80
81 assertEqualsDates(EOMONTH(DATE(1992, 6, 24), 1), new Date('7/31/1992'));
82
83+
84+// Test ERF
85 assertEquals(ERF(2), 0.9953222650189527);
86+assertEquals(ERF("2"), 0.9953222650189527);
87+assertEquals(ERF(0), 1.1102230246251565e-16);
88+assertEquals(ERF(1), 0.8427007929497149);
89+assertEquals(ERF(true), 0.8427007929497149);
90+assertEquals(ERF(false), 1.1102230246251565e-16);
91+catchAndAssertEquals(function() {
92+ ERF();
93+}, ERRORS.NA_ERROR);
94+catchAndAssertEquals(function() {
95+ ERF([]);
96+}, ERRORS.REF_ERROR);
97+assertEquals(ERF(1, 2), 0.15262147206923782);
98+assertEquals(ERF(2, 1), -0.15262147206923782);
99+
100+
101+
102
103 assertEquals(ERFC(2), 0.004677734981047288);
104