aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXuejie Xiao <xxuejie@gmail.com>2012-11-19 15:52:26 -0500
committerXuejie Xiao <xxuejie@gmail.com>2012-11-19 15:52:26 -0500
commit9be35831f0741070e495622e6c7ba51fbbb6475c (patch)
treee4f479962d094dbfc237737aa088894bd9d3517f
parent357e70c0481081e92ac458f291afd038aab92788 (diff)
Add erf and erfc implementations
-rw-r--r--AUTHORS1
-rw-r--r--src/library.js57
-rwxr-xr-xtests/runner.py18
3 files changed, 76 insertions, 0 deletions
diff --git a/AUTHORS b/AUTHORS
index 554d7bfd..9ff2ed45 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -40,4 +40,5 @@ a license to everyone to use it as detailed in LICENSE.)
* Lars Schneider <lars.schneider@autodesk.com> (copyright owned by Autodesk, Inc.)
* Joel Martin <github@martintribe.org>
* Manuel Wellmann <manuel.wellmann@autodesk.com> (copyright owned by Autodesk, Inc.)
+* Xuejie xiao <xxuejie@gmail.com>
diff --git a/src/library.js b/src/library.js
index eb4aad40..ea43609d 100644
--- a/src/library.js
+++ b/src/library.js
@@ -5127,6 +5127,63 @@ LibraryManager.library = {
atan2f: 'Math.atan2',
exp: 'Math.exp',
expf: 'Math.exp',
+
+ // The erf and erfc functions are inspired from
+ // http://www.digitalmars.com/archives/cplusplus/3634.html
+ // and mruby source code at
+ // https://github.com/mruby/mruby/blob/master/src/math.c
+ erfc: function (x) {
+ var MATH_TOLERANCE = 1E-12;
+ var ONE_SQRTPI = 0.564189583547756287;
+ var a = 1;
+ var b = x;
+ var c = x;
+ var d = x * x + 0.5;
+ var n = 1.0
+ var q1, q2, t;
+
+ if (Math.abs(x) < 2.2) {
+ return 1.0 - _erf(x);
+ }
+ if (x < 0) {
+ return 2.0 - _erfc(-x);
+ }
+ do {
+ t = a * n + b * x;
+ a = b;
+ b = t;
+ t = c * n + d * x;
+ c = d;
+ d = t;
+ n += 0.5;
+ q1 = q2;
+ q2 = b / d;
+ } while (Math.abs(q1 - q2) / q2 > MATH_TOLERANCE);
+ return (ONE_SQRTPI * Math.exp(- x * x) * q2);
+ },
+ erfcf: 'erfcf',
+ erf: function (x) {
+ var MATH_TOLERANCE = 1E-12;
+ var TWO_SQRTPI = 1.128379167095512574;
+ var sum = x;
+ var term = x;
+ var xsqr = x*x;
+ var j = 1;
+
+ if (Math.abs(x) > 2.2) {
+ return 1.0 - _erfc(x);
+ }
+ do {
+ term *= xsqr / j;
+ sum -= term / (2 * j + 1);
+ ++j;
+ term *= xsqr / j;
+ sum += term / (2 * j + 1);
+ ++j;
+ } while (Math.abs(term / sum) > MATH_TOLERANCE);
+ return (TWO_SQRTPI * sum);
+ },
+ erff: 'erf',
log: 'Math.log',
logf: 'Math.log',
sqrt: 'Math.sqrt',
diff --git a/tests/runner.py b/tests/runner.py
index de964809..99af7109 100755
--- a/tests/runner.py
+++ b/tests/runner.py
@@ -1450,6 +1450,24 @@ c5,de,15,8a
'''
self.do_run(src, '*3.14,-3.14,1,0,0,0,1,0,1,1,0,2,3,0.0,1.0,0.0,1.0*')
+ def test_erf(self):
+ src = '''
+ #include <math.h>
+ #include <stdio.h>
+ int main()
+ {
+ printf("%1.6f, %1.6f, %1.6f, %1.6f, %1.6f, %1.6f\\n",
+ erf(1.0),
+ erf(3.0),
+ erf(-1.0),
+ erfc(1.0),
+ erfc(3.0),
+ erfc(-1.5));
+ return 0;
+ }
+ '''
+ self.do_run(src, '0.842701, 0.999978, -0.842701, 0.157299, 0.000022, 1.966105')
+
def test_math_hyperbolic(self):
src = open(path_from_root('tests', 'hyperbolic', 'src.c'), 'r').read()
expected = open(path_from_root('tests', 'hyperbolic', 'output.txt'), 'r').read()