Repository: josdejong/mathjs
Pull request #288 (2015-02-26 05:58:14)

Fixes the calculation of norm() and abs() of large complex numbers
Fixes the calculation of norm() and abs() of large complex numbers like:

abs(1e200 - 4e200i)


Patch:
diff --git a/HISTORY.md b/HISTORY.md
index 7d374a43b..a558a41ae 100644
--- a/HISTORY.md
+++ b/HISTORY.md
@@ -3,9 +3,8 @@
 ## not yet released, version 1.4.0-SNAPSHOT
 
 - Implemented trigonometric functions:
-  `acosh`, `acoth`, `acsch`, `asech`, `asinh`, `atanh`, `acot`, `acsc`, `asec`.
-  Thanks @BigFav.
-- Added BigNumber support for functions: `cot`, `csc`, `sec`, `coth`,
+  `acosh`, `acoth`, `acsch`, `asech`, `asinh`, `atanh`. Thanks @BigFav.
+- Implemented BigNumber support for functions: `cot`, `csc`, `sec`, `coth`,
   `csch`, `sech`. Thanks @BigFav.
 - Implemented support for serialization and deserialization of math.js data
   types.
diff --git a/docs/expressions/syntax.md b/docs/expressions/syntax.md
index af0158a4a..6a8e75db0 100644
--- a/docs/expressions/syntax.md
+++ b/docs/expressions/syntax.md
@@ -86,9 +86,6 @@ Operator    | Name                    | Syntax      | Associativity | Example
 `<=`        | Smallereq               | `x <= y`    | Left to right | `4 <= 3`              | `false`
 `>=`        | Largereq                | `x >= y`    | Left to right | `2 + 4 >= 6`          | `true`
 
-
-## Precedence
-
 The operators have the following precedence, from highest to lowest:
 
 Operators                         | Description
diff --git a/docs/serialization.md b/docs/serialization.md
index 30ed4fc82..680996bc9 100644
--- a/docs/serialization.md
+++ b/docs/serialization.md
@@ -1,13 +1,9 @@
 # Serialization
 
 Math.js has a number of data types like `Matrix`, `Complex`, and `Unit`. These
-types are instantiated JavaScript objects. To be able to store these data types
-or share them between processes, they must be serialized. The data types of
-math.js can be serialized to JSON. Use cases:
-
-- Store data in a database or on disk.
-- Share data between a server and a client.
-- Share data between a web worker and the browser.
+types are instantiated JavaScript objects. In order to share these data types
+between a server and a client, or a web worker and the browser, these data
+types must be serialized. The data types of math.js can be serialized to JSON.
 
 Math.js types can be serialized using JavaScript's built-in `JSON.stringify`
 function:
@@ -29,10 +25,10 @@ var x    = JSON.parse(json, math.json.reviver);   // Complex 2 + 3i
 ```
 
 Note that if math.js is used in conjunction with other data types, it is
-possible to use multiple reviver functions at the same time by cascading them:
+possible to use multiple reviver functions by cascading them, like:
 
 ```js
 var reviver = function (key, value) {
-  return reviver1(key, reviver2(key, value));
+  return math.json.reviver(key, otherReviver(key, value));
 }
 ```
diff --git a/lib/function/arithmetic/abs.js b/lib/function/arithmetic/abs.js
index f7d38e52a..23e780d67 100644
--- a/lib/function/arithmetic/abs.js
+++ b/lib/function/arithmetic/abs.js
@@ -47,7 +47,15 @@ module.exports = function (math) {
     }
 
     if (isComplex(x)) {
-      return Math.sqrt(x.re * x.re + x.im * x.im);
+      // do not compute sqrt(re * re + im * im) since it will overflow with big numbers!
+      var re = Math.abs(x.re);
+      var im = Math.abs(x.im);
+      if (re >= im) {
+        var x = im / re;
+        return re * Math.sqrt(1 + x * x);
+      }
+      var y = re / im;
+      return im * Math.sqrt(1 + y * y);
     }
 
     if (x instanceof BigNumber) {
diff --git a/lib/function/arithmetic/norm.js b/lib/function/arithmetic/norm.js
index 28e6a306f..4b5184d67 100644
--- a/lib/function/arithmetic/norm.js
+++ b/lib/function/arithmetic/norm.js
@@ -64,8 +64,15 @@ module.exports = function (math) {
     }
 
     if (isComplex(x)) {
-      // ignore p, complex numbers
-      return Math.sqrt(x.re * x.re + x.im * x.im);
+      // do not compute sqrt(re * re + im * im) since it will overflow with big numbers!
+      var re = Math.abs(x.re);
+      var im = Math.abs(x.im);
+      if (re >= im) {
+        var x = im / re;
+        return re * Math.sqrt(1 + x * x);
+      }
+      var y = re / im;
+      return im * Math.sqrt(1 + y * y);
     }
 
     if (x instanceof BigNumber) {
diff --git a/lib/function/trigonometry/acos.js b/lib/function/trigonometry/acos.js
index 5c49ea63c..2c619c1e8 100644
--- a/lib/function/trigonometry/acos.js
+++ b/lib/function/trigonometry/acos.js
@@ -12,7 +12,7 @@ module.exports = function (math) {
       isComplex = Complex.isComplex,
       isCollection = collection.isCollection,
 
-      bigArcCos = util.bignumber.arccos_arcsec;
+      bigArcCos = util.bignumber.arccos;
 
   /**
    * Calculate the inverse cosine of a value.
@@ -80,7 +80,7 @@ module.exports = function (math) {
     }
 
     if (x instanceof BigNumber) {
-      return bigArcCos(x, false);
+      return bigArcCos(x);
     }
 
     throw new math.error.UnsupportedTypeError('acos', math['typeof'](x));
diff --git a/lib/function/trigonometry/acosh.js b/lib/function/trigonometry/acosh.js
index d4177e180..07885c12e 100644
--- a/lib/function/trigonometry/acosh.js
+++ b/lib/function/trigonometry/acosh.js
@@ -18,7 +18,7 @@ module.exports = function (math) {
 
   /**
    * Calculate the hyperbolic arccos of a value,
-   * defined as `acosh(x) = ln(sqrt(x^2 - 1) + x)`.
+   * defined as `acosh(x) = ln(x + sqrt(x^2 - 1))`.
    *
    * For matrices, the function is evaluated element wise.
    *
@@ -43,13 +43,7 @@ module.exports = function (math) {
     }
 
     if (isNumber(x)) {
-      if (x >= 1) {
-        return Math.log(Math.sqrt(x*x - 1) + x);
-      }
-      if (x <= -1) { 
-        return new Complex(Math.log(Math.sqrt(x*x - 1) - x), Math.PI);
-      }
-      return acosh(new Complex(x, 0));
+      return Math.log(x + Math.sqrt(x*x - 1));
     }
 
     if (isComplex(x)) {
@@ -75,7 +69,7 @@ module.exports = function (math) {
     }
 
     if (isBoolean(x) || x === null) {
-      return (x) ? 0 : new Complex(0, 1.5707963267948966);
+      return (x) ? 0 : NaN;
     }
 
     if (x instanceof BigNumber) {
diff --git a/lib/function/trigonometry/acot.js b/lib/function/trigonometry/acot.js
deleted file mode 100644
index f52fccdc2..000000000
--- a/lib/function/trigonometry/acot.js
+++ /dev/null
@@ -1,82 +0,0 @@
-'use strict';
-
-module.exports = function (math) {
-  var util = require('../../util/index'),
-
-      BigNumber = math.type.BigNumber,
-      Complex = require('../../type/Complex'),
-      collection = require('../../type/collection'),
-
-      isNumber = util.number.isNumber,
-      isBoolean = util['boolean'].isBoolean,
-      isComplex = Complex.isComplex,
-      isCollection = collection.isCollection,
-
-      bigArcCot = util.bignumber.arctan_arccot;
-
-  /**
-   * Calculate the inverse cotangent of a value.
-   *
-   * For matrices, the function is evaluated element wise.
-   *
-   * Syntax:
-   *
-   *    math.acot(x)
-   *
-   * Examples:
-   *
-   *    math.acot(0.5);           // returns Number 0.4636476090008061
-   *    math.acot(math.cot(1.5)); // returns Number 1.5
-   *
-   *    math.acot(2);             // returns Complex 1.5707963267948966 -1.3169578969248166 i
-   *
-   * See also:
-   *
-   *    cot, atan
-   *
-   * @param {Number | Boolean | Complex | Array | Matrix | null} x   Function input
-   * @return {Number | Complex | Array | Matrix} The arc cotangent of x
-   */
-  math.acot = function acot(x) {
-    if (arguments.length != 1) {
-      throw new math.error.ArgumentsError('acot', arguments.length, 1);
-    }
-
-    if (isNumber(x)) {
-      return (x) ? Math.atan(1 / x) : halfPi;
-    }
-
-    if (isComplex(x)) {
-      if (x.im == 0) {
-        return new Complex(x.re ? Math.atan(1 / x.re) : halfPi, 0);
-      }
-
-      var den = x.re*x.re + x.im*x.im;
-      x = (den != 0)
-        ? new Complex(
-            x.re =  x.re / den,
-            x.im = -x.im / den)
-        : new Complex(
-            (x.re != 0) ?  (x.re / 0) : 0,
-            (x.im != 0) ? -(x.im / 0) : 0);
-
-      return math.atan(x);
-    }
-
-    if (isCollection(x)) {
-      return collection.deepMap(x, acot);
-    }
-
-    if (isBoolean(x) || x === null) {
-      return (x) ? 0.7853981633974483 : halfPi;
-    }
-
-    if (x instanceof BigNumber) {
-      return bigArcCot(x, true);
-    }
-
-    throw new math.error.UnsupportedTypeError('acot', math['typeof'](x));
-  };
-
-  var halfPi = 1.5707963267948966;
-};
diff --git a/lib/function/trigonometry/acoth.js b/lib/function/trigonometry/acoth.js
index 34b8efe02..13efed051 100644
--- a/lib/function/trigonometry/acoth.js
+++ b/lib/function/trigonometry/acoth.js
@@ -43,28 +43,23 @@ module.exports = function (math) {
     }
 
     if (isNumber(x)) {
-      if (x >= 1 || x <= -1) {
-        return isFinite(x) ? (Math.log((x+1)/x) + Math.log(x/(x-1))) / 2 : 0;
-      }
-      return (x) ? acoth(new Complex(x, 0)) : new Complex(0, halfPi);
+      return isFinite(x) ? (Math.log((x+1)/x) + Math.log(x/(x-1))) / 2 : 0;
     }
 
     if (isComplex(x)) {
       if (x.re == 0 && x.im == 0) {
-        return new Complex(0, halfPi);
+        return new Complex(0, 1.5707963267948966);
       }
 
       // acoth(z) = -i*atanh(1/z)
       var den = x.re*x.re + x.im*x.im;
-      x = (den != 0)
-        ? new Complex(
-            x.re / den,
-           -x.im / den
-          )
-        : new Complex(
-            (x.re != 0) ?  (x.re / 0) : 0,
-            (x.im != 0) ? -(x.im / 0) : 0
-          );
+      if (den != 0) {
+        x.re =  x.re / den;
+        x.im = -x.im / den;
+      } else {
+        x.re = (x.re != 0) ?  (x.re / 0) : 0;
+        x.im = (x.im != 0) ? -(x.im / 0) : 0;
+      }
 
       return math.atanh(x);
     }
@@ -74,7 +69,7 @@ module.exports = function (math) {
     }
 
     if (isBoolean(x) || x === null) {
-      return (x) ? Infinity : new Complex(0, halfPi);
+      return (x) ? Infinity : NaN;
     }
 
     if (x instanceof BigNumber) {
@@ -83,6 +78,4 @@ module.exports = function (math) {
 
     throw new math.error.UnsupportedTypeError('acoth', math['typeof'](x));
   };
-
-  var halfPi = 1.5707963267948966;
 };
diff --git a/lib/function/trigonometry/acsc.js b/lib/function/trigonometry/acsc.js
deleted file mode 100644
index 13920e370..000000000
--- a/lib/function/trigonometry/acsc.js
+++ /dev/null
@@ -1,86 +0,0 @@
-'use strict';
-
-module.exports = function (math) {
-  var util = require('../../util/index'),
-
-      BigNumber = math.type.BigNumber,
-      Complex = require('../../type/Complex'),
-      collection = require('../../type/collection'),
-
-      isNumber = util.number.isNumber,
-      isBoolean = util['boolean'].isBoolean,
-      isComplex = Complex.isComplex,
-      isCollection = collection.isCollection,
-
-      bigArcCsc = util.bignumber.arcsin_arccsc;
-
-  /**
-   * Calculate the inverse cosecant of a value.
-   *
-   * For matrices, the function is evaluated element wise.
-   *
-   * Syntax:
-   *
-   *    math.acsc(x)
-   *
-   * Examples:
-   *
-   *    math.acsc(0.5);           // returns Number 0.5235987755982989
-   *    math.acsc(math.csc(1.5)); // returns Number ~1.5
-   *
-   *    math.acsc(2);             // returns Complex 1.5707963267948966 -1.3169578969248166 i
-   *
-   * See also:
-   *
-   *    csc, asin, asec
-   *
-   * @param {Number | Boolean | Complex | Array | Matrix | null} x   Function input
-   * @return {Number | Complex | Array | Matrix} The arc cosecant of x
-   */
-  math.acsc = function acsc(x) {
-
-    if (arguments.length != 1) {
-      throw new math.error.ArgumentsError('acsc', arguments.length, 1);
-    }
-
-    if (isNumber(x)) {
-      if (x <= -1 || x >= 1) {
-        return Math.asin(1 / x);
-      }
-      return acsc(new Complex(x, 0));
-    }
-
-    if (isComplex(x)) {
-      if (x.re == 0 && x.im == 0) {
-        return new Complex(halfPi, Infinity);
-      }
-
-      var den = x.re*x.re + x.im*x.im;
-      x = (den != 0)
-        ? new Complex(
-            x.re =  x.re / den,
-            x.im = -x.im / den)
-        : new Complex(
-            (x.re != 0) ?  (x.re / 0) : 0,
-            (x.im != 0) ? -(x.im / 0) : 0);
-
-      return math.asin(x);
-    }
-
-    if (isCollection(x)) {
-      return collection.deepMap(x, acsc);
-    }
-
-    if (isBoolean(x) || x === null) {
-      return (x) ? halfPi : new Complex(halfPi, Infinity);
-    }
-
-    if (x instanceof BigNumber) {
-      return bigArcCsc(x, true);
-    }
-
-    throw new math.error.UnsupportedTypeError('acsc', math['typeof'](x));
-  };
-
-  var halfPi = 1.5707963267948966;
-};
diff --git a/lib/function/trigonometry/acsch.js b/lib/function/trigonometry/acsch.js
index 0ce66bda7..12b545869 100644
--- a/lib/function/trigonometry/acsch.js
+++ b/lib/function/trigonometry/acsch.js
@@ -48,26 +48,22 @@ module.exports = function (math) {
     }
 
     if (isComplex(x)) {
-      if (x.im == 0) {
-        x = (x.re != 0)
-          ? Math.log(x.re + Math.sqrt(x.re*x.re + 1))
-          : Infinity;
-        return new Complex(x, 0);
-      }
-
       // acsch(z) = -i*asinh(1/z)
       var den = x.re*x.re + x.im*x.im;
-      x = (den != 0) 
-        ? new Complex(
-            x.re / den,
-           -x.im / den
-          )
-        : new Complex(
-            (x.re != 0) ?  (x.re / 0) : 0,
-            (x.im != 0) ? -(x.im / 0) : 0
-          );
+      if (den != 0) {
+        x.re =  x.re / den;
+        x.im = -x.im / den;
+      } else {
+        x.re = (x.re != 0) ?  (x.re / 0) : 0;
+        x.im = (x.im != 0) ? -(x.im / 0) : 0;
+      }
+
+      if (x.im) {
+        return math.asinh(x);
+      }
 
-      return math.asinh(x);
+      x = 1 / x.re;
+      return new Complex(Math.log(x + Math.sqrt(x*x + 1)), 0);
     }
 
     if (isCollection(x)) {
diff --git a/lib/function/trigonometry/asec.js b/lib/function/trigonometry/asec.js
deleted file mode 100644
index 9e04fa6fb..000000000
--- a/lib/function/trigonometry/asec.js
+++ /dev/null
@@ -1,83 +0,0 @@
-'use strict';
-
-module.exports = function (math) {
-  var util = require('../../util/index'),
-
-      BigNumber = math.type.BigNumber,
-      Complex = require('../../type/Complex'),
-      collection = require('../../type/collection'),
-
-      isNumber = util.number.isNumber,
-      isBoolean = util['boolean'].isBoolean,
-      isComplex = Complex.isComplex,
-      isCollection = collection.isCollection,
-
-      bigArcSec = util.bignumber.arccos_arcsec;
-
-  /**
-   * Calculate the inverse secant of a value.
-   *
-   * For matrices, the function is evaluated element wise.
-   *
-   * Syntax:
-   *
-   *    math.asec(x)
-   *
-   * Examples:
-   *
-   *    math.asec(0.5);           // returns 1.0471975511965979
-   *    math.asec(math.sec(1.5)); // returns 1.5
-   *
-   *    math.asec(2);             // returns 0 + 1.3169578969248166 i
-   *
-   * See also:
-   *
-   *    acos, acot, acsc
-   *
-   * @param {Number | Boolean | Complex | Array | Matrix | null} x  Function input
-   * @return {Number | Complex | Array | Matrix} The arc secant of x
-   */
-  math.asec = function asec(x) {
-    if (arguments.length != 1) {
-      throw new math.error.ArgumentsError('asec', arguments.length, 1);
-    }
-
-    if (isNumber(x)) {
-      if (x <= -1 || x >= 1) {
-        return Math.acos(1 / x);
-      }
-      return asec(new Complex(x, 0));
-    }
-
-    if (isComplex(x)) {
-      if (x.re == 0 && x.im == 0) {
-        return new Complex(0, Infinity);
-      }
-
-      var den = x.re*x.re + x.im*x.im;
-      x = (den != 0)
-        ? new Complex(
-            x.re =  x.re / den,
-            x.im = -x.im / den)
-        : new Complex(
-            (x.re != 0) ?  (x.re / 0) : 0,
-            (x.im != 0) ? -(x.im / 0) : 0);
-
-      return math.acos(x);
-    }
-
-    if (isCollection(x)) {
-      return collection.deepMap(x, asec);
-    }
-
-    if (isBoolean(x) || x === null) {
-      return (x) ? 0 : new Complex(0, Infinity);
-    }
-
-    if (x instanceof BigNumber) {
-      return bigArcSec(x, true);
-    }
-
-    throw new math.error.UnsupportedTypeError('asec', math['typeof'](x));
-  };
-};
diff --git a/lib/function/trigonometry/asech.js b/lib/function/trigonometry/asech.js
index 869f7b4f1..b5a9fefec 100644
--- a/lib/function/trigonometry/asech.js
+++ b/lib/function/trigonometry/asech.js
@@ -18,7 +18,7 @@ module.exports = function (math) {
 
   /**
    * Calculate the hyperbolic arccos of a value,
-   * defined as `asech(x) = ln(sqrt(1/x^2 - 1) + 1/x)`.
+   * defined as `asech(x) = ln(1/x + sqrt(1/x^2 - 1))`.
    *
    * For matrices, the function is evaluated element wise.
    *
@@ -43,18 +43,8 @@ module.exports = function (math) {
     }
 
     if (isNumber(x)) {
-      if (x <= 1 && x >= -1) {
-        x = 1 / x;
-
-        var ret = Math.sqrt(x*x - 1);
-        if (x > 0) {
-          return Math.log(ret + x);
-        }
-
-        return new Complex(Math.log(ret - x), Math.PI);
-      }
-
-      return asech(new Complex(x, 0));
+      x = 1 / x;
+      return Math.log(x + Math.sqrt(x*x - 1));
     }
 
     if (isComplex(x)) {
@@ -64,15 +54,13 @@ module.exports = function (math) {
 
       // acsch(z) = -i*asinh(1/z)
       var den = x.re*x.re + x.im*x.im;
-      x = (den != 0)
-        ? new Complex(
-            x.re / den,
-           -x.im / den
-          )
-        : new Complex(
-            (x.re != 0) ?  (x.re / 0) : 0,
-            (x.im != 0) ? -(x.im / 0) : 0
-          );
+      if (den != 0) {
+        x.re =  x.re / den;
+        x.im = -x.im / den;
+      } else {
+        x.re = (x.re != 0) ?  (x.re / 0) : 0;
+        x.im = (x.im != 0) ? -(x.im / 0) : 0;
+      }
 
       return math.acosh(x);
     }
diff --git a/lib/function/trigonometry/asin.js b/lib/function/trigonometry/asin.js
index 671b8826c..8a6a5b8c9 100644
--- a/lib/function/trigonometry/asin.js
+++ b/lib/function/trigonometry/asin.js
@@ -12,7 +12,7 @@ module.exports = function (math) {
       isComplex = Complex.isComplex,
       isCollection = collection.isCollection,
 
-      bigArcSin = util.bignumber.arcsin_arccsc;
+      bigArcSin = util.bignumber.arcsin;
 
   /**
    * Calculate the inverse sine of a value.
@@ -78,7 +78,7 @@ module.exports = function (math) {
     }
 
     if (x instanceof BigNumber) {
-      return bigArcSin(x, false);
+      return bigArcSin(x);
     }
 
     throw new math.error.UnsupportedTypeError('asin', math['typeof'](x));
diff --git a/lib/function/trigonometry/asinh.js b/lib/function/trigonometry/asinh.js
index 06404e1c9..0313f02ee 100644
--- a/lib/function/trigonometry/asinh.js
+++ b/lib/function/trigonometry/asinh.js
@@ -43,7 +43,7 @@ module.exports = function (math) {
     }
 
     if (isNumber(x)) {
-      return Math.log(Math.sqrt(x*x + 1) + x);
+      return Math.log(x + Math.sqrt(x*x + 1));
     }
 
     if (isComplex(x)) {
@@ -53,11 +53,6 @@ module.exports = function (math) {
       x.re = temp;
 
       var asin = math.asin(x);
-
-      // restore original values
-      x.re = -x.im;
-      x.im = temp;
-
       temp = asin.re;
       asin.re = -asin.im;
       asin.im = temp;
diff --git a/lib/function/trigonometry/atan.js b/lib/function/trigonometry/atan.js
index 896b379b1..1317745a2 100644
--- a/lib/function/trigonometry/atan.js
+++ b/lib/function/trigonometry/atan.js
@@ -12,7 +12,7 @@ module.exports = function (math) {
       isComplex = Complex.isComplex,
       isCollection = collection.isCollection,
 
-      bigArcTan = util.bignumber.arctan_arccot;
+      bigArcTan = util.bignumber.arctan;
 
   /**
    * Calculate the inverse tangent of a value.
@@ -47,15 +47,6 @@ module.exports = function (math) {
     }
 
     if (isComplex(x)) {
-      if (x.re == 0) {
-        if (x.im == 1) {
-          return new Complex(0, Infinity);
-        }
-        if (x.im == -1) {
-          return new Complex(0, -Infinity);
-        }
-      }
-
       // atan(z) = 1/2 * i * (ln(1-iz) - ln(1+iz))
       var re = x.re;
       var im = x.im;
@@ -82,7 +73,7 @@ module.exports = function (math) {
     }
 
     if (x instanceof BigNumber) {
-      return bigArcTan(x, false);
+      return bigArcTan(x);
     }
 
     throw new math.error.UnsupportedTypeError('atan', math['typeof'](x));
diff --git a/lib/function/trigonometry/atanh.js b/lib/function/trigonometry/atanh.js
index 40c36ad5a..5bdfd3a9f 100644
--- a/lib/function/trigonometry/atanh.js
+++ b/lib/function/trigonometry/atanh.js
@@ -43,10 +43,7 @@ module.exports = function (math) {
     }
 
     if (isNumber(x)) {
-      if (x <= 1 && x >= -1) {
-        return Math.log((1 + x)/(1 - x)) / 2;
-      }
-      return atanh(new Complex(x, 0));
+      return Math.log((1 + x)/(1 - x)) / 2;
     }
 
     if (isComplex(x)) {
diff --git a/lib/math.js b/lib/math.js
index a8a1d041b..6a4babe5b 100644
--- a/lib/math.js
+++ b/lib/math.js
@@ -298,11 +298,8 @@ function create (config) {
   // functions - trigonometry
   require('./function/trigonometry/acos')(math, _config);
   require('./function/trigonometry/acosh')(math, _config);
-  require('./function/trigonometry/acot')(math, _config);
   require('./function/trigonometry/acoth')(math, _config);
-  require('./function/trigonometry/acsc')(math, _config);
   require('./function/trigonometry/acsch')(math, _config);
-  require('./function/trigonometry/asec')(math, _config);
   require('./function/trigonometry/asech')(math, _config);
   require('./function/trigonometry/asin')(math, _config);
   require('./function/trigonometry/asinh')(math, _config);
diff --git a/lib/util/bignumber.js b/lib/util/bignumber.js
index 5742ec897..c657ed7b4 100644
--- a/lib/util/bignumber.js
+++ b/lib/util/bignumber.js
@@ -484,24 +484,17 @@ function decCoefficientToBinaryString(x) {
  *************************************/
 
 /**
- * Calculate the arccosine or arcsecant of x
+ * Calculate the arccosine of x
  *
  * acos(x) = 2*atan(sqrt(1-x^2)/(1+x))
  *
- * asec(x) = acos(1/x)
- *
  * @param {BigNumber} x
- * @param {Boolean} reciprocal  is sec
- * @returns {BigNumber} arccosine or arcsecant of x
+ * @returns {BigNumber} arccosine of x
  */
-exports.arccos_arcsec = function (x, reciprocal) {
+exports.arccos = function (x) {
   var Big = x.constructor;
   var precision = Big.precision;
-  if (reciprocal) {
-    if (x.abs().lt(Big.ONE)) {
-      throw new Error('asec() only has non-complex values for |x| >= 1.');
-    }
-  } else if (x.abs().gt(Big.ONE)) {
+  if (x.abs().gt(Big.ONE)) {
     throw new Error('acos() only has non-complex values for |x| <= 1.');
   }
   if (x.eq(-1)) {
@@ -509,47 +502,35 @@ exports.arccos_arcsec = function (x, reciprocal) {
   }
 
   Big.config({precision: precision + 4});
-
-  if (reciprocal) {
-    x = Big.ONE.div(x);
-  }
-
-  var acos = exports.arctan_arccot(Big.ONE.minus(x.times(x)).sqrt()
-                                      .div(x.plus(Big.ONE))).times(2);
-
+  var acos = exports.arctan(Big.ONE.minus(x.times(x)).sqrt()
+                                .div(x.plus(Big.ONE))).times(2);
   Big.config({precision: precision});
+
   return acos.toDP(precision - 1);
 };
 
 /**
- * Calculate the arcsine or arccosecant of x
+ * Calculate the arcsine of x
  *
  * @param {BigNumber} x
- * @param {Boolean} reciprocal  is csc
- * @returns {BigNumber} arcsine or arccosecant of x
+ * @returns {BigNumber} arcsine of x
  */
-exports.arcsin_arccsc = function (x, reciprocal) {
+exports.arcsin = function (x) {
   var Big = x.constructor;
-  var precision = Big.precision;
   if (x.isNaN()) {
     return new Big(NaN);
   }
+  if (x.isZero()) {
+    return new Big(0);
+  }
 
   var absX = x.abs();
-  if (reciprocal) {
-    if (absX.lt(Big.ONE)) {
-      throw new Error('acsc() only has non-complex values for |x| >= 1.');
-    }
-
-    Big.config({precision: precision + 2});
-    x = Big.ONE.div(x); 
-    Big.config({precision: precision});
-
-    absX = x.abs();
-  } else if (absX.gt(Big.ONE)) {
+  if (absX.gt(1)) {
     throw new Error('asin() only has non-complex values for |x| <= 1.');
   }
 
+  var precision = Big.precision;
+
   // Get x below 0.58
   if (absX.gt(0.8)) {
     Big.config({precision: precision + 4});
@@ -557,7 +538,7 @@ exports.arcsin_arccsc = function (x, reciprocal) {
     // arcsin(x) = sign(x)*(Pi/2 - arcsin(sqrt(1 - x^2)))
     var sign = x.s;
     var halfPi = exports.pi(precision + 4).div(2);
-    x = halfPi.minus(exports.arcsin_arccsc(Big.ONE.minus(x.times(x)).sqrt()));
+    x = halfPi.minus(exports.arcsin(Big.ONE.minus(x.times(x)).sqrt()));
     x.s = sign;
 
     x.constructor = Big;
@@ -587,22 +568,21 @@ exports.arcsin_arccsc = function (x, reciprocal) {
 };
 
 /**
- * Calculate the arctangent or arccotangent of x
+ * Calculate the arctangent of x
  *
  * @param {BigNumber} x
- * @param {Boolean} reciprocal  is cot
- * @returns {BigNumber} arctangent or arccotangent of x
+ * @returns {BigNumber} arctangent of x
  */
-exports.arctan_arccot = function (x, reciprocal) {
+exports.arctan = function (x) {
   var Big = x.constructor;
   if (x.isNaN()) {
     return new Big(NaN);
   }
-  if ((!reciprocal && x.isZero()) || (reciprocal && !x.isFinite())) {
+  if (x.isZero()) {
     return new Big(0);
   }
   var precision = Big.precision;
-  if ((!reciprocal && !x.isFinite()) || (reciprocal && x.isZero())) {
+  if (!x.isFinite()) {
     var halfPi = exports.pi(precision + 2).div(2).toDP(precision - 1);
     halfPi.s = x.s;
 
@@ -611,10 +591,6 @@ exports.arctan_arccot = function (x, reciprocal) {
 
   Big.config({precision: precision + 4});
 
-  if (reciprocal) {
-    x = Big.ONE.div(x);
-  }
-
   var absX = x.abs();
   if (absX.lte(0.875)) {
     var ret = arctan_taylor(x);
@@ -638,7 +614,7 @@ exports.arctan_arccot = function (x, reciprocal) {
   x = x.div(x.times(x).plus(1).sqrt());
 
   Big.config({precision: precision});
-  return exports.arcsin_arccsc(x, false);
+  return exports.arcsin(x);
 };
 
 /**


Test patch:
diff --git a/test/function/arithmetic/abs.test.js b/test/function/arithmetic/abs.test.js
index 51f3d2eb2..fa9945507 100644
--- a/test/function/arithmetic/abs.test.js
+++ b/test/function/arithmetic/abs.test.js
@@ -28,6 +28,8 @@ describe('abs', function () {
 
   it('should return the absolute value of a complex number', function () {
     assert.equal(math.abs(math.complex(3, -4)), 5);
+    assert.equal(math.abs(math.complex(1e200, -4e200)), 4.12310562561766e+200);
+    assert.equal(math.norm(math.complex(-4e200, 1e200)), 4.12310562561766e+200);
   });
 
   it('should return the absolute value of all elements in a matrix', function () {
diff --git a/test/function/arithmetic/norm.test.js b/test/function/arithmetic/norm.test.js
index 1ceb3107b..0ab222417 100644
--- a/test/function/arithmetic/norm.test.js
+++ b/test/function/arithmetic/norm.test.js
@@ -33,6 +33,8 @@ describe('norm', function () {
 
   it('should return the norm of a complex number', function () {
     assert.equal(math.norm(math.complex(3, -4)), 5);
+    assert.equal(math.norm(math.complex(1e200, -4e200)), 4.12310562561766e+200);
+    assert.equal(math.norm(math.complex(-4e200, 1e200)), 4.12310562561766e+200);
   });
 
   it('should return the norm of a vector', function () {
diff --git a/test/function/trigonometry/acosh.test.js b/test/function/trigonometry/acosh.test.js
index 3168fffff..0e996f2ed 100644
--- a/test/function/trigonometry/acosh.test.js
+++ b/test/function/trigonometry/acosh.test.js
@@ -14,21 +14,16 @@ var assert = require('assert'),
 describe('acosh', function() {
   it('should return the hyperbolic arccos of a boolean', function () {
     assert.equal(acosh(true), 0);
-    approx.deepEqual(acosh(false), complex(0, pi / 2));
-    //assert.ok(isNaN(acosh(false)));
+    assert.ok(isNaN(acosh(false)));
   });
 
   it('should return the hyperbolic arccos of null', function () {
-    approx.deepEqual(acosh(null), complex(0, pi / 2));
-    //assert.ok(isNaN(acosh(null)));
+    assert.ok(isNaN(acosh(null)));
   });
 
   it('should return the hyperbolic arccos of a number', function() {
-    approx.deepEqual(acosh(-2), complex(1.31695789692481670862504634730797, pi));
-    approx.deepEqual(acosh(0), complex(0, pi / 2));
-    //assert.ok(isNaN(acosh(-2)));
-    //assert.ok(isNaN(acosh(0)));
-
+    assert.ok(isNaN(acosh(-1.5)));
+    assert.ok(isNaN(acosh(0)));
     approx.equal(acosh(1), 0);
     approx.equal(acosh(2), 1.31695789692481670862504634730797);
     approx.equal(acosh(3), 1.7627471740390860504652186499595);
@@ -65,14 +60,11 @@ describe('acosh', function() {
     //assert.deepEqual(acosh(bigmath.cosh(Big(0.5))), Big(0.5));
   });
 
-  it('should throw an error if the bignumber result is complex', function() {
+/*it('should throw an error if the bignumber result is complex', function() {
     assert.throws(function () {
       acosh(Big(0.5));
-    }, /acosh\(\) only has non-complex values for x >= 1./);
-    assert.throws(function () {
-      acosh(Big(-0.5));
-    }, /acosh\(\) only has non-complex values for x >= 1./);
-  });
+    }, /acosh() only has non-complex values for x >= 1./);
+  });*/
 
   it('should return the arccosh of a complex number', function() {
     approx.deepEqual(acosh(complex('2+3i')), complex(1.9833870299165, 1.000143542473797));
diff --git a/test/function/trigonometry/acot.test.js b/test/function/trigonometry/acot.test.js
deleted file mode 100644
index 7788f669d..000000000
--- a/test/function/trigonometry/acot.test.js
+++ /dev/null
@@ -1,113 +0,0 @@
-var assert = require('assert'),
-    error = require('../../../lib/error/index'),
-    math = require('../../../index'),
-    approx = require('../../../tools/approx'),
-    pi = math.pi,
-    complex = math.complex,
-    matrix = math.matrix,
-    unit = math.unit,
-    acot = math.acot,
-    cot = math.cot,
-    bigmath = math.create({number: 'bignumber', precision: 20}),
-    Big = bigmath.bignumber;
-
-describe('acot', function() {
-  it('should return the arccot of a boolean', function () {
-    approx.equal(acot(true), pi / 4);
-    assert.equal(acot(false), pi / 2);
-  });
-
-  it('should return the arccot of null', function () {
-    assert.equal(acot(null), pi / 2);
-  });
-
-  it('should return the arccot of a number', function() {
-    approx.equal(acot(-1) / pi, -0.25);
-    approx.equal(acot(-0.5), -1.107148717794);
-    assert.equal(acot(0), pi / 2);
-    approx.equal(acot(0.5), 1.107148717794);
-    approx.equal(acot(1) / pi, 0.25);
-
-    assert.equal(acot(-Infinity), 0);
-    assert.equal(acot(Infinity), 0);
-  });
-
-  it('should return the arccot of a bignumber', function() {
-    var arg2 = Big(-1);
-    var arg3 = Big(-0.5);
-    var arg4 = Big(0);
-    var arg7 = Big(2);
-    var arg8 = Big(Infinity);
-
-    assert.deepEqual(acot(Big(-2)), Big('-0.4636476090008061162'));
-    assert.deepEqual(acot(arg2), Big('-0.7853981633974483096'));
-    assert.deepEqual(acot(arg3), Big('-1.107148717794090503'));
-    assert.deepEqual(acot(arg4).toString(), '1.5707963267948966192');
-    assert.deepEqual(acot(Big(1)), Big('0.7853981633974483096'));
-    assert.deepEqual(acot(arg7), Big('0.4636476090008061162'));
-    assert.deepEqual(acot(arg8), Big(0));
-
-    // Ensure the arguments where not changed
-    assert.deepEqual(arg2, Big(-1));
-    assert.deepEqual(arg3, Big(-0.5));
-    assert.deepEqual(arg4, Big(0));
-    assert.deepEqual(arg7, Big(2));
-    assert.deepEqual(arg8, Big(Infinity));
-
-    // Hit Newton's method case
-    bigmath.config({precision: 61});
-    assert.deepEqual(acot(Big(1.1)).toString(), '0.73781506012046491381362812980339020358273335525044448963405');
-  });
-
-  it('should be the inverse function of cot', function() {
-    approx.equal(acot(cot(-1)), -1);
-    approx.equal(acot(cot(0)), 0);
-    approx.equal(acot(cot(0.1)), 0.1);
-    approx.equal(acot(cot(0.5)), 0.5);
-    approx.equal(acot(cot(2)), -1.14159265358979);
-  });
-
-  it('should be the inverse function of bignumber cot', function() {
-    bigmath.config({precision: 20});
-    assert.deepEqual(acot(bigmath.cot(Big(-1))).toString(), '-1');
-    assert.ok(acot(bigmath.cot(Big(0))).isZero());
-    assert.deepEqual(acot(bigmath.cot(Big(0.1))).toString(), '0.1');
-    assert.deepEqual(acot(bigmath.cot(Big(0.5))).toString(), '0.5');
-    assert.deepEqual(acot(bigmath.cot(Big(2))).toString(), '-1.1415926535897932385');
-    assert.deepEqual(acot(bigmath.cot(bigmath.pi.div(2))).toString(), '1.5707963267948966192');
-  });
-
-  it('should return the arccot of a complex number', function() {
-    var re = 0.160875277198321;
-    var im = 0.229072682968539;
-    approx.deepEqual(acot(complex('2+3i')), complex(re, -im));
-    approx.deepEqual(acot(complex('2-3i')), complex(re, im));
-    approx.deepEqual(acot(complex('-2+3i')), complex(-re, -im));
-    approx.deepEqual(acot(complex('-2-3i')), complex(-re, im));
-    approx.deepEqual(acot(complex('i')), complex(0, -Infinity));
-    approx.deepEqual(acot(complex('1')), complex(pi / 4, 0));
-    approx.deepEqual(acot(complex('1+i')), complex(0.553574358897, -0.4023594781085));
-  });
-
-  it('should throw an error if called with a unit', function() {
-    assert.throws(function () {acot(unit('45deg'))});
-    assert.throws(function () {acot(unit('5 celsius'))});
-  });
-
-  it('should throw an error if called with a string', function() {
-    assert.throws(function () {acot('string')});
-  });
-
-  it('should calculate the arccot element-wise for arrays and matrices', function() {
-    // matrix, array, range
-    var acot123 = [pi / 4, 0.4636476090008, 0.3217505543966];
-    approx.deepEqual(acot([1,2,3]), acot123);
-    approx.deepEqual(acot(matrix([1,2,3])), matrix(acot123));
-  });
-
-  it('should throw an error in case of invalid number of arguments', function() {
-    assert.throws(function () {acot()}, error.ArgumentsError);
-    assert.throws(function () {acot(1, 2)}, error.ArgumentsError);
-  });
-
-});
diff --git a/test/function/trigonometry/acoth.test.js b/test/function/trigonometry/acoth.test.js
index 06dcc3d8d..498bb39cf 100644
--- a/test/function/trigonometry/acoth.test.js
+++ b/test/function/trigonometry/acoth.test.js
@@ -14,20 +14,17 @@ var assert = require('assert'),
 describe('acoth', function() {
   it('should return the hyperbolic arccot of a boolean', function () {
     assert.equal(acoth(true), Infinity);
-    approx.deepEqual(acoth(false), complex(0, pi / 2));
-    //assert.ok(isNaN(acoth(false)));
+    assert.ok(isNaN(acoth(false)));
   });
 
   it('should return the hyperbolic arccot of null', function () {
-    approx.deepEqual(acoth(null), complex(0, pi / 2));
-    //assert.ok(isNaN(acoth(null)));
+    assert.ok(isNaN(acoth(null)));
   });
 
   it('should return the hyperbolic arccot of a number', function() {
-    approx.deepEqual(acoth(0), complex(0, pi / 2));
-    approx.deepEqual(acoth(0.5), complex(0.5493061443340548, -1.5707963267949));
-    //assert.ok(isNaN(acoth(0)));
-    //assert.ok(isNaN(acoth(0.5)));
+    assert.ok(isNaN(acoth(-0.5)));
+    assert.ok(isNaN(acoth(0)));
+    assert.ok(isNaN(acoth(0.5)));
 
     approx.equal(acoth(-2), -0.54930614433405484569762261846);
     assert.equal(acoth(-1), -Infinity);
diff --git a/test/function/trigonometry/acsc.test.js b/test/function/trigonometry/acsc.test.js
deleted file mode 100644
index e9a2057de..000000000
--- a/test/function/trigonometry/acsc.test.js
+++ /dev/null
@@ -1,138 +0,0 @@
-var assert = require('assert'),
-    error = require('../../../lib/error/index'),
-    math = require('../../../index'),
-    approx = require('../../../tools/approx'),
-    pi = math.pi,
-    complex = math.complex,
-    matrix = math.matrix,
-    unit = math.unit,
-    acsc = math.acsc,
-    csc = math.csc,
-    bigmath = math.create({number: 'bignumber', precision: 20}),
-    Big = bigmath.bignumber;
-
-describe('acsc', function() {
-  it('should return the arccsc of a boolean', function () {
-    approx.equal(acsc(true), pi / 2);
-    assert.ok(isNaN(acsc(false)));
-    //assert.deepEqual(acsc(false), complex(0, Infinity));
-  });
-
-  it('should return the arccsc of null', function () {
-    assert.ok(isNaN(acsc(null)));
-    //assert.deepEqual(acsc(null), complex(0, Infinity));
-  });
-
-  it('should return the arccsc of a number', function() {
-    approx.equal(acsc(-2) / pi, -1/6);
-    approx.equal(acsc(-1) / pi, -0.5);
-    assert.ok(isNaN(acsc(0)));
-    //assert.deepEqual(acsc(0), complex(0, Infinity));
-    approx.equal(acsc(1) / pi, 0.5);
-    approx.equal(acsc(2) / pi, 1/6);
-  });
-
-  it('should return the arccsc of a bignumber', function() {
-    var arg1 = Big(-2);
-    var arg2 = Big(-1.71);
-    var arg3 = Big(-1);
-
-    assert.deepEqual(acsc(arg1), Big('-0.5235987755982988731'));
-    assert.deepEqual(acsc(arg2), Big('-0.624627713324716013'));
-    assert.deepEqual(acsc(arg3), Big('-1.5707963267948966192'));
-    assert.deepEqual(acsc(Big(1)), Big('1.5707963267948966192'));
-    assert.deepEqual(acsc(Big(1.71)), Big('0.624627713324716013'));
-    assert.deepEqual(acsc(Big(2)), Big('0.5235987755982988731'));
-
-    // Make sure args were not changed
-    assert.deepEqual(arg1, Big(-2));
-    assert.deepEqual(arg2, Big(-1.71));
-    assert.deepEqual(arg3, Big(-1));
-
-    // Hit Newton's method case
-    bigmath.config({precision: 61});
-
-    var arg4 = Big(1.00000001);
-    assert.deepEqual(acsc(arg4).toString(), '1.570654905439248565373629613450057180739125884090554026623514');
-    assert.deepEqual(arg4, Big(1.00000001));
-  });
-
-  it('should be the inverse function of csc', function() {
-    approx.equal(acsc(csc(-1)), -1);
-    approx.equal(acsc(csc(0)), 0);
-    approx.equal(acsc(csc(0.1)), 0.1);
-    approx.equal(acsc(csc(0.5)), 0.5);
-    approx.equal(acsc(csc(2)), 1.14159265358979);
-  });
-
-  it('should be the inverse function of bignumber csc', function() {
-    // More Newton's method test cases
-    assert.deepEqual(acsc(bigmath.csc(Big(-2))).toString(), '-1.141592653589793238462643383279502884197169399375105820974945');
-    assert.deepEqual(acsc(bigmath.csc(Big(-0.5))).toString(), '-0.5');
-    assert.deepEqual(acsc(bigmath.csc(Big(-0.1))).toString(), '-0.1');
-    assert.deepEqual(acsc(bigmath.csc(Big(0.1))).toString(), '0.1');
-    assert.deepEqual(acsc(bigmath.csc(Big(0.5))).toString(), '0.5');
-    assert.deepEqual(acsc(bigmath.csc(Big(2))).toString(), '1.141592653589793238462643383279502884197169399375105820974945');
-
-    bigmath.config({precision: 20});
-    // Full decimal Taylor test cases
-    /* csc(-1) =                      -0.8414709848078965067
-       acsc(-0.8414709848078965067) = -1.00000000000000000008 => (rounding up) -1.0000000000000000001
-    assert.deepEqual(acsc(bigmath.csc(Big(-1))), Big('-1')); */
-
-    assert.ok(acsc(bigmath.csc(Big(0))).isZero());
-    assert.deepEqual(acsc(bigmath.csc(Big(0.1))).toString(), '0.1');
-    assert.deepEqual(acsc(bigmath.csc(Big(0.5))).toString(), '0.5');
-    //assert.deepEqual(acsc(bigmath.csc(Big(2))).toString(), '1.1415926535897932385');
-  });
-
-  it('should throw an error if the bignumber result is complex', function() {
-    assert.throws(function () {
-      acsc(Big(0.5));
-    }, /acsc() only has non-complex values for |x| >= 1./);
-    assert.throws(function () {
-      acsc(Big(0));
-    }, /acsc() only has non-complex values for |x| >= 1./);
-    assert.throws(function () {
-      acsc(Big(-0.5));
-    }, /acsc() only has non-complex values for |x| >= 1./);
-  });
-
-  it('should return the arccsc of a complex number', function() {
-    var re = 0.150385604327861963;
-    var im = 0.231334698573973315;
-    approx.deepEqual(acsc(complex('2+3i')), complex(re, -im));
-    approx.deepEqual(acsc(complex('2-3i')), complex(re, im));
-    approx.deepEqual(acsc(complex('-2+3i')), complex(-re, -im));
-    approx.deepEqual(acsc(complex('-2-3i')), complex(-re, im));
-    approx.deepEqual(acsc(complex('1+i')), complex(0.4522784471511907,-0.53063753095251783));
-    approx.deepEqual(acsc(complex('i')), complex(0, -0.881373587019543));
-
-    approx.deepEqual(acsc(complex('-1')), complex(-pi / 2, 0));
-    approx.deepEqual(acsc(complex('-0.5')), complex(-pi / 2, 1.3169578969248));
-    assert.deepEqual(acsc(complex('0')), complex(pi / 2, Infinity));
-    approx.deepEqual(acsc(complex('0.5')), complex(pi / 2, -1.3169578969248));
-    approx.deepEqual(acsc(complex('1')), complex(pi / 2, 0));
-  });
-
-  it('should throw an error if called with a unit', function() {
-    assert.throws(function () {acsc(unit('45deg'))});
-    assert.throws(function () {acsc(unit('5 celsius'))});
-  });
-
-  it('should throw an error if called with a string', function() {
-    assert.throws(function () {acsc('string')});
-  });
-
-  it('should calculate the arccsc element-wise for arrays and matrices', function() {
-    var acsc123 = [pi / 2, pi / 6, 0.339836909454];
-    approx.deepEqual(acsc([1,2,3]), acsc123);
-    approx.deepEqual(acsc(matrix([1,2,3])), matrix(acsc123));
-  });
-
-  it('should throw an error in case of invalid number of arguments', function() {
-    assert.throws(function () {acsc()}, error.ArgumentsError);
-    assert.throws(function () {acsc(1, 2)}, error.ArgumentsError);
-  });
-
-});
diff --git a/test/function/trigonometry/asec.test.js b/test/function/trigonometry/asec.test.js
deleted file mode 100644
index c2b5d4820..000000000
--- a/test/function/trigonometry/asec.test.js
+++ /dev/null
@@ -1,114 +0,0 @@
-var assert = require('assert'),
-    error = require('../../../lib/error/index'),
-    math = require('../../../index'),
-    approx = require('../../../tools/approx'),
-    pi = math.pi,
-    asec = math.asec,
-    sec = math.sec,
-    complex = math.complex,
-    matrix = math.matrix,
-    unit = math.unit,
-    bigmath = math.create({number: 'bignumber', precision: 20}),
-    Big = bigmath.bignumber;
-
-describe('asec', function() {
-  it('should return the arcsec of a boolean', function () {
-    assert.equal(asec(true), 0);
-    assert.deepEqual(asec(false), complex(0, Infinity));
-    //assert.ok(isNaN(asec(false)));
-  });
-
-  it('should return the arcsec of null', function () {
-    assert.deepEqual(asec(null), complex(0, Infinity));
-    //assert.ok(isNaN(asec(null)));
-  });
-
-  it('should return the arcsec of a number', function() {
-    approx.equal(asec(-2) / pi, 2 / 3);
-    approx.equal(asec(-1) / pi, 1);
-    /*approx.equal(asec(-0.5) / pi, 2 / 3);
-    approx.equal(asec(0.5) / pi, 1 / 3);*/
-    approx.equal(asec(1) / pi, 0);
-    approx.equal(asec(2) / pi, 1 / 3);
-  });
-
-  it('should return the arcsec of a bignumber', function() {
-    var arg1 = Big(-2);
-    var arg2 = Big(-1);
-    assert.deepEqual(asec(arg1).toString(), bigmath.tau.div(3).toString());
-    assert.deepEqual(asec(arg2).toString(), bigmath.pi.toString());
-    assert.deepEqual(asec(Big(1)), Big(0));
-    assert.deepEqual(asec(Big(2)).toString(), bigmath.pi.div(3).toString());
-
-    // Hit Newton's method case
-    bigmath.config({precision: 61});
-    assert.deepEqual(asec(Big(3.00000001)).toString(), '1.230959418519285979938614206185297709155969929825366328254265');
-
-    //Make sure arg was not changed
-    assert.deepEqual(arg1, Big(-2));
-    assert.deepEqual(arg2, Big(-1));
-  });
-
-  it('should be the inverse function of sec', function() {
-    approx.equal(asec(sec(-1)), 1);
-    approx.equal(asec(sec(0)), 0);
-    approx.equal(asec(sec(0.1)), 0.1);
-    approx.equal(asec(sec(0.5)), 0.5);
-    approx.equal(asec(sec(2)), 2);
-  });
-
-  it('should be the inverse function of bignumber sec', function() {
-    bigmath.config({precision: 20});
-    assert.deepEqual(asec(bigmath.sec(Big(-1))).toString(), '1');
-    assert.ok(asec(bigmath.sec(Big(0))).isZero());
-    //assert.deepEqual(asec(bigmath.sec(Big(0.1))).toString(), '0.1');
-    assert.deepEqual(asec(bigmath.sec(Big(0.5))).toString(), '0.5');
-    assert.deepEqual(asec(bigmath.sec(Big(2))).toString(), '2');
-  });
-
-  it('should throw an error if the bignumber result is complex', function() {
-    assert.throws(function () {
-      asec(Big(0.5));
-    }, /asec() only has non-complex values for |x| >= 1./);
-    assert.throws(function () {
-      asec(Big(0));
-    }, /asec() only has non-complex values for |x| >= 1./);
-    assert.throws(function () {
-      asec(Big(-0.5));
-    }, /asec() only has non-complex values for |x| >= 1./);
-  });
-
-  it('should return the arcsec of a complex number', function() {
-    approx.deepEqual(asec(complex('2+3i')), complex(1.42041072246703,  0.23133469857397));
-    approx.deepEqual(asec(complex('2-3i')), complex(1.42041072246703, -0.23133469857397));
-    approx.deepEqual(asec(complex('-2+3i')), complex(1.7211819311228, 0.2313346985739733));
-    approx.deepEqual(asec(complex('-2-3i')), complex(1.7211819311228, -0.2313346985739733));
-    approx.deepEqual(asec(complex('i')), complex(1.570796326794897, 0.881373587019543));
-    approx.deepEqual(asec(complex('1+i')), complex(1.1185178796437059, 0.530637530952517826));
-    approx.deepEqual(asec(complex('1')), complex(0, 0));
-    approx.deepEqual(asec(complex('0.5')), complex(0, 1.3169578969248));
-    approx.deepEqual(asec(complex('0')), complex(0, Infinity));
-    approx.deepEqual(asec(complex('-0.5')), complex(pi, -1.3169578969248));
-  });
-
-  it('should throw an error if called with a unit', function() {
-    assert.throws(function () {asec(unit('45deg'))});
-    assert.throws(function () {asec(unit('5 celsius'))});
-  });
-
-  it('should throw an error if called with a string', function() {
-    assert.throws(function () {asec('string')});
-  });
-
-  it('should calculate the arcsec element-wise for arrays and matrices', function() {
-    var asec123 = [0, pi / 3, 1.23095941734077468];
-    approx.deepEqual(asec([1,2,3]), asec123);
-    approx.deepEqual(asec(matrix([1,2,3])), matrix(asec123));
-  });
-
-  it('should throw an error in case of invalid number of arguments', function() {
-    assert.throws(function () {asec()}, error.ArgumentsError);
-    assert.throws(function () {asec(1, 2)}, error.ArgumentsError);
-  });
-
-});
diff --git a/test/function/trigonometry/asech.test.js b/test/function/trigonometry/asech.test.js
index aaae77937..f8b2e2d32 100644
--- a/test/function/trigonometry/asech.test.js
+++ b/test/function/trigonometry/asech.test.js
@@ -2,7 +2,6 @@ var assert = require('assert'),
     error = require('../../../lib/error/index'),
     math = require('../../../index'),
     approx = require('../../../tools/approx'),
-    pi = math.pi,
     asech = math.asech,
     sech = math.sech,
     complex = math.complex,
@@ -22,10 +21,8 @@ describe('asech', function() {
   });
 
   it('should return the hyperbolic arcsec of a number', function() {
-    approx.deepEqual(asech(-0.5), complex(1.3169578969, pi));
-    approx.deepEqual(asech(2), complex(0, pi / 3));
-    //assert.ok(isNaN(asech(-0.5)));
-    //assert.ok(isNaN(asech(2)));
+    assert.ok(isNaN(asech(-1)));
+    assert.ok(isNaN(asech(1.1)));
 
     assert.equal(asech(0), Infinity);
     approx.equal(asech(0.25), 2.0634370688955605467272811726201);
@@ -67,14 +64,14 @@ describe('asech', function() {
     //assert.deepEqual(asech(bigmath.sech(Big(0.1))), Big(0.1));
   });
 
-  it('should throw an error if the bignumber result is complex', function() {
+/*it('should throw an error if the bignumber result is complex', function() {
     assert.throws(function () {
       asech(Big(-1));
-    }, /asech\(\) only has non-complex values for 0 <= x <= 1./);
+    }, /asech() only has non-complex values for 0 <= x <= 1./);
     assert.throws(function () {
       asech(Big(2));
-    }, /asech\(\) only has non-complex values for 0 <= x <= 1./);
-  });
+    }, /asech() only has non-complex values for 0 <= x <= 1./);
+  });*/
 
   it('should return the arcsech of a complex number', function() {
     approx.deepEqual(asech(complex('2+3i')), complex(0.23133469857397, -1.420410722467035));
@@ -83,12 +80,12 @@ describe('asech', function() {
     approx.deepEqual(asech(complex('-2-3i')), complex(0.23133469857397, 1.72118193112275858));
     approx.deepEqual(asech(complex('1+i')), complex(0.5306375309525178, -1.11851787964370594));
     approx.deepEqual(asech(complex('i')), complex(0.881373587019543, -1.570796326794897));
-    approx.deepEqual(asech(complex('2')), complex(0, pi / 3));
+    approx.deepEqual(asech(complex('2')), complex(0, math.pi / 3));
     assert.deepEqual(asech(complex('1')), complex(0, 0));
     approx.deepEqual(asech(complex('0.5')), complex(1.3169578969248, 0));
     assert.deepEqual(asech(complex('0')), complex(Infinity, 0));
-    approx.deepEqual(asech(complex('-0.5')), complex(1.3169578969248, pi));
-    approx.deepEqual(asech(complex('-1')), complex(0, pi));
+    approx.deepEqual(asech(complex('-0.5')), complex(1.3169578969248, math.pi));
+    approx.deepEqual(asech(complex('-1')), complex(0, math.pi));
   });
 
   it('should throw an error if called with a unit', function() {
diff --git a/test/function/trigonometry/asin.test.js b/test/function/trigonometry/asin.test.js
index ca5b136ed..7542e2959 100644
--- a/test/function/trigonometry/asin.test.js
+++ b/test/function/trigonometry/asin.test.js
@@ -34,9 +34,9 @@ describe('asin', function() {
     var arg2 = Big(-0.581);
     var arg3 = Big(-0.5);
 
-    assert.deepEqual(asin(arg1), Big('-1.5707963267948966192'));
-    assert.deepEqual(asin(arg2), Big('-0.6199567994522537004'));
-    assert.deepEqual(asin(arg3), Big('-0.5235987755982988731'));
+    assert.deepEqual(asin(Big(-1)), Big('-1.5707963267948966192'));
+    assert.deepEqual(asin(Big(-0.581)), Big('-0.6199567994522537004'));
+    assert.deepEqual(asin(Big(-0.5)), Big('-0.5235987755982988731'));
     assert.deepEqual(asin(Big(0)), Big(0));
     assert.deepEqual(asin(Big(0.5)), Big('0.5235987755982988731'));
     assert.deepEqual(asin(Big(0.581)), Big('0.6199567994522537004'));
diff --git a/test/function/trigonometry/atan.test.js b/test/function/trigonometry/atan.test.js
index 71ef530a8..1997bd859 100644
--- a/test/function/trigonometry/atan.test.js
+++ b/test/function/trigonometry/atan.test.js
@@ -77,8 +77,7 @@ describe('atan', function() {
     approx.deepEqual(atan(complex('2-3i')), complex(re, -im));
     approx.deepEqual(atan(complex('-2+3i')), complex(-re, im));
     approx.deepEqual(atan(complex('-2-3i')), complex(-re, -im));
-    approx.deepEqual(atan(complex('i')), complex(0, Infinity));
-    approx.deepEqual(atan(complex('-i')), complex(0, -Infinity));
+    approx.deepEqual(atan(complex('i')), complex(NaN, NaN)); // TODO: should return NaN + Infi instead
     approx.deepEqual(atan(complex('1')), complex(0.785398163397448, 0));
     approx.deepEqual(atan(complex('1+i')), complex(1.017221967897851, 0.402359478108525));
   });
diff --git a/test/function/trigonometry/atanh.test.js b/test/function/trigonometry/atanh.test.js
index 8af2906a7..e024c3c99 100644
--- a/test/function/trigonometry/atanh.test.js
+++ b/test/function/trigonometry/atanh.test.js
@@ -22,10 +22,8 @@ describe('atanh', function() {
   });
 
   it('should return the hyperbolic arctan of a number', function() {
-    approx.deepEqual(atanh(-2), complex(-0.54930614433405485, pi / 2));
-    approx.deepEqual(atanh(2),  complex(0.54930614433405485, -pi / 2));
-    //assert.ok(isNaN(atanh(-2)));
-    //assert.ok(isNaN(atanh(2)));
+    assert.ok(isNaN(atanh(-1.1)));
+    assert.ok(isNaN(atanh(1.1)));
 
     approx.equal(atanh(-1), -Infinity);
     approx.equal(atanh(-0.5), -0.54930614433405484569762261846);
@@ -82,11 +80,9 @@ describe('atanh', function() {
     approx.deepEqual(atanh(complex('-2-3i')), complex(-0.1469466662255, -1.33897252229449));
     approx.deepEqual(atanh(complex('1+i')), complex(0.402359478108525, 1.01722196789785137));
     approx.deepEqual(atanh(complex('i')), complex(0, pi / 4));
-
-    approx.deepEqual(atanh(complex('2')), complex(0.54930614433405485, -pi / 2));
+    approx.deepEqual(atanh(complex('2')), complex(0.54930614433405485, -1.5707963267948966));
     assert.deepEqual(atanh(complex('1')), complex(Infinity, 0));
     assert.deepEqual(atanh(complex('0')), complex(0, 0));
-    approx.deepEqual(atanh(complex('-2')), complex(-0.54930614433405485, pi / 2));
   });
 
   it('should throw an error if called with a unit', function() {