← Back to team overview

ubuntu-touch-coreapps-reviewers team mailing list archive

[Merge] lp:~gang65/ubuntu-calculator-app/ubuntu-calculator-app-math-2.4-upgrade into lp:ubuntu-calculator-app

 

Bartosz Kosiorek has proposed merging lp:~gang65/ubuntu-calculator-app/ubuntu-calculator-app-math-2.4-upgrade into lp:ubuntu-calculator-app.

Commit message:
Upgrade math.js to 2.4.0 to resolve wrong calculation of sin and cos functions,
for values around multiples of tau (i.e. sin(7)) (LP: #1507799)

Requested reviews:
  Ubuntu Calculator Developers (ubuntu-calculator-dev)
Related bugs:
  Bug #1507799 in Ubuntu Calculator App: "sin(12) and sin(13) are wrongly calculated"
  https://bugs.launchpad.net/ubuntu-calculator-app/+bug/1507799

For more details, see:
https://code.launchpad.net/~gang65/ubuntu-calculator-app/ubuntu-calculator-app-math-2.4-upgrade/+merge/274958

Upgrade math.js to 2.4.0 to resolve wrong calculation of sin and cos functions,
for values around multiples of tau (i.e. sin(7)) (LP: #1507799)
-- 
The attached diff has been truncated due to its size.
Your team Ubuntu Calculator Developers is requested to review the proposed merge of lp:~gang65/ubuntu-calculator-app/ubuntu-calculator-app-math-2.4-upgrade into lp:ubuntu-calculator-app.
=== modified file 'app/engine/math.js'
--- app/engine/math.js	2015-08-30 23:09:36 +0000
+++ app/engine/math.js	2015-10-19 22:38:24 +0000
@@ -14,8 +14,8 @@
  * It features real and complex numbers, units, matrices, a large set of
  * mathematical functions, and a flexible expression parser.
  *
- * @version 2.2.0
- * @date    2015-08-30
+ * @version 2.4.0
+ * @date    2015-10-09
  *
  * @license
  * Copyright (C) 2013-2015 Jos de Jong <wjosdejong@xxxxxxxxx>
@@ -133,10 +133,10 @@
 /* 2 */
 /***/ function(module, exports, __webpack_require__) {
 
-	var isFactory = __webpack_require__(5).isFactory;
-	var deepExtend = __webpack_require__(5).deepExtend;
-	var typedFactory = __webpack_require__(6);
-	var emitter = __webpack_require__(3);
+	var isFactory = __webpack_require__(3).isFactory;
+	var deepExtend = __webpack_require__(3).deepExtend;
+	var typedFactory = __webpack_require__(4);
+	var emitter = __webpack_require__(8);
 
 	var importFactory = __webpack_require__(10);
 	var configFactory = __webpack_require__(12);
@@ -261,101 +261,6 @@
 
 /***/ },
 /* 3 */
-/***/ function(module, exports, __webpack_require__) {
-
-	var Emitter = __webpack_require__(4);
-
-	/**
-	 * Extend given object with emitter functions `on`, `off`, `once`, `emit`
-	 * @param {Object} obj
-	 * @return {Object} obj
-	 */
-	exports.mixin = function (obj) {
-	  // create event emitter
-	  var emitter = new Emitter();
-
-	  // bind methods to obj (we don't want to expose the emitter.e Array...)
-	  obj.on   = emitter.on.bind(emitter);
-	  obj.off  = emitter.off.bind(emitter);
-	  obj.once = emitter.once.bind(emitter);
-	  obj.emit = emitter.emit.bind(emitter);
-
-	  return obj;
-	};
-
-
-/***/ },
-/* 4 */
-/***/ function(module, exports) {
-
-	function E () {
-		// Keep this empty so it's easier to inherit from
-	  // (via https://github.com/lipsmack from https://github.com/scottcorgan/tiny-emitter/issues/3)
-	}
-
-	E.prototype = {
-		on: function (name, callback, ctx) {
-	    var e = this.e || (this.e = {});
-	    
-	    (e[name] || (e[name] = [])).push({
-	      fn: callback,
-	      ctx: ctx
-	    });
-	    
-	    return this;
-	  },
-
-	  once: function (name, callback, ctx) {
-	    var self = this;
-	    var fn = function () {
-	      self.off(name, fn);
-	      callback.apply(ctx, arguments);
-	    };
-	    
-	    return this.on(name, fn, ctx);
-	  },
-
-	  emit: function (name) {
-	    var data = [].slice.call(arguments, 1);
-	    var evtArr = ((this.e || (this.e = {}))[name] || []).slice();
-	    var i = 0;
-	    var len = evtArr.length;
-	    
-	    for (i; i < len; i++) {
-	      evtArr[i].fn.apply(evtArr[i].ctx, data);
-	    }
-	    
-	    return this;
-	  },
-
-	  off: function (name, callback) {
-	    var e = this.e || (this.e = {});
-	    var evts = e[name];
-	    var liveEvents = [];
-	    
-	    if (evts && callback) {
-	      for (var i = 0, len = evts.length; i < len; i++) {
-	        if (evts[i].fn !== callback) liveEvents.push(evts[i]);
-	      }
-	    }
-	    
-	    // Remove event from queue to prevent memory leak
-	    // Suggested by https://github.com/lazd
-	    // Ref: https://github.com/scottcorgan/tiny-emitter/commit/c6ebfaa9bc973b33d110a84a307742b7cf94c953#commitcomment-5024910
-
-	    (liveEvents.length) 
-	      ? e[name] = liveEvents
-	      : delete e[name];
-	    
-	    return this;
-	  }
-	};
-
-	module.exports = E;
-
-
-/***/ },
-/* 5 */
 /***/ function(module, exports) {
 
 	'use strict';
@@ -602,11 +507,11 @@
 
 
 /***/ },
-/* 6 */
+/* 4 */
 /***/ function(module, exports, __webpack_require__) {
 
-	var typedFunction = __webpack_require__(7);
-	var digits = __webpack_require__(8).digits;
+	var typedFunction = __webpack_require__(5);
+	var digits = __webpack_require__(6).digits;
 
 	// returns a new instance of typed-function
 	var createTyped = function () {
@@ -765,7 +670,7 @@
 
 
 /***/ },
-/* 7 */
+/* 5 */
 /***/ function(module, exports, __webpack_require__) {
 
 	var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/**
@@ -2022,7 +1927,7 @@
 	     */
 	    function convert (value, type) {
 	      var from = getTypeOf(value);
-	      
+
 	      // check conversion is needed
 	      if (type === from) {
 	        return value;
@@ -2076,12 +1981,12 @@
 
 
 /***/ },
-/* 8 */
+/* 6 */
 /***/ function(module, exports, __webpack_require__) {
 
 	'use strict';
 
-	var NumberFormatter = __webpack_require__(9);
+	var NumberFormatter = __webpack_require__(7);
 
 	/**
 	 * Test whether value is a number
@@ -2343,7 +2248,7 @@
 
 
 /***/ },
-/* 9 */
+/* 7 */
 /***/ function(module, exports) {
 
 	'use strict';
@@ -2556,15 +2461,110 @@
 
 
 /***/ },
+/* 8 */
+/***/ function(module, exports, __webpack_require__) {
+
+	var Emitter = __webpack_require__(9);
+
+	/**
+	 * Extend given object with emitter functions `on`, `off`, `once`, `emit`
+	 * @param {Object} obj
+	 * @return {Object} obj
+	 */
+	exports.mixin = function (obj) {
+	  // create event emitter
+	  var emitter = new Emitter();
+
+	  // bind methods to obj (we don't want to expose the emitter.e Array...)
+	  obj.on   = emitter.on.bind(emitter);
+	  obj.off  = emitter.off.bind(emitter);
+	  obj.once = emitter.once.bind(emitter);
+	  obj.emit = emitter.emit.bind(emitter);
+
+	  return obj;
+	};
+
+
+/***/ },
+/* 9 */
+/***/ function(module, exports) {
+
+	function E () {
+		// Keep this empty so it's easier to inherit from
+	  // (via https://github.com/lipsmack from https://github.com/scottcorgan/tiny-emitter/issues/3)
+	}
+
+	E.prototype = {
+		on: function (name, callback, ctx) {
+	    var e = this.e || (this.e = {});
+	    
+	    (e[name] || (e[name] = [])).push({
+	      fn: callback,
+	      ctx: ctx
+	    });
+	    
+	    return this;
+	  },
+
+	  once: function (name, callback, ctx) {
+	    var self = this;
+	    var fn = function () {
+	      self.off(name, fn);
+	      callback.apply(ctx, arguments);
+	    };
+	    
+	    return this.on(name, fn, ctx);
+	  },
+
+	  emit: function (name) {
+	    var data = [].slice.call(arguments, 1);
+	    var evtArr = ((this.e || (this.e = {}))[name] || []).slice();
+	    var i = 0;
+	    var len = evtArr.length;
+	    
+	    for (i; i < len; i++) {
+	      evtArr[i].fn.apply(evtArr[i].ctx, data);
+	    }
+	    
+	    return this;
+	  },
+
+	  off: function (name, callback) {
+	    var e = this.e || (this.e = {});
+	    var evts = e[name];
+	    var liveEvents = [];
+	    
+	    if (evts && callback) {
+	      for (var i = 0, len = evts.length; i < len; i++) {
+	        if (evts[i].fn !== callback) liveEvents.push(evts[i]);
+	      }
+	    }
+	    
+	    // Remove event from queue to prevent memory leak
+	    // Suggested by https://github.com/lazd
+	    // Ref: https://github.com/scottcorgan/tiny-emitter/commit/c6ebfaa9bc973b33d110a84a307742b7cf94c953#commitcomment-5024910
+
+	    (liveEvents.length) 
+	      ? e[name] = liveEvents
+	      : delete e[name];
+	    
+	    return this;
+	  }
+	};
+
+	module.exports = E;
+
+
+/***/ },
 /* 10 */
 /***/ function(module, exports, __webpack_require__) {
 
 	'use strict';
 
-	var lazy = __webpack_require__(5).lazy;
-	var isFactory = __webpack_require__(5).isFactory;
-	var traverse = __webpack_require__(5).traverse;
-	var extend = __webpack_require__(5).extend;
+	var lazy = __webpack_require__(3).lazy;
+	var isFactory = __webpack_require__(3).isFactory;
+	var traverse = __webpack_require__(3).traverse;
+	var extend = __webpack_require__(3).extend;
 	var ArgumentsError = __webpack_require__(11);
 
 	function factory (type, config, load, typed, math) {
@@ -2863,7 +2863,7 @@
 
 	'use strict';
 
-	var object = __webpack_require__(5);
+	var object = __webpack_require__(3);
 
 	function factory (type, config, load, typed, math) {
 	  /**
@@ -2915,12 +2915,12 @@
 /***/ function(module, exports, __webpack_require__) {
 
 	module.exports = [
-	  __webpack_require__(244),        // data types (Matrix, Complex, Unit, ...)
-	  __webpack_require__(281),   // constants
-	  __webpack_require__(283),  // expression parsing
-	  __webpack_require__(14),    // functions
-	  __webpack_require__(489),        // serialization utility (math.json.reviver)
-	  __webpack_require__(491)        // errors
+	  __webpack_require__(14),        // data types (Matrix, Complex, Unit, ...)
+	  __webpack_require__(76),   // constants
+	  __webpack_require__(80),  // expression parsing
+	  __webpack_require__(312),    // functions
+	  __webpack_require__(495),        // serialization utility (math.json.reviver)
+	  __webpack_require__(497)        // errors
 	];
 
 
@@ -2929,20 +2929,16 @@
 /***/ function(module, exports, __webpack_require__) {
 
 	module.exports = [
-	  __webpack_require__(61),
-	  __webpack_require__(91),
-	  __webpack_require__(120),
-	  __webpack_require__(136),
-	  __webpack_require__(149),
-	  __webpack_require__(154),
-	  __webpack_require__(156),
 	  __webpack_require__(15),
-	  __webpack_require__(161),
-	  __webpack_require__(173),
-	  __webpack_require__(179),
-	  __webpack_require__(191),
-	  __webpack_require__(232),
-	  __webpack_require__(234)
+	  __webpack_require__(20),
+	  __webpack_require__(21),
+	  __webpack_require__(26),
+	  __webpack_require__(31),
+	  __webpack_require__(37),
+	  __webpack_require__(69),
+	  __webpack_require__(70),
+	  __webpack_require__(72),
+	  __webpack_require__(73)
 	];
 
 
@@ -2951,23 +2947,11 @@
 /***/ function(module, exports, __webpack_require__) {
 
 	module.exports = [
+	  // type
 	  __webpack_require__(16),
-	  __webpack_require__(24),
-	  __webpack_require__(43),
-	  __webpack_require__(46),
-	  __webpack_require__(47),
-	  __webpack_require__(48),
-	  __webpack_require__(49),
-	  __webpack_require__(50),
-	  __webpack_require__(52),
-	  __webpack_require__(53),
-	  __webpack_require__(54),
-	  __webpack_require__(55),
-	  __webpack_require__(56),
-	  __webpack_require__(57),
-	  __webpack_require__(58),
-	  __webpack_require__(59),
-	  __webpack_require__(60)
+
+	  // construction function
+	  __webpack_require__(18)
 	];
 
 
@@ -2975,28177 +2959,8 @@
 /* 16 */
 /***/ function(module, exports, __webpack_require__) {
 
-	'use strict';
-
-	var clone = __webpack_require__(5).clone;
-	var isInteger = __webpack_require__(8).isInteger;
-	var array = __webpack_require__(18);
-	var IndexError = __webpack_require__(17);
-	var DimensionError = __webpack_require__(22);
-
-	function factory (type, config, load, typed) {
-	  var matrix = load(__webpack_require__(23));
-
-	  /**
-	   * Concatenate two or more matrices.
-	   *
-	   * Syntax:
-	   *
-	   *     math.concat(A, B, C, ...)
-	   *     math.concat(A, B, C, ..., dim)
-	   *
-	   * Where:
-	   *
-	   * - `dim: number` is a zero-based dimension over which to concatenate the matrices.
-	   *   By default the last dimension of the matrices.
-	   *
-	   * Examples:
-	   *
-	   *    var A = [[1, 2], [5, 6]];
-	   *    var B = [[3, 4], [7, 8]];
-	   *
-	   *    math.concat(A, B);                  // returns [[1, 2, 3, 4], [5, 6, 7, 8]]
-	   *    math.concat(A, B, 0);               // returns [[1, 2], [5, 6], [3, 4], [7, 8]]
-	   *    math.concat('hello', ' ', 'world'); // returns 'hello world'
-	   *
-	   * See also:
-	   *
-	   *    size, squeeze, subset, transpose
-	   *
-	   * @param {... Array | Matrix} args     Two or more matrices
-	   * @return {Array | Matrix} Concatenated matrix
-	   */
-	  var concat = typed('concat', {
-	    // TODO: change signature to '...Array | Matrix, dim?' when supported
-	    '...Array | Matrix | number | BigNumber': function (args) {
-	      var i;
-	      var len = args.length;
-	      var dim = -1;  // zero-based dimension
-	      var prevDim;
-	      var asMatrix = false;
-	      var matrices = [];  // contains multi dimensional arrays
-
-	      for (i = 0; i < len; i++) {
-	        var arg = args[i];
-
-	        // test whether we need to return a Matrix (if not we return an Array)
-	        if (arg && arg.isMatrix === true) {
-	          asMatrix = true;
-	        }
-
-	        if (typeof arg === 'number' || (arg && arg.isBigNumber === true)) {
-	          if (i !== len - 1) {
-	            throw new Error('Dimension must be specified as last argument');
-	          }
-
-	          // last argument contains the dimension on which to concatenate
-	          prevDim = dim;
-	          dim = arg.valueOf(); // change BigNumber to number
-
-	          if (!isInteger(dim)) {
-	            throw new TypeError('Integer number expected for dimension');
-	          }
-
-	          if (dim < 0) {
-	            // TODO: would be more clear when throwing a DimensionError here
-	            throw new IndexError(dim);
-	          }
-	          if (i > 0 && dim > prevDim) {
-	            // TODO: would be more clear when throwing a DimensionError here
-	            throw new IndexError(dim, prevDim + 1);
-	          }
-	        }
-	        else {
-	          // this is a matrix or array
-	          var m = clone(arg).valueOf();
-	          var size = array.size(m);
-	          matrices[i] = m;
-	          prevDim = dim;
-	          dim = size.length - 1;
-
-	          // verify whether each of the matrices has the same number of dimensions
-	          if (i > 0 && dim != prevDim) {
-	            throw new DimensionError(prevDim + 1, dim + 1);
-	          }
-	        }
-	      }
-
-	      if (matrices.length == 0) {
-	        throw new SyntaxError('At least one matrix expected');
-	      }
-
-	      var res = matrices.shift();
-	      while (matrices.length) {
-	        res = _concat(res, matrices.shift(), dim, 0);
-	      }
-
-	      return asMatrix ? matrix(res) : res;
-	    },
-
-	    '...string': function (args) {
-	      return args.join('');
-	    }
-	  });
-
-	  concat.toTex = '\\mathrm{${name}}\\left(${args}\\right)';
-
-	  return concat;
-	}
-
-	/**
-	 * Recursively concatenate two matrices.
-	 * The contents of the matrices is not cloned.
-	 * @param {Array} a             Multi dimensional array
-	 * @param {Array} b             Multi dimensional array
-	 * @param {number} concatDim    The dimension on which to concatenate (zero-based)
-	 * @param {number} dim          The current dim (zero-based)
-	 * @return {Array} c            The concatenated matrix
-	 * @private
-	 */
-	function _concat(a, b, concatDim, dim) {
-	  if (dim < concatDim) {
-	    // recurse into next dimension
-	    if (a.length != b.length) {
-	      throw new DimensionError(a.length, b.length);
-	    }
-
-	    var c = [];
-	    for (var i = 0; i < a.length; i++) {
-	      c[i] = _concat(a[i], b[i], concatDim, dim + 1);
-	    }
-	    return c;
-	  }
-	  else {
-	    // concatenate this dimension
-	    return a.concat(b);
-	  }
-	}
-
-	exports.name = 'concat';
-	exports.factory = factory;
-
-
-/***/ },
-/* 17 */
-/***/ function(module, exports) {
-
-	'use strict';
-
-	/**
-	 * Create a range error with the message:
-	 *     'Index out of range (index < min)'
-	 *     'Index out of range (index < max)'
-	 *
-	 * @param {number} index     The actual index
-	 * @param {number} [min=0]   Minimum index (included)
-	 * @param {number} [max]     Maximum index (excluded)
-	 * @extends RangeError
-	 */
-	function IndexError(index, min, max) {
-	  if (!(this instanceof IndexError)) {
-	    throw new SyntaxError('Constructor must be called with the new operator');
-	  }
-
-	  this.index = index;
-	  if (arguments.length < 3) {
-	    this.min = 0;
-	    this.max = min;
-	  }
-	  else {
-	    this.min = min;
-	    this.max = max;
-	  }
-
-	  if (this.min !== undefined && this.index < this.min) {
-	    this.message = 'Index out of range (' + this.index + ' < ' + this.min + ')';
-	  }
-	  else if (this.max !== undefined && this.index >= this.max) {
-	    this.message = 'Index out of range (' + this.index + ' > ' + (this.max - 1) + ')';
-	  }
-	  else {
-	    this.message = 'Index out of range (' + this.index + ')';
-	  }
-
-	  this.stack = (new Error()).stack;
-	}
-
-	IndexError.prototype = new RangeError();
-	IndexError.prototype.constructor = RangeError;
-	IndexError.prototype.name = 'IndexError';
-	IndexError.prototype.isIndexError = true;
-
-	module.exports = IndexError;
-
-
-/***/ },
-/* 18 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	var number = __webpack_require__(8);
-	var string = __webpack_require__(20);
-	var object = __webpack_require__(5);
-	var types = __webpack_require__(19);
-
-	var DimensionError = __webpack_require__(22);
-	var IndexError = __webpack_require__(17);
-
-	/**
-	 * Calculate the size of a multi dimensional array.
-	 * This function checks the size of the first entry, it does not validate
-	 * whether all dimensions match. (use function `validate` for that)
-	 * @param {Array} x
-	 * @Return {Number[]} size
-	 */
-	exports.size = function (x) {
-	  var s = [];
-
-	  while (Array.isArray(x)) {
-	    s.push(x.length);
-	    x = x[0];
-	  }
-
-	  return s;
-	};
-
-	/**
-	 * Recursively validate whether each element in a multi dimensional array
-	 * has a size corresponding to the provided size array.
-	 * @param {Array} array    Array to be validated
-	 * @param {number[]} size  Array with the size of each dimension
-	 * @param {number} dim   Current dimension
-	 * @throws DimensionError
-	 * @private
-	 */
-	function _validate(array, size, dim) {
-	  var i;
-	  var len = array.length;
-
-	  if (len != size[dim]) {
-	    throw new DimensionError(len, size[dim]);
-	  }
-
-	  if (dim < size.length - 1) {
-	    // recursively validate each child array
-	    var dimNext = dim + 1;
-	    for (i = 0; i < len; i++) {
-	      var child = array[i];
-	      if (!Array.isArray(child)) {
-	        throw new DimensionError(size.length - 1, size.length, '<');
-	      }
-	      _validate(array[i], size, dimNext);
-	    }
-	  }
-	  else {
-	    // last dimension. none of the childs may be an array
-	    for (i = 0; i < len; i++) {
-	      if (Array.isArray(array[i])) {
-	        throw new DimensionError(size.length + 1, size.length, '>');
-	      }
-	    }
-	  }
-	}
-
-	/**
-	 * Validate whether each element in a multi dimensional array has
-	 * a size corresponding to the provided size array.
-	 * @param {Array} array    Array to be validated
-	 * @param {number[]} size  Array with the size of each dimension
-	 * @throws DimensionError
-	 */
-	exports.validate = function(array, size) {
-	  var isScalar = (size.length == 0);
-	  if (isScalar) {
-	    // scalar
-	    if (Array.isArray(array)) {
-	      throw new DimensionError(array.length, 0);
-	    }
-	  }
-	  else {
-	    // array
-	    _validate(array, size, 0);
-	  }
-	};
-
-	/**
-	 * Test whether index is an integer number with index >= 0 and index < length
-	 * @param {number} index    Zero-based index
-	 * @param {number} [length] Length of the array
-	 */
-	exports.validateIndex = function(index, length) {
-	  if (!number.isNumber(index) || !number.isInteger(index)) {
-	    throw new TypeError('Index must be an integer (value: ' + index + ')');
-	  }
-	  if (index < 0) {
-	    throw new IndexError(index);
-	  }
-	  if (length !== undefined && index >= length) {
-	    throw new IndexError(index, length);
-	  }
-	};
-
-	// a constant used to specify an undefined defaultValue
-	exports.UNINITIALIZED = {};
-
-	/**
-	 * Resize a multi dimensional array. The resized array is returned.
-	 * @param {Array} array         Array to be resized
-	 * @param {Array.<number>} size Array with the size of each dimension
-	 * @param {*} [defaultValue=0]  Value to be filled in in new entries,
-	 *                              zero by default. To leave new entries undefined,
-	 *                              specify array.UNINITIALIZED as defaultValue
-	 * @return {Array} array         The resized array
-	 */
-	exports.resize = function(array, size, defaultValue) {
-	  // TODO: add support for scalars, having size=[] ?
-
-	  // check the type of the arguments
-	  if (!Array.isArray(array) || !Array.isArray(size)) {
-	    throw new TypeError('Array expected');
-	  }
-	  if (size.length === 0) {
-	    throw new Error('Resizing to scalar is not supported');
-	  }
-
-	  // check whether size contains positive integers
-	  size.forEach(function (value) {
-	    if (!number.isNumber(value) || !number.isInteger(value) || value < 0) {
-	      throw new TypeError('Invalid size, must contain positive integers ' +
-	          '(size: ' + string.format(size) + ')');
-	    }
-	  });
-
-	  // recursively resize the array
-	  var _defaultValue = (defaultValue !== undefined) ? defaultValue : 0;
-	  _resize(array, size, 0, _defaultValue);
-
-	  return array;
-	};
-
-	/**
-	 * Recursively resize a multi dimensional array
-	 * @param {Array} array         Array to be resized
-	 * @param {number[]} size       Array with the size of each dimension
-	 * @param {number} dim          Current dimension
-	 * @param {*} [defaultValue]    Value to be filled in in new entries,
-	 *                              undefined by default.
-	 * @private
-	 */
-	function _resize (array, size, dim, defaultValue) {
-	  var i;
-	  var elem;
-	  var oldLen = array.length;
-	  var newLen = size[dim];
-	  var minLen = Math.min(oldLen, newLen);
-
-	  // apply new length
-	  array.length = newLen;
-
-	  if (dim < size.length - 1) {
-	    // non-last dimension
-	    var dimNext = dim + 1;
-
-	    // resize existing child arrays
-	    for (i = 0; i < minLen; i++) {
-	      // resize child array
-	      elem = array[i];
-	      if (!Array.isArray(elem)) {
-	        elem = [elem]; // add a dimension
-	        array[i] = elem;
-	      }
-	      _resize(elem, size, dimNext, defaultValue);
-	    }
-
-	    // create new child arrays
-	    for (i = minLen; i < newLen; i++) {
-	      // get child array
-	      elem = [];
-	      array[i] = elem;
-
-	      // resize new child array
-	      _resize(elem, size, dimNext, defaultValue);
-	    }
-	  }
-	  else {
-	    // last dimension
-
-	    // remove dimensions of existing values
-	    for (i = 0; i < minLen; i++) {
-	      while (Array.isArray(array[i])) {
-	        array[i] = array[i][0];
-	      }
-	    }
-
-	    if(defaultValue !== exports.UNINITIALIZED) {
-	      // fill new elements with the default value
-	      for (i = minLen; i < newLen; i++) {
-	        array[i] = object.clone(defaultValue);
-	      }
-	    }
-	  }
-	}
-
-	/**
-	 * Squeeze a multi dimensional array
-	 * @param {Array} array
-	 * @param {Array} [size]
-	 * @returns {Array} returns the array itself
-	 */
-	exports.squeeze = function(array, size) {
-	  var s = size || exports.size(array);
-
-	  // squeeze outer dimensions
-	  while (Array.isArray(array) && array.length === 1) {
-	    array = array[0];
-	    s.shift();
-	  }
-
-	  // find the first dimension to be squeezed
-	  var dims = s.length;
-	  while (s[dims - 1] === 1) {
-	    dims--;
-	  }
-
-	  // squeeze inner dimensions
-	  if (dims < s.length) {
-	    array = _squeeze(array, dims, 0);
-	    s.length = dims;
-	  }
-
-	  return array;
-	};
-
-	/**
-	 * Recursively squeeze a multi dimensional array
-	 * @param {Array} array
-	 * @param {number} dims Required number of dimensions
-	 * @param {number} dim  Current dimension
-	 * @returns {Array | *} Returns the squeezed array
-	 * @private
-	 */
-	function _squeeze (array, dims, dim) {
-	  var i, ii;
-
-	  if (dim < dims) {
-	    var next = dim + 1;
-	    for (i = 0, ii = array.length; i < ii; i++) {
-	      array[i] = _squeeze(array[i], dims, next);
-	    }
-	  }
-	  else {
-	    while (Array.isArray(array)) {
-	      array = array[0];
-	    }
-	  }
-
-	  return array;
-	}
-
-	/**
-	 * Unsqueeze a multi dimensional array: add dimensions when missing
-	 * @param {Array} array
-	 * @param {number} dims     Desired number of dimensions of the array
-	 * @param {number} [outer]  Number of outer dimensions to be added
-	 * @param {Array} [size]    Current size of array
-	 * @returns {Array} returns the array itself
-	 * @private
-	 */
-	exports.unsqueeze = function(array, dims, outer, size) {
-	  var s = size || exports.size(array);
-
-	  // unsqueeze outer dimensions
-	  if (outer) {
-	    for (var i = 0; i < outer; i++) {
-	      array = [array];
-	      s.unshift(1);
-	    }
-	  }
-
-	  // unsqueeze inner dimensions
-	  array = _unsqueeze(array, dims, 0);
-	  while (s.length < dims) {
-	    s.push(1);
-	  }
-
-	  return array;
-	};
-
-	/**
-	 * Recursively unsqueeze a multi dimensional array
-	 * @param {Array} array
-	 * @param {number} dims Required number of dimensions
-	 * @param {number} dim  Current dimension
-	 * @returns {Array | *} Returns the squeezed array
-	 * @private
-	 */
-	function _unsqueeze (array, dims, dim) {
-	  var i, ii;
-
-	  if (Array.isArray(array)) {
-	    var next = dim + 1;
-	    for (i = 0, ii = array.length; i < ii; i++) {
-	      array[i] = _unsqueeze(array[i], dims, next);
-	    }
-	  }
-	  else {
-	    for (var d = dim; d < dims; d++) {
-	      array = [array];
-	    }
-	  }
-
-	  return array;
-	}
-	/**
-	 * Flatten a multi dimensional array, put all elements in a one dimensional
-	 * array
-	 * @param {Array} array   A multi dimensional array
-	 * @return {Array}        The flattened array (1 dimensional)
-	 */
-	exports.flatten = function(array) {
-	  if (!Array.isArray(array)) {
-	    //if not an array, return as is
-	    return array;
-	  }
-	  var flat = [];
-
-	  array.forEach(function callback(value) {
-	    if (Array.isArray(value)) {
-	      value.forEach(callback);  //traverse through sub-arrays recursively
-	    }
-	    else {
-	      flat.push(value);
-	    }
-	  });
-
-	  return flat;
-	};
-
-	/**
-	 * Test whether an object is an array
-	 * @param {*} value
-	 * @return {boolean} isArray
-	 */
-	exports.isArray = Array.isArray;
-
-
-/***/ },
-/* 19 */
-/***/ function(module, exports) {
-
-	'use strict';
-
-	/**
-	 * Determine the type of a variable
-	 *
-	 *     type(x)
-	 *
-	 * The following types are recognized:
-	 *
-	 *     'undefined'
-	 *     'null'
-	 *     'boolean'
-	 *     'number'
-	 *     'string'
-	 *     'Array'
-	 *     'Function'
-	 *     'Date'
-	 *     'RegExp'
-	 *     'Object'
-	 *
-	 * @param {*} x
-	 * @return {string} Returns the name of the type. Primitive types are lower case,
-	 *                  non-primitive types are upper-camel-case.
-	 *                  For example 'number', 'string', 'Array', 'Date'.
-	 */
-	exports.type = function(x) {
-	  var type = typeof x;
-
-	  if (type === 'object') {
-	    if (x === null)           return 'null';
-	    if (x instanceof Boolean) return 'boolean';
-	    if (x instanceof Number)  return 'number';
-	    if (x instanceof String)  return 'string';
-	    if (Array.isArray(x))     return 'Array';
-	    if (x instanceof Date)    return 'Date';
-	    if (x instanceof RegExp)  return 'RegExp';
-
-	    return 'Object';
-	  }
-
-	  if (type === 'function')    return 'Function';
-
-	  return type;
-	};
-
-
-/***/ },
-/* 20 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	var formatNumber = __webpack_require__(8).format;
-	var formatBigNumber = __webpack_require__(21).format;
-
-	/**
-	 * Test whether value is a string
-	 * @param {*} value
-	 * @return {boolean} isString
-	 */
-	exports.isString = function(value) {
-	  return typeof value === 'string';
-	};
-
-	/**
-	 * Check if a text ends with a certain string.
-	 * @param {string} text
-	 * @param {string} search
-	 */
-	exports.endsWith = function(text, search) {
-	  var start = text.length - search.length;
-	  var end = text.length;
-	  return (text.substring(start, end) === search);
-	};
-
-	/**
-	 * Format a value of any type into a string.
-	 *
-	 * Usage:
-	 *     math.format(value)
-	 *     math.format(value, precision)
-	 *
-	 * If value is a function, the returned string is 'function' unless the function
-	 * has a property `description`, in that case this properties value is returned.
-	 *
-	 * Example usage:
-	 *     math.format(2/7);                // '0.2857142857142857'
-	 *     math.format(math.pi, 3);         // '3.14'
-	 *     math.format(new Complex(2, 3));  // '2 + 3i'
-	 *     math.format('hello');            // '"hello"'
-	 *
-	 * @param {*} value             Value to be stringified
-	 * @param {Object | number | Function} [options]  Formatting options. See
-	 *                                                lib/utils/number:format for a
-	 *                                                description of the available
-	 *                                                options.
-	 * @return {string} str
-	 */
-	exports.format = function(value, options) {
-	  if (typeof value === 'number') {
-	    return formatNumber(value, options);
-	  }
-
-	  if (value && value.isBigNumber === true) {
-	    return formatBigNumber(value, options);
-	  }
-
-	  if (value && value.isFraction === true) {
-	    if (!options || options.fraction !== 'decimal') {
-	      // output as ratio, like '1/3'
-	      return (value.s * value.n) + '/' + value.d;
-	    }
-	    else {
-	      // output as decimal, like '0.(3)'
-	      return value.toString();
-	    }
-	  }
-
-	  if (Array.isArray(value)) {
-	    return formatArray(value, options);
-	  }
-
-	  if (exports.isString(value)) {
-	    return '"' + value + '"';
-	  }
-
-	  if (typeof value === 'function') {
-	    return value.syntax ? value.syntax + '' : 'function';
-	  }
-
-	  if (typeof value === 'object') {
-	    if (typeof value.format === 'function') {
-	      return value.format(options);
-	    }
-	    else {
-	      return value.toString();
-	    }
-	  }
-
-	  return String(value);
-	};
-
-	/**
-	 * Recursively format an n-dimensional matrix
-	 * Example output: "[[1, 2], [3, 4]]"
-	 * @param {Array} array
-	 * @param {Object | number | Function} [options]  Formatting options. See
-	 *                                                lib/utils/number:format for a
-	 *                                                description of the available
-	 *                                                options.
-	 * @returns {string} str
-	 */
-	function formatArray (array, options) {
-	  if (Array.isArray(array)) {
-	    var str = '[';
-	    var len = array.length;
-	    for (var i = 0; i < len; i++) {
-	      if (i != 0) {
-	        str += ', ';
-	      }
-	      str += formatArray(array[i], options);
-	    }
-	    str += ']';
-	    return str;
-	  }
-	  else {
-	    return exports.format(array, options);
-	  }
-	}
-
-
-/***/ },
-/* 21 */
-/***/ function(module, exports) {
-
-	/**
-	 * Convert a BigNumber to a formatted string representation.
-	 *
-	 * Syntax:
-	 *
-	 *    format(value)
-	 *    format(value, options)
-	 *    format(value, precision)
-	 *    format(value, fn)
-	 *
-	 * Where:
-	 *
-	 *    {number} value   The value to be formatted
-	 *    {Object} options An object with formatting options. Available options:
-	 *                     {string} notation
-	 *                         Number notation. Choose from:
-	 *                         'fixed'          Always use regular number notation.
-	 *                                          For example '123.40' and '14000000'
-	 *                         'exponential'    Always use exponential notation.
-	 *                                          For example '1.234e+2' and '1.4e+7'
-	 *                         'auto' (default) Regular number notation for numbers
-	 *                                          having an absolute value between
-	 *                                          `lower` and `upper` bounds, and uses
-	 *                                          exponential notation elsewhere.
-	 *                                          Lower bound is included, upper bound
-	 *                                          is excluded.
-	 *                                          For example '123.4' and '1.4e7'.
-	 *                     {number} precision   A number between 0 and 16 to round
-	 *                                          the digits of the number.
-	 *                                          In case of notations 'exponential' and
-	 *                                          'auto', `precision` defines the total
-	 *                                          number of significant digits returned
-	 *                                          and is undefined by default.
-	 *                                          In case of notation 'fixed',
-	 *                                          `precision` defines the number of
-	 *                                          significant digits after the decimal
-	 *                                          point, and is 0 by default.
-	 *                     {Object} exponential An object containing two parameters,
-	 *                                          {number} lower and {number} upper,
-	 *                                          used by notation 'auto' to determine
-	 *                                          when to return exponential notation.
-	 *                                          Default values are `lower=1e-3` and
-	 *                                          `upper=1e5`.
-	 *                                          Only applicable for notation `auto`.
-	 *    {Function} fn    A custom formatting function. Can be used to override the
-	 *                     built-in notations. Function `fn` is called with `value` as
-	 *                     parameter and must return a string. Is useful for example to
-	 *                     format all values inside a matrix in a particular way.
-	 *
-	 * Examples:
-	 *
-	 *    format(6.4);                                        // '6.4'
-	 *    format(1240000);                                    // '1.24e6'
-	 *    format(1/3);                                        // '0.3333333333333333'
-	 *    format(1/3, 3);                                     // '0.333'
-	 *    format(21385, 2);                                   // '21000'
-	 *    format(12.071, {notation: 'fixed'});                // '12'
-	 *    format(2.3,    {notation: 'fixed', precision: 2});  // '2.30'
-	 *    format(52.8,   {notation: 'exponential'});          // '5.28e+1'
-	 *
-	 * @param {BigNumber} value
-	 * @param {Object | Function | number} [options]
-	 * @return {string} str The formatted value
-	 */
-	exports.format = function (value, options) {
-	  if (typeof options === 'function') {
-	    // handle format(value, fn)
-	    return options(value);
-	  }
-
-	  // handle special cases
-	  if (!value.isFinite()) {
-	    return value.isNaN() ? 'NaN' : (value.gt(0) ? 'Infinity' : '-Infinity');
-	  }
-
-	  // default values for options
-	  var notation = 'auto';
-	  var precision = undefined;
-
-	  if (options !== undefined) {
-	    // determine notation from options
-	    if (options.notation) {
-	      notation = options.notation;
-	    }
-
-	    // determine precision from options
-	    if (typeof options === 'number') {
-	      precision = options;
-	    }
-	    else if (options.precision) {
-	      precision = options.precision;
-	    }
-	  }
-
-	  // handle the various notations
-	  switch (notation) {
-	    case 'fixed':
-	      return exports.toFixed(value, precision);
-
-	    case 'exponential':
-	      return exports.toExponential(value, precision);
-
-	    case 'auto':
-	      // determine lower and upper bound for exponential notation.
-	      // TODO: implement support for upper and lower to be BigNumbers themselves
-	      var lower = 1e-3;
-	      var upper = 1e5;
-	      if (options && options.exponential) {
-	        if (options.exponential.lower !== undefined) {
-	          lower = options.exponential.lower;
-	        }
-	        if (options.exponential.upper !== undefined) {
-	          upper = options.exponential.upper;
-	        }
-	      }
-
-	      // adjust the configuration of the BigNumber constructor (yeah, this is quite tricky...)
-	      var oldConfig = {
-	        toExpNeg: value.constructor.toExpNeg,
-	        toExpPos: value.constructor.toExpPos
-	      };
-
-	      value.constructor.config({
-	        toExpNeg: Math.round(Math.log(lower) / Math.LN10),
-	        toExpPos: Math.round(Math.log(upper) / Math.LN10)
-	      });
-
-	      // handle special case zero
-	      if (value.isZero()) return '0';
-
-	      // determine whether or not to output exponential notation
-	      var str;
-	      var abs = value.abs();
-	      if (abs.gte(lower) && abs.lt(upper)) {
-	        // normal number notation
-	        str = value.toSignificantDigits(precision).toFixed();
-	      }
-	      else {
-	        // exponential notation
-	        str = exports.toExponential(value, precision);
-	      }
-
-	      // remove trailing zeros after the decimal point
-	      return str.replace(/((\.\d*?)(0+))($|e)/, function () {
-	        var digits = arguments[2];
-	        var e = arguments[4];
-	        return (digits !== '.') ? digits + e : e;
-	      });
-
-	    default:
-	      throw new Error('Unknown notation "' + notation + '". ' +
-	          'Choose "auto", "exponential", or "fixed".');
-	  }
-	};
-
-	/**
-	 * Format a number in exponential notation. Like '1.23e+5', '2.3e+0', '3.500e-3'
-	 * @param {BigNumber} value
-	 * @param {number} [precision]  Number of digits in formatted output.
-	 *                              If not provided, the maximum available digits
-	 *                              is used.
-	 * @returns {string} str
-	 */
-	exports.toExponential = function (value, precision) {
-	  if (precision !== undefined) {
-	    return value.toExponential(precision - 1); // Note the offset of one
-	  }
-	  else {
-	    return value.toExponential();
-	  }
-	};
-
-	/**
-	 * Format a number with fixed notation.
-	 * @param {BigNumber} value
-	 * @param {number} [precision=0]        Optional number of decimals after the
-	 *                                      decimal point. Zero by default.
-	 */
-	exports.toFixed = function (value, precision) {
-	  return value.toFixed(precision || 0);
-	  // Note: the (precision || 0) is needed as the toFixed of BigNumber has an
-	  // undefined default precision instead of 0.
-	}
-
-
-/***/ },
-/* 22 */
-/***/ function(module, exports) {
-
-	'use strict';
-
-	/**
-	 * Create a range error with the message:
-	 *     'Dimension mismatch (<actual size> != <expected size>)'
-	 * @param {number | number[]} actual        The actual size
-	 * @param {number | number[]} expected      The expected size
-	 * @param {string} [relation='!=']          Optional relation between actual
-	 *                                          and expected size: '!=', '<', etc.
-	 * @extends RangeError
-	 */
-	function DimensionError(actual, expected, relation) {
-	  if (!(this instanceof DimensionError)) {
-	    throw new SyntaxError('Constructor must be called with the new operator');
-	  }
-
-	  this.actual   = actual;
-	  this.expected = expected;
-	  this.relation = relation;
-
-	  this.message = 'Dimension mismatch (' +
-	      (Array.isArray(actual) ? ('[' + actual.join(', ') + ']') : actual) +
-	      ' ' + (this.relation || '!=') + ' ' +
-	      (Array.isArray(expected) ? ('[' + expected.join(', ') + ']') : expected) +
-	      ')';
-
-	  this.stack = (new Error()).stack;
-	}
-
-	DimensionError.prototype = new RangeError();
-	DimensionError.prototype.constructor = RangeError;
-	DimensionError.prototype.name = 'DimensionError';
-	DimensionError.prototype.isDimensionError = true;
-
-	module.exports = DimensionError;
-
-
-/***/ },
-/* 23 */
-/***/ function(module, exports) {
-
-	'use strict';
-
-	function factory (type, config, load, typed) {
-	  /**
-	   * Create a Matrix. The function creates a new `math.type.Matrix` object from
-	   * an `Array`. A Matrix has utility functions to manipulate the data in the
-	   * matrix, like getting the size and getting or setting values in the matrix.
-	   * Supported storage formats are 'dense' and 'sparse'.
-	   *
-	   * Syntax:
-	   *
-	   *    math.matrix()                         // creates an empty matrix using default storage format (dense).
-	   *    math.matrix(data)                     // creates a matrix with initial data using default storage format (dense).
-	   *    math.matrix('dense')                  // creates an empty matrix using the given storage format.
-	   *    math.matrix(data, 'dense')            // creates a matrix with initial data using the given storage format.
-	   *    math.matrix(data, 'sparse')           // creates a sparse matrix with initial data.
-	   *    math.matrix(data, 'sparse', 'number') // creates a sparse matrix with initial data, number data type.
-	   *
-	   * Examples:
-	   *
-	   *    var m = math.matrix([[1, 2], [3, 4]]);
-	   *    m.size();                        // Array [2, 2]
-	   *    m.resize([3, 2], 5);
-	   *    m.valueOf();                     // Array [[1, 2], [3, 4], [5, 5]]
-	   *    m.get([1, 0])                    // number 3
-	   *
-	   * See also:
-	   *
-	   *    bignumber, boolean, complex, index, number, string, unit, sparse
-	   *
-	   * @param {Array | Matrix} [data]    A multi dimensional array
-	   * @param {string} [format]          The Matrix storage format
-	   *
-	   * @return {Matrix} The created matrix
-	   */
-	  var matrix = typed('matrix', {
-	    '': function () {
-	      return _create([]);
-	    },
-
-	    'string': function (format) {
-	      return _create([], format);
-	    },
-	    
-	    'string, string': function (format, datatype) {
-	      return _create([], format, datatype);
-	    },
-
-	    'Array': function (data) {
-	      return _create(data);
-	    },
-	      
-	    'Matrix': function (data) {
-	      return _create(data, data.storage());
-	    },
-	    
-	    'Array | Matrix, string': _create,
-	    
-	    'Array | Matrix, string, string': _create
-	  });
-
-	  matrix.toTex = {
-	    0: '\\begin{bmatrix}\\end{bmatrix}',
-	    1: '\\left(${args[0]}\\right)',
-	    2: '\\left(${args[0]}\\right)'
-	  };
-
-	  return matrix;
-
-	  /**
-	   * Create a new Matrix with given storage format
-	   * @param {Array} data
-	   * @param {string} [format]
-	   * @param {string} [datatype]
-	   * @returns {Matrix} Returns a new Matrix
-	   * @private
-	   */
-	  function _create(data, format, datatype) {
-	    // get storage format constructor
-	    var M = type.Matrix.storage(format || 'default');
-
-	    // create instance
-	    return new M(data, datatype);
-	  }
-	}
-
-	exports.name = 'matrix';
-	exports.factory = factory;
-
-
-/***/ },
-/* 24 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	var size = __webpack_require__(18).size;
-
-	function factory (type, config, load, typed) {
-	  var matrix   = load(__webpack_require__(23));
-	  var subtract = load(__webpack_require__(25));
-	  var multiply = load(__webpack_require__(40));
-
-	  /**
-	   * Calculate the cross product for two vectors in three dimensional space.
-	   * The cross product of `A = [a1, a2, a3]` and `B =[b1, b2, b3]` is defined
-	   * as:
-	   *
-	   *    cross(A, B) = [
-	   *      a2 * b3 - a3 * b2,
-	   *      a3 * b1 - a1 * b3,
-	   *      a1 * b2 - a2 * b1
-	   *    ]
-	   *
-	   * Syntax:
-	   *
-	   *    math.cross(x, y)
-	   *
-	   * Examples:
-	   *
-	   *    math.cross([1, 1, 0],  [0, 1, 1]);  // Returns [1, -1, 1]
-	   *    math.cross([3, -3, 1], [4, 9, 2]);  // Returns [-15, -2, 39]
-	   *    math.cross([2, 3, 4],  [5, 6, 7]);  // Returns [-3, 6, -3]
-	   *
-	   * See also:
-	   *
-	   *    dot, multiply
-	   *
-	   * @param  {Array | Matrix} x   First vector
-	   * @param  {Array | Matrix} y   Second vector
-	   * @return {Array | Matrix}     Returns the cross product of `x` and `y`
-	   */
-	  var cross = typed('cross', {
-	    'Matrix, Matrix': function (x, y) {
-	      return matrix(_cross(x.toArray(), y.toArray()));
-	    },
-
-	    'Matrix, Array': function (x, y) {
-	      return matrix(_cross(x.toArray(), y));
-	    },
-
-	    'Array, Matrix': function (x, y) {
-	      return matrix(_cross(x, y.toArray()));
-	    },
-
-	    'Array, Array': _cross
-	  });
-
-	  cross.toTex = '\\left(${args[0]}\\right)\\times\\left(${args[1]}\\right)';
-
-	  return cross;
-
-	  /**
-	   * Calculate the cross product for two arrays
-	   * @param {Array} x  First vector
-	   * @param {Array} y  Second vector
-	   * @returns {Array} Returns the cross product of x and y
-	   * @private
-	   */
-	  function _cross(x, y) {
-	    var xSize= size(x);
-	    var ySize = size(y);
-
-	    if (xSize.length != 1 || ySize.length != 1 || xSize[0] != 3 || ySize[0] != 3) {
-	      throw new RangeError('Vectors with length 3 expected ' +
-	      '(Size A = [' + xSize.join(', ') + '], B = [' + ySize.join(', ') + '])');
-	    }
-
-	    return [
-	      subtract(multiply(x[1], y[2]), multiply(x[2], y[1])),
-	      subtract(multiply(x[2], y[0]), multiply(x[0], y[2])),
-	      subtract(multiply(x[0], y[1]), multiply(x[1], y[0]))
-	    ];
-	  }
-	}
-
-	exports.name = 'cross';
-	exports.factory = factory;
-
-
-/***/ },
-/* 25 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	var DimensionError = __webpack_require__(22);
-
-	function factory (type, config, load, typed) {
-	  var latex = __webpack_require__(26);
-
-	  var matrix = load(__webpack_require__(23));
-	  var addScalar = load(__webpack_require__(27));
-	  var unaryMinus = load(__webpack_require__(28));
-
-	  var algorithm01 = load(__webpack_require__(30));
-	  var algorithm03 = load(__webpack_require__(31));
-	  var algorithm05 = load(__webpack_require__(32));
-	  var algorithm10 = load(__webpack_require__(34));
-	  var algorithm13 = load(__webpack_require__(35));
-	  var algorithm14 = load(__webpack_require__(39));
-
-	  /**
-	   * Subtract two values, `x - y`.
-	   * For matrices, the function is evaluated element wise.
-	   *
-	   * Syntax:
-	   *
-	   *    math.subtract(x, y)
-	   *
-	   * Examples:
-	   *
-	   *    math.subtract(5.3, 2);        // returns number 3.3
-	   *
-	   *    var a = math.complex(2, 3);
-	   *    var b = math.complex(4, 1);
-	   *    math.subtract(a, b);          // returns Complex -2 + 2i
-	   *
-	   *    math.subtract([5, 7, 4], 4);  // returns Array [1, 3, 0]
-	   *
-	   *    var c = math.unit('2.1 km');
-	   *    var d = math.unit('500m');
-	   *    math.subtract(c, d);          // returns Unit 1.6 km
-	   *
-	   * See also:
-	   *
-	   *    add
-	   *
-	   * @param  {number | BigNumber | Fraction | Complex | Unit | Array | Matrix} x
-	   *            Initial value
-	   * @param  {number | BigNumber | Fraction | Complex | Unit | Array | Matrix} y
-	   *            Value to subtract from `x`
-	   * @return {number | BigNumber | Fraction | Complex | Unit | Array | Matrix}
-	   *            Subtraction of `x` and `y`
-	   */
-	  var subtract = typed('subtract', {
-
-	    'number, number': function (x, y) {
-	      return x - y;
-	    },
-
-	    'Complex, Complex': function (x, y) {
-	      return new type.Complex (
-	          x.re - y.re,
-	          x.im - y.im
-	      );
-	    },
-
-	    'BigNumber, BigNumber': function (x, y) {
-	      return x.minus(y);
-	    },
-
-	    'Fraction, Fraction': function (x, y) {
-	      return x.sub(y);
-	    },
-
-	    'Unit, Unit': function (x, y) {
-	      if (x.value == null) {
-	        throw new Error('Parameter x contains a unit with undefined value');
-	      }
-
-	      if (y.value == null) {
-	        throw new Error('Parameter y contains a unit with undefined value');
-	      }
-
-	      if (!x.equalBase(y)) {
-	        throw new Error('Units do not match');
-	      }
-
-	      var res = x.clone();
-	      res.value -= y.value;
-	      res.fixPrefix = false;
-
-	      return res;
-	    },
-	    
-	    'Matrix, Matrix': function (x, y) {
-	      // matrix sizes
-	      var xsize = x.size();
-	      var ysize = y.size();
-
-	      // check dimensions
-	      if (xsize.length !== ysize.length)
-	        throw new DimensionError(xsize.length, ysize.length);
-
-	      // result
-	      var c;
-
-	      // process matrix storage
-	      switch (x.storage()) {
-	        case 'sparse':
-	          switch (y.storage()) {
-	            case 'sparse':
-	              // sparse - sparse
-	              c = algorithm05(x, y, subtract);
-	              break;
-	            default:
-	              // sparse - dense
-	              c = algorithm03(y, x, subtract, true);
-	              break;
-	          }
-	          break;
-	        default:
-	          switch (y.storage()) {
-	            case 'sparse':
-	              // dense - sparse
-	              c = algorithm01(x, y, subtract, false);
-	              break;
-	            default:
-	              // dense - dense
-	              c = algorithm13(x, y, subtract);
-	              break;
-	          }
-	          break;
-	      }
-	      return c;
-	    },
-	    
-	    'Array, Array': function (x, y) {
-	      // use matrix implementation
-	      return subtract(matrix(x), matrix(y)).valueOf();
-	    },
-
-	    'Array, Matrix': function (x, y) {
-	      // use matrix implementation
-	      return subtract(matrix(x), y);
-	    },
-
-	    'Matrix, Array': function (x, y) {
-	      // use matrix implementation
-	      return subtract(x, matrix(y));
-	    },
-	    
-	    'Matrix, any': function (x, y) {
-	      // result
-	      var c;
-	      // check storage format
-	      switch (x.storage()) {
-	        case 'sparse':
-	          // algorithm 7 is faster than 9 since it calls f() for nonzero items only!
-	          c = algorithm10(x, unaryMinus(y), addScalar);
-	          break;
-	        default:
-	          c = algorithm14(x, y, subtract);
-	          break;
-	      }
-	      return c;
-	    },
-
-	    'any, Matrix': function (x, y) {
-	      // result
-	      var c;
-	      // check storage format
-	      switch (y.storage()) {
-	        case 'sparse':
-	          c = algorithm10(y, x, subtract, true);
-	          break;
-	        default:
-	          c = algorithm14(y, x, subtract, true);
-	          break;
-	      }
-	      return c;
-	    },
-
-	    'Array, any': function (x, y) {
-	      // use matrix implementation
-	      return algorithm14(matrix(x), y, subtract, false).valueOf();
-	    },
-
-	    'any, Array': function (x, y) {
-	      // use matrix implementation
-	      return algorithm14(matrix(y), x, subtract, true).valueOf();
-	    }
-	  });
-
-	  subtract.toTex = '\\left(${args[0]}' + latex.operators['subtract'] + '${args[1]}\\right)';
-
-	  return subtract;
-	}
-
-	exports.name = 'subtract';
-	exports.factory = factory;
-
-
-/***/ },
-/* 26 */
-/***/ function(module, exports) {
-
-	'use strict';
-
-	exports.symbols = {
-	  // GREEK LETTERS
-	  Alpha: 'A',     alpha: '\\alpha',
-	  Beta: 'B',      beta: '\\beta',
-	  Gamma: '\\Gamma',    gamma: '\\gamma',
-	  Delta: '\\Delta',    delta: '\\delta',
-	  Epsilon: 'E',   epsilon: '\\epsilon',  varepsilon: '\\varepsilon',
-	  Zeta: 'Z',      zeta: '\\zeta',
-	  Eta: 'H',       eta: '\\eta',
-	  Theta: '\\Theta',    theta: '\\theta',    vartheta: '\\vartheta',
-	  Iota: 'I',      iota: '\\iota',
-	  Kappa: 'K',     kappa: '\\kappa',    varkappa: '\\varkappa',
-	  Lambda: '\\Lambda',   lambda: '\\lambda',
-	  Mu: 'M',        mu: '\\mu',
-	  Nu: 'N',        nu: '\\nu',
-	  Xi: '\\Xi',       xi: '\\xi',
-	  Omicron: 'O',   omicron: 'o',
-	  Pi: '\\Pi',       pi: '\\pi',       varpi: '\\varpi',
-	  Rho: 'P',       rho: '\\rho',      varrho: '\\varrho',
-	  Sigma: '\\Sigma',    sigma: '\\sigma',    varsigma: '\\varsigma',
-	  Tau: 'T',       tau: '\\tau',
-	  Upsilon: '\\Upsilon',  upsilon: '\\upsilon',
-	  Phi: '\\Phi',      phi: '\\phi',      varphi: '\\varphi',
-	  Chi: 'X',       chi: '\\chi',
-	  Psi: '\\Psi',      psi: '\\psi',
-	  Omega: '\\Omega',    omega: '\\omega',
-	  //logic
-	  'true': '\\mathrm{True}',
-	  'false': '\\mathrm{False}',
-	  //other
-	  i: 'i', //TODO use \i ??
-	  inf: '\\infty',
-	  Inf: '\\infty',
-	  infinity: '\\infty',
-	  Infinity: '\\infty',
-	  oo: '\\infty',
-	  lim: '\\lim',
-	  'undefined': '\\mathbf{?}'
-	};
-
-	exports.operators = {
-	  'transpose': '^\\top',
-	  'factorial': '!',
-	  'pow': '^',
-	  'dotPow': '.^\\wedge', //TODO find ideal solution
-	  'unaryPlus': '+',
-	  'unaryMinus': '-',
-	  'bitNot': '~', //TODO find ideal solution
-	  'not': '\\neg',
-	  'multiply': '\\cdot',
-	  'divide': '\\frac', //TODO how to handle that properly?
-	  'dotMultiply': '.\\cdot', //TODO find ideal solution
-	  'dotDivide': '.:', //TODO find ideal solution
-	  'mod': '\\mod',
-	  'add': '+',
-	  'subtract': '-',
-	  'to': '\\rightarrow',
-	  'leftShift': '<<',
-	  'rightArithShift': '>>',
-	  'rightLogShift': '>>>',
-	  'equal': '=',
-	  'unequal': '\\neq',
-	  'smaller': '<',
-	  'larger': '>',
-	  'smallerEq': '\\leq',
-	  'largerEq': '\\geq',
-	  'bitAnd': '\\&',
-	  'bitXor': '\\underline{|}',
-	  'bitOr': '|',
-	  'and': '\\wedge',
-	  'xor': '\\veebar',
-	  'or': '\\vee'
-	};
-
-	exports.defaultTemplate = '\\mathrm{${name}}\\left(${args}\\right)';
-
-	var units = {
-	  deg: '^\\circ'
-	};
-
-	//@param {string} name
-	//@param {boolean} isUnit
-	exports.toSymbol = function (name, isUnit) {
-	  isUnit = typeof isUnit === 'undefined' ? false : isUnit;
-	  if (isUnit) {
-	    if (units.hasOwnProperty(name)) {
-	      return units[name];
-	    }
-	    return '\\mathrm{' + name + '}';
-	  }
-
-	  if (exports.symbols.hasOwnProperty(name)) {
-	    return exports.symbols[name];
-	  }
-	  else if (name.indexOf('_') !== -1) {
-	    //symbol with index (eg. alpha_1)
-	    var index = name.indexOf('_');
-	    return exports.toSymbol(name.substring(0, index)) + '_{'
-	      + exports.toSymbol(name.substring(index + 1)) + '}';
-	  }
-	  return name;
-	};
-
-
-/***/ },
-/* 27 */
-/***/ function(module, exports) {
-
-	'use strict';
-
-	function factory(type, config, load, typed) {
-
-	  /**
-	   * Add two scalar values, `x + y`.
-	   * This function is meant for internal use: it is used by the public function
-	   * `add`
-	   *
-	   * This function does not support collections (Array or Matrix), and does
-	   * not validate the number of of inputs.
-	   *
-	   * @param  {number | BigNumber | Fraction | Complex | Unit} x   First value to add
-	   * @param  {number | BigNumber | Fraction | Complex} y          Second value to add
-	   * @return {number | BigNumber | Fraction | Complex | Unit}                      Sum of `x` and `y`
-	   * @private
-	   */
-	  return typed('add', {
-
-	    'number, number': function (x, y) {
-	      return x + y;
-	    },
-
-	    'Complex, Complex': function (x, y) {
-	      return new type.Complex(
-	        x.re + y.re,
-	        x.im + y.im
-	      );
-	    },
-
-	    'BigNumber, BigNumber': function (x, y) {
-	      return x.plus(y);
-	    },
-
-	    'Fraction, Fraction': function (x, y) {
-	      return x.add(y);
-	    },
-
-	    'Unit, Unit': function (x, y) {
-	      if (x.value == null) throw new Error('Parameter x contains a unit with undefined value');
-	      if (y.value == null) throw new Error('Parameter y contains a unit with undefined value');
-	      if (!x.equalBase(y)) throw new Error('Units do not match');
-
-	      var res = x.clone();
-	      res.value += y.value;
-	      res.fixPrefix = false;
-	      return res;
-	    }
-	  });
-	}
-
-	exports.factory = factory;
-
-
-/***/ },
-/* 28 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	var deepMap = __webpack_require__(29);
-
-	function factory (type, config, load, typed) {
-	  var latex = __webpack_require__(26);
-
-	  /**
-	   * Inverse the sign of a value, apply a unary minus operation.
-	   *
-	   * For matrices, the function is evaluated element wise. Boolean values and
-	   * strings will be converted to a number. For complex numbers, both real and
-	   * complex value are inverted.
-	   *
-	   * Syntax:
-	   *
-	   *    math.unaryMinus(x)
-	   *
-	   * Examples:
-	   *
-	   *    math.unaryMinus(3.5);      // returns -3.5
-	   *    math.unaryMinus(-4.2);     // returns 4.2
-	   *
-	   * See also:
-	   *
-	   *    add, subtract, unaryPlus
-	   *
-	   * @param  {number | BigNumber | Fraction | Complex | Unit | Array | Matrix} x Number to be inverted.
-	   * @return {number | BigNumber | Fraction | Complex | Unit | Array | Matrix} Returns the value with inverted sign.
-	   */
-	  var unaryMinus = typed('unaryMinus', {
-	    'number': function (x) {
-	      return -x;
-	    },
-
-	    'Complex': function (x) {
-	      return new type.Complex(-x.re, -x.im);
-	    },
-
-	    'BigNumber': function (x) {
-	      return x.neg();
-	    },
-
-	    'Fraction': function (x) {
-	      var tmp = x.clone();
-	      tmp.s = -tmp.s;
-	      return tmp;
-	    },
-
-	    'Unit': function (x) {
-	      var res = x.clone();
-	      res.value = -x.value;
-	      return res;
-	    },
-
-	    'Array | Matrix': function (x) {
-	      // deep map collection, skip zeros since unaryMinus(0) = 0
-	      return deepMap(x, unaryMinus, true);
-	    }
-
-	    // TODO: add support for string
-	  });
-
-	  unaryMinus.toTex = latex.operators['unaryMinus'] + '\\left(${args[0]}\\right)';
-
-	  return unaryMinus;
-	}
-
-	exports.name = 'unaryMinus';
-	exports.factory = factory;
-
-
-/***/ },
-/* 29 */
-/***/ function(module, exports) {
-
-	'use strict';
-
-	/**
-	 * Execute the callback function element wise for each element in array and any
-	 * nested array
-	 * Returns an array with the results
-	 * @param {Array | Matrix} array
-	 * @param {Function} callback   The callback is called with two parameters:
-	 *                              value1 and value2, which contain the current
-	 *                              element of both arrays.
-	 * @param {boolean} [skipZeros] Invoke callback function for non-zero values only.
-	 *
-	 * @return {Array | Matrix} res
-	 */
-	module.exports = function deepMap(array, callback, skipZeros) {
-	  if (array && (typeof array.map === 'function')) {
-	    // TODO: replace array.map with a for loop to improve performance
-	    return array.map(function (x) {
-	      return deepMap(x, callback, skipZeros);
-	    });
-	  }
-	  else {
-	    return callback(array);
-	  }
-	};
-
-
-/***/ },
-/* 30 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	var DimensionError = __webpack_require__(22);
-
-	function factory (type, config, load, typed) {
-
-	  var DenseMatrix = type.DenseMatrix;
-
-	  /**
-	   * Iterates over SparseMatrix nonzero items and invokes the callback function f(Dij, Sij). 
-	   * Callback function invoked NNZ times (number of nonzero items in SparseMatrix).
-	   *
-	   *
-	   *          ┌  f(Dij, Sij)  ; S(i,j) !== 0
-	   * C(i,j) = ┤
-	   *          └  Dij          ; otherwise
-	   *
-	   *
-	   * @param {Matrix}   denseMatrix       The DenseMatrix instance (D)
-	   * @param {Matrix}   sparseMatrix      The SparseMatrix instance (S)
-	   * @param {Function} callback          The f(Dij,Sij) operation to invoke, where Dij = DenseMatrix(i,j) and Sij = SparseMatrix(i,j)
-	   * @param {boolean}  inverse           A true value indicates callback should be invoked f(Sij,Dij)
-	   *
-	   * @return {Matrix}                    DenseMatrix (C)
-	   *
-	   * see https://github.com/josdejong/mathjs/pull/346#issuecomment-97477571
-	   */
-	  var algorithm01 = function (denseMatrix, sparseMatrix, callback, inverse) {
-	    // dense matrix arrays
-	    var adata = denseMatrix._data;
-	    var asize = denseMatrix._size;
-	    var adt = denseMatrix._datatype;
-	    // sparse matrix arrays
-	    var bvalues = sparseMatrix._values;
-	    var bindex = sparseMatrix._index;
-	    var bptr = sparseMatrix._ptr;
-	    var bsize = sparseMatrix._size;
-	    var bdt = sparseMatrix._datatype;
-
-	    // validate dimensions
-	    if (asize.length !== bsize.length)
-	      throw new DimensionError(asize.length, bsize.length);
-
-	    // check rows & columns
-	    if (asize[0] !== bsize[0] || asize[1] !== bsize[1])
-	      throw new RangeError('Dimension mismatch. Matrix A (' + asize + ') must match Matrix B (' + bsize + ')');
-
-	    // sparse matrix cannot be a Pattern matrix
-	    if (!bvalues)
-	      throw new Error('Cannot perform operation on Dense Matrix and Pattern Sparse Matrix');
-
-	    // rows & columns
-	    var rows = asize[0];
-	    var columns = asize[1];
-
-	    // process data types
-	    var dt = typeof adt === 'string' && adt === bdt ? adt : undefined;
-	    // callback function
-	    var cf = dt ? typed.find(callback, [dt, dt]) : callback;
-
-	    // vars
-	    var i, j;
-	    
-	    // result (DenseMatrix)
-	    var cdata = [];
-	    // initialize c
-	    for (i = 0; i < rows; i++)
-	      cdata[i] = [];      
-	    
-	    // workspace
-	    var x = [];
-	    // marks indicating we have a value in x for a given column
-	    var w = [];
-
-	    // loop columns in b
-	    for (j = 0; j < columns; j++) {
-	      // column mark
-	      var mark = j + 1;
-	      // values in column j
-	      for (var k0 = bptr[j], k1 = bptr[j + 1], k = k0; k < k1; k++) {
-	        // row
-	        i = bindex[k];
-	        // update workspace
-	        x[i] = inverse ? cf(bvalues[k], adata[i][j]) : cf(adata[i][j], bvalues[k]);
-	        // mark i as updated
-	        w[i] = mark;
-	      }
-	      // loop rows
-	      for (i = 0; i < rows; i++) {
-	        // check row is in workspace
-	        if (w[i] === mark) {
-	          // c[i][j] was already calculated
-	          cdata[i][j] = x[i];
-	        }
-	        else {
-	          // item does not exist in S
-	          cdata[i][j] = adata[i][j];
-	        }
-	      }
-	    }
-
-	    // return dense matrix
-	    return new DenseMatrix({
-	      data: cdata,
-	      size: [rows, columns],
-	      datatype: dt
-	    });
-	  };
-	  
-	  return algorithm01;
-	}
-
-	exports.name = 'algorithm01';
-	exports.factory = factory;
-
-
-/***/ },
-/* 31 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	var DimensionError = __webpack_require__(22);
-
-	function factory (type, config, load, typed) {
-
-	  var DenseMatrix = type.DenseMatrix;
-
-	  /**
-	   * Iterates over SparseMatrix items and invokes the callback function f(Dij, Sij).
-	   * Callback function invoked M*N times.
-	   *
-	   *
-	   *          ┌  f(Dij, Sij)  ; S(i,j) !== 0
-	   * C(i,j) = ┤
-	   *          └  f(Dij, 0)    ; otherwise
-	   *
-	   *
-	   * @param {Matrix}   denseMatrix       The DenseMatrix instance (D)
-	   * @param {Matrix}   sparseMatrix      The SparseMatrix instance (C)
-	   * @param {Function} callback          The f(Dij,Sij) operation to invoke, where Dij = DenseMatrix(i,j) and Sij = SparseMatrix(i,j)
-	   * @param {boolean}  inverse           A true value indicates callback should be invoked f(Sij,Dij)
-	   *
-	   * @return {Matrix}                    DenseMatrix (C)
-	   *
-	   * see https://github.com/josdejong/mathjs/pull/346#issuecomment-97477571
-	   */
-	  var algorithm03 = function (denseMatrix, sparseMatrix, callback, inverse) {
-	    // dense matrix arrays
-	    var adata = denseMatrix._data;
-	    var asize = denseMatrix._size;
-	    var adt = denseMatrix._datatype;
-	    // sparse matrix arrays
-	    var bvalues = sparseMatrix._values;
-	    var bindex = sparseMatrix._index;
-	    var bptr = sparseMatrix._ptr;
-	    var bsize = sparseMatrix._size;
-	    var bdt = sparseMatrix._datatype;
-
-	    // validate dimensions
-	    if (asize.length !== bsize.length)
-	      throw new DimensionError(asize.length, bsize.length);
-
-	    // check rows & columns
-	    if (asize[0] !== bsize[0] || asize[1] !== bsize[1])
-	      throw new RangeError('Dimension mismatch. Matrix A (' + asize + ') must match Matrix B (' + bsize + ')');
-
-	    // sparse matrix cannot be a Pattern matrix
-	    if (!bvalues)
-	      throw new Error('Cannot perform operation on Dense Matrix and Pattern Sparse Matrix');
-
-	    // rows & columns
-	    var rows = asize[0];
-	    var columns = asize[1];
-
-	    // datatype
-	    var dt;
-	    // zero value
-	    var zero = 0;
-	    // callback signature to use
-	    var cf = callback;
-
-	    // process data types
-	    if (typeof adt === 'string' && adt === bdt) {
-	      // datatype
-	      dt = adt;
-	      // convert 0 to the same datatype
-	      zero = typed.convert(0, dt);
-	      // callback
-	      cf = typed.find(callback, [dt, dt]);
-	    }
-
-	    // result (DenseMatrix)
-	    var cdata = [];
-
-	    // initialize dense matrix
-	    for (var z = 0; z < rows; z++) {
-	      // initialize row
-	      cdata[z] = [];
-	    }
-
-	    // workspace
-	    var x = [];
-	    // marks indicating we have a value in x for a given column
-	    var w = [];
-
-	    // loop columns in b
-	    for (var j = 0; j < columns; j++) {
-	      // column mark
-	      var mark = j + 1;
-	      // values in column j
-	      for (var k0 = bptr[j], k1 = bptr[j + 1], k = k0; k < k1; k++) {
-	        // row
-	        var i = bindex[k];
-	        // update workspace
-	        x[i] = inverse ? cf(bvalues[k], adata[i][j]) : cf(adata[i][j], bvalues[k]);
-	        w[i] = mark;
-	      }
-	      // process workspace
-	      for (var y = 0; y < rows; y++) {
-	        // check we have a calculated value for current row
-	        if (w[y] === mark) {
-	          // use calculated value
-	          cdata[y][j] = x[y];
-	        }
-	        else {
-	          // calculate value
-	          cdata[y][j] = inverse ? cf(zero, adata[y][j]) : cf(adata[y][j], zero);
-	        }
-	      }
-	    }
-
-	    // return dense matrix
-	    return new DenseMatrix({
-	      data: cdata,
-	      size: [rows, columns],
-	      datatype: dt
-	    });
-	  };
-	  
-	  return algorithm03;
-	}
-
-	exports.name = 'algorithm03';
-	exports.factory = factory;
-
-
-/***/ },
-/* 32 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	var DimensionError = __webpack_require__(22);
-
-	function factory (type, config, load, typed) {
-
-	  var equalScalar = load(__webpack_require__(33));
-	  
-	  var SparseMatrix = type.SparseMatrix;
-
-	  /**
-	   * Iterates over SparseMatrix A and SparseMatrix B nonzero items and invokes the callback function f(Aij, Bij). 
-	   * Callback function invoked MAX(NNZA, NNZB) times
-	   *
-	   *
-	   *          ┌  f(Aij, Bij)  ; A(i,j) !== 0 || B(i,j) !== 0
-	   * C(i,j) = ┤  
-	   *          └  0            ; otherwise
-	   *
-	   *
-	   * @param {Matrix}   a                 The SparseMatrix instance (A)
-	   * @param {Matrix}   b                 The SparseMatrix instance (B)
-	   * @param {Function} callback          The f(Aij,Bij) operation to invoke
-	   *
-	   * @return {Matrix}                    SparseMatrix (C)
-	   *
-	   * see https://github.com/josdejong/mathjs/pull/346#issuecomment-97620294
-	   */
-	  var algorithm05 = function (a, b, callback) {
-	    // sparse matrix arrays
-	    var avalues = a._values;
-	    var aindex = a._index;
-	    var aptr = a._ptr;
-	    var asize = a._size;
-	    var adt = a._datatype;
-	    // sparse matrix arrays
-	    var bvalues = b._values;
-	    var bindex = b._index;
-	    var bptr = b._ptr;
-	    var bsize = b._size;
-	    var bdt = b._datatype;
-
-	    // validate dimensions
-	    if (asize.length !== bsize.length)
-	      throw new DimensionError(asize.length, bsize.length);
-
-	    // check rows & columns
-	    if (asize[0] !== bsize[0] || asize[1] !== bsize[1])
-	      throw new RangeError('Dimension mismatch. Matrix A (' + asize + ') must match Matrix B (' + bsize + ')');
-
-	    // rows & columns
-	    var rows = asize[0];
-	    var columns = asize[1];
-
-	    // datatype
-	    var dt;
-	    // equal signature to use
-	    var eq = equalScalar;
-	    // zero value
-	    var zero = 0;
-	    // callback signature to use
-	    var cf = callback;
-
-	    // process data types
-	    if (typeof adt === 'string' && adt === bdt) {
-	      // datatype
-	      dt = adt;
-	      // find signature that matches (dt, dt)
-	      eq = typed.find(equalScalar, [dt, dt]);
-	      // convert 0 to the same datatype
-	      zero = typed.convert(0, dt);
-	      // callback
-	      cf = typed.find(callback, [dt, dt]);
-	    }
-
-	    // result arrays
-	    var cvalues = avalues && bvalues ? [] : undefined;
-	    var cindex = [];
-	    var cptr = [];
-	    // matrix
-	    var c = new SparseMatrix({
-	      values: cvalues,
-	      index: cindex,
-	      ptr: cptr,
-	      size: [rows, columns],
-	      datatype: dt
-	    });
-
-	    // workspaces
-	    var xa = cvalues ? [] : undefined;
-	    var xb = cvalues ? [] : undefined;
-	    // marks indicating we have a value in x for a given column
-	    var wa = [];
-	    var wb = [];
-
-	    // vars
-	    var i, j, k, k1;
-	    
-	    // loop columns
-	    for (j = 0; j < columns; j++) {
-	      // update cptr
-	      cptr[j] = cindex.length;
-	      // columns mark
-	      var mark = j + 1;
-	      // loop values A(:,j)
-	      for (k = aptr[j], k1 = aptr[j + 1]; k < k1; k++) {
-	        // row
-	        i = aindex[k];
-	        // push index
-	        cindex.push(i);
-	        // update workspace
-	        wa[i] = mark;
-	        // check we need to process values
-	        if (xa)
-	          xa[i] = avalues[k];
-	      }
-	      // loop values B(:,j)
-	      for (k = bptr[j], k1 = bptr[j + 1]; k < k1; k++) {
-	        // row
-	        i = bindex[k];
-	        // check row existed in A
-	        if (wa[i] !== mark) {
-	          // push index
-	          cindex.push(i);
-	        }
-	        // update workspace
-	        wb[i] = mark;
-	        // check we need to process values
-	        if (xb)
-	          xb[i] = bvalues[k];
-	      }
-	      // check we need to process values (non pattern matrix)
-	      if (cvalues) {
-	        // initialize first index in j
-	        k = cptr[j];
-	        // loop index in j
-	        while (k < cindex.length) {
-	          // row
-	          i = cindex[k];
-	          // marks
-	          var wai = wa[i];
-	          var wbi = wb[i];
-	          // check Aij or Bij are nonzero
-	          if (wai === mark || wbi === mark) {
-	            // matrix values @ i,j
-	            var va = wai === mark ? xa[i] : zero;
-	            var vb = wbi === mark ? xb[i] : zero;
-	            // Cij
-	            var vc = cf(va, vb);
-	            // check for zero
-	            if (!eq(vc, zero)) {
-	              // push value
-	              cvalues.push(vc);
-	              // increment pointer
-	              k++;
-	            }
-	            else {
-	              // remove value @ i, do not increment pointer
-	              cindex.splice(k, 1);
-	            }
-	          }
-	        }
-	      }
-	    }
-	    // update cptr
-	    cptr[columns] = cindex.length;
-
-	    // return sparse matrix
-	    return c;
-	  };
-
-	  return algorithm05;
-	}
-
-	exports.name = 'algorithm05';
-	exports.factory = factory;
-
-
-/***/ },
-/* 33 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	var nearlyEqual = __webpack_require__(8).nearlyEqual;
-
-	function factory (type, config, load, typed) {
-	  
-	  /**
-	   * Test whether two values are equal.
-	   *
-	   * @param  {number | BigNumber | Fraction | boolean | Complex | Unit} x   First value to compare
-	   * @param  {number | BigNumber | Fraction | boolean | Complex} y          Second value to compare
-	   * @return {boolean}                                                  Returns true when the compared values are equal, else returns false
-	   * @private
-	   */
-	  var equalScalar = typed('equalScalar', {
-
-	    'boolean, boolean': function (x, y) {
-	      return x === y;
-	    },
-
-	    'number, number': function (x, y) {
-	      return x === y || nearlyEqual(x, y, config.epsilon);
-	    },
-
-	    'BigNumber, BigNumber': function (x, y) {
-	      return x.eq(y);
-	    },
-
-	    'Fraction, Fraction': function (x, y) {
-	      return x.equals(y);
-	    },
-
-	    'Complex, Complex': function (x, y) {
-	      return (x.re === y.re || nearlyEqual(x.re, y.re, config.epsilon)) &&
-	        (x.im === y.im || nearlyEqual(x.im, y.im, config.epsilon));
-	    },
-
-	    'Unit, Unit': function (x, y) {
-	      if (!x.equalBase(y)) {
-	        throw new Error('Cannot compare units with different base');
-	      }
-	      return x.value === y.value || nearlyEqual(x.value, y.value, config.epsilon);
-	    },
-
-	    'string, string': function (x, y) {
-	      return x === y;
-	    }
-	  });
-	  
-	  return equalScalar;
-	}
-
-	exports.factory = factory;
-
-
-/***/ },
-/* 34 */
-/***/ function(module, exports) {
-
-	'use strict';
-
-	function factory (type, config, load, typed) {
-
-	  var DenseMatrix = type.DenseMatrix;
-
-	  /**
-	   * Iterates over SparseMatrix S nonzero items and invokes the callback function f(Sij, b). 
-	   * Callback function invoked NZ times (number of nonzero items in S).
-	   *
-	   *
-	   *          ┌  f(Sij, b)  ; S(i,j) !== 0
-	   * C(i,j) = ┤  
-	   *          └  b          ; otherwise
-	   *
-	   *
-	   * @param {Matrix}   s                 The SparseMatrix instance (S)
-	   * @param {Scalar}   b                 The Scalar value
-	   * @param {Function} callback          The f(Aij,b) operation to invoke
-	   * @param {boolean}  inverse           A true value indicates callback should be invoked f(b,Sij)
-	   *
-	   * @return {Matrix}                    DenseMatrix (C)
-	   *
-	   * https://github.com/josdejong/mathjs/pull/346#issuecomment-97626813
-	   */
-	  var algorithm10 = function (s, b, callback, inverse) {
-	    // sparse matrix arrays
-	    var avalues = s._values;
-	    var aindex = s._index;
-	    var aptr = s._ptr;
-	    var asize = s._size;
-	    var adt = s._datatype;
-
-	    // sparse matrix cannot be a Pattern matrix
-	    if (!avalues)
-	      throw new Error('Cannot perform operation on Pattern Sparse Matrix and Scalar value');
-
-	    // rows & columns
-	    var rows = asize[0];
-	    var columns = asize[1];
-
-	    // datatype
-	    var dt;
-	    // callback signature to use
-	    var cf = callback;
-
-	    // process data types
-	    if (typeof adt === 'string') {
-	      // datatype
-	      dt = adt;
-	      // convert b to the same datatype
-	      b = typed.convert(b, dt);
-	      // callback
-	      cf = typed.find(callback, [dt, dt]);
-	    }
-
-	    // result arrays
-	    var cdata = [];
-	    // matrix
-	    var c = new DenseMatrix({
-	      data: cdata,
-	      size: [rows, columns],
-	      datatype: dt
-	    });
-
-	    // workspaces
-	    var x = [];
-	    // marks indicating we have a value in x for a given column
-	    var w = [];
-
-	    // loop columns
-	    for (var j = 0; j < columns; j++) {
-	      // columns mark
-	      var mark = j + 1;
-	      // values in j
-	      for (var k0 = aptr[j], k1 = aptr[j + 1], k = k0; k < k1; k++) {
-	        // row
-	        var r = aindex[k];
-	        // update workspace
-	        x[r] = avalues[k];
-	        w[r] = mark;
-	      }
-	      // loop rows
-	      for (var i = 0; i < rows; i++) {
-	        // initialize C on first column
-	        if (j === 0) {
-	          // create row array
-	          cdata[i] = [];
-	        }
-	        // check sparse matrix has a value @ i,j
-	        if (w[i] === mark) {
-	          // invoke callback, update C
-	          cdata[i][j] = inverse ? cf(b, x[i]) : cf(x[i], b);
-	        }
-	        else {
-	          // dense matrix value @ i, j
-	          cdata[i][j] = b;
-	        }
-	      }
-	    }
-
-	    // return sparse matrix
-	    return c;
-	  };
-
-	  return algorithm10;
-	}
-
-	exports.name = 'algorithm10';
-	exports.factory = factory;
-
-
-/***/ },
-/* 35 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	var util = __webpack_require__(36);
-	var DimensionError = __webpack_require__(22);
-
-	var string = util.string,
-	    isString = string.isString;
-
-	function factory (type, config, load, typed) {
-
-	  var DenseMatrix = type.DenseMatrix;
-
-	  /**
-	   * Iterates over DenseMatrix items and invokes the callback function f(Aij..z, Bij..z). 
-	   * Callback function invoked MxN times.
-	   *
-	   * C(i,j,...z) = f(Aij..z, Bij..z)
-	   *
-	   * @param {Matrix}   a                 The DenseMatrix instance (A)
-	   * @param {Matrix}   b                 The DenseMatrix instance (B)
-	   * @param {Function} callback          The f(Aij..z,Bij..z) operation to invoke
-	   *
-	   * @return {Matrix}                    DenseMatrix (C)
-	   *
-	   * https://github.com/josdejong/mathjs/pull/346#issuecomment-97658658
-	   */
-	  var algorithm13 = function (a, b, callback) {
-	    // a arrays
-	    var adata = a._data;
-	    var asize = a._size;
-	    var adt = a._datatype;
-	    // b arrays
-	    var bdata = b._data;
-	    var bsize = b._size;
-	    var bdt = b._datatype;
-	    // c arrays
-	    var csize = [];
-
-	    // validate dimensions
-	    if (asize.length !== bsize.length)
-	      throw new DimensionError(asize.length, bsize.length);
-
-	    // validate each one of the dimension sizes
-	    for (var s = 0; s < asize.length; s++) {
-	      // must match
-	      if (asize[s] !== bsize[s])
-	        throw new RangeError('Dimension mismatch. Matrix A (' + asize + ') must match Matrix B (' + bsize + ')');
-	      // update dimension in c
-	      csize[s] = asize[s];
-	    }
-
-	    // datatype
-	    var dt;
-	    // callback signature to use
-	    var cf = callback;
-
-	    // process data types
-	    if (typeof adt === 'string' && adt === bdt) {
-	      // datatype
-	      dt = adt;
-	      // convert b to the same datatype
-	      b = typed.convert(b, dt);
-	      // callback
-	      cf = typed.find(callback, [dt, dt]);
-	    }
-
-	    // populate cdata, iterate through dimensions
-	    var cdata = csize.length > 0 ? _iterate(cf, 0, csize, csize[0], adata, bdata) : [];
-	    
-	    // c matrix
-	    return new DenseMatrix({
-	      data: cdata,
-	      size: csize,
-	      datatype: dt
-	    });
-	  };
-	  
-	  // recursive function
-	  var _iterate = function (f, level, s, n, av, bv) {
-	    // initialize array for this level
-	    var cv = [];
-	    // check we reach the last level
-	    if (level === s.length - 1) {
-	      // loop arrays in last level
-	      for (var i = 0; i < n; i++) {
-	        // invoke callback and store value
-	        cv[i] = f(av[i], bv[i]);
-	      }
-	    }
-	    else {
-	      // iterate current level
-	      for (var j = 0; j < n; j++) {
-	        // iterate next level
-	        cv[j] = _iterate(f, level + 1, s, s[level + 1], av[j], bv[j]);
-	      }
-	    }
-	    return cv;
-	  };
-	  
-	  return algorithm13;
-	}
-
-	exports.name = 'algorithm13';
-	exports.factory = factory;
-
-
-/***/ },
-/* 36 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	exports.array = __webpack_require__(18);
-	exports['boolean'] = __webpack_require__(37);
-	exports['function'] = __webpack_require__(38);
-	exports.number = __webpack_require__(8);
-	exports.object = __webpack_require__(5);
-	exports.string = __webpack_require__(20);
-	exports.types = __webpack_require__(19);
-	exports.emitter = __webpack_require__(3);
-
-
-/***/ },
-/* 37 */
-/***/ function(module, exports) {
-
-	'use strict';
-
-	/**
-	 * Test whether value is a boolean
-	 * @param {*} value
-	 * @return {boolean} isBoolean
-	 */
-	exports.isBoolean = function(value) {
-	  return typeof value == 'boolean';
-	};
-
-
-/***/ },
-/* 38 */
-/***/ function(module, exports) {
-
-	// function utils
-
-	/*
-	 * Memoize a given function by caching the computed result.
-	 * The cache of a memoized function can be cleared by deleting the `cache`
-	 * property of the function.
-	 *
-	 * @param {function} fn                     The function to be memoized.
-	 *                                          Must be a pure function.
-	 * @param {function(args: Array)} [hasher]  A custom hash builder.
-	 *                                          Is JSON.stringify by default.
-	 * @return {function}                       Returns the memoized function
-	 */
-	exports.memoize = function(fn, hasher) {
-	  return function memoize() {
-	    if (typeof memoize.cache !== 'object') {
-	      memoize.cache = {};
-	    }
-
-	    var args = [];
-	    for (var i = 0; i < arguments.length; i++) {
-	      args[i] = arguments[i];
-	    }
-
-	    var hash = hasher ? hasher(args) : JSON.stringify(args);
-	    if (!(hash in memoize.cache)) {
-	      return memoize.cache[hash] = fn.apply(fn, args);
-	    }
-	    return memoize.cache[hash];
-	  };
-	};
-
-
-/***/ },
-/* 39 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	var clone = __webpack_require__(5).clone;
-
-	function factory (type, config, load, typed) {
-
-	  var DenseMatrix = type.DenseMatrix;
-
-	  /**
-	   * Iterates over DenseMatrix items and invokes the callback function f(Aij..z, b). 
-	   * Callback function invoked MxN times.
-	   *
-	   * C(i,j,...z) = f(Aij..z, b)
-	   *
-	   * @param {Matrix}   a                 The DenseMatrix instance (A)
-	   * @param {Scalar}   b                 The Scalar value
-	   * @param {Function} callback          The f(Aij..z,b) operation to invoke
-	   * @param {boolean}  inverse           A true value indicates callback should be invoked f(b,Aij..z)
-	   *
-	   * @return {Matrix}                    DenseMatrix (C)
-	   *
-	   * https://github.com/josdejong/mathjs/pull/346#issuecomment-97659042
-	   */
-	  var algorithm14 = function (a, b, callback, inverse) {
-	    // a arrays
-	    var adata = a._data;
-	    var asize = a._size;
-	    var adt = a._datatype;
-	    
-	    // datatype
-	    var dt;
-	    // callback signature to use
-	    var cf = callback;
-
-	    // process data types
-	    if (typeof adt === 'string') {
-	      // datatype
-	      dt = adt;
-	      // convert b to the same datatype
-	      b = typed.convert(b, dt);
-	      // callback
-	      cf = typed.find(callback, [dt, dt]);
-	    }
-	    
-	    // populate cdata, iterate through dimensions
-	    var cdata = asize.length > 0 ? _iterate(cf, 0, asize, asize[0], adata, b, inverse) : [];
-
-	    // c matrix
-	    return new DenseMatrix({
-	      data: cdata,
-	      size: clone(asize),
-	      datatype: dt
-	    });
-	  };
-	  
-	  // recursive function
-	  var _iterate = function (f, level, s, n, av, bv, inverse) {
-	    // initialize array for this level
-	    var cv = [];
-	    // check we reach the last level
-	    if (level === s.length - 1) {
-	      // loop arrays in last level
-	      for (var i = 0; i < n; i++) {
-	        // invoke callback and store value
-	        cv[i] = inverse ? f(bv, av[i]) : f(av[i], bv);
-	      }
-	    }
-	    else {
-	      // iterate current level
-	      for (var j = 0; j < n; j++) {
-	        // iterate next level
-	        cv[j] = _iterate(f, level + 1, s, s[level + 1], av[j], bv, inverse);
-	      }
-	    }
-	    return cv;
-	  };
-
-	  return algorithm14;
-	}
-
-	exports.name = 'algorithm14';
-	exports.factory = factory;
-
-
-/***/ },
-/* 40 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	var extend = __webpack_require__(5).extend;
-	var array = __webpack_require__(18);
-
-	function factory (type, config, load, typed) {
-	  var latex = __webpack_require__(26);
-
-	  var matrix = load(__webpack_require__(23));
-	  var addScalar = load(__webpack_require__(27));
-	  var multiplyScalar = load(__webpack_require__(41));
-	  var equalScalar = load(__webpack_require__(33));
-
-	  var algorithm11 = load(__webpack_require__(42));
-	  var algorithm14 = load(__webpack_require__(39));
-	  
-	  var DenseMatrix = type.DenseMatrix;
-	  var SparseMatrix = type.SparseMatrix;
-
-	  /**
-	   * Multiply two values, `x * y`. The result is squeezed.
-	   * For matrices, the matrix product is calculated.
-	   *
-	   * Syntax:
-	   *
-	   *    math.multiply(x, y)
-	   *
-	   * Examples:
-	   *
-	   *    math.multiply(4, 5.2);        // returns number 20.8
-	   *
-	   *    var a = math.complex(2, 3);
-	   *    var b = math.complex(4, 1);
-	   *    math.multiply(a, b);          // returns Complex 5 + 14i
-	   *
-	   *    var c = [[1, 2], [4, 3]];
-	   *    var d = [[1, 2, 3], [3, -4, 7]];
-	   *    math.multiply(c, d);          // returns Array [[7, -6, 17], [13, -4, 33]]
-	   *
-	   *    var e = math.unit('2.1 km');
-	   *    math.multiply(3, e);          // returns Unit 6.3 km
-	   *
-	   * See also:
-	   *
-	   *    divide
-	   *
-	   * @param  {number | BigNumber | Fraction | Complex | Unit | Array | Matrix} x First value to multiply
-	   * @param  {number | BigNumber | Fraction | Complex | Unit | Array | Matrix} y Second value to multiply
-	   * @return {number | BigNumber | Fraction | Complex | Unit | Array | Matrix} Multiplication of `x` and `y`
-	   */
-	  var multiply = typed('multiply', extend({
-	    // we extend the signatures of multiplyScalar with signatures dealing with matrices
-
-	    'Array, Array': function (x, y) {
-	      // check dimensions
-	      _validateMatrixDimensions(array.size(x), array.size(y));
-
-	      // use dense matrix implementation
-	      var m = multiply(matrix(x), matrix(y));
-	      // return array or scalar
-	      return (m && m.isMatrix === true) ? m.valueOf() : m;
-	    },
-
-	    'Matrix, Matrix': function (x, y) {
-	      // dimensions
-	      var xsize = x.size();
-	      var ysize = y.size();
-
-	      // check dimensions
-	      _validateMatrixDimensions(xsize, ysize);
-
-	      // process dimensions
-	      if (xsize.length === 1) {
-	        // process y dimensions
-	        if (ysize.length === 1) {
-	          // Vector * Vector
-	          return _multiplyVectorVector(x, y, xsize[0]);
-	        }
-	        // Vector * Matrix
-	        return _multiplyVectorMatrix(x, y);
-	      }
-	      // process y dimensions
-	      if (ysize.length === 1) {
-	        // Matrix * Vector
-	        return _multiplyMatrixVector(x, y);
-	      }
-	      // Matrix * Matrix
-	      return _multiplyMatrixMatrix(x, y);
-	    },
-
-	    'Matrix, Array': function (x, y) {
-	      // use Matrix * Matrix implementation
-	      return multiply(x, matrix(y));
-	    },
-
-	    'Array, Matrix': function (x, y) {
-	      // use Matrix * Matrix implementation
-	      return multiply(matrix(x, y.storage()), y);
-	    },
-
-	    'Matrix, any': function (x, y) {
-	      // result
-	      var c;
-	      
-	      // process storage format
-	      switch (x.storage()) {
-	        case 'sparse':
-	          c = algorithm11(x, y, multiplyScalar, false);
-	          break;
-	        case 'dense':
-	          c = algorithm14(x, y, multiplyScalar, false);
-	          break;
-	      }
-	      return c;
-	    },
-
-	    'any, Matrix': function (x, y) {
-	      // result
-	      var c;
-	      // check storage format
-	      switch (y.storage()) {
-	        case 'sparse':
-	          c = algorithm11(y, x, multiplyScalar, true);
-	          break;
-	        case 'dense':
-	          c = algorithm14(y, x, multiplyScalar, true);
-	          break;
-	      }
-	      return c;
-	    },
-
-	    'Array, any': function (x, y) {
-	      // use matrix implementation
-	      return algorithm14(matrix(x), y, multiplyScalar, false).valueOf();
-	    },
-
-	    'any, Array': function (x, y) {
-	      // use matrix implementation
-	      return algorithm14(matrix(y), x, multiplyScalar, true).valueOf();
-	    }
-	  }, multiplyScalar.signatures));
-
-	  var _validateMatrixDimensions = function (size1, size2) {
-	    // check left operand dimensions
-	    switch (size1.length) {
-	      case 1:
-	        // check size2
-	        switch (size2.length) {
-	          case 1:
-	            // Vector x Vector
-	            if (size1[0] !== size2[0]) {
-	              // throw error
-	              throw new RangeError('Dimension mismatch in multiplication. Vectors must have the same length');
-	            }
-	            break;
-	          case 2:
-	            // Vector x Matrix
-	            if (size1[0] !== size2[0]) {
-	              // throw error
-	              throw new RangeError('Dimension mismatch in multiplication. Vector length (' + size1[0] + ') must match Matrix rows (' + size2[0] + ')');
-	            }
-	            break;
-	          default:
-	            throw new Error('Can only multiply a 1 or 2 dimensional matrix (Matrix B has ' + size2.length + ' dimensions)');
-	        }
-	        break;
-	      case 2:
-	        // check size2
-	        switch (size2.length) {
-	          case 1:
-	            // Matrix x Vector
-	            if (size1[1] !== size2[0]) {
-	              // throw error
-	              throw new RangeError('Dimension mismatch in multiplication. Matrix columns (' + size1[1] + ') must match Vector length (' + size2[0] + ')');
-	            }
-	            break;
-	          case 2:
-	            // Matrix x Matrix
-	            if (size1[1] !== size2[0]) {
-	              // throw error
-	              throw new RangeError('Dimension mismatch in multiplication. Matrix A columns (' + size1[1] + ') must match Matrix B rows (' + size2[0] + ')');
-	            }
-	            break;
-	          default:
-	            throw new Error('Can only multiply a 1 or 2 dimensional matrix (Matrix B has ' + size2.length + ' dimensions)');
-	        }
-	        break;
-	      default:
-	        throw new Error('Can only multiply a 1 or 2 dimensional matrix (Matrix A has ' + size1.length + ' dimensions)');
-	    }
-	  };
-
-	  /**
-	   * C = A * B
-	   *
-	   * @param {Matrix} a            Dense Vector   (N)
-	   * @param {Matrix} b            Dense Vector   (N)
-	   *
-	   * @return {number}             Scalar value
-	   */
-	  var _multiplyVectorVector = function (a, b, n) {
-	    // check empty vector
-	    if (n === 0)
-	      throw new Error('Cannot multiply two empty vectors');
-
-	    // a dense
-	    var adata = a._data;
-	    var adt = a._datatype;
-	    // b dense
-	    var bdata = b._data;
-	    var bdt = b._datatype;
-
-	    // datatype
-	    var dt;
-	    // addScalar signature to use
-	    var af = addScalar;
-	    // multiplyScalar signature to use
-	    var mf = multiplyScalar;
-
-	    // process data types
-	    if (adt && bdt && adt === bdt && typeof adt === 'string') {
-	      // datatype
-	      dt = adt;
-	      // find signatures that matches (dt, dt)
-	      af = typed.find(addScalar, [dt, dt]);
-	      mf = typed.find(multiplyScalar, [dt, dt]);
-	    }
-	    
-	    // result (do not initialize it with zero)
-	    var c = mf(adata[0], bdata[0]);
-	    // loop data
-	    for (var i = 1; i < n; i++) {
-	      // multiply and accumulate
-	      c = af(c, mf(adata[i], bdata[i]));
-	    }
-	    return c;
-	  };
-
-	  /**
-	   * C = A * B
-	   *
-	   * @param {Matrix} a            Dense Vector   (M)
-	   * @param {Matrix} b            Matrix         (MxN)
-	   *
-	   * @return {Matrix}             Dense Vector   (N)
-	   */
-	  var _multiplyVectorMatrix = function (a, b) {
-	    // process storage
-	    switch (b.storage()) {
-	      case 'dense':
-	        return _multiplyVectorDenseMatrix(a, b);
-	    }
-	    throw new Error('Not implemented');
-	  };
-
-	  /**
-	   * C = A * B
-	   *
-	   * @param {Matrix} a            Dense Vector   (M)
-	   * @param {Matrix} b            Dense Matrix   (MxN)
-	   *
-	   * @return {Matrix}             Dense Vector   (N)
-	   */
-	  var _multiplyVectorDenseMatrix = function (a, b) {
-	    // a dense
-	    var adata = a._data;
-	    var asize = a._size;
-	    var adt = a._datatype;
-	    // b dense
-	    var bdata = b._data;
-	    var bsize = b._size;
-	    var bdt = b._datatype;
-	    // rows & columns
-	    var alength = asize[0];
-	    var bcolumns = bsize[1];
-
-	    // datatype
-	    var dt;
-	    // addScalar signature to use
-	    var af = addScalar;
-	    // multiplyScalar signature to use
-	    var mf = multiplyScalar;
-
-	    // process data types
-	    if (adt && bdt && adt === bdt && typeof adt === 'string') {
-	      // datatype
-	      dt = adt;
-	      // find signatures that matches (dt, dt)
-	      af = typed.find(addScalar, [dt, dt]);
-	      mf = typed.find(multiplyScalar, [dt, dt]);
-	    }
-
-	    // result
-	    var c = [];
-
-	    // loop matrix columns
-	    for (var j = 0; j < bcolumns; j++) {
-	      // sum (do not initialize it with zero)
-	      var sum = mf(adata[0], bdata[0][j]);      
-	      // loop vector
-	      for (var i = 1; i < alength; i++) {
-	        // multiply & accumulate
-	        sum = af(sum, mf(adata[i], bdata[i][j]));
-	      }
-	      c[j] = sum;
-	    }
-
-	    // check we need to squeeze the result into a scalar
-	    if (bcolumns === 1)
-	      return c[0];
-
-	    // return matrix
-	    return new DenseMatrix({
-	      data: c,
-	      size: [bcolumns],
-	      datatype: dt
-	    });
-	  };
-
-	  /**
-	   * C = A * B
-	   *
-	   * @param {Matrix} a            Matrix         (MxN)
-	   * @param {Matrix} b            Dense Vector   (N)
-	   *
-	   * @return {Matrix}             Dense Vector   (M)
-	   */
-	  var _multiplyMatrixVector = function (a, b) {
-	    // process storage
-	    switch (a.storage()) {
-	      case 'dense':
-	        return _multiplyDenseMatrixVector(a, b);
-	      case 'sparse':
-	        return _multiplySparseMatrixVector(a, b);
-	    }
-	  };
-
-	  /**
-	   * C = A * B
-	   *
-	   * @param {Matrix} a            Matrix         (MxN)
-	   * @param {Matrix} b            Matrix         (NxC)
-	   *
-	   * @return {Matrix}             Matrix         (MxC)
-	   */
-	  var _multiplyMatrixMatrix = function (a, b) {
-	    // process storage
-	    switch (a.storage()) {
-	      case 'dense':
-	        // process storage
-	        switch (b.storage()) {
-	          case 'dense':
-	            return _multiplyDenseMatrixDenseMatrix(a, b);
-	          case 'sparse':
-	            return _multiplyDenseMatrixSparseMatrix(a, b);
-	        }
-	        break;
-	      case 'sparse':
-	        // process storage
-	        switch (b.storage()) {
-	          case 'dense':
-	            return _multiplySparseMatrixDenseMatrix(a, b);
-	          case 'sparse':
-	            return _multiplySparseMatrixSparseMatrix(a, b);
-	        }
-	        break;
-	    }
-	  };
-
-	  /**
-	   * C = A * B
-	   *
-	   * @param {Matrix} a            DenseMatrix  (MxN)
-	   * @param {Matrix} b            Dense Vector (N)
-	   *
-	   * @return {Matrix}             Dense Vector (M) 
-	   */ 
-	  var _multiplyDenseMatrixVector = function (a, b) {
-	    // a dense
-	    var adata = a._data;
-	    var asize = a._size;
-	    var adt = a._datatype;
-	    // b dense
-	    var bdata = b._data;
-	    var bdt = b._datatype;
-	    // rows & columns
-	    var arows = asize[0];
-	    var acolumns = asize[1];
-
-	    // datatype
-	    var dt;
-	    // addScalar signature to use
-	    var af = addScalar;
-	    // multiplyScalar signature to use
-	    var mf = multiplyScalar;
-
-	    // process data types
-	    if (adt && bdt && adt === bdt && typeof adt === 'string') {
-	      // datatype
-	      dt = adt;
-	      // find signatures that matches (dt, dt)
-	      af = typed.find(addScalar, [dt, dt]);
-	      mf = typed.find(multiplyScalar, [dt, dt]);
-	    }
-
-	    // result
-	    var c = [];
-
-	    // loop matrix a rows
-	    for (var i = 0; i < arows; i++) {
-	      // current row
-	      var row = adata[i];
-	      // sum (do not initialize it with zero)
-	      var sum = mf(row[0], bdata[0]);
-	      // loop matrix a columns
-	      for (var j = 1; j < acolumns; j++) {
-	        // multiply & accumulate
-	        sum = af(sum, mf(row[j], bdata[j]));
-	      }
-	      c[i] = sum;
-	    }
-	    // check we need to squeeze the result into a scalar
-	    if (arows === 1)
-	      return c[0];
-
-	    // return matrix
-	    return new DenseMatrix({
-	      data: c,
-	      size: [arows],
-	      datatype: dt
-	    });
-	  };
-
-	  /**
-	   * C = A * B
-	   *
-	   * @param {Matrix} a            DenseMatrix    (MxN)
-	   * @param {Matrix} b            DenseMatrix    (NxC)
-	   *
-	   * @return {Matrix}             DenseMatrix    (MxC)
-	   */
-	  var _multiplyDenseMatrixDenseMatrix = function (a, b) {
-	    // a dense
-	    var adata = a._data;
-	    var asize = a._size;
-	    var adt = a._datatype;
-	    // b dense
-	    var bdata = b._data;
-	    var bsize = b._size;
-	    var bdt = b._datatype;
-	    // rows & columns
-	    var arows = asize[0];
-	    var acolumns = asize[1];
-	    var bcolumns = bsize[1];
-
-	    // datatype
-	    var dt;
-	    // addScalar signature to use
-	    var af = addScalar;
-	    // multiplyScalar signature to use
-	    var mf = multiplyScalar;
-
-	    // process data types
-	    if (adt && bdt && adt === bdt && typeof adt === 'string') {
-	      // datatype
-	      dt = adt;
-	      // find signatures that matches (dt, dt)
-	      af = typed.find(addScalar, [dt, dt]);
-	      mf = typed.find(multiplyScalar, [dt, dt]);
-	    }
-	    
-	    // result
-	    var c = [];
-
-	    // loop matrix a rows
-	    for (var i = 0; i < arows; i++) {
-	      // current row
-	      var row = adata[i];
-	      // initialize row array
-	      c[i] = [];
-	      // loop matrix b columns
-	      for (var j = 0; j < bcolumns; j++) {
-	        // sum (avoid initializing sum to zero)
-	        var sum = mf(row[0], bdata[0][j]);
-	        // loop matrix a columns
-	        for (var x = 1; x < acolumns; x++) {
-	          // multiply & accumulate
-	          sum = af(sum, mf(row[x], bdata[x][j]));
-	        }
-	        c[i][j] = sum;
-	      }
-	    }
-	    // check we need to squeeze the result into a scalar
-	    if (arows === 1 && bcolumns === 1)
-	      return c[0][0];
-
-	    // return matrix
-	    return new DenseMatrix({
-	      data: c,
-	      size: [arows, bcolumns],
-	      datatype: dt
-	    });
-	  };
-
-	  /**
-	   * C = A * B
-	   *
-	   * @param {Matrix} a            DenseMatrix    (MxN)
-	   * @param {Matrix} b            SparseMatrix   (NxC)
-	   *
-	   * @return {Matrix}             SparseMatrix   (MxC)
-	   */
-	  var _multiplyDenseMatrixSparseMatrix = function (a, b) {
-	    // a dense
-	    var adata = a._data;
-	    var asize = a._size;
-	    var adt = a._datatype;
-	    // b sparse
-	    var bvalues = b._values;
-	    var bindex = b._index;
-	    var bptr = b._ptr;
-	    var bsize = b._size;
-	    var bdt = b._datatype;
-	    // validate b matrix
-	    if (!bvalues)
-	      throw new Error('Cannot multiply Dense Matrix times Pattern only Matrix');
-	    // rows & columns
-	    var arows = asize[0];
-	    var bcolumns = bsize[1];
-	    
-	    // datatype
-	    var dt;
-	    // addScalar signature to use
-	    var af = addScalar;
-	    // multiplyScalar signature to use
-	    var mf = multiplyScalar;
-	    // equalScalar signature to use
-	    var eq = equalScalar;
-	    // zero value
-	    var zero = 0;
-
-	    // process data types
-	    if (adt && bdt && adt === bdt && typeof adt === 'string') {
-	      // datatype
-	      dt = adt;
-	      // find signatures that matches (dt, dt)
-	      af = typed.find(addScalar, [dt, dt]);
-	      mf = typed.find(multiplyScalar, [dt, dt]);
-	      eq = typed.find(equalScalar, [dt, dt]);
-	      // convert 0 to the same datatype
-	      zero = typed.convert(0, dt);
-	    }
-
-	    // result
-	    var cvalues = [];
-	    var cindex = [];
-	    var cptr = [];
-	    // c matrix
-	    var c = new SparseMatrix({
-	      values : cvalues,
-	      index: cindex,
-	      ptr: cptr,
-	      size: [arows, bcolumns],
-	      datatype: dt
-	    });
-
-	    // loop b columns
-	    for (var jb = 0; jb < bcolumns; jb++) {
-	      // update ptr
-	      cptr[jb] = cindex.length;
-	      // indeces in column jb
-	      var kb0 = bptr[jb];
-	      var kb1 = bptr[jb + 1];
-	      // do not process column jb if no data exists
-	      if (kb1 > kb0) {
-	        // last row mark processed
-	        var last = 0;
-	        // loop a rows
-	        for (var i = 0; i < arows; i++) {
-	          // column mark
-	          var mark = i + 1;
-	          // C[i, jb]
-	          var cij;
-	          // values in b column j
-	          for (var kb = kb0; kb < kb1; kb++) {
-	            // row
-	            var ib = bindex[kb];
-	            // check value has been initialized
-	            if (last !== mark) {
-	              // first value in column jb
-	              cij = mf(adata[i][ib], bvalues[kb]);
-	              // update mark
-	              last = mark;
-	            }
-	            else {
-	              // accumulate value
-	              cij = af(cij, mf(adata[i][ib], bvalues[kb]));
-	            }
-	          }
-	          // check column has been processed and value != 0
-	          if (last === mark && !eq(cij, zero)) {
-	            // push row & value
-	            cindex.push(i);
-	            cvalues.push(cij);
-	          }
-	        }
-	      }
-	    }
-	    // update ptr
-	    cptr[bcolumns] = cindex.length;
-
-	    // check we need to squeeze the result into a scalar
-	    if (arows === 1 && bcolumns === 1)
-	      return cvalues.length === 1 ? cvalues[0] : 0;
-
-	    // return sparse matrix
-	    return c;
-	  };
-
-	  /**
-	   * C = A * B
-	   *
-	   * @param {Matrix} a            SparseMatrix    (MxN)
-	   * @param {Matrix} b            Dense Vector (N)
-	   *
-	   * @return {Matrix}             SparseMatrix    (M, 1) 
-	   */
-	  var _multiplySparseMatrixVector = function (a, b) {
-	    // a sparse
-	    var avalues = a._values;
-	    var aindex = a._index;
-	    var aptr = a._ptr;
-	    var adt = a._datatype;
-	    // validate a matrix
-	    if (!avalues)
-	      throw new Error('Cannot multiply Pattern only Matrix times Dense Matrix');
-	    // b dense
-	    var bdata = b._data;
-	    var bdt = b._datatype;
-	    // rows & columns
-	    var arows = a._size[0];
-	    var brows = b._size[0];
-	    // result
-	    var cvalues = [];
-	    var cindex = [];
-	    var cptr = [];
-	    
-	    // datatype
-	    var dt;
-	    // addScalar signature to use
-	    var af = addScalar;
-	    // multiplyScalar signature to use
-	    var mf = multiplyScalar;
-	    // equalScalar signature to use
-	    var eq = equalScalar;
-	    // zero value
-	    var zero = 0;
-
-	    // process data types
-	    if (adt && bdt && adt === bdt && typeof adt === 'string') {
-	      // datatype
-	      dt = adt;
-	      // find signatures that matches (dt, dt)
-	      af = typed.find(addScalar, [dt, dt]);
-	      mf = typed.find(multiplyScalar, [dt, dt]);
-	      eq = typed.find(equalScalar, [dt, dt]);
-	      // convert 0 to the same datatype
-	      zero = typed.convert(0, dt);
-	    }
-
-	    // workspace
-	    var x = [];
-	    // vector with marks indicating a value x[i] exists in a given column
-	    var w = [];
-
-	    // update ptr
-	    cptr[0] = 0;
-	    // rows in b
-	    for (var ib = 0; ib < brows; ib++) {
-	      // b[ib]
-	      var vbi = bdata[ib];
-	      // check b[ib] != 0, avoid loops
-	      if (!eq(vbi, zero)) {
-	        // A values & index in ib column
-	        for (var ka0 = aptr[ib], ka1 = aptr[ib + 1], ka = ka0; ka < ka1; ka++) {
-	          // a row
-	          var ia = aindex[ka];
-	          // check value exists in current j
-	          if (!w[ia]) {
-	            // ia is new entry in j
-	            w[ia] = true;
-	            // add i to pattern of C
-	            cindex.push(ia);
-	            // x(ia) = A
-	            x[ia] = mf(vbi, avalues[ka]);
-	          }
-	          else {
-	            // i exists in C already
-	            x[ia] = af(x[ia], mf(vbi, avalues[ka]));
-	          }
-	        }
-	      }
-	    }
-	    // copy values from x to column jb of c
-	    for (var p1 = cindex.length, p = 0; p < p1; p++) {
-	      // row
-	      var ic = cindex[p];
-	      // copy value
-	      cvalues[p] = x[ic];
-	    }
-	    // update ptr
-	    cptr[1] = cindex.length;
-
-	    // check we need to squeeze the result into a scalar
-	    if (arows === 1)
-	      return cvalues.length === 1 ? cvalues[0] : 0;
-
-	    // return sparse matrix
-	    return new SparseMatrix({
-	      values : cvalues,
-	      index: cindex,
-	      ptr: cptr,
-	      size: [arows, 1],
-	      datatype: dt
-	    });
-	  };
-
-	  /**
-	   * C = A * B
-	   *
-	   * @param {Matrix} a            SparseMatrix      (MxN)
-	   * @param {Matrix} b            DenseMatrix       (NxC)
-	   *
-	   * @return {Matrix}             SparseMatrix      (MxC)
-	   */
-	  var _multiplySparseMatrixDenseMatrix = function (a, b) {
-	    // a sparse
-	    var avalues = a._values;
-	    var aindex = a._index;
-	    var aptr = a._ptr;
-	    var adt = a._datatype;
-	    // validate a matrix
-	    if (!avalues)
-	      throw new Error('Cannot multiply Pattern only Matrix times Dense Matrix');
-	    // b dense
-	    var bdata = b._data;
-	    var bdt = b._datatype;
-	    // rows & columns
-	    var arows = a._size[0];
-	    var brows = b._size[0];
-	    var bcolumns = b._size[1];
-
-	    // datatype
-	    var dt;
-	    // addScalar signature to use
-	    var af = addScalar;
-	    // multiplyScalar signature to use
-	    var mf = multiplyScalar;
-	    // equalScalar signature to use
-	    var eq = equalScalar;
-	    // zero value
-	    var zero = 0;
-
-	    // process data types
-	    if (adt && bdt && adt === bdt && typeof adt === 'string') {
-	      // datatype
-	      dt = adt;
-	      // find signatures that matches (dt, dt)
-	      af = typed.find(addScalar, [dt, dt]);
-	      mf = typed.find(multiplyScalar, [dt, dt]);
-	      eq = typed.find(equalScalar, [dt, dt]);
-	      // convert 0 to the same datatype
-	      zero = typed.convert(0, dt);
-	    }
-
-	    // result
-	    var cvalues = [];
-	    var cindex = [];
-	    var cptr = [];
-	    // c matrix
-	    var c = new SparseMatrix({
-	      values : cvalues,
-	      index: cindex,
-	      ptr: cptr,
-	      size: [arows, bcolumns],
-	      datatype: dt
-	    });
-
-	    // workspace
-	    var x = [];
-	    // vector with marks indicating a value x[i] exists in a given column
-	    var w = [];
-
-	    // loop b columns
-	    for (var jb = 0; jb < bcolumns; jb++) {
-	      // update ptr
-	      cptr[jb] = cindex.length;
-	      // mark in workspace for current column
-	      var mark = jb + 1;
-	      // rows in jb
-	      for (var ib = 0; ib < brows; ib++) {
-	        // b[ib, jb]
-	        var vbij = bdata[ib][jb];
-	        // check b[ib, jb] != 0, avoid loops
-	        if (!eq(vbij, zero)) {
-	          // A values & index in ib column
-	          for (var ka0 = aptr[ib], ka1 = aptr[ib + 1], ka = ka0; ka < ka1; ka++) {
-	            // a row
-	            var ia = aindex[ka];
-	            // check value exists in current j
-	            if (w[ia] !== mark) {
-	              // ia is new entry in j
-	              w[ia] = mark;
-	              // add i to pattern of C
-	              cindex.push(ia);
-	              // x(ia) = A
-	              x[ia] = mf(vbij, avalues[ka]);
-	            }
-	            else {
-	              // i exists in C already
-	              x[ia] = af(x[ia], mf(vbij, avalues[ka]));
-	            }
-	          }
-	        }
-	      }
-	      // copy values from x to column jb of c
-	      for (var p0 = cptr[jb], p1 = cindex.length, p = p0; p < p1; p++) {
-	        // row
-	        var ic = cindex[p];
-	        // copy value
-	        cvalues[p] = x[ic];
-	      }
-	    }
-	    // update ptr
-	    cptr[bcolumns] = cindex.length;
-
-	    // check we need to squeeze the result into a scalar
-	    if (arows === 1 && bcolumns === 1)
-	      return cvalues.length === 1 ? cvalues[0] : 0;
-
-	    // return sparse matrix
-	    return c;
-	  };
-
-	  /**
-	   * C = A * B
-	   *
-	   * @param {Matrix} a            SparseMatrix      (MxN)
-	   * @param {Matrix} b            SparseMatrix      (NxC)
-	   *
-	   * @return {Matrix}             SparseMatrix      (MxC)
-	   */
-	  var _multiplySparseMatrixSparseMatrix = function (a, b) {
-	    // a sparse
-	    var avalues = a._values;
-	    var aindex = a._index;
-	    var aptr = a._ptr;
-	    var adt = a._datatype;
-	    // b sparse
-	    var bvalues = b._values;
-	    var bindex = b._index;
-	    var bptr = b._ptr;
-	    var bdt = b._datatype;
-	    
-	    // rows & columns
-	    var arows = a._size[0];
-	    var bcolumns = b._size[1];
-	    // flag indicating both matrices (a & b) contain data
-	    var values = avalues && bvalues;
-
-	    // datatype
-	    var dt;
-	    // addScalar signature to use
-	    var af = addScalar;
-	    // multiplyScalar signature to use
-	    var mf = multiplyScalar;
-
-	    // process data types
-	    if (adt && bdt && adt === bdt && typeof adt === 'string') {
-	      // datatype
-	      dt = adt;
-	      // find signatures that matches (dt, dt)
-	      af = typed.find(addScalar, [dt, dt]);
-	      mf = typed.find(multiplyScalar, [dt, dt]);
-	    }
-	    
-	    // result
-	    var cvalues = values ? [] : undefined;
-	    var cindex = [];
-	    var cptr = [];
-	    // c matrix
-	    var c = new SparseMatrix({
-	      values : cvalues,
-	      index: cindex,
-	      ptr: cptr,
-	      size: [arows, bcolumns],
-	      datatype: dt
-	    });
-
-	    // workspace
-	    var x = values ? [] : undefined;
-	    // vector with marks indicating a value x[i] exists in a given column
-	    var w = [];
-	    // variables
-	    var ka, ka0, ka1, kb, kb0, kb1, ia, ib;
-	    // loop b columns
-	    for (var jb = 0; jb < bcolumns; jb++) {
-	      // update ptr
-	      cptr[jb] = cindex.length;
-	      // mark in workspace for current column
-	      var mark = jb + 1;
-	      // B values & index in j
-	      for (kb0 = bptr[jb], kb1 = bptr[jb + 1], kb = kb0; kb < kb1; kb++) {
-	        // b row
-	        ib = bindex[kb];
-	        // check we need to process values
-	        if (values) {
-	          // loop values in a[:,ib]
-	          for (ka0 = aptr[ib], ka1 = aptr[ib + 1], ka = ka0; ka < ka1; ka++) {
-	            // row
-	            ia = aindex[ka];
-	            // check value exists in current j
-	            if (w[ia] !== mark) {
-	              // ia is new entry in j
-	              w[ia] = mark;
-	              // add i to pattern of C
-	              cindex.push(ia);
-	              // x(ia) = A
-	              x[ia] = mf(bvalues[kb], avalues[ka]);
-	            }
-	            else {
-	              // i exists in C already
-	              x[ia] = af(x[ia], mf(bvalues[kb], avalues[ka]));
-	            }
-	          }
-	        }
-	        else {
-	          // loop values in a[:,ib]
-	          for (ka0 = aptr[ib], ka1 = aptr[ib + 1], ka = ka0; ka < ka1; ka++) {
-	            // row
-	            ia = aindex[ka];
-	            // check value exists in current j
-	            if (w[ia] !== mark) {
-	              // ia is new entry in j
-	              w[ia] = mark;
-	              // add i to pattern of C
-	              cindex.push(ia);
-	            }
-	          }
-	        }
-	      }
-	      // check we need to process matrix values (pattern matrix)
-	      if (values) {
-	        // copy values from x to column jb of c
-	        for (var p0 = cptr[jb], p1 = cindex.length, p = p0; p < p1; p++) {
-	          // row
-	          var ic = cindex[p];
-	          // copy value
-	          cvalues[p] = x[ic];
-	        }
-	      }
-	    }
-	    // update ptr
-	    cptr[bcolumns] = cindex.length;
-
-	    // check we need to squeeze the result into a scalar
-	    if (arows === 1 && bcolumns === 1 && values)
-	      return cvalues.length === 1 ? cvalues[0] : 0;
-
-	    // return sparse matrix
-	    return c;
-	  };
-
-	  multiply.toTex = '\\left(${args[0]}' + latex.operators['multiply'] + '${args[1]}\\right)';
-
-	  return multiply;
-	}
-
-	exports.name = 'multiply';
-	exports.factory = factory;
-
-
-/***/ },
-/* 41 */
-/***/ function(module, exports) {
-
-	'use strict';
-
-	function factory(type, config, load, typed) {
-	  
-	  /**
-	   * Multiply two scalar values, `x * y`.
-	   * This function is meant for internal use: it is used by the public function
-	   * `multiply`
-	   *
-	   * This function does not support collections (Array or Matrix), and does
-	   * not validate the number of of inputs.
-	   *
-	   * @param  {number | BigNumber | Fraction | Complex | Unit} x   First value to multiply
-	   * @param  {number | BigNumber | Fraction | Complex} y          Second value to multiply
-	   * @return {number | BigNumber | Fraction | Complex | Unit}                      Multiplication of `x` and `y`
-	   * @private
-	   */
-	  var multiplyScalar = typed('multiplyScalar', {
-
-	    'number, number': function (x, y) {
-	      return x * y;
-	    },
-
-	    'Complex, Complex': function (x, y) {
-	      return new type.Complex(
-	        x.re * y.re - x.im * y.im,
-	        x.re * y.im + x.im * y.re
-	      );
-	    },
-
-	    'BigNumber, BigNumber': function (x, y) {
-	      return x.times(y);
-	    },
-
-	    'Fraction, Fraction': function (x, y) {
-	      return x.mul(y);
-	    },
-
-	    'number, Unit': function (x, y) {
-	      var res = y.clone();
-	      res.value = (res.value === null) ? res._normalize(x) : (res.value * x);
-	      return res;
-	    },
-
-	    'Unit, number': function (x, y) {
-	      var res = x.clone();
-	      res.value = (res.value === null) ? res._normalize(y) : (res.value * y);
-	      return res;
-	    },
-
-	    'Unit, Unit': function (x, y) {
-	      return x.multiply(y);
-	    }
-
-	  });
-
-	  return multiplyScalar;
-	}
-
-	exports.factory = factory;
-
-
-/***/ },
-/* 42 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	function factory (type, config, load, typed) {
-
-	  var equalScalar = load(__webpack_require__(33));
-
-	  var SparseMatrix = type.SparseMatrix;
-
-	  /**
-	   * Iterates over SparseMatrix S nonzero items and invokes the callback function f(Sij, b). 
-	   * Callback function invoked NZ times (number of nonzero items in S).
-	   *
-	   *
-	   *          ┌  f(Sij, b)  ; S(i,j) !== 0
-	   * C(i,j) = ┤  
-	   *          └  0          ; otherwise
-	   *
-	   *
-	   * @param {Matrix}   s                 The SparseMatrix instance (S)
-	   * @param {Scalar}   b                 The Scalar value
-	   * @param {Function} callback          The f(Aij,b) operation to invoke
-	   * @param {boolean}  inverse           A true value indicates callback should be invoked f(b,Sij)
-	   *
-	   * @return {Matrix}                    SparseMatrix (C)
-	   *
-	   * https://github.com/josdejong/mathjs/pull/346#issuecomment-97626813
-	   */
-	  var algorithm11 = function (s, b, callback, inverse) {
-	    // sparse matrix arrays
-	    var avalues = s._values;
-	    var aindex = s._index;
-	    var aptr = s._ptr;
-	    var asize = s._size;
-	    var adt = s._datatype;
-
-	    // sparse matrix cannot be a Pattern matrix
-	    if (!avalues)
-	      throw new Error('Cannot perform operation on Pattern Sparse Matrix and Scalar value');
-
-	    // rows & columns
-	    var rows = asize[0];
-	    var columns = asize[1];
-
-	    // datatype
-	    var dt;
-	    // equal signature to use
-	    var eq = equalScalar;
-	    // zero value
-	    var zero = 0;
-	    // callback signature to use
-	    var cf = callback;
-
-	    // process data types
-	    if (typeof adt === 'string') {
-	      // datatype
-	      dt = adt;
-	      // find signature that matches (dt, dt)
-	      eq = typed.find(equalScalar, [dt, dt]);
-	      // convert 0 to the same datatype
-	      zero = typed.convert(0, dt);
-	      // convert b to the same datatype
-	      b = typed.convert(b, dt);
-	      // callback
-	      cf = typed.find(callback, [dt, dt]);
-	    }
-
-	    // result arrays
-	    var cvalues = [];
-	    var cindex = [];
-	    var cptr = [];
-	    // matrix
-	    var c = new SparseMatrix({
-	      values: cvalues,
-	      index: cindex,
-	      ptr: cptr,
-	      size: [rows, columns],
-	      datatype: dt
-	    });
-
-	    // loop columns
-	    for (var j = 0; j < columns; j++) {
-	      // initialize ptr
-	      cptr[j] = cindex.length;
-	      // values in j
-	      for (var k0 = aptr[j], k1 = aptr[j + 1], k = k0; k < k1; k++) {
-	        // row
-	        var i = aindex[k];
-	        // invoke callback
-	        var v = inverse ? cf(b, avalues[k]) : cf(avalues[k], b);
-	        // check value is zero
-	        if (!eq(v, zero)) {
-	          // push index & value
-	          cindex.push(i);
-	          cvalues.push(v);
-	        }
-	      }
-	    }
-	    // update ptr
-	    cptr[columns] = cindex.length;
-
-	    // return sparse matrix
-	    return c;
-	  };
-
-	  return algorithm11;
-	}
-
-	exports.name = 'algorithm11';
-	exports.factory = factory;
-
-
-/***/ },
-/* 43 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	var util = __webpack_require__(36);
-	var object = util.object;
-	var string = util.string;
-
-	function factory (type, config, load, typed) {
-	  var matrix = load(__webpack_require__(23));
-	  var add = load(__webpack_require__(44));
-	  var subtract = load(__webpack_require__(25));
-	  var multiply = load(__webpack_require__(40));
-	  var unaryMinus = load(__webpack_require__(28));
-
-	  /**
-	   * Calculate the determinant of a matrix.
-	   *
-	   * Syntax:
-	   *
-	   *    math.det(x)
-	   *
-	   * Examples:
-	   *
-	   *    math.det([[1, 2], [3, 4]]); // returns -2
-	   *
-	   *    var A = [
-	   *      [-2, 2, 3],
-	   *      [-1, 1, 3],
-	   *      [2, 0, -1]
-	   *    ]
-	   *    math.det(A); // returns 6
-	   *
-	   * See also:
-	   *
-	   *    inv
-	   *
-	   * @param {Array | Matrix} x  A matrix
-	   * @return {number} The determinant of `x`
-	   */
-	  var det = typed('det', {
-	    'any': function (x) {
-	      return object.clone(x);
-	    },
-
-	    'Array | Matrix': function det (x) {
-	      var size;
-	      if (x && x.isMatrix === true) {
-	        size = x.size();
-	      }
-	      else if (Array.isArray(x)) {
-	        x = matrix(x);
-	        size = x.size();
-	      }
-	      else {
-	        // a scalar
-	        size = [];
-	      }
-
-	      switch (size.length) {
-	        case 0:
-	          // scalar
-	          return object.clone(x);
-
-	        case 1:
-	          // vector
-	          if (size[0] == 1) {
-	            return object.clone(x.valueOf()[0]);
-	          }
-	          else {
-	            throw new RangeError('Matrix must be square ' +
-	            '(size: ' + string.format(size) + ')');
-	          }
-
-	        case 2:
-	          // two dimensional array
-	          var rows = size[0];
-	          var cols = size[1];
-	          if (rows == cols) {
-	            return _det(x.clone().valueOf(), rows, cols);
-	          }
-	          else {
-	            throw new RangeError('Matrix must be square ' +
-	            '(size: ' + string.format(size) + ')');
-	          }
-
-	        default:
-	          // multi dimensional array
-	          throw new RangeError('Matrix must be two dimensional ' +
-	          '(size: ' + string.format(size) + ')');
-	      }
-	    }
-	  });
-
-	  det.toTex = '\\det\\left(${args[0]}\\right)';
-
-	  return det;
-
-	  /**
-	   * Calculate the determinant of a matrix
-	   * @param {Array[]} matrix  A square, two dimensional matrix
-	   * @param {number} rows     Number of rows of the matrix (zero-based)
-	   * @param {number} cols     Number of columns of the matrix (zero-based)
-	   * @returns {number} det
-	   * @private
-	   */
-	  function _det (matrix, rows, cols) {
-	    if (rows == 1) {
-	      // this is a 1 x 1 matrix
-	      return object.clone(matrix[0][0]);
-	    }
-	    else if (rows == 2) {
-	      // this is a 2 x 2 matrix
-	      // the determinant of [a11,a12;a21,a22] is det = a11*a22-a21*a12
-	      return subtract(
-	          multiply(matrix[0][0], matrix[1][1]),
-	          multiply(matrix[1][0], matrix[0][1])
-	      );
-	    }
-	    else {
-	      // this is an n x n matrix
-	      var compute_mu = function (matrix) {
-	        var i, j;
-
-	        // Compute the matrix with zero lower triangle, same upper triangle,
-	        // and diagonals given by the negated sum of the below diagonal
-	        // elements.
-	        var mu = new Array(matrix.length);
-	        var sum = 0;
-	        for (i = 1; i < matrix.length; i++) {
-	          sum = add(sum, matrix[i][i]);
-	        }
-
-	        for (i = 0; i < matrix.length; i++) {
-	          mu[i] = new Array(matrix.length);
-	          mu[i][i] = unaryMinus(sum);
-
-	          for (j = 0; j < i; j++) {
-	            mu[i][j] = 0; // TODO: make bignumber 0 in case of bignumber computation
-	          }
-
-	          for (j = i + 1; j < matrix.length; j++) {
-	            mu[i][j] = matrix[i][j];
-	          }
-
-	          if (i+1 < matrix.length) {
-	            sum = subtract(sum, matrix[i + 1][i + 1]);
-	          }
-	        }
-
-	        return mu;
-	      };
-
-	      var fa = matrix;
-	      for (var i = 0; i < rows - 1; i++) {
-	        fa = multiply(compute_mu(fa), matrix);
-	      }
-
-	      if (rows % 2 == 0) {
-	        return unaryMinus(fa[0][0]);
-	      } else {
-	        return fa[0][0];
-	      }
-	    }
-	  }
-	}
-
-	exports.name = 'det';
-	exports.factory = factory;
-
-
-
-/***/ },
-/* 44 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	var extend = __webpack_require__(5).extend;
-
-	function factory (type, config, load, typed) {
-
-	  var matrix = load(__webpack_require__(23));
-	  var addScalar = load(__webpack_require__(27));
-	  var latex = __webpack_require__(26);
-	  
-	  var algorithm01 = load(__webpack_require__(30));
-	  var algorithm04 = load(__webpack_require__(45));
-	  var algorithm10 = load(__webpack_require__(34));
-	  var algorithm13 = load(__webpack_require__(35));
-	  var algorithm14 = load(__webpack_require__(39));
-
-	  /**
-	   * Add two values, `x + y`.
-	   * For matrices, the function is evaluated element wise.
-	   *
-	   * Syntax:
-	   *
-	   *    math.add(x, y)
-	   *
-	   * Examples:
-	   *
-	   *    math.add(2, 3);               // returns number 5
-	   *
-	   *    var a = math.complex(2, 3);
-	   *    var b = math.complex(-4, 1);
-	   *    math.add(a, b);               // returns Complex -2 + 4i
-	   *
-	   *    math.add([1, 2, 3], 4);       // returns Array [5, 6, 7]
-	   *
-	   *    var c = math.unit('5 cm');
-	   *    var d = math.unit('2.1 mm');
-	   *    math.add(c, d);               // returns Unit 52.1 mm
-	   *
-	   *    math.add("2.3", "4");         // returns number 6.3
-	   *
-	   * See also:
-	   *
-	   *    subtract
-	   *
-	   * @param  {number | BigNumber | Fraction | Complex | Unit | Array | Matrix} x First value to add
-	   * @param  {number | BigNumber | Fraction | Complex | Unit | Array | Matrix} y Second value to add
-	   * @return {number | BigNumber | Fraction | Complex | Unit | Array | Matrix} Sum of `x` and `y`
-	   */
-	  var add = typed('add', extend({
-	    // we extend the signatures of addScalar with signatures dealing with matrices
-
-	    'Matrix, Matrix': function (x, y) {
-	      // result
-	      var c;
-	      
-	      // process matrix storage
-	      switch (x.storage()) {
-	        case 'sparse':
-	          switch (y.storage()) {
-	            case 'sparse':
-	              // sparse + sparse
-	              c = algorithm04(x, y, addScalar);
-	              break;
-	            default:
-	              // sparse + dense
-	              c = algorithm01(y, x, addScalar, true);
-	              break;
-	          }
-	          break;
-	        default:
-	          switch (y.storage()) {
-	            case 'sparse':
-	              // dense + sparse
-	              c = algorithm01(x, y, addScalar, false);
-	              break;
-	            default:
-	              // dense + dense
-	              c = algorithm13(x, y, addScalar);
-	              break;
-	          }
-	          break;
-	      }
-	      return c;
-	    },
-	    
-	    'Array, Array': function (x, y) {
-	      // use matrix implementation
-	      return add(matrix(x), matrix(y)).valueOf();
-	    },
-	    
-	    'Array, Matrix': function (x, y) {
-	      // use matrix implementation
-	      return add(matrix(x), y);
-	    },
-	    
-	    'Matrix, Array': function (x, y) {
-	      // use matrix implementation
-	      return add(x, matrix(y));
-	    },
-	    
-	    'Matrix, any': function (x, y) {
-	      // result
-	      var c;
-	      // check storage format
-	      switch (x.storage()) {
-	        case 'sparse':
-	          c = algorithm10(x, y, addScalar, false);
-	          break;
-	        default:
-	          c = algorithm14(x, y, addScalar, false);
-	          break;
-	      }
-	      return c;
-	    },
-	    
-	    'any, Matrix': function (x, y) {
-	      // result
-	      var c;
-	      // check storage format
-	      switch (y.storage()) {
-	        case 'sparse':
-	          c = algorithm10(y, x, addScalar, true);
-	          break;
-	        default:
-	          c = algorithm14(y, x, addScalar, true);
-	          break;
-	      }
-	      return c;
-	    },
-	    
-	    'Array, any': function (x, y) {
-	      // use matrix implementation
-	      return algorithm14(matrix(x), y, addScalar, false).valueOf();
-	    },
-
-	    'any, Array': function (x, y) {
-	      // use matrix implementation
-	      return algorithm14(matrix(y), x, addScalar, true).valueOf();
-	    }
-	  }, addScalar.signatures));
-
-	  add.toTex = '\\left(${args[0]}' + latex.operators['add'] + '${args[1]}\\right)';
-	  
-	  return add;
-	}
-
-	exports.name = 'add';
-	exports.factory = factory;
-
-
-/***/ },
-/* 45 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	var DimensionError = __webpack_require__(22);
-
-	function factory (type, config, load, typed) {
-
-	  var equalScalar = load(__webpack_require__(33));
-
-	  var SparseMatrix = type.SparseMatrix;
-
-	  /**
-	   * Iterates over SparseMatrix A and SparseMatrix B nonzero items and invokes the callback function f(Aij, Bij). 
-	   * Callback function invoked MAX(NNZA, NNZB) times
-	   *
-	   *
-	   *          ┌  f(Aij, Bij)  ; A(i,j) !== 0 && B(i,j) !== 0
-	   * C(i,j) = ┤  A(i,j)       ; A(i,j) !== 0
-	   *          └  B(i,j)       ; B(i,j) !== 0
-	   *
-	   *
-	   * @param {Matrix}   a                 The SparseMatrix instance (A)
-	   * @param {Matrix}   b                 The SparseMatrix instance (B)
-	   * @param {Function} callback          The f(Aij,Bij) operation to invoke
-	   *
-	   * @return {Matrix}                    SparseMatrix (C)
-	   *
-	   * see https://github.com/josdejong/mathjs/pull/346#issuecomment-97620294
-	   */
-	  var algorithm04 = function (a, b, callback) {
-	    // sparse matrix arrays
-	    var avalues = a._values;
-	    var aindex = a._index;
-	    var aptr = a._ptr;
-	    var asize = a._size;
-	    var adt = a._datatype;
-	    // sparse matrix arrays
-	    var bvalues = b._values;
-	    var bindex = b._index;
-	    var bptr = b._ptr;
-	    var bsize = b._size;
-	    var bdt = b._datatype;
-
-	    // validate dimensions
-	    if (asize.length !== bsize.length)
-	      throw new DimensionError(asize.length, bsize.length);
-
-	    // check rows & columns
-	    if (asize[0] !== bsize[0] || asize[1] !== bsize[1])
-	      throw new RangeError('Dimension mismatch. Matrix A (' + asize + ') must match Matrix B (' + bsize + ')');
-
-	    // rows & columns
-	    var rows = asize[0];
-	    var columns = asize[1];
-
-	    // datatype
-	    var dt;
-	    // equal signature to use
-	    var eq = equalScalar;
-	    // zero value
-	    var zero = 0;
-	    // callback signature to use
-	    var cf = callback;
-
-	    // process data types
-	    if (typeof adt === 'string' && adt === bdt) {
-	      // datatype
-	      dt = adt;
-	      // find signature that matches (dt, dt)
-	      eq = typed.find(equalScalar, [dt, dt]);
-	      // convert 0 to the same datatype
-	      zero = typed.convert(0, dt);
-	      // callback
-	      cf = typed.find(callback, [dt, dt]);
-	    }
-
-	    // result arrays
-	    var cvalues = avalues && bvalues ? [] : undefined;
-	    var cindex = [];
-	    var cptr = [];
-	    // matrix
-	    var c = new SparseMatrix({
-	      values: cvalues,
-	      index: cindex,
-	      ptr: cptr,
-	      size: [rows, columns],
-	      datatype: dt
-	    });
-
-	    // workspace
-	    var xa = avalues && bvalues ? [] : undefined;
-	    var xb = avalues && bvalues ? [] : undefined;
-	    // marks indicating we have a value in x for a given column
-	    var wa = [];
-	    var wb = [];
-
-	    // vars 
-	    var i, j, k, k0, k1;
-	    
-	    // loop columns
-	    for (j = 0; j < columns; j++) {
-	      // update cptr
-	      cptr[j] = cindex.length;
-	      // columns mark
-	      var mark = j + 1;
-	      // loop A(:,j)
-	      for (k0 = aptr[j], k1 = aptr[j + 1], k = k0; k < k1; k++) {
-	        // row
-	        i = aindex[k];
-	        // update c
-	        cindex.push(i);
-	        // update workspace
-	        wa[i] = mark;
-	        // check we need to process values
-	        if (xa)
-	          xa[i] = avalues[k];
-	      }
-	      // loop B(:,j)
-	      for (k0 = bptr[j], k1 = bptr[j + 1], k = k0; k < k1; k++) {
-	        // row
-	        i = bindex[k];
-	        // check row exists in A
-	        if (wa[i] === mark) {
-	          // update record in xa @ i
-	          if (xa) {
-	            // invoke callback
-	            var v = cf(xa[i], bvalues[k]);
-	            // check for zero
-	            if (!eq(v, zero)) {
-	              // update workspace
-	              xa[i] = v;              
-	            }
-	            else {
-	              // remove mark (index will be removed later)
-	              wa[i] = null;
-	            }
-	          }
-	        }
-	        else {
-	          // update c
-	          cindex.push(i);
-	          // update workspace
-	          wb[i] = mark;
-	          // check we need to process values
-	          if (xb)
-	            xb[i] = bvalues[k];
-	        }
-	      }
-	      // check we need to process values (non pattern matrix)
-	      if (xa && xb) {
-	        // initialize first index in j
-	        k = cptr[j];
-	        // loop index in j
-	        while (k < cindex.length) {
-	          // row
-	          i = cindex[k];
-	          // check workspace has value @ i
-	          if (wa[i] === mark) {
-	            // push value (Aij != 0 || (Aij != 0 && Bij != 0))
-	            cvalues[k] = xa[i];
-	            // increment pointer
-	            k++;
-	          }
-	          else if (wb[i] === mark) {
-	            // push value (bij != 0)
-	            cvalues[k] = xb[i];
-	            // increment pointer
-	            k++;
-	          }
-	          else {
-	            // remove index @ k
-	            cindex.splice(k, 1);
-	          }
-	        }
-	      }
-	    }
-	    // update cptr
-	    cptr[columns] = cindex.length;
-
-	    // return sparse matrix
-	    return c;
-	  };
-	  
-	  return algorithm04;
-	}
-
-	exports.name = 'algorithm04';
-	exports.factory = factory;
-
-
-/***/ },
-/* 46 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	var array     = __webpack_require__(18);
-	var clone     = __webpack_require__(5).clone;
-	var isInteger = __webpack_require__(8).isInteger;
-
-	function factory (type, config, load, typed) {
-
-	  var matrix = load(__webpack_require__(23));
-	  
-	  /**
-	   * Create a diagonal matrix or retrieve the diagonal of a matrix
-	   *
-	   * When `x` is a vector, a matrix with vector `x` on the diagonal will be returned.
-	   * When `x` is a two dimensional matrix, the matrixes `k`th diagonal will be returned as vector.
-	   * When k is positive, the values are placed on the super diagonal.
-	   * When k is negative, the values are placed on the sub diagonal.
-	   *
-	   * Syntax:
-	   *
-	   *     math.diag(X)
-	   *     math.diag(X, format)
-	   *     math.diag(X, k)
-	   *     math.diag(X, k, format)
-	   *
-	   * Examples:
-	   *
-	   *     // create a diagonal matrix
-	   *     math.diag([1, 2, 3]);      // returns [[1, 0, 0], [0, 2, 0], [0, 0, 3]]
-	   *     math.diag([1, 2, 3], 1);   // returns [[0, 1, 0, 0], [0, 0, 2, 0], [0, 0, 0, 3]]
-	   *     math.diag([1, 2, 3], -1);  // returns [[0, 0, 0], [1, 0, 0], [0, 2, 0], [0, 0, 3]]
-	   *
-	   *    // retrieve the diagonal from a matrix
-	   *    var a = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
-	   *    math.diag(a);   // returns [1, 5, 9]
-	   *
-	   * See also:
-	   *
-	   *     ones, zeros, eye
-	   *
-	   * @param {Matrix | Array} x          A two dimensional matrix or a vector
-	   * @param {number | BigNumber} [k=0]  The diagonal where the vector will be filled
-	   *                                    in or retrieved.
-	   * @param {string} [format='dense']   The matrix storage format.
-	   *
-	   * @returns {Matrix | Array} Diagonal matrix from input vector, or diagonal from input matrix.
-	   */
-	  var diag = typed('diag', {
-	    // FIXME: simplify this huge amount of signatures as soon as typed-function supports optional arguments
-
-	    'Array': function (x) {
-	      return _diag(x, 0, array.size(x), null);
-	    },
-
-	    'Array, number': function (x, k) {
-	      return _diag(x, k, array.size(x), null);
-	    },
-	    
-	    'Array, BigNumber': function (x, k) {
-	      return _diag(x, k.toNumber(), array.size(x), null);
-	    },
-
-	    'Array, string': function (x, format) {
-	      return _diag(x, 0, array.size(x), format);
-	    },
-
-	    'Array, number, string': function (x, k, format) {
-	      return _diag(x, k, array.size(x), format);
-	    },
-
-	    'Array, BigNumber, string': function (x, k, format) {
-	      return _diag(x, k.toNumber(), array.size(x), format);
-	    },
-
-	    'Matrix': function (x) {
-	      return _diag(x, 0, x.size(), x.storage());
-	    },
-
-	    'Matrix, number': function (x, k) {
-	      return _diag(x, k, x.size(), x.storage());
-	    },
-
-	    'Matrix, BigNumber': function (x, k) {
-	      return _diag(x, k.toNumber(), x.size(), x.storage());
-	    },
-
-	    'Matrix, string': function (x, format) {
-	      return _diag(x, 0, x.size(), format);
-	    },
-
-	    'Matrix, number, string': function (x, k, format) {
-	      return _diag(x, k, x.size(), format);
-	    },
-
-	    'Matrix, BigNumber, string': function (x, k, format) {
-	      return _diag(x, k.toNumber(), x.size(), format);
-	    }
-	  });
-
-	  diag.toTex = '\\mathrm{${name}}\\left(${args}\\right)';
-
-	  return diag;
-
-	  /**
-	   * Creeate diagonal matrix from a vector or vice versa
-	   * @param {Array | Matrix} x
-	   * @param {number} k
-	   * @param {string} format Storage format for matrix. If null,
-	   *                          an Array is returned
-	   * @returns {Array | Matrix}
-	   * @private
-	   */
-	  function _diag (x, k, size, format) {
-	    if (!isInteger(k)) {
-	      throw new TypeError ('Second parameter in function diag must be an integer');
-	    }
-	    
-	    var kSuper = k > 0 ? k : 0;
-	    var kSub = k < 0 ? -k : 0;
-
-	    // check dimensions
-	    switch (size.length) {
-	      case 1:
-	        return _createDiagonalMatrix(x, k, format, size[0], kSub, kSuper);
-	      case 2:
-	        return _getDiagonal(x, k, format, size, kSub, kSuper);
-	    }
-	    throw new RangeError('Matrix for function diag must be 2 dimensional');
-	  }
-	  
-	  function _createDiagonalMatrix(x, k, format, l, kSub, kSuper) {
-	    // matrix size
-	    var ms = [l + kSub, l + kSuper];
-	    // get matrix constructor
-	    var F = type.Matrix.storage(format || 'dense');
-	    // create diagonal matrix
-	    var m = F.diagonal(ms, x, k);
-	    // check we need to return a matrix
-	    return format !== null ? m : m.valueOf();
-	  }
-	  
-	  function _getDiagonal(x, k, format, s, kSub, kSuper) {
-	    // check x is a Matrix
-	    if (x && x.isMatrix === true) {
-	      // get diagonal matrix
-	      var dm = x.diagonal(k);
-	      // check we need to return a matrix
-	      if (format !== null) {
-	        // check we need to change matrix format
-	        if (format !== dm.storage())
-	          return matrix(dm, format);
-	        return dm;
-	      }
-	      return dm.valueOf();
-	    }
-	    // vector size
-	    var n = Math.min(s[0] - kSub, s[1] - kSuper);
-	    // diagonal values
-	    var vector = [];
-	    // loop diagonal
-	    for (var i = 0; i < n; i++) {
-	      vector[i] = clone(x[i + kSub][i + kSuper]);
-	    }
-	    // check we need to return a matrix
-	    return format !== null ? matrix(vector) : vector;
-	  }
-	}
-
-	exports.name = 'diag';
-	exports.factory = factory;
-
-
-/***/ },
-/* 47 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	var size = __webpack_require__(18).size;
-
-	function factory (type, config, load, typed) {
-	  var add      = load(__webpack_require__(44));
-	  var multiply = load(__webpack_require__(40));
-
-	  /**
-	   * Calculate the dot product of two vectors. The dot product of
-	   * `A = [a1, a2, a3, ..., an]` and `B = [b1, b2, b3, ..., bn]` is defined as:
-	   *
-	   *    dot(A, B) = a1 * b1 + a2 * b2 + a3 * b3 + ... + an * bn
-	   *
-	   * Syntax:
-	   *
-	   *    math.dot(x, y)
-	   *
-	   * Examples:
-	   *
-	   *    math.dot([2, 4, 1], [2, 2, 3]);       // returns number 15
-	   *    math.multiply([2, 4, 1], [2, 2, 3]);  // returns number 15
-	   *
-	   * See also:
-	   *
-	   *    multiply, cross
-	   *
-	   * @param  {Array | Matrix} x     First vector
-	   * @param  {Array | Matrix} y     Second vector
-	   * @return {number}               Returns the dot product of `x` and `y`
-	   */
-	  var dot = typed('dot', {
-	    'Matrix, Matrix': function (x, y) {
-	      return _dot(x.toArray(), y.toArray());
-	    },
-
-	    'Matrix, Array': function (x, y) {
-	      return _dot(x.toArray(), y);
-	    },
-
-	    'Array, Matrix': function (x, y) {
-	      return _dot(x, y.toArray());
-	    },
-
-	    'Array, Array': _dot
-	  });
-	  
-	  dot.toTex = '\\left(${args[0]}\\cdot${args[1]}\\right)';
-
-	  return dot;
-
-	  /**
-	   * Calculate the dot product for two arrays
-	   * @param {Array} x  First vector
-	   * @param {Array} y  Second vector
-	   * @returns {number} Returns the dot product of x and y
-	   * @private
-	   */
-	  // TODO: double code with math.multiply
-	  function _dot(x, y) {
-	    var xSize= size(x);
-	    var ySize = size(y);
-	    var len = xSize[0];
-
-	    if (xSize.length !== 1 || ySize.length !== 1) throw new RangeError('Vector expected'); // TODO: better error message
-	    if (xSize[0] != ySize[0]) throw new RangeError('Vectors must have equal length (' + xSize[0] + ' != ' + ySize[0] + ')');
-	    if (len == 0) throw new RangeError('Cannot calculate the dot product of empty vectors');
-
-	    var prod = 0;
-	    for (var i = 0; i < len; i++) {
-	      prod = add(prod, multiply(x[i], y[i]));
-	    }
-
-	    return prod;
-	  }
-	}
-
-	exports.name = 'dot';
-	exports.factory = factory;
-
-
-/***/ },
-/* 48 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	var array = __webpack_require__(18);
-	var isInteger = __webpack_require__(8).isInteger;
-
-	function factory (type, config, load, typed) {
-	  
-	  var matrix = load(__webpack_require__(23));
-	  
-	  /**
-	   * Create a 2-dimensional identity matrix with size m x n or n x n.
-	   * The matrix has ones on the diagonal and zeros elsewhere.
-	   *
-	   * Syntax:
-	   *
-	   *    math.eye(n)
-	   *    math.eye(n, format)
-	   *    math.eye(m, n)
-	   *    math.eye(m, n, format)
-	   *    math.eye([m, n])
-	   *    math.eye([m, n], format)
-	   *
-	   * Examples:
-	   *
-	   *    math.eye(3);                    // returns [[1, 0, 0], [0, 1, 0], [0, 0, 1]]
-	   *    math.eye(3, 2);                 // returns [[1, 0], [0, 1], [0, 0]]
-	   *
-	   *    var A = [[1, 2, 3], [4, 5, 6]];
-	   *    math.eye(math.size(b));         // returns [[1, 0, 0], [0, 1, 0]]
-	   *
-	   * See also:
-	   *
-	   *    diag, ones, zeros, size, range
-	   *
-	   * @param {...number | Matrix | Array} size   The size for the matrix
-	   * @param {string} [format]                   The Matrix storage format
-	   *
-	   * @return {Matrix | Array | number} A matrix with ones on the diagonal.
-	   */
-	  var eye = typed('eye', {
-	    '': function () {
-	      return (config.matrix === 'matrix') ? matrix([]) : [];
-	    },
-
-	    'string': function (format) {
-	      return matrix(format);
-	    },
-
-	    'number | BigNumber': function (rows) {
-	      return _eye(rows, rows, config.matrix === 'matrix' ? 'default' : undefined);
-	    },
-	    
-	    'number | BigNumber, string': function (rows, format) {
-	      return _eye(rows, rows, format);
-	    },
-
-	    'number | BigNumber, number | BigNumber': function (rows, cols) {
-	      return _eye(rows, cols, config.matrix === 'matrix' ? 'default' : undefined);
-	    },
-	    
-	    'number | BigNumber, number | BigNumber, string': function (rows, cols, format) {
-	      return _eye(rows, cols, format);
-	    },
-
-	    'Array':  function (size) {
-	      return _eyeVector(size);
-	    },
-	    
-	    'Array, string':  function (size, format) {
-	      return _eyeVector(size, format);
-	    },
-
-	    'Matrix': function (size) {
-	      return _eyeVector(size.valueOf(), size.storage());
-	    },
-	    
-	    'Matrix, string': function (size, format) {
-	      return _eyeVector(size.valueOf(), format);
-	    }
-	  });
-
-	  eye.toTex = '\\mathrm{${name}}\\left(${args}\\right)';
-
-	  return eye;
-
-	  function _eyeVector (size, format) {
-	    switch (size.length) {
-	      case 0: return format ? matrix(format) : [];
-	      case 1: return _eye(size[0], size[0], format);
-	      case 2: return _eye(size[0], size[1], format);
-	      default: throw new Error('Vector containing two values expected');
-	    }
-	  }
-
-	  /**
-	   * Create an identity matrix
-	   * @param {number | BigNumber} rows
-	   * @param {number | BigNumber} cols
-	   * @param {string} [format]
-	   * @returns {Matrix}
-	   * @private
-	   */
-	  function _eye (rows, cols, format) {
-	    // BigNumber constructor with the right precision
-	    var Big = (rows && rows.isBigNumber === true)
-	        ? type.BigNumber
-	        : (cols && cols.isBigNumber === true)
-	            ? type.BigNumber
-	            : null;
-
-	    if (rows && rows.isBigNumber === true) rows = rows.toNumber();
-	    if (cols && cols.isBigNumber === true) cols = cols.toNumber();
-
-	    if (!isInteger(rows) || rows < 1) {
-	      throw new Error('Parameters in function eye must be positive integers');
-	    }
-	    if (!isInteger(cols) || cols < 1) {
-	      throw new Error('Parameters in function eye must be positive integers');
-	    }
-	    
-	    var one = Big ? new type.BigNumber(1) : 1;
-	    var defaultValue = Big ? new Big(0) : 0;
-	    var size = [rows, cols];
-	    
-	    // check we need to return a matrix
-	    if (format) {
-	      // get matrix storage constructor
-	      var F = type.Matrix.storage(format);
-	      // create diagonal matrix (use optimized implementation for storage format)
-	      return F.diagonal(size, one, 0, defaultValue);
-	    }
-	    
-	    // create and resize array
-	    var res = array.resize([], size, defaultValue);
-	    // fill in ones on the diagonal
-	    var minimum = rows < cols ? rows : cols;
-	    // fill diagonal
-	    for (var d = 0; d < minimum; d++) {
-	      res[d][d] = one;
-	    }
-	    return res;
-	  }
-	}
-
-	exports.name = 'eye';
-	exports.factory = factory;
-
-
-/***/ },
-/* 49 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	var clone = __webpack_require__(5).clone;
-	var _flatten = __webpack_require__(18).flatten;
-
-	function factory (type, config, load, typed) {
-	  var matrix = load(__webpack_require__(23));
-
-	  /**
-	   * Flatten a multi dimensional matrix into a single dimensional matrix.
-	   *
-	   * Syntax:
-	   *
-	   *    math.flatten(x)
-	   *
-	   * Examples:
-	   *
-	   *    math.flatten([[1,2], [3,4]]);   // returns [1, 2, 3, 4]
-	   *
-	   * See also:
-	   *
-	   *    concat, resize, size, squeeze
-	   *
-	   * @param {Matrix | Array} x   Matrix to be flattened
-	   * @return {Matrix | Array} Returns the flattened matrix
-	   */
-	  var flatten = typed('flatten', {
-	    'Array': function (x) {
-	      return _flatten(clone(x));
-	    },
-
-	    'Matrix': function (x) {
-	      var flat = _flatten(clone(x.toArray()));
-	      // TODO: return the same matrix type as x
-	      return matrix(flat);
-	    }
-	  });
-
-	  flatten.toTex = '\\mathrm{${name}}\\left(${args}\\right)';
-
-	  return flatten;
-	}
-
-	exports.name = 'flatten';
-	exports.factory = factory;
-
-
-/***/ },
-/* 50 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	var util = __webpack_require__(36);
-
-	function factory (type, config, load, typed) {
-	  var matrix       = load(__webpack_require__(23));
-	  var divideScalar = load(__webpack_require__(51));
-	  var addScalar    = load(__webpack_require__(27));
-	  var multiply     = load(__webpack_require__(40));
-	  var unaryMinus   = load(__webpack_require__(28));
-	  var det          = load(__webpack_require__(43));
-	  var eye          = load(__webpack_require__(48));
-
-	  /**
-	   * Calculate the inverse of a square matrix.
-	   *
-	   * Syntax:
-	   *
-	   *     math.inv(x)
-	   *
-	   * Examples:
-	   *
-	   *     math.inv([[1, 2], [3, 4]]);  // returns [[-2, 1], [1.5, -0.5]]
-	   *     math.inv(4);                 // returns 0.25
-	   *     1 / 4;                       // returns 0.25
-	   *
-	   * See also:
-	   *
-	   *     det, transpose
-	   *
-	   * @param {number | Complex | Array | Matrix} x     Matrix to be inversed
-	   * @return {number | Complex | Array | Matrix} The inverse of `x`.
-	   */
-	  var inv = typed('inv', {
-	    'Array | Matrix': function (x) {
-	      var size = (x.isMatrix === true) ? x.size() : util.array.size(x);
-	      switch (size.length) {
-	        case 1:
-	          // vector
-	          if (size[0] == 1) {
-	            if (x.isMatrix === true) {
-	              return matrix([
-	                divideScalar(1, x.valueOf()[0])
-	              ]);
-	            }
-	            else {
-	              return [
-	                divideScalar(1, x[0])
-	              ];
-	            }
-	          }
-	          else {
-	            throw new RangeError('Matrix must be square ' +
-	            '(size: ' + util.string.format(size) + ')');
-	          }
-
-	        case 2:
-	          // two dimensional array
-	          var rows = size[0];
-	          var cols = size[1];
-	          if (rows == cols) {
-	            if (x.isMatrix === true) {
-	              return matrix(
-	                  _inv(x.valueOf(), rows, cols),
-	                  x.storage()
-	              );
-	            }
-	            else {
-	              // return an Array
-	              return _inv(x, rows, cols);
-	            }
-	          }
-	          else {
-	            throw new RangeError('Matrix must be square ' +
-	            '(size: ' + util.string.format(size) + ')');
-	          }
-
-	        default:
-	          // multi dimensional array
-	          throw new RangeError('Matrix must be two dimensional ' +
-	          '(size: ' + util.string.format(size) + ')');
-	      }
-	    },
-
-	    'any': function (x) {
-	      // scalar
-	      return divideScalar(1, x); // FIXME: create a BigNumber one when configured for bignumbers
-	    }
-	  });
-
-	  /**
-	   * Calculate the inverse of a square matrix
-	   * @param {Array[]} mat     A square matrix
-	   * @param {number} rows     Number of rows
-	   * @param {number} cols     Number of columns, must equal rows
-	   * @return {Array[]} inv    Inverse matrix
-	   * @private
-	   */
-	  function _inv (mat, rows, cols){
-	    var r, s, f, value, temp;
-
-	    if (rows == 1) {
-	      // this is a 1 x 1 matrix
-	      value = mat[0][0];
-	      if (value == 0) {
-	        throw Error('Cannot calculate inverse, determinant is zero');
-	      }
-	      return [[
-	        divideScalar(1, value)
-	      ]];
-	    }
-	    else if (rows == 2) {
-	      // this is a 2 x 2 matrix
-	      var d = det(mat);
-	      if (d == 0) {
-	        throw Error('Cannot calculate inverse, determinant is zero');
-	      }
-	      return [
-	        [
-	          divideScalar(mat[1][1], d),
-	          divideScalar(unaryMinus(mat[0][1]), d)
-	        ],
-	        [
-	          divideScalar(unaryMinus(mat[1][0]), d),
-	          divideScalar(mat[0][0], d)
-	        ]
-	      ];
-	    }
-	    else {
-	      // this is a matrix of 3 x 3 or larger
-	      // calculate inverse using gauss-jordan elimination
-	      //      http://en.wikipedia.org/wiki/Gaussian_elimination
-	      //      http://mathworld.wolfram.com/MatrixInverse.html
-	      //      http://math.uww.edu/~mcfarlat/inverse.htm
-
-	      // make a copy of the matrix (only the arrays, not of the elements)
-	      var A = mat.concat();
-	      for (r = 0; r < rows; r++) {
-	        A[r] = A[r].concat();
-	      }
-
-	      // create an identity matrix which in the end will contain the
-	      // matrix inverse
-	      var B = eye(rows).valueOf();
-
-	      // loop over all columns, and perform row reductions
-	      for (var c = 0; c < cols; c++) {
-	        // element Acc should be non zero. if not, swap content
-	        // with one of the lower rows
-	        r = c;
-	        while (r < rows && A[r][c] == 0) {
-	          r++;
-	        }
-	        if (r == rows || A[r][c] == 0) {
-	          // TODO: in case of zero det, just return a matrix wih Infinity values? (like octave)
-	          throw Error('Cannot calculate inverse, determinant is zero');
-	        }
-	        if (r != c) {
-	          temp = A[c]; A[c] = A[r]; A[r] = temp;
-	          temp = B[c]; B[c] = B[r]; B[r] = temp;
-	        }
-
-	        // eliminate non-zero values on the other rows at column c
-	        var Ac = A[c],
-	            Bc = B[c];
-	        for (r = 0; r < rows; r++) {
-	          var Ar = A[r],
-	              Br = B[r];
-	          if(r != c) {
-	            // eliminate value at column c and row r
-	            if (Ar[c] != 0) {
-	              f = divideScalar(unaryMinus(Ar[c]), Ac[c]);
-
-	              // add (f * row c) to row r to eliminate the value
-	              // at column c
-	              for (s = c; s < cols; s++) {
-	                Ar[s] = addScalar(Ar[s], multiply(f, Ac[s]));
-	              }
-	              for (s = 0; s < cols; s++) {
-	                Br[s] = addScalar(Br[s],  multiply(f, Bc[s]));
-	              }
-	            }
-	          }
-	          else {
-	            // normalize value at Acc to 1,
-	            // divide each value on row r with the value at Acc
-	            f = Ac[c];
-	            for (s = c; s < cols; s++) {
-	              Ar[s] = divideScalar(Ar[s], f);
-	            }
-	            for (s = 0; s < cols; s++) {
-	              Br[s] = divideScalar(Br[s], f);
-	            }
-	          }
-	        }
-	      }
-	      return B;
-	    }
-	  }
-
-	  inv.toTex = '\\left(${args[0]}\\right)^{-1}';
-
-	  return inv;
-	}
-
-	exports.name = 'inv';
-	exports.factory = factory;
-
-
-/***/ },
-/* 51 */
-/***/ function(module, exports) {
-
-	'use strict';
-
-	function factory(type, config, load, typed) {
-	  /**
-	   * Divide two scalar values, `x / y`.
-	   * This function is meant for internal use: it is used by the public functions
-	   * `divide` and `inv`.
-	   *
-	   * This function does not support collections (Array or Matrix), and does
-	   * not validate the number of of inputs.
-	   *
-	   * @param  {number | BigNumber | Fraction | Complex | Unit} x   Numerator
-	   * @param  {number | BigNumber | Fraction | Complex} y          Denominator
-	   * @return {number | BigNumber | Fraction | Complex | Unit}                      Quotient, `x / y`
-	   * @private
-	   */
-	  var divideScalar = typed('divide', {
-	    'number, number': function (x, y) {
-	      return x / y;
-	    },
-
-	    'Complex, Complex': _divideComplex,
-
-	    'BigNumber, BigNumber': function (x, y) {
-	      return x.div(y);
-	    },
-
-	    'Fraction, Fraction': function (x, y) {
-	      return x.div(y);
-	    },
-
-	    'Unit, number': function (x, y) {
-	      var res = x.clone();
-	      res.value = ((res.value === null) ? res._normalize(1) : res.value) / y;
-	      return res;
-	    },
-
-	    'number, Unit': function (x, y) {
-	      var res = y.pow(-1);
-	      res.value = ((res.value === null) ? res._normalize(1) : res.value) * x;
-	      return res;
-	    },
-
-	    'Unit, Unit': function (x, y) {
-	      return x.divide(y);
-	    }
-
-	  });
-
-	  /**
-	   * Divide two complex numbers. x / y or divide(x, y)
-	   * @param {Complex} x
-	   * @param {Complex} y
-	   * @return {Complex} res
-	   * @private
-	   */
-	  function _divideComplex (x, y) {
-	    var den = y.re * y.re + y.im * y.im;
-	    if (den != 0) {
-	      return new type.Complex(
-	          (x.re * y.re + x.im * y.im) / den,
-	          (x.im * y.re - x.re * y.im) / den
-	      );
-	    }
-	    else {
-	      // both y.re and y.im are zero
-	      return new type.Complex(
-	          (x.re != 0) ? (x.re / 0) : 0,
-	          (x.im != 0) ? (x.im / 0) : 0
-	      );
-	    }
-	  }
-
-	  return divideScalar;
-	}
-
-	exports.factory = factory;
-
-
-/***/ },
-/* 52 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	var isInteger = __webpack_require__(8).isInteger;
-	var resize = __webpack_require__(18).resize;
-
-	function factory (type, config, load, typed) {
-	  var matrix = load(__webpack_require__(23));
-
-	  /**
-	   * Create a matrix filled with ones. The created matrix can have one or
-	   * multiple dimensions.
-	   *
-	   * Syntax:
-	   *
-	   *    math.ones(m)
-	   *    math.ones(m, format)
-	   *    math.ones(m, n)
-	   *    math.ones(m, n, format)
-	   *    math.ones([m, n])
-	   *    math.ones([m, n], format)
-	   *    math.ones([m, n, p, ...])
-	   *    math.ones([m, n, p, ...], format)
-	   *
-	   * Examples:
-	   *
-	   *    math.ones(3);                   // returns [1, 1, 1]
-	   *    math.ones(3, 2);                // returns [[1, 1], [1, 1], [1, 1]]
-	   *    math.ones(3, 2, 'dense');       // returns Dense Matrix [[1, 1], [1, 1], [1, 1]]
-	   *
-	   *    var A = [[1, 2, 3], [4, 5, 6]];
-	   *    math.ones(math.size(A));       // returns [[1, 1, 1], [1, 1, 1]]
-	   *
-	   * See also:
-	   *
-	   *    zeros, eye, size, range
-	   *
-	   * @param {...number | Array} size    The size of each dimension of the matrix
-	   * @param {string} [format]           The Matrix storage format
-	   *
-	   * @return {Array | Matrix | number}  A matrix filled with ones
-	   */
-	  var ones = typed('ones', {
-	    '': function () {
-	      return (config.matrix === 'array')
-	          ? _ones([])
-	          : _ones([], 'default');
-	    },
-
-	    // math.ones(m, n, p, ..., format)
-	    // TODO: more accurate signature '...number | BigNumber, string' as soon as typed-function supports this
-	    '...number | BigNumber | string': function (size) {
-	      var last = size[size.length - 1];
-	      if (typeof last === 'string') {
-	        var format = size.pop();
-	        return _ones(size, format);
-	      }
-	      else if (config.matrix === 'array') {
-	        return _ones(size);
-	      }
-	      else {
-	        return _ones(size, 'default');
-	      }
-	    },
-
-	    'Array': _ones,
-
-	    'Matrix': function (size) {
-	      var format = size.storage();
-	      return _ones(size.valueOf(), format);
-	    },
-
-	    'Array | Matrix, string': function (size, format) {
-	      return _ones (size.valueOf(), format);
-	    }
-	  });
-
-	  ones.toTex = '\\mathrm{${name}}\\left(${args}\\right)';
-
-	  return ones;
-
-	  /**
-	   * Create an Array or Matrix with ones
-	   * @param {Array} size
-	   * @param {string} [format='default']
-	   * @return {Array | Matrix}
-	   * @private
-	   */
-	  function _ones(size, format) {
-	    var hasBigNumbers = _normalize(size);
-	    var defaultValue = hasBigNumbers ? new type.BigNumber(1) : 1;
-	    _validate(size);
-
-	    if (format) {
-	      // return a matrix
-	      var m = matrix(format);
-	      if (size.length > 0) {
-	        return m.resize(size, defaultValue);
-	      }
-	      return m;
-	    }
-	    else {
-	      // return an Array
-	      var arr = [];
-	      if (size.length > 0) {
-	        return resize(arr, size, defaultValue);
-	      }
-	      return arr;
-	    }
-	  }
-
-	  // replace BigNumbers with numbers, returns true if size contained BigNumbers
-	  function _normalize(size) {
-	    var hasBigNumbers = false;
-	    size.forEach(function (value, index, arr) {
-	      if (value && value.isBigNumber === true) {
-	        hasBigNumbers = true;
-	        arr[index] = value.toNumber();
-	      }
-	    });
-	    return hasBigNumbers;
-	  }
-
-	  // validate arguments
-	  function _validate (size) {
-	    size.forEach(function (value) {
-	      if (typeof value !== 'number' || !isInteger(value) || value < 0) {
-	        throw new Error('Parameters in function ones must be positive integers');
-	      }
-	    });
-	  }
-	}
-
-	exports.name = 'ones';
-	exports.factory = factory;
-
-
-/***/ },
-/* 53 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	function factory (type, config, load, typed) {
-	  var matrix = load(__webpack_require__(23));
-
-	  var ZERO = new type.BigNumber(0);
-	  var ONE = new type.BigNumber(1);
-
-	  /**
-	   * Create an array from a range.
-	   * By default, the range end is excluded. This can be customized by providing
-	   * an extra parameter `includeEnd`.
-	   *
-	   * Syntax:
-	   *
-	   *     math.range(str [, includeEnd])               // Create a range from a string,
-	   *                                                  // where the string contains the
-	   *                                                  // start, optional step, and end,
-	   *                                                  // separated by a colon.
-	   *     math.range(start, end [, includeEnd])        // Create a range with start and
-	   *                                                  // end and a step size of 1.
-	   *     math.range(start, end, step [, includeEnd])  // Create a range with start, step,
-	   *                                                  // and end.
-	   *
-	   * Where:
-	   *
-	   * - `str: string`
-	   *   A string 'start:end' or 'start:step:end'
-	   * - `start: {number | BigNumber}`
-	   *   Start of the range
-	   * - `end: number | BigNumber`
-	   *   End of the range, excluded by default, included when parameter includeEnd=true
-	   * - `step: number | BigNumber`
-	   *   Step size. Default value is 1.
-	   * - `includeEnd: boolean`
-	   *   Option to specify whether to include the end or not. False by default.
-	   *
-	   * Examples:
-	   *
-	   *     math.range(2, 6);        // [2, 3, 4, 5]
-	   *     math.range(2, -3, -1);   // [2, 1, 0, -1, -2]
-	   *     math.range('2:1:6');     // [2, 3, 4, 5]
-	   *     math.range(2, 6, true);  // [2, 3, 4, 5, 6]
-	   *
-	   * See also:
-	   *
-	   *     ones, zeros, size, subset
-	   *
-	   * @param {*} args   Parameters describing the ranges `start`, `end`, and optional `step`.
-	   * @return {Array | Matrix} range
-	   */
-	  var range = typed('range', {
-	    // TODO: simplify signatures when typed-function supports default values and optional arguments
-
-	    // TODO: a number or boolean should not be converted to string here
-	    'string': _strRange,
-	    'string, boolean': _strRange,
-
-	    'number, number':  function (start, end) {
-	      return _out(_rangeEx(start, end, 1));
-	    },
-	    'number, number, number': function (start, end, step) {
-	      return _out(_rangeEx(start, end, step));
-	    },
-	    'number, number, boolean': function (start, end, includeEnd) {
-	      return includeEnd
-	          ? _out(_rangeInc(start, end, 1))
-	          : _out(_rangeEx(start, end, 1));
-	    },
-	    'number, number, number, boolean': function (start, end, step, includeEnd) {
-	      return includeEnd
-	          ? _out(_rangeInc(start, end, step))
-	          : _out(_rangeEx(start, end, step));
-	    },
-
-	    'BigNumber, BigNumber':  function (start, end) {
-	      return _out(_bigRangeEx(start, end, ONE));
-	    },
-	    'BigNumber, BigNumber, BigNumber': function (start, end, step) {
-	      return _out(_bigRangeEx(start, end, step));
-	    },
-	    'BigNumber, BigNumber, boolean': function (start, end, includeEnd) {
-	      return includeEnd
-	          ? _out(_bigRangeInc(start, end, ONE))
-	          : _out(_bigRangeEx(start, end, ONE));
-	    },
-	    'BigNumber, BigNumber, BigNumber, boolean': function (start, end, step, includeEnd) {
-	      return includeEnd
-	          ? _out(_bigRangeInc(start, end, step))
-	          : _out(_bigRangeEx(start, end, step));
-	    }
-
-	  });
-
-	  range.toTex = '\\mathrm{${name}}\\left(${args}\\right)';
-
-	  return range;
-
-	  function _out(arr) {
-	    return config.matrix === 'array' ? arr : matrix(arr);
-	  }
-
-	  function _strRange (str, includeEnd) {
-	    var r = _parse(str);
-	    if (!r){
-	      throw new SyntaxError('String "' + str + '" is no valid range');
-	    }
-
-	    var fn;
-	    if (config.number === 'bignumber') {
-	      fn = includeEnd ? _bigRangeInc : _bigRangeEx;
-	      return _out(fn(
-	          new type.BigNumber(r.start),
-	          new type.BigNumber(r.end),
-	          new type.BigNumber(r.step)));
-	    }
-	    else {
-	      fn = includeEnd ? _rangeInc : _rangeEx;
-	      return _out(fn(r.start, r.end, r.step));
-	    }
-	  }
-
-	  /**
-	   * Create a range with numbers. End is excluded
-	   * @param {number} start
-	   * @param {number} end
-	   * @param {number} step
-	   * @returns {Array} range
-	   * @private
-	   */
-	  function _rangeEx (start, end, step) {
-	    var array = [],
-	        x = start;
-	    if (step > 0) {
-	      while (x < end) {
-	        array.push(x);
-	        x += step;
-	      }
-	    }
-	    else if (step < 0) {
-	      while (x > end) {
-	        array.push(x);
-	        x += step;
-	      }
-	    }
-
-	    return array;
-	  }
-
-	  /**
-	   * Create a range with numbers. End is included
-	   * @param {number} start
-	   * @param {number} end
-	   * @param {number} step
-	   * @returns {Array} range
-	   * @private
-	   */
-	  function _rangeInc (start, end, step) {
-	    var array = [],
-	        x = start;
-	    if (step > 0) {
-	      while (x <= end) {
-	        array.push(x);
-	        x += step;
-	      }
-	    }
-	    else if (step < 0) {
-	      while (x >= end) {
-	        array.push(x);
-	        x += step;
-	      }
-	    }
-
-	    return array;
-	  }
-
-	  /**
-	   * Create a range with big numbers. End is excluded
-	   * @param {BigNumber} start
-	   * @param {BigNumber} end
-	   * @param {BigNumber} step
-	   * @returns {Array} range
-	   * @private
-	   */
-	  function _bigRangeEx (start, end, step) {
-	    var array = [],
-	        x = start;
-	    if (step.gt(ZERO)) {
-	      while (x.lt(end)) {
-	        array.push(x);
-	        x = x.plus(step);
-	      }
-	    }
-	    else if (step.lt(ZERO)) {
-	      while (x.gt(end)) {
-	        array.push(x);
-	        x = x.plus(step);
-	      }
-	    }
-
-	    return array;
-	  }
-
-	  /**
-	   * Create a range with big numbers. End is included
-	   * @param {BigNumber} start
-	   * @param {BigNumber} end
-	   * @param {BigNumber} step
-	   * @returns {Array} range
-	   * @private
-	   */
-	  function _bigRangeInc (start, end, step) {
-	    var array = [],
-	        x = start;
-	    if (step.gt(ZERO)) {
-	      while (x.lte(end)) {
-	        array.push(x);
-	        x = x.plus(step);
-	      }
-	    }
-	    else if (step.lt(ZERO)) {
-	      while (x.gte(end)) {
-	        array.push(x);
-	        x = x.plus(step);
-	      }
-	    }
-
-	    return array;
-	  }
-
-	  /**
-	   * Parse a string into a range,
-	   * The string contains the start, optional step, and end, separated by a colon.
-	   * If the string does not contain a valid range, null is returned.
-	   * For example str='0:2:11'.
-	   * @param {string} str
-	   * @return {{start: number, end: number, step: number} | null} range Object containing properties start, end, step
-	   * @private
-	   */
-	  function _parse (str) {
-	    var args = str.split(':');
-
-	    // number
-	    var nums = args.map(function (arg) {
-	      // use Number and not parseFloat as Number returns NaN on invalid garbage in the string
-	      return Number(arg);
-	    });
-
-	    var invalid = nums.some(function (num) {
-	      return isNaN(num);
-	    });
-	    if(invalid) {
-	      return null;
-	    }
-
-	    switch (nums.length) {
-	      case 2:
-	        return {
-	          start: nums[0],
-	          end: nums[1],
-	          step: 1
-	        };
-
-	      case 3:
-	        return {
-	          start: nums[0],
-	          end: nums[2],
-	          step: nums[1]
-	        };
-
-	      default:
-	        return null;
-	    }
-	  }
-
-	}
-
-	exports.name = 'range';
-	exports.factory = factory;
-
-
-/***/ },
-/* 54 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	var DimensionError = __webpack_require__(22);
-	var ArgumentsError = __webpack_require__(11);
-
-	var isInteger = __webpack_require__(8).isInteger;
-	var format = __webpack_require__(20).format;
-	var clone = __webpack_require__(5).clone;
-	var array = __webpack_require__(18);
-
-	function factory (type, config, load, typed) {
-	  var matrix = load(__webpack_require__(23));
-
-	  /**
-	   * Resize a matrix
-	   *
-	   * Syntax:
-	   *
-	   *     math.resize(x, size)
-	   *     math.resize(x, size, defaultValue)
-	   *
-	   * Examples:
-	   *
-	   *     math.resize([1, 2, 3, 4, 5], [3]); // returns Array  [1, 2, 3]
-	   *     math.resize([1, 2, 3], [5], 0);    // returns Array  [1, 2, 3, 0, 0]
-	   *     math.resize(2, [2, 3], 0);         // returns Matrix [[2, 0, 0], [0, 0, 0]]
-	   *     math.resize("hello", [8], "!");    // returns string 'hello!!!'
-	   *
-	   * See also:
-	   *
-	   *     size, squeeze, subset
-	   *
-	   * @param {Array | Matrix | *} x             Matrix to be resized
-	   * @param {Array | Matrix} size              One dimensional array with numbers
-	   * @param {number | string} [defaultValue=0] Zero by default, except in
-	   *                                           case of a string, in that case
-	   *                                           defaultValue = ' '
-	   * @return {* | Array | Matrix} A resized clone of matrix `x`
-	   */
-	  // TODO: rework resize to a typed-function
-	  var resize = function resize (x, size, defaultValue) {
-	    if (arguments.length != 2 && arguments.length != 3) {
-	      throw new ArgumentsError('resize', arguments.length, 2, 3);
-	    }
-
-	    if (size && size.isMatrix === true) {
-	      size = size.valueOf(); // get Array
-	    }
-
-	    if (size.length && size[0] && size[0].isBigNumber === true) {
-	      // convert bignumbers to numbers
-	      size = size.map(function (value) {
-	        return (value && value.isBigNumber === true) ? value.toNumber() : value;
-	      });
-	    }
-	    
-	    // check x is a Matrix
-	    if (x && x.isMatrix === true) {
-	      // use optimized matrix implementation, return copy
-	      return x.resize(size, defaultValue, true);
-	    }
-	    
-	    if (typeof x === 'string') {
-	      // resize string
-	      return _resizeString(x, size, defaultValue);
-	    }
-	    
-	    // check result should be a matrix
-	    var asMatrix = Array.isArray(x) ? false : (config.matrix !== 'array');
-
-	    if (size.length == 0) {
-	      // output a scalar
-	      while (Array.isArray(x)) {
-	        x = x[0];
-	      }
-
-	      return clone(x);
-	    }
-	    else {
-	      // output an array/matrix
-	      if (!Array.isArray(x)) {
-	        x = [x];
-	      }
-	      x = clone(x);
-
-	      var res = array.resize(x, size, defaultValue);
-	      return asMatrix ? matrix(res) : res;
-	    }
-	  };
-
-	  resize.toTex = '\\mathrm{${name}}\\left(${args}\\right)';
-
-	  return resize;
-
-	  /**
-	   * Resize a string
-	   * @param {string} str
-	   * @param {number[]} size
-	   * @param {string} [defaultChar=' ']
-	   * @private
-	   */
-	  function _resizeString(str, size, defaultChar) {
-	    if (defaultChar !== undefined) {
-	      if (typeof defaultChar !== 'string' || defaultChar.length !== 1) {
-	        throw new TypeError('Single character expected as defaultValue');
-	      }
-	    }
-	    else {
-	      defaultChar = ' ';
-	    }
-
-	    if (size.length !== 1) {
-	      throw new DimensionError(size.length, 1);
-	    }
-	    var len = size[0];
-	    if (typeof len !== 'number' || !isInteger(len)) {
-	      throw new TypeError('Invalid size, must contain positive integers ' +
-	          '(size: ' + format(size) + ')');
-	    }
-
-	    if (str.length > len) {
-	      return str.substring(0, len);
-	    }
-	    else if (str.length < len) {
-	      var res = str;
-	      for (var i = 0, ii = len - str.length; i < ii; i++) {
-	        res += defaultChar;
-	      }
-	      return res;
-	    }
-	    else {
-	      return str;
-	    }
-	  }
-	}
-
-	exports.name = 'resize';
-	exports.factory = factory;
-
-
-/***/ },
-/* 55 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	var array = __webpack_require__(18);
-
-	function factory (type, config, load, typed) {
-	  var matrix = load(__webpack_require__(23));
-
-	  /**
-	   * Calculate the size of a matrix or scalar.
-	   *
-	   * Syntax:
-	   *
-	   *     math.size(x)
-	   *
-	   * Examples:
-	   *
-	   *     math.size(2.3);                  // returns []
-	   *     math.size('hello world');        // returns [11]
-	   *
-	   *     var A = [[1, 2, 3], [4, 5, 6]];
-	   *     math.size(A);                    // returns [2, 3]
-	   *     math.size(math.range(1,6));      // returns [5]
-	   *
-	   * See also:
-	   *
-	   *     resize, squeeze, subset
-	   *
-	   * @param {boolean | number | Complex | Unit | string | Array | Matrix} x  A matrix
-	   * @return {Array | Matrix} A vector with size of `x`.
-	   */
-	  var size = typed('size', {
-	    'Matrix': function (x) {
-	      // TODO: return the same matrix type as the input
-	      return matrix(x.size());
-	    },
-
-	    'Array': array.size,
-
-	    'string': function (x) {
-	      return (config.matrix === 'array') ? [x.length] : matrix([x.length]);
-	    },
-
-	    'number | Complex | BigNumber | Unit | boolean | null': function (x) {
-	      // scalar
-	      return (config.matrix === 'array') ? [] : matrix([]);
-	    }
-	  });
-
-	  size.toTex = '\\mathrm{${name}}\\left(${args}\\right)';
-
-	  return size;
-	}
-
-	exports.name = 'size';
-	exports.factory = factory;
-
-
-/***/ },
-/* 56 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	var object = __webpack_require__(5);
-	var array = __webpack_require__(18);
-
-	function factory (type, config, load, typed) {
-	  var matrix = load(__webpack_require__(23));
-
-	  /**
-	   * Squeeze a matrix, remove inner and outer singleton dimensions from a matrix.
-	   *
-	   * Syntax:
-	   *
-	   *     math.squeeze(x)
-	   *
-	   * Examples:
-	   *
-	   *     math.squeeze([3]);           // returns 3
-	   *     math.squeeze([[3]]);         // returns 3
-	   *
-	   *     var A = math.zeros(3, 1);    // returns [[0], [0], [0]] (size 3x1)
-	   *     math.squeeze(A);             // returns [0, 0, 0] (size 3)
-	   *
-	   *     var B = math.zeros(1, 3);    // returns [[0, 0, 0]] (size 1x3)
-	   *     math.squeeze(B);             // returns [0, 0, 0] (size 3)
-	   *
-	   *     // only inner and outer dimensions are removed
-	   *     var C = math.zeros(2, 1, 3); // returns [[[0, 0, 0]], [[0, 0, 0]]] (size 2x1x3)
-	   *     math.squeeze(C);             // returns [[[0, 0, 0]], [[0, 0, 0]]] (size 2x1x3)
-	   *
-	   * See also:
-	   *
-	   *     subset
-	   *
-	   * @param {Matrix | Array} x      Matrix to be squeezed
-	   * @return {Matrix | Array} Squeezed matrix
-	   */
-	  var squeeze = typed('squeeze', {
-	    'Array': function (x) {
-	      return array.squeeze(object.clone(x));
-	    },
-
-	    'Matrix': function (x) {
-	      var res = array.squeeze(x.toArray());
-	      // FIXME: return the same type of matrix as the input
-	      return Array.isArray(res) ? matrix(res) : res;
-	    },
-
-	    'any': function (x) {
-	      // scalar
-	      return object.clone(x);
-	    }
-	  });
-
-	  squeeze.toTex = '\\mathrm{${name}}\\left(${args}\\right)';
-
-	  return squeeze;
-	}
-
-	exports.name = 'squeeze';
-	exports.factory = factory;
-
-
-/***/ },
-/* 57 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	var clone = __webpack_require__(5).clone;
-	var validateIndex = __webpack_require__(18).validateIndex;
-	var DimensionError = __webpack_require__(22);
-
-	function factory (type, config, load, typed) {
-	  var matrix = load(__webpack_require__(23));
-
-	  /**
-	   * Get or set a subset of a matrix or string.
-	   *
-	   * Syntax:
-	   *     math.subset(value, index)                                // retrieve a subset
-	   *     math.subset(value, index, replacement [, defaultValue])  // replace a subset
-	   *
-	   * Examples:
-	   *
-	   *     // get a subset
-	   *     var d = [[1, 2], [3, 4]];
-	   *     math.subset(d, math.index(1, 0));        // returns 3
-	   *     math.subset(d, math.index([0, 2], 1));   // returns [[2], [4]]
-	   *
-	   *     // replace a subset
-	   *     var e = [];
-	   *     var f = math.subset(e, math.index(0, [0, 2]), [5, 6]);  // f = [[5, 6]]
-	   *     var g = math.subset(f, math.index(1, 1), 7, 0);         // g = [[5, 6], [0, 7]]
-	   *
-	   * See also:
-	   *
-	   *     size, resize, squeeze, index
-	   *
-	   * @param {Array | Matrix | string} matrix  An array, matrix, or string
-	   * @param {Index} index                     An index containing ranges for each
-	   *                                          dimension
-	   * @param {*} [replacement]                 An array, matrix, or scalar.
-	   *                                          If provided, the subset is replaced with replacement.
-	   *                                          If not provided, the subset is returned
-	   * @param {*} [defaultValue=undefined]      Default value, filled in on new entries when
-	   *                                          the matrix is resized. If not provided,
-	   *                                          math.matrix elements will be left undefined.
-	   * @return {Array | Matrix | string} Either the retrieved subset or the updated matrix.
-	   */
-	  var subset = typed('subset', {
-	    // get subset
-	    'Array, Index': function (value, index) {
-	      var m = matrix(value);
-	      var subset = m.subset(index);       // returns a Matrix
-	      return subset && subset.valueOf();  // return an Array (like the input)
-	    },
-
-	    'Matrix, Index': function (value, index) {
-	      return value.subset(index);
-	    },
-
-	    'string, Index': _getSubstring,
-
-	    // set subset
-	    'Array, Index, any': function (value, index, replacement) {
-	      return matrix(clone(value))
-	          .subset(index, replacement, undefined)
-	          .valueOf();
-	    },
-
-	    'Array, Index, any, any': function (value, index, replacement, defaultValue) {
-	      return matrix(clone(value))
-	          .subset(index, replacement, defaultValue)
-	          .valueOf();
-	    },
-
-	    'Matrix, Index, any': function (value, index, replacement) {
-	      return value.clone().subset(index, replacement);
-	    },
-
-	    'Matrix, Index, any, any': function (value, index, replacement, defaultValue) {
-	      return value.clone().subset(index, replacement, defaultValue);
-	    },
-
-	    'string, Index, string': _setSubstring,
-	    'string, Index, string, string': _setSubstring
-	  });
-
-	  subset.toTex = '\\mathrm{${name}}\\left(${args}\\right)';
-
-	  return subset;
-
-	  /**
-	   * Retrieve a subset of a string
-	   * @param {string} str            string from which to get a substring
-	   * @param {Index} index           An index containing ranges for each dimension
-	   * @returns {string} substring
-	   * @private
-	   */
-	  function _getSubstring(str, index) {
-	    if (!index || index.isIndex !== true) {
-	      // TODO: better error message
-	      throw new TypeError('Index expected');
-	    }
-	    if (index.size().length != 1) {
-	      throw new DimensionError(index.size().length, 1);
-	    }
-
-	    // validate whether the range is out of range
-	    var strLen = str.length;
-	    validateIndex(index.min()[0], strLen);
-	    validateIndex(index.max()[0], strLen);
-
-	    var range = index.dimension(0);
-
-	    var substr = '';
-	    range.forEach(function (v) {
-	      substr += str.charAt(v);
-	    });
-
-	    return substr;
-	  }
-
-	  /**
-	   * Replace a substring in a string
-	   * @param {string} str            string to be replaced
-	   * @param {Index} index           An index containing ranges for each dimension
-	   * @param {string} replacement    Replacement string
-	   * @param {string} [defaultValue] Default value to be uses when resizing
-	   *                                the string. is ' ' by default
-	   * @returns {string} result
-	   * @private
-	   */
-	  function _setSubstring(str, index, replacement, defaultValue) {
-	    if (!index || index.isIndex !== true) {
-	      // TODO: better error message
-	      throw new TypeError('Index expected');
-	    }
-	    if (index.size().length != 1) {
-	      throw new DimensionError(index.size().length, 1);
-	    }
-	    if (defaultValue !== undefined) {
-	      if (typeof defaultValue !== 'string' || defaultValue.length !== 1) {
-	        throw new TypeError('Single character expected as defaultValue');
-	      }
-	    }
-	    else {
-	      defaultValue = ' ';
-	    }
-
-	    var range = index.dimension(0);
-	    var len = range.size()[0];
-
-	    if (len != replacement.length) {
-	      throw new DimensionError(range.size()[0], replacement.length);
-	    }
-
-	    // validate whether the range is out of range
-	    var strLen = str.length;
-	    validateIndex(index.min()[0]);
-	    validateIndex(index.max()[0]);
-
-	    // copy the string into an array with characters
-	    var chars = [];
-	    for (var i = 0; i < strLen; i++) {
-	      chars[i] = str.charAt(i);
-	    }
-
-	    range.forEach(function (v, i) {
-	      chars[v] = replacement.charAt(i[0]);
-	    });
-
-	    // initialize undefined characters with a space
-	    if (chars.length > strLen) {
-	      for (i = strLen - 1, len = chars.length; i < len; i++) {
-	        if (!chars[i]) {
-	          chars[i] = defaultValue;
-	        }
-	      }
-	    }
-
-	    return chars.join('');
-	  }
-	}
-
-	exports.name = 'subset';
-	exports.factory = factory;
-
-
-/***/ },
-/* 58 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	var clone = __webpack_require__(5).clone;
-	var format = __webpack_require__(20).format;
-
-	function factory (type, config, load, typed) {
-	  
-	  var matrix = load(__webpack_require__(23));
-	  var add = load(__webpack_require__(44));
-
-	  /**
-	   * Calculate the trace of a matrix: the sum of the elements on the main
-	   * diagonal of a square matrix.
-	   *
-	   * Syntax:
-	   *
-	   *    math.trace(x)
-	   *
-	   * Examples:
-	   *
-	   *    math.trace([[1, 2], [3, 4]]); // returns 5
-	   *
-	   *    var A = [
-	   *      [1, 2, 3],
-	   *      [-1, 2, 3],
-	   *      [2, 0, 3]
-	   *    ]
-	   *    math.trace(A); // returns 6
-	   *
-	   * See also:
-	   *
-	   *    diag
-	   *
-	   * @param {Array | Matrix} x  A matrix
-	   *
-	   * @return {number} The trace of `x`
-	   */
-	  var trace = typed('trace', {
-	    
-	    'Array': function (x) {
-	      // use dense matrix implementation
-	      return trace(matrix(x));
-	    },
-
-	    'Matrix': function (x) {
-	      // result
-	      var c;
-	      // process storage format
-	      switch (x.storage()) {
-	        case 'dense':
-	          c = _denseTrace(x);
-	          break;
-	        case 'sparse':
-	          c = _sparseTrace(x);
-	          break;
-	      }
-	      return c;
-	    },
-	    
-	    'any': clone
-	  });
-	  
-	  var _denseTrace = function (m) {
-	    // matrix size & data
-	    var size = m._size;
-	    var data = m._data;
-	    
-	    // process dimensions
-	    switch (size.length) {
-	      case 1:
-	        // vector
-	        if (size[0] == 1) {
-	          // return data[0]
-	          return clone(data[0]);
-	        }
-	        throw new RangeError('Matrix must be square (size: ' + format(size) + ')');
-	      case 2:
-	        // two dimensional
-	        var rows = size[0];
-	        var cols = size[1];
-	        if (rows === cols) {
-	          // calulate sum
-	          var sum = 0;
-	          // loop diagonal
-	          for (var i = 0; i < rows; i++)
-	            sum = add(sum, data[i][i]);
-	          // return trace
-	          return sum;
-	        }
-	        throw new RangeError('Matrix must be square (size: ' + format(size) + ')');        
-	      default:
-	        // multi dimensional
-	        throw new RangeError('Matrix must be two dimensional (size: ' + format(size) + ')');
-	    }
-	  };
-	  
-	  var _sparseTrace = function (m) {
-	    // matrix arrays
-	    var values = m._values;
-	    var index = m._index;
-	    var ptr = m._ptr;
-	    var size = m._size;
-	    // check dimensions
-	    var rows = size[0];
-	    var columns = size[1];
-	    // matrix must be square
-	    if (rows === columns) {
-	      // calulate sum
-	      var sum = 0;
-	      // check we have data (avoid looping columns)
-	      if (values.length > 0) {
-	        // loop columns
-	        for (var j = 0; j < columns; j++) {
-	          // k0 <= k < k1 where k0 = _ptr[j] && k1 = _ptr[j+1]
-	          var k0 = ptr[j];
-	          var k1 = ptr[j + 1];
-	          // loop k within [k0, k1[
-	          for (var k = k0; k < k1; k++) {
-	            // row index
-	            var i = index[k];
-	            // check row
-	            if (i === j) {
-	              // accumulate value
-	              sum = add(sum, values[k]);
-	              // exit loop
-	              break;
-	            }
-	            if (i > j) {
-	              // exit loop, no value on the diagonal for column j
-	              break;
-	            }
-	          }
-	        }
-	      }
-	      // return trace
-	      return sum;
-	    }
-	    throw new RangeError('Matrix must be square (size: ' + format(size) + ')');   
-	  };
-
-	  trace.toTex = '\\mathrm{tr}\\left(${args[0]}\\right)';
-	  
-	  return trace;
-	}
-
-	exports.name = 'trace';
-	exports.factory = factory;
-
-
-/***/ },
-/* 59 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	var clone = __webpack_require__(5).clone;
-	var format = __webpack_require__(20).format;
-
-	function factory (type, config, load, typed) {
-	  var latex = __webpack_require__(26);
-
-	  var matrix = load(__webpack_require__(23));
-
-	  var DenseMatrix = type.DenseMatrix,
-	      SparseMatrix = type.SparseMatrix;
-
-	  /**
-	   * Transpose a matrix. All values of the matrix are reflected over its
-	   * main diagonal. Only two dimensional matrices are supported.
-	   *
-	   * Syntax:
-	   *
-	   *     math.transpose(x)
-	   *
-	   * Examples:
-	   *
-	   *     var A = [[1, 2, 3], [4, 5, 6]];
-	   *     math.transpose(A);               // returns [[1, 4], [2, 5], [3, 6]]
-	   *
-	   * See also:
-	   *
-	   *     diag, inv, subset, squeeze
-	   *
-	   * @param {Array | Matrix} x  Matrix to be transposed
-	   * @return {Array | Matrix}   The transposed matrix
-	   */
-	  var transpose = typed('transpose', {
-
-	    'Array': function (x) {
-	      // use dense matrix implementation
-	      return transpose(matrix(x)).valueOf();
-	    },
-
-	    'Matrix': function (x) {
-	      // matrix size
-	      var size = x.size();
-
-	      // result
-	      var c;
-	      
-	      // process dimensions
-	      switch (size.length) {
-	        case 1:
-	          // vector
-	          c = x.clone();
-	          break;
-
-	        case 2:
-	          // rows and columns
-	          var rows = size[0];
-	          var columns = size[1];
-
-	          // check columns
-	          if (columns === 0) {
-	            // throw exception
-	            throw new RangeError('Cannot transpose a 2D matrix with no columns (size: ' + format(size) + ')');
-	          }
-
-	          // process storage format
-	          switch (x.storage()) {
-	            case 'dense':
-	              c = _denseTranspose(x, rows, columns);
-	              break;
-	            case 'sparse':
-	              c = _sparseTranspose(x, rows, columns);
-	              break;
-	          }
-	          break;
-	          
-	        default:
-	          // multi dimensional
-	          throw new RangeError('Matrix must be a vector or two dimensional (size: ' + format(this._size) + ')');
-	      }
-	      return c;
-	    },
-
-	    // scalars
-	    'any': function (x) {
-	      return clone(x);
-	    }
-	  });
-
-	  var _denseTranspose = function (m, rows, columns) {
-	    // matrix array
-	    var data = m._data;
-	    // transposed matrix data
-	    var transposed = [];
-	    var transposedRow;
-	    // loop columns
-	    for (var j = 0; j < columns; j++) {
-	      // initialize row
-	      transposedRow = transposed[j] = [];
-	      // loop rows
-	      for (var i = 0; i < rows; i++) {
-	        // set data
-	        transposedRow[i] = clone(data[i][j]);
-	      }
-	    }
-	    // return matrix
-	    return new DenseMatrix({
-	      data: transposed,
-	      size: [columns, rows],
-	      datatype: m._datatype
-	    });
-	  };
-
-	  var _sparseTranspose = function (m, rows, columns) {
-	    // matrix arrays
-	    var values = m._values;
-	    var index = m._index;
-	    var ptr = m._ptr;
-	    // result matrices
-	    var cvalues = values ? [] : undefined;
-	    var cindex = [];
-	    var cptr = [];
-	    // row counts
-	    var w = [];
-	    for (var x = 0; x < rows; x++)
-	      w[x] = 0;
-	    // vars
-	    var p, l, j;
-	    // loop values in matrix
-	    for (p = 0, l = index.length; p < l; p++) {
-	      // number of values in row
-	      w[index[p]]++;
-	    }
-	    // cumulative sum
-	    var sum = 0;
-	    // initialize cptr with the cummulative sum of row counts
-	    for (var i = 0; i < rows; i++) {
-	      // update cptr
-	      cptr.push(sum);
-	      // update sum
-	      sum += w[i];
-	      // update w
-	      w[i] = cptr[i];
-	    }
-	    // update cptr
-	    cptr.push(sum);
-	    // loop columns
-	    for (j = 0; j < columns; j++) {
-	      // values & index in column
-	      for (var k0 = ptr[j], k1 = ptr[j + 1], k = k0; k < k1; k++) {
-	        // C values & index
-	        var q = w[index[k]]++;
-	        // C[j, i] = A[i, j]
-	        cindex[q] = j;
-	        // check we need to process values (pattern matrix)
-	        if (values)
-	          cvalues[q] = clone(values[k]);
-	      }
-	    }
-	    // return matrix
-	    return new SparseMatrix({
-	      values: cvalues,
-	      index: cindex,
-	      ptr: cptr,
-	      size: [columns, rows],
-	      datatype: m._datatype
-	    });
-	  };
-
-	  transpose.toTex = '\\left(${args[0]}\\right)' + latex.operators['transpose'];
-
-	  return transpose;
-	}
-
-	exports.name = 'transpose';
-	exports.factory = factory;
-
-
-/***/ },
-/* 60 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	var isInteger = __webpack_require__(8).isInteger;
-	var resize = __webpack_require__(18).resize;
-
-	function factory (type, config, load, typed) {
-	  var matrix = load(__webpack_require__(23));
-
-	  /**
-	   * Create a matrix filled with zeros. The created matrix can have one or
-	   * multiple dimensions.
-	   *
-	   * Syntax:
-	   *
-	   *    math.zeros(m)
-	   *    math.zeros(m, format)
-	   *    math.zeros(m, n)
-	   *    math.zeros(m, n, format)
-	   *    math.zeros([m, n])
-	   *    math.zeros([m, n], format)
-	   *
-	   * Examples:
-	   *
-	   *    math.zeros(3);                  // returns [0, 0, 0]
-	   *    math.zeros(3, 2);               // returns [[0, 0], [0, 0], [0, 0]]
-	   *    math.zeros(3, 'dense');         // returns [0, 0, 0]
-	   *
-	   *    var A = [[1, 2, 3], [4, 5, 6]];
-	   *    math.zeros(math.size(A));       // returns [[0, 0, 0], [0, 0, 0]]
-	   *
-	   * See also:
-	   *
-	   *    ones, eye, size, range
-	   *
-	   * @param {...number | Array} size    The size of each dimension of the matrix
-	   * @param {string} [format]           The Matrix storage format
-	   *
-	   * @return {Array | Matrix}           A matrix filled with zeros
-	   */
-	  var zeros = typed('zeros', {
-	    '': function () {
-	      return (config.matrix === 'array')
-	          ? _zeros([])
-	          : _zeros([], 'default');
-	    },
-
-	    // math.zeros(m, n, p, ..., format)
-	    // TODO: more accurate signature '...number | BigNumber, string' as soon as typed-function supports this
-	    '...number | BigNumber | string': function (size) {
-	      var last = size[size.length - 1];
-	      if (typeof last === 'string') {
-	        var format = size.pop();
-	        return _zeros(size, format);
-	      }
-	      else if (config.matrix === 'array') {
-	        return _zeros(size);
-	      }
-	      else {
-	        return _zeros(size, 'default');
-	      }
-	    },
-
-	    'Array': _zeros,
-
-	    'Matrix': function (size) {
-	      var format = size.storage();
-	      return _zeros(size.valueOf(), format);
-	    },
-
-	    'Array | Matrix, string': function (size, format) {
-	      return _zeros (size.valueOf(), format);
-	    }
-	  });
-
-	  zeros.toTex = '\\mathrm{${name}}\\left(${args}\\right)';
-
-	  return zeros;
-
-	  /**
-	   * Create an Array or Matrix with zeros
-	   * @param {Array} size
-	   * @param {string} [format='default']
-	   * @return {Array | Matrix}
-	   * @private
-	   */
-	  function _zeros(size, format) {
-	    var hasBigNumbers = _normalize(size);
-	    var defaultValue = hasBigNumbers ? new type.BigNumber(0) : 0;
-	    _validate(size);
-
-	    if (format) {
-	      // return a matrix
-	      var m = matrix(format);
-	      if (size.length > 0) {
-	        return m.resize(size, defaultValue);
-	      }
-	      return m;
-	    }
-	    else {
-	      // return an Array
-	      var arr = [];
-	      if (size.length > 0) {
-	        return resize(arr, size, defaultValue);
-	      }
-	      return arr;
-	    }
-	  }
-
-	  // replace BigNumbers with numbers, returns true if size contained BigNumbers
-	  function _normalize(size) {
-	    var hasBigNumbers = false;
-	    size.forEach(function (value, index, arr) {
-	      if (value && value.isBigNumber === true) {
-	        hasBigNumbers = true;
-	        arr[index] = value.toNumber();
-	      }
-	    });
-	    return hasBigNumbers;
-	  }
-
-	  // validate arguments
-	  function _validate (size) {
-	    size.forEach(function (value) {
-	      if (typeof value !== 'number' || !isInteger(value) || value < 0) {
-	        throw new Error('Parameters in function zeros must be positive integers');
-	      }
-	    });
-	  }
-	}
-
-	// TODO: zeros contains almost the same code as ones. Reuse this?
-
-	exports.name = 'zeros';
-	exports.factory = factory;
-
-
-/***/ },
-/* 61 */
-/***/ function(module, exports, __webpack_require__) {
-
-	module.exports = [
-	  // decomposition
-	  __webpack_require__(62),
-	  __webpack_require__(67),
-
-	  // solver
-	  __webpack_require__(86),
-	  __webpack_require__(88),
-	  __webpack_require__(90)
-	];
-
-
-/***/ },
-/* 62 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	var util = __webpack_require__(36);
-
-	var object = util.object;
-
-	function factory (type, config, load, typed) {
-
-	  var matrix = load(__webpack_require__(23));
-	  var abs = load(__webpack_require__(63));
-	  var addScalar = load(__webpack_require__(27));
-	  var divideScalar = load(__webpack_require__(51));
-	  var multiplyScalar = load(__webpack_require__(41));
-	  var subtract = load(__webpack_require__(25));
-	  var larger = load(__webpack_require__(64));
-	  var equalScalar = load(__webpack_require__(33));
-	  var unaryMinus = load(__webpack_require__(28));
-	  
-	  var SparseMatrix = type.SparseMatrix;
-	  var DenseMatrix = type.DenseMatrix;
-	  var Spa = type.Spa;
-	  
-	  /**
-	   * Calculate the Matrix LU decomposition with partial pivoting. Matrix `A` is decomposed in two matrices (`L`, `U`) and a
-	   * row permutation vector `p` where `A[p,:] = L * U`
-	   *
-	   * Syntax:
-	   *
-	   *    math.lup(A);
-	   *
-	   * Example:
-	   *
-	   *    var m = [[2, 1], [1, 4]];
-	   *    var r = math.lup();
-	   *    // r = {
-	   *    //   L: [[1, 0], [0.5, 1]],
-	   *    //   U: [[2, 1], [0, 3.5]],
-	   *    //   P: [0, 1]
-	   *    // }
-	   *
-	   * See also:
-	   *
-	   *    slu, lsolve, lusolve, usolve
-	   *
-	   * @param {Matrix | Array} A    A two dimensional matrix or array for which to get the LUP decomposition.
-	   *
-	   * @return {Array<Matrix>}      The lower triangular matrix, the upper triangular matrix and the permutation matrix.
-	   */
-	  var lup = typed('lup', {
-
-	    'DenseMatrix': function (m) {
-	      return _denseLUP(m);
-	    },
-	    
-	    'SparseMatrix': function (m) {
-	      return _sparseLUP(m);
-	    },
-
-	    'Array': function (a) {
-	      // create dense matrix from array
-	      var m = matrix(a);
-	      // lup, use matrix implementation
-	      var r = _denseLUP(m);
-	      // result
-	      return {
-	        L: r.L.valueOf(),
-	        U: r.U.valueOf(),
-	        p: r.p
-	      };
-	    }
-	  });
-
-	  var _denseLUP = function (m) {
-	    // rows & columns
-	    var rows = m._size[0];
-	    var columns = m._size[1];
-	    // minimum rows and columns
-	    var n = Math.min(rows, columns);
-	    // matrix array, clone original data
-	    var data = object.clone(m._data);
-	    // l matrix arrays
-	    var ldata = [];
-	    var lsize = [rows, n];
-	    // u matrix arrays
-	    var udata = [];
-	    var usize = [n, columns];
-	    // vars
-	    var i, j, k;
-	    // permutation vector    
-	    var p = [];
-	    for (i = 0; i < rows; i++)
-	      p[i] = i;    
-	    // loop columns
-	    for (j = 0; j < columns; j++) {
-	      // skip first column in upper triangular matrix
-	      if (j > 0) {
-	        // loop rows
-	        for (i = 0; i < rows; i++) {
-	          // min i,j
-	          var min = Math.min(i, j);
-	          // v[i, j]
-	          var s = 0;
-	          // loop up to min
-	          for (k = 0; k < min; k++) {
-	            // s = l[i, k] - data[k, j]
-	            s = addScalar(s, multiplyScalar(data[i][k], data[k][j]));
-	          }
-	          data[i][j] = subtract(data[i][j], s);
-	        }
-	      }      
-	      // row with larger value in cvector, row >= j
-	      var pi = j;
-	      var pabsv = 0;
-	      var vjj = 0;
-	      // loop rows
-	      for (i = j; i < rows; i++) {
-	        // data @ i, j
-	        var v = data[i][j];
-	        // absolute value
-	        var absv = abs(v);
-	        // value is greater than pivote value
-	        if (larger(absv, pabsv)) {
-	          // store row
-	          pi = i;
-	          // update max value
-	          pabsv = absv;
-	          // value @ [j, j]
-	          vjj = v;
-	        }
-	      }
-	      // swap rows (j <-> pi)
-	      if (j !== pi) {
-	        // swap values j <-> pi in p
-	        p[j] = [p[pi], p[pi] = p[j]][0];
-	        // swap j <-> pi in data
-	        DenseMatrix._swapRows(j, pi, data);
-	      }
-	      // check column is in lower triangular matrix
-	      if (j < rows) {
-	        // loop rows (lower triangular matrix)
-	        for (i = j + 1; i < rows; i++) {
-	          // value @ i, j
-	          var vij = data[i][j];
-	          if (!equalScalar(vij, 0)) {
-	            // update data
-	            data[i][j] = divideScalar(data[i][j], vjj);
-	          }
-	        }
-	      }
-	    }
-	    // loop columns
-	    for (j = 0; j < columns; j++) {
-	      // loop rows
-	      for (i = 0; i < rows; i++) {
-	        // initialize row in arrays
-	        if (j === 0) {
-	          // check row exists in upper triangular matrix
-	          if (i < columns) {
-	            // U
-	            udata[i] = [];
-	          }
-	          // L
-	          ldata[i] = [];
-	        }
-	        // check we are in the upper triangular matrix
-	        if (i < j) {
-	          // check row exists in upper triangular matrix
-	          if (i < columns) {
-	            // U
-	            udata[i][j] = data[i][j];
-	          }
-	          // check column exists in lower triangular matrix
-	          if (j < rows) {
-	            // L
-	            ldata[i][j] = 0;
-	          }
-	          continue;
-	        }
-	        // diagonal value
-	        if (i === j) {
-	          // check row exists in upper triangular matrix
-	          if (i < columns) {
-	            // U
-	            udata[i][j] = data[i][j];
-	          }
-	          // check column exists in lower triangular matrix
-	          if (j < rows) {
-	            // L
-	            ldata[i][j] = 1;
-	          }
-	          continue;
-	        }
-	        // check row exists in upper triangular matrix
-	        if (i < columns) {
-	          // U
-	          udata[i][j] = 0;
-	        }
-	        // check column exists in lower triangular matrix
-	        if (j < rows) {
-	          // L
-	          ldata[i][j] = data[i][j];
-	        }
-	      }
-	    }
-	    // l matrix
-	    var l =  new DenseMatrix({
-	      data: ldata,
-	      size: lsize
-	    });
-	    // u matrix
-	    var u =  new DenseMatrix({
-	      data: udata,
-	      size: usize
-	    });
-	    // p vector
-	    var pv = [];
-	    for (i = 0, n = p.length; i < n; i++)
-	      pv[p[i]] = i;
-	    // return matrices
-	    return { 
-	      L: l, 
-	      U: u, 
-	      p: pv, 
-	      toString: function () {
-	        return 'L: ' + this.L.toString() + '\nU: ' + this.U.toString() + '\nP: ' + this.p;
-	      }
-	    };
-	  };
-	  
-	  var _sparseLUP = function (m) {
-	    // rows & columns
-	    var rows = m._size[0];
-	    var columns = m._size[1];
-	    // minimum rows and columns
-	    var n = Math.min(rows, columns);
-	    // matrix arrays (will not be modified, thanks to permutation vector)
-	    var values = m._values;
-	    var index = m._index;
-	    var ptr = m._ptr;
-	    // l matrix arrays
-	    var lvalues = [];
-	    var lindex = [];
-	    var lptr = [];
-	    var lsize = [rows, n];
-	    // u matrix arrays
-	    var uvalues = [];
-	    var uindex = [];
-	    var uptr = [];
-	    var usize = [n, columns];
-	    // vars
-	    var i, j, k;
-	    // permutation vectors, (current index -> original index) and (original index -> current index)
-	    var pv_co = [];
-	    var pv_oc = [];
-	    for (i = 0; i < rows; i++) {
-	      pv_co[i] = i;
-	      pv_oc[i] = i;
-	    }
-	    // swap indices in permutation vectors (condition x < y)!
-	    var swapIndeces = function (x, y) {      
-	      // find pv indeces getting data from x and y
-	      var kx = pv_oc[x];
-	      var ky = pv_oc[y];
-	      // update permutation vector current -> original
-	      pv_co[kx] = y;
-	      pv_co[ky] = x;
-	      // update permutation vector original -> current
-	      pv_oc[x] = ky;
-	      pv_oc[y] = kx;
-	    };
-	    // loop columns
-	    for (j = 0; j < columns; j++) {
-	      // sparse accumulator
-	      var spa = new Spa();            
-	      // check lower triangular matrix has a value @ column j
-	      if (j < rows) {
-	        // update ptr
-	        lptr.push(lvalues.length);
-	        // first value in j column for lower triangular matrix
-	        lvalues.push(1);
-	        lindex.push(j);
-	      }
-	      // update ptr
-	      uptr.push(uvalues.length);
-	      // k0 <= k < k1 where k0 = _ptr[j] && k1 = _ptr[j+1]
-	      var k0 = ptr[j];
-	      var k1 = ptr[j + 1];
-	      // copy column j into sparse accumulator
-	      for (k = k0; k < k1; k++) {
-	        // row
-	        i = index[k];
-	        // copy column values into sparse accumulator (use permutation vector)
-	        spa.set(pv_co[i], values[k]);
-	      }
-	      // skip first column in upper triangular matrix
-	      if (j > 0) {
-	        // loop rows in column j (above diagonal)
-	        spa.forEach(0, j - 1, function (k, vkj) {
-	          // loop rows in column k (L)
-	          SparseMatrix._forEachRow(k, lvalues, lindex, lptr, function (i, vik) {
-	            // check row is below k
-	            if (i > k) {
-	              // update spa value
-	              spa.accumulate(i, unaryMinus(multiplyScalar(vik, vkj)));
-	            }
-	          });
-	        });        
-	      }
-	      // row with larger value in spa, row >= j
-	      var pi = j;
-	      var vjj = spa.get(j);
-	      var pabsv = abs(vjj);      
-	      // loop values in spa (order by row, below diagonal)
-	      spa.forEach(j + 1, rows - 1, function (x, v) {
-	        // absolute value
-	        var absv = abs(v);
-	        // value is greater than pivote value
-	        if (larger(absv, pabsv)) {
-	          // store row
-	          pi = x;
-	          // update max value
-	          pabsv = absv;
-	          // value @ [j, j]
-	          vjj = v;
-	        }
-	      });
-	      // swap rows (j <-> pi)
-	      if (j !== pi) {
-	        // swap values j <-> pi in L
-	        SparseMatrix._swapRows(j, pi, lsize[1], lvalues, lindex, lptr);
-	        // swap values j <-> pi in U
-	        SparseMatrix._swapRows(j, pi, usize[1], uvalues, uindex, uptr);
-	        // swap values in spa
-	        spa.swap(j, pi);
-	        // update permutation vector (swap values @ j, pi)
-	        swapIndeces(j, pi);
-	      }
-	      // loop values in spa (order by row)
-	      spa.forEach(0, rows - 1, function (x, v) {
-	        // check we are above diagonal
-	        if (x <= j) {
-	          // update upper triangular matrix
-	          uvalues.push(v);
-	          uindex.push(x);
-	        }
-	        else {
-	          // update value
-	          v = divideScalar(v, vjj);
-	          // check value is non zero
-	          if (!equalScalar(v, 0)) {
-	            // update lower triangular matrix
-	            lvalues.push(v);
-	            lindex.push(x);
-	          }
-	        }
-	      });
-	    }
-	    // update ptrs
-	    uptr.push(uvalues.length);
-	    lptr.push(lvalues.length);
-
-	    // return matrices
-	    return {
-	      L: new SparseMatrix({
-	        values: lvalues,
-	        index: lindex,
-	        ptr: lptr,
-	        size: lsize
-	      }), 
-	      U: new SparseMatrix({
-	        values: uvalues,
-	        index: uindex,
-	        ptr: uptr,
-	        size: usize
-	      }),
-	      p: pv_co,
-	      toString: function () {
-	        return 'L: ' + this.L.toString() + '\nU: ' + this.U.toString() + '\nP: ' + this.p;
-	      }
-	    };
-	  };
-	  
-	  return lup;
-	}
-
-	exports.name = 'lup';
-	exports.factory = factory;
-
-
-/***/ },
-/* 63 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	var deepMap = __webpack_require__(29);
-
-	function factory (type, config, load, typed) {
-	  /**
-	   * Calculate the absolute value of a number. For matrices, the function is
-	   * evaluated element wise.
-	   *
-	   * Syntax:
-	   *
-	   *    math.abs(x)
-	   *
-	   * Examples:
-	   *
-	   *    math.abs(3.5);                // returns number 3.5
-	   *    math.abs(-4.2);               // returns number 4.2
-	   *
-	   *    math.abs([3, -5, -1, 0, 2]);  // returns Array [3, 5, 1, 0, 2]
-	   *
-	   * See also:
-	   *
-	   *    sign
-	   *
-	   * @param  {number | BigNumber | Fraction | Complex | Array | Matrix | Unit} x
-	   *            A number or matrix for which to get the absolute value
-	   * @return {number | BigNumber | Fraction | Complex | Array | Matrix | Unit}
-	   *            Absolute value of `x`
-	   */
-	  var abs = typed('abs', {
-	    'number': Math.abs,
-
-	    'Complex': function (x) {
-	      var re = Math.abs(x.re);
-	      var im = Math.abs(x.im);
-	      if (re < 1000 && im < 1000) {
-	        return Math.sqrt(re * re + im * im);
-	      }
-	      else {
-	        // prevent overflow for large numbers
-	        if (re >= im) {
-	          var i = im / re;
-	          return re * Math.sqrt(1 + i * i);
-	        }
-	        else {
-	          var j = re / im;
-	          return im * Math.sqrt(1 + j * j);
-	        }
-	      }
-	    },
-
-	    'BigNumber': function (x) {
-	      return x.abs();
-	    },
-
-	    'Fraction': function (x) {
-	      return x.abs();
-	    },
-
-	    'Array | Matrix': function (x) {
-	      // deep map collection, skip zeros since abs(0) = 0
-	      return deepMap(x, abs, true);
-	    },
-
-	    'Unit': function(x) {
-	      // This gives correct, but unexpected, results for units with an offset.
-	      // For example, abs(-283.15 degC) = -263.15 degC !!!
-	      var ret = x.clone();
-	      ret.value = Math.abs(ret.value);
-	      return ret;
-	    }
-	  });
-
-	  abs.toTex = '\\left|${args[0]}\\right|';
-
-	  return abs;
-	}
-
-	exports.name = 'abs';
-	exports.factory = factory;
-
-
-/***/ },
-/* 64 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	var nearlyEqual = __webpack_require__(8).nearlyEqual;
-
-	function factory (type, config, load, typed) {
-	  
-	  var matrix = load(__webpack_require__(23));
-
-	  var algorithm03 = load(__webpack_require__(31));
-	  var algorithm07 = load(__webpack_require__(66));
-	  var algorithm12 = load(__webpack_require__(65));
-	  var algorithm13 = load(__webpack_require__(35));
-	  var algorithm14 = load(__webpack_require__(39));
-
-	  var latex = __webpack_require__(26);
-
-	  /**
-	   * Test whether value x is larger than y.
-	   *
-	   * The function returns true when x is larger than y and the relative
-	   * difference between x and y is larger than the configured epsilon. The
-	   * function cannot be used to compare values smaller than approximately 2.22e-16.
-	   *
-	   * For matrices, the function is evaluated element wise.
-	   *
-	   * Syntax:
-	   *
-	   *    math.larger(x, y)
-	   *
-	   * Examples:
-	   *
-	   *    math.larger(2, 3);             // returns false
-	   *    math.larger(5, 2 + 2);         // returns true
-	   *
-	   *    var a = math.unit('5 cm');
-	   *    var b = math.unit('2 inch');
-	   *    math.larger(a, b);             // returns false
-	   *
-	   * See also:
-	   *
-	   *    equal, unequal, smaller, smallerEq, largerEq, compare
-	   *
-	   * @param  {number | BigNumber | Fraction | boolean | Unit | string | Array | Matrix} x First value to compare
-	   * @param  {number | BigNumber | Fraction | boolean | Unit | string | Array | Matrix} y Second value to compare
-	   * @return {boolean | Array | Matrix} Returns true when the x is larger than y, else returns false
-	   */
-	  var larger = typed('larger', {
-
-	    'boolean, boolean': function (x, y) {
-	      return x > y;
-	    },
-
-	    'number, number': function (x, y) {
-	      return x > y && !nearlyEqual(x, y, config.epsilon);
-	    },
-
-	    'BigNumber, BigNumber': function (x, y) {
-	      return x.gt(y);
-	    },
-
-	    'Fraction, Fraction': function (x, y) {
-	      return x.compare(y) === 1;
-	    },
-
-	    'Complex, Complex': function () {
-	      throw new TypeError('No ordering relation is defined for complex numbers');
-	    },
-
-	    'Unit, Unit': function (x, y) {
-	      if (!x.equalBase(y)) {
-	        throw new Error('Cannot compare units with different base');
-	      }
-	      return x.value > y.value && !nearlyEqual(x.value, y.value, config.epsilon);
-	    },
-
-	    'string, string': function (x, y) {
-	      return x > y;
-	    },
-
-	    'Matrix, Matrix': function (x, y) {
-	      // result
-	      var c;
-
-	      // process matrix storage
-	      switch (x.storage()) {
-	        case 'sparse':
-	          switch (y.storage()) {
-	            case 'sparse':
-	              // sparse + sparse
-	              c = algorithm07(x, y, larger);
-	              break;
-	            default:
-	              // sparse + dense
-	              c = algorithm03(y, x, larger, true);
-	              break;
-	          }
-	          break;
-	        default:
-	          switch (y.storage()) {
-	            case 'sparse':
-	              // dense + sparse
-	              c = algorithm03(x, y, larger, false);
-	              break;
-	            default:
-	              // dense + dense
-	              c = algorithm13(x, y, larger);
-	              break;
-	          }
-	          break;
-	      }
-	      return c;
-	    },
-
-	    'Array, Array': function (x, y) {
-	      // use matrix implementation
-	      return larger(matrix(x), matrix(y)).valueOf();
-	    },
-
-	    'Array, Matrix': function (x, y) {
-	      // use matrix implementation
-	      return larger(matrix(x), y);
-	    },
-
-	    'Matrix, Array': function (x, y) {
-	      // use matrix implementation
-	      return larger(x, matrix(y));
-	    },
-
-	    'Matrix, any': function (x, y) {
-	      // result
-	      var c;
-	      // check storage format
-	      switch (x.storage()) {
-	        case 'sparse':
-	          c = algorithm12(x, y, larger, false);
-	          break;
-	        default:
-	          c = algorithm14(x, y, larger, false);
-	          break;
-	      }
-	      return c;
-	    },
-
-	    'any, Matrix': function (x, y) {
-	      // result
-	      var c;
-	      // check storage format
-	      switch (y.storage()) {
-	        case 'sparse':
-	          c = algorithm12(y, x, larger, true);
-	          break;
-	        default:
-	          c = algorithm14(y, x, larger, true);
-	          break;
-	      }
-	      return c;
-	    },
-
-	    'Array, any': function (x, y) {
-	      // use matrix implementation
-	      return algorithm14(matrix(x), y, larger, false).valueOf();
-	    },
-
-	    'any, Array': function (x, y) {
-	      // use matrix implementation
-	      return algorithm14(matrix(y), x, larger, true).valueOf();
-	    }
-	  });
-
-	  larger.toTex = '\\left(${args[0]}' + latex.operators['larger'] + '${args[1]}\\right)';
-
-	  return larger;
-	}
-
-	exports.name = 'larger';
-	exports.factory = factory;
-
-
-/***/ },
-/* 65 */
-/***/ function(module, exports) {
-
-	'use strict';
-
-	function factory (type, config, load, typed) {
-
-	  var DenseMatrix = type.DenseMatrix;
-
-	  /**
-	   * Iterates over SparseMatrix S nonzero items and invokes the callback function f(Sij, b). 
-	   * Callback function invoked MxN times.
-	   *
-	   *
-	   *          ┌  f(Sij, b)  ; S(i,j) !== 0
-	   * C(i,j) = ┤  
-	   *          └  f(0, b)    ; otherwise
-	   *
-	   *
-	   * @param {Matrix}   s                 The SparseMatrix instance (S)
-	   * @param {Scalar}   b                 The Scalar value
-	   * @param {Function} callback          The f(Aij,b) operation to invoke
-	   * @param {boolean}  inverse           A true value indicates callback should be invoked f(b,Sij)
-	   *
-	   * @return {Matrix}                    DenseMatrix (C)
-	   *
-	   * https://github.com/josdejong/mathjs/pull/346#issuecomment-97626813
-	   */
-	  var algorithm12 = function (s, b, callback, inverse) {
-	    // sparse matrix arrays
-	    var avalues = s._values;
-	    var aindex = s._index;
-	    var aptr = s._ptr;
-	    var asize = s._size;
-	    var adt = s._datatype;
-
-	    // sparse matrix cannot be a Pattern matrix
-	    if (!avalues)
-	      throw new Error('Cannot perform operation on Pattern Sparse Matrix and Scalar value');
-
-	    // rows & columns
-	    var rows = asize[0];
-	    var columns = asize[1];
-
-	    // datatype
-	    var dt;
-	    // callback signature to use
-	    var cf = callback;
-
-	    // process data types
-	    if (typeof adt === 'string') {
-	      // datatype
-	      dt = adt;
-	      // convert b to the same datatype
-	      b = typed.convert(b, dt);
-	      // callback
-	      cf = typed.find(callback, [dt, dt]);
-	    }
-	    
-	    // result arrays
-	    var cdata = [];
-	    // matrix
-	    var c = new DenseMatrix({
-	      data: cdata,
-	      size: [rows, columns],
-	      datatype: dt
-	    });
-
-	    // workspaces
-	    var x = [];
-	    // marks indicating we have a value in x for a given column
-	    var w = [];
-
-	    // loop columns
-	    for (var j = 0; j < columns; j++) {
-	      // columns mark
-	      var mark = j + 1;
-	      // values in j
-	      for (var k0 = aptr[j], k1 = aptr[j + 1], k = k0; k < k1; k++) {
-	        // row
-	        var r = aindex[k];
-	        // update workspace
-	        x[r] = avalues[k];
-	        w[r] = mark;
-	      }
-	      // loop rows
-	      for (var i = 0; i < rows; i++) {
-	        // initialize C on first column
-	        if (j === 0) {
-	          // create row array
-	          cdata[i] = [];
-	        }
-	        // check sparse matrix has a value @ i,j
-	        if (w[i] === mark) {
-	          // invoke callback, update C
-	          cdata[i][j] = inverse ? cf(b, x[i]) : cf(x[i], b);
-	        }
-	        else {
-	          // dense matrix value @ i, j
-	          cdata[i][j] = inverse ? cf(b, 0) : cf(0, b);
-	        }
-	      }
-	    }
-
-	    // return sparse matrix
-	    return c;
-	  };
-	  
-	  return algorithm12;
-	}
-
-	exports.name = 'algorithm12';
-	exports.factory = factory;
-
-
-/***/ },
-/* 66 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	var DimensionError = __webpack_require__(22);
-
-	function factory (type, config, load, typed) {
-
-	  var DenseMatrix = type.DenseMatrix;
-
-	  /**
-	   * Iterates over SparseMatrix A and SparseMatrix B items (zero and nonzero) and invokes the callback function f(Aij, Bij). 
-	   * Callback function invoked MxN times.
-	   *
-	   * C(i,j) = f(Aij, Bij)
-	   *
-	   * @param {Matrix}   a                 The SparseMatrix instance (A)
-	   * @param {Matrix}   b                 The SparseMatrix instance (B)
-	   * @param {Function} callback          The f(Aij,Bij) operation to invoke
-	   *
-	   * @return {Matrix}                    DenseMatrix (C)
-	   *
-	   * see https://github.com/josdejong/mathjs/pull/346#issuecomment-97620294
-	   */
-	  var algorithm07 = function (a, b, callback) {
-	    // sparse matrix arrays
-	    var asize = a._size;
-	    var adt = a._datatype;
-	    // sparse matrix arrays
-	    var bsize = b._size;
-	    var bdt = b._datatype;
-
-	    // validate dimensions
-	    if (asize.length !== bsize.length)
-	      throw new DimensionError(asize.length, bsize.length);
-
-	    // check rows & columns
-	    if (asize[0] !== bsize[0] || asize[1] !== bsize[1])
-	      throw new RangeError('Dimension mismatch. Matrix A (' + asize + ') must match Matrix B (' + bsize + ')');
-
-	    // rows & columns
-	    var rows = asize[0];
-	    var columns = asize[1];
-
-	    // datatype
-	    var dt;
-	    // zero value
-	    var zero = 0;
-	    // callback signature to use
-	    var cf = callback;
-
-	    // process data types
-	    if (typeof adt === 'string' && adt === bdt) {
-	      // datatype
-	      dt = adt;
-	      // convert 0 to the same datatype
-	      zero = typed.convert(0, dt);
-	      // callback
-	      cf = typed.find(callback, [dt, dt]);
-	    }
-
-	    // vars
-	    var i, j;
-	    
-	    // result arrays
-	    var cdata = [];
-	    // initialize c
-	    for (i = 0; i < rows; i++)
-	      cdata[i] = [];
-
-	    // matrix
-	    var c = new DenseMatrix({
-	      data: cdata,
-	      size: [rows, columns],
-	      datatype: dt
-	    });
-
-	    // workspaces
-	    var xa = [];
-	    var xb = [];
-	    // marks indicating we have a value in x for a given column
-	    var wa = [];
-	    var wb = [];
-
-	    // loop columns
-	    for (j = 0; j < columns; j++) {
-	      // columns mark
-	      var mark = j + 1;
-	      // scatter the values of A(:,j) into workspace
-	      _scatter(a, j, wa, xa, mark);
-	      // scatter the values of B(:,j) into workspace
-	      _scatter(b, j, wb, xb, mark);
-	      // loop rows
-	      for (i = 0; i < rows; i++) {
-	        // matrix values @ i,j
-	        var va = wa[i] === mark ? xa[i] : zero;
-	        var vb = wb[i] === mark ? xb[i] : zero;
-	        // invoke callback
-	        cdata[i][j] = cf(va, vb);
-	      }          
-	    }
-
-	    // return sparse matrix
-	    return c;
-	  };
-	  
-	  var _scatter = function (m, j, w, x, mark) {
-	    // a arrays
-	    var values = m._values;
-	    var index = m._index;
-	    var ptr = m._ptr;
-	    // loop values in column j
-	    for (var k = ptr[j], k1 = ptr[j + 1]; k < k1; k++) {
-	      // row
-	      var i = index[k];
-	      // update workspace
-	      w[i] = mark;
-	      x[i] = values[k];
-	    }
-	  };
-	  
-	  return algorithm07;
-	}
-
-	exports.name = 'algorithm07';
-	exports.factory = factory;
-
-
-/***/ },
-/* 67 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	var util = __webpack_require__(36);
-
-	var number = util.number,
-	    
-	    isInteger = number.isInteger;
-
-	function factory (type, config, load, typed) {
-
-	  var cs_sqr = load(__webpack_require__(68));
-	  var cs_lu = load(__webpack_require__(78));
-
-	  /**
-	   * Calculate the Sparse Matrix LU decomposition with full pivoting. Sparse Matrix `A` is decomposed in two matrices (`L`, `U`) and two permutation vectors (`pinv`, `q`) where
-	   *
-	   * `P * A * Q = L * U`
-	   *
-	   * Syntax:
-	   *
-	   *    math.slu(A, order, threshold);
-	   *
-	   * See also:
-	   *
-	   *    lup, lsolve, usolve, lusolve
-	   *
-	   * @param {SparseMatrix} A              A two dimensional sparse matrix for which to get the LU decomposition.
-	   * @param {Number}       order          The Symbolic Ordering and Analysis order:
-	   *                                       0 - Natural ordering, no permutation vector q is returned
-	   *                                       1 - Matrix must be square, symbolic ordering and analisis is performed on M = A + A'
-	   *                                       2 - Symbolic ordering and analisis is performed on M = A' * A. Dense columns from A' are dropped, A recreated from A'. 
-	   *                                           This is appropriatefor LU factorization of unsymmetric matrices.
-	   *                                       3 - Symbolic ordering and analisis is performed on M = A' * A. This is best used for LU factorization is matrix M has no dense rows.
-	   *                                           A dense row is a row with more than 10*sqr(columns) entries.
-	   * @param {Number}       threshold       Partial pivoting threshold (1 for partial pivoting)
-	   *
-	   * @return {Object} The lower triangular matrix, the upper triangular matrix and the permutation vectors.
-	   */
-	  var slu = typed('slu', {
-
-	    'SparseMatrix, number, number': function (a, order, threshold) {
-	      // verify order
-	      if (!isInteger(order) || order < 0 || order > 3)
-	        throw new Error('Symbolic Ordering and Analysis order must be an integer number in the interval [0, 3]');
-	      // verify threshold
-	      if (threshold < 0 || threshold > 1)
-	        throw new Error('Partial pivoting threshold must be a number from 0 to 1');
-	      
-	      // perform symbolic ordering and analysis
-	      var s = cs_sqr(order, a, false);
-	      
-	      // perform lu decomposition
-	      var f = cs_lu(a, s, threshold);
-	      
-	      // return decomposition
-	      return {
-	        L: f.L,
-	        U: f.U,
-	        p: f.pinv,
-	        q: s.q,
-	        toString: function () {
-	          return 'L: ' + this.L.toString() + '\nU: ' + this.U.toString() + '\np: ' + this.p.toString() + (this.q ? '\nq: ' + this.q.toString() : '') + '\n';
-	        }
-	      };
-	    }
-	  });
-
-	  return slu;
-	}
-
-	exports.name = 'slu';
-	exports.factory = factory;
-
-
-/***/ },
-/* 68 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	function factory (type, config, load) {
-
-	  var cs_amd = load(__webpack_require__(69));
-	  var cs_permute = load(__webpack_require__(73));
-	  var cs_etree = load(__webpack_require__(74));
-	  var cs_post = load(__webpack_require__(75));
-	  var cs_counts = load(__webpack_require__(76));
-
-	  /**
-	   * Symbolic ordering and analysis for QR and LU decompositions.
-	   *
-	   * @param {Number}  order           The ordering strategy (see cs_amd for more details)
-	   * @param {Matrix}  a               The A matrix
-	   * @param {boolean} qr              Symbolic ordering and analysis for QR decomposition (true) or
-	   *                                  symbolic ordering and analysis for LU decomposition (false)
-	   *
-	   * @return {Object}                 The Symbolic ordering and analysis for matrix A
-	   *
-	   * Reference: http://faculty.cse.tamu.edu/davis/publications.html
-	   */
-	  var cs_sqr = function (order, a, qr) {
-	    // a arrays
-	    var aptr = a._ptr;
-	    var asize = a._size;
-	    // columns
-	    var n = asize[1];
-	    // vars
-	    var k;
-	    // symbolic analysis result
-	    var s = {};    
-	    // fill-reducing ordering
-	    s.q = cs_amd(order, a);
-	    // validate results
-	    if (order && !s.q) 
-	      return null;
-	    // QR symbolic analysis
-	    if (qr) {
-	      // apply permutations if needed
-	      var c = order ? cs_permute(a, null, s.q, 0) : a;
-	      // etree of C'*C, where C=A(:,q)
-	      s.parent = cs_etree(c, 1);
-	      // post order elimination tree
-	      var post = cs_post (s.parent, n);
-	      // col counts chol(C'*C)
-	      s.cp = cs_counts(c, s.parent, post, 1);
-	      // check we have everything needed to calculate number of nonzero elements
-	      if (c && s.parent && s.cp && _vcount(c, s)) {
-	        // calculate number of nonzero elements
-	        for (s.unz = 0, k = 0; k < n; k++) 
-	          s.unz += s.cp[k];
-	      }
-	    }
-	    else {
-	      // for LU factorization only, guess nnz(L) and nnz(U)
-	      s.unz = 4 * (aptr[n]) + n;
-	      s.lnz = s.unz;
-	    }
-	    // return result S
-	    return s;
-	  };
-	  
-	  /**
-	   * Compute nnz(V) = s.lnz, s.pinv, s.leftmost, s.m2 from A and s.parent
-	   */
-	  var _vcount = function (a, s) {
-	    // a arrays
-	    var aptr = a._ptr;
-	    var aindex = a._index;
-	    var asize = a._size;
-	    // rows & columns
-	    var m = asize[0];
-	    var n = asize[1];
-	    // initialize s arrays
-	    s.pinv = []; // (m + n);
-	    s.leftmost = []; // (m);
-	    // vars
-	    var parent = s.parent;
-	    var pinv = s.pinv;
-	    var leftmost = s.leftmost;
-	    // workspace, next: first m entries, head: next n entries, tail: next n entries, nque: next n entries
-	    var w = []; // (m + 3 * n);
-	    var next = 0;
-	    var head = m;
-	    var tail = m + n;
-	    var nque = m + 2 * n;
-	    // vars
-	    var i, k, p, p0, p1;
-	    // initialize w
-	    for (k = 0; k < n; k++) {
-	      // queue k is empty
-	      w[head + k] = -1;
-	      w[tail + k] = -1;
-	      w[nque + k] = 0;
-	    }
-	    // initialize row arrays
-	    for (i = 0; i < m; i++) 
-	      leftmost[i] = -1;
-	    // loop columns backwards    
-	    for (k = n - 1; k >= 0; k--) {
-	      // values & index for column k
-	      for (p0 = aptr[k], p1 = aptr[k + 1], p = p0; p < p1; p++) {
-	        // leftmost[i] = min(find(A(i,:)))
-	        leftmost[aindex[p]] = k;
-	      }
-	    }
-	    // scan rows in reverse order
-	    for (i = m - 1; i >= 0; i--) {
-	      // row i is not yet ordered
-	      pinv[i] = -1;
-	      k = leftmost[i];
-	      // check row i is empty
-	      if (k == -1) 
-	        continue;
-	      // first row in queue k
-	      if (w[nque + k]++ === 0) 
-	        w[tail + k] = i;
-	      // put i at head of queue k
-	      w[next + i] = w[head + k];
-	      w[head + k] = i;
-	    }
-	    s.lnz = 0;
-	    s.m2 = m;
-	    // find row permutation and nnz(V)
-	    for (k = 0; k < n; k++) {
-	      // remove row i from queue k
-	      i = w[head + k];
-	      // count V(k,k) as nonzero
-	      s.lnz++;
-	      // add a fictitious row
-	      if (i < 0) 
-	        i = s.m2++;
-	      // associate row i with V(:,k)
-	      pinv[i] = k;
-	      // skip if V(k+1:m,k) is empty
-	      if (--nque[k] <= 0) 
-	        continue;
-	      // nque[k] is nnz (V(k+1:m,k))
-	      s.lnz += w[nque + k];
-	      // move all rows to parent of k
-	      var pa = parent[k];
-	      if (pa != -1) {
-	        if (w[nque + pa] === 0) 
-	          w[tail + pa] = w[tail + k];
-	        w[next + w[tail + k]] = w[head + pa];
-	        w[head + pa] = w[next + i];
-	        w[nque + pa] += w[nque + k];
-	      }
-	    }
-	    for (i = 0; i < m; i++) {
-	      if (pinv[i] < 0) 
-	        pinv[i] = k++;
-	    }
-	    return true;
-	  };
-
-	  return cs_sqr;
-	}
-
-	exports.name = 'cs_sqr';
-	exports.path = 'sparse';
-	exports.factory = factory;
-
-
-/***/ },
-/* 69 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	function factory (type, config, load) {
-
-	  var cs_flip = load(__webpack_require__(70));
-	  var cs_fkeep = load(__webpack_require__(71));
-	  var cs_tdfs = load(__webpack_require__(72));
-	  
-	  var add       = load(__webpack_require__(44));
-	  var multiply  = load(__webpack_require__(40));
-	  var transpose = load(__webpack_require__(59));
-
-	  /**
-	   * Approximate minimum degree ordering. The minimum degree algorithm is a widely used 
-	   * heuristic for finding a permutation P so that P*A*P' has fewer nonzeros in its factorization
-	   * than A. It is a gready method that selects the sparsest pivot row and column during the course
-	   * of a right looking sparse Cholesky factorization.
-	   *
-	   * Reference: http://faculty.cse.tamu.edu/davis/publications.html
-	   *
-	   * @param {Number} order    0: Natural, 1: Cholesky, 2: LU, 3: QR
-	   * @param {Matrix} m        Sparse Matrix
-	   *
-	   * Reference: http://faculty.cse.tamu.edu/davis/publications.html
-	   */
-	  var cs_amd = function (order, a) {
-	    // check input parameters
-	    if (!a || order <= 0 || order > 3)
-	      return null;
-	    // a matrix arrays
-	    var asize = a._size;
-	    // rows and columns
-	    var m = asize[0];
-	    var n = asize[1];    
-	    // initialize vars
-	    var lemax = 0;
-	    // dense threshold
-	    var dense = Math.max(16, 10 * Math.sqrt(n));
-	    dense = Math.min(n - 2, dense);
-	    // create target matrix C
-	    var cm = _createTargetMatrix(order, a, m, n, dense);
-	    // drop diagonal entries
-	    cs_fkeep(cm, _diag, null);
-	    // C matrix arrays
-	    var cindex = cm._index;
-	    var cptr = cm._ptr;
-
-	    // number of nonzero elements in C
-	    var cnz = cptr[n];
-	    
-	    // allocate result (n+1)
-	    var P = [];
-	    
-	    // create workspace (8 * (n + 1))
-	    var W = [];
-	    var len = 0; // first n + 1 entries
-	    var nv = n + 1; // next n + 1 entries
-	    var next = 2 * (n + 1); // next n + 1 entries
-	    var head = 3 * (n + 1);  // next n + 1 entries
-	    var elen = 4 * (n + 1);  // next n + 1 entries
-	    var degree = 5 * (n + 1);  // next n + 1 entries
-	    var w = 6 * (n + 1);  // next n + 1 entries
-	    var hhead = 7 * (n + 1);  // last n + 1 entries    
-
-	    // use P as workspace for last
-	    var last = P;
-	    
-	    // initialize quotient graph
-	    var mark = _initializeQuotientGraph(n, cptr, W, len, head, last, next, hhead, nv, w, elen, degree);
-	    
-	    // initialize degree lists
-	    var nel = _initializeDegreeLists(n, cptr, W, degree, elen, w, dense, nv, head, last, next);
-	    
-	    // minimum degree node
-	    var mindeg = 0;
-	    
-	    // vars
-	    var i, j, k, k1, k2, e, pj, ln, nvi, pk, eln, p1, p2, pn, h, d;
-	    
-	    // while (selecting pivots) do
-	    while (nel < n) {
-	      // select node of minimum approximate degree. amd() is now ready to start eliminating the graph. It first
-	      // finds a node k of minimum degree and removes it from its degree list. The variable nel keeps track of thow
-	      // many nodes have been eliminated.
-	      for (k = -1; mindeg < n && (k = W[head + mindeg]) == -1; mindeg++);      
-	      if (W[next + k] != -1) 
-	        last[W[next + k]] = -1;
-	      // remove k from degree list
-	      W[head + mindeg] = W[next + k];
-	      // elenk = |Ek|
-	      var elenk = W[elen + k];
-	      // # of nodes k represents
-	      var nvk = W[nv + k];
-	      // W[nv + k] nodes of A eliminated
-	      nel += nvk;
-
-	      // Construct a new element. The new element Lk is constructed in place if |Ek| = 0. nv[i] is 
-	      // negated for all nodes i in Lk to flag them as members of this set. Each node i is removed from the
-	      // degree lists. All elements e in Ek are absorved into element k.
-	      var dk = 0;
-	      // flag k as in Lk
-	      W[nv + k] = -nvk;
-	      var p = cptr[k];
-	      // do in place if W[elen + k] == 0
-	      var pk1 = (elenk === 0) ? p : cnz;
-	      var pk2 = pk1;
-	      for (k1 = 1; k1 <= elenk + 1; k1++) {
-	        if (k1 > elenk) {
-	          // search the nodes in k
-	          e = k;
-	          // list of nodes starts at cindex[pj]
-	          pj = p;
-	          // length of list of nodes in k
-	          ln = W[len + k] - elenk;
-	        }
-	        else {
-	          // search the nodes in e
-	          e = cindex[p++];
-	          pj = cptr[e];
-	          // length of list of nodes in e
-	          ln = W[len + e];
-	        }
-	        for (k2 = 1; k2 <= ln; k2++) {
-	          i = cindex[pj++];
-	          // check  node i dead, or seen
-	          if ((nvi = W[nv + i]) <= 0) 
-	            continue;
-	          // W[degree + Lk] += size of node i
-	          dk += nvi;
-	          // negate W[nv + i] to denote i in Lk
-	          W[nv + i] = -nvi;
-	          // place i in Lk
-	          cindex[pk2++] = i;
-	          if (W[next + i] != -1) 
-	            last[W[next + i]] = last[i];
-	          // check we need to remove i from degree list
-	          if (last[i] != -1) 
-	            W[next + last[i]] = W[next + i];
-	          else
-	            W[head + W[degree + i]] = W[next + i];
-	        }
-	        if (e != k) {
-	          // absorb e into k
-	          cptr[e] = cs_flip(k);
-	          // e is now a dead element
-	          W[w + e] = 0;
-	        }
-	      }
-	      // cindex[cnz...nzmax] is free
-	      if (elenk !== 0) 
-	        cnz = pk2;
-	      // external degree of k - |Lk\i|
-	      W[degree + k] = dk;
-	      // element k is in cindex[pk1..pk2-1]
-	      cptr[k] = pk1;
-	      W[len + k] = pk2 - pk1;
-	      // k is now an element
-	      W[elen + k] = -2;
-	            
-	      // Find set differences. The scan1 function now computes the set differences |Le \ Lk| for all elements e. At the start of the
-	      // scan, no entry in the w array is greater than or equal to mark.
-	      
-	      // clear w if necessary
-	      mark = _wclear(mark, lemax, w, n);
-	      // scan 1: find |Le\Lk|
-	      for (pk = pk1; pk < pk2; pk++) {
-	        i = cindex[pk];
-	        // check if W[elen + i] empty, skip it
-	        if ((eln = W[elen + i]) <= 0) 
-	          continue;
-	        // W[nv + i] was negated
-	        nvi = -W[nv + i];
-	        var wnvi = mark - nvi;
-	        // scan Ei
-	        for (p = cptr[i], p1 = cptr[i] + eln - 1; p <= p1; p++) {
-	          e = cindex[p];
-	          if (W[w + e] >= mark) {
-	            // decrement |Le\Lk|
-	            W[w + e] -= nvi;
-	          }
-	          else if (W[w + e] !== 0) {
-	            // ensure e is a live element, 1st time e seen in scan 1
-	            W[w + e] = W[degree + e] + wnvi;
-	          }
-	        }
-	      }
-	      
-	      // degree update
-	      // The second pass computes the approximate degree di, prunes the sets Ei and Ai, and computes a hash
-	      // function h(i) for all nodes in Lk.
-	      
-	      // scan2: degree update
-	      for (pk = pk1; pk < pk2; pk++) {
-	        // consider node i in Lk
-	        i = cindex[pk];
-	        p1 = cptr[i];
-	        p2 = p1 + W[elen + i] - 1;
-	        pn = p1;
-	        // scan Ei
-	        for (h = 0, d = 0, p = p1; p <= p2; p++) {
-	          e = cindex[p];
-	          // check e is an unabsorbed element
-	          if (W[w + e] !== 0) {
-	            // dext = |Le\Lk|
-	            var dext = W[w + e] - mark;
-	            if (dext > 0) {
-	              // sum up the set differences
-	              d += dext;
-	              // keep e in Ei
-	              cindex[pn++] = e;
-	              // compute the hash of node i
-	              h += e;
-	            }
-	            else {
-	              // aggressive absorb. e->k
-	              cptr[e] = cs_flip(k);
-	              // e is a dead element
-	              W[w + e] = 0;
-	            }
-	          }
-	        }
-	        // W[elen + i] = |Ei|
-	        W[elen + i] = pn - p1 + 1;
-	        var p3 = pn;
-	        var p4 = p1 + W[len + i];
-	        // prune edges in Ai
-	        for (p = p2 + 1; p < p4; p++) {
-	          j = cindex[p];
-	          // check node j dead or in Lk
-	          var nvj = W[nv + j];
-	          if (nvj <= 0) 
-	            continue;
-	          // degree(i) += |j|
-	          d += nvj;
-	          // place j in node list of i
-	          cindex[pn++] = j;
-	          // compute hash for node i
-	          h += j;
-	        }
-	        // check for mass elimination
-	        if (d === 0) {
-	          // absorb i into k
-	          cptr[i] = cs_flip(k);
-	          nvi = -W[nv + i];
-	          // |Lk| -= |i|
-	          dk -= nvi;
-	          // |k| += W[nv + i]
-	          nvk += nvi;
-	          nel += nvi;
-	          W[nv + i] = 0;
-	          // node i is dead
-	          W[elen + i] = -1;
-	        }
-	        else {
-	          // update degree(i)
-	          W[degree + i] = Math.min(W[degree + i], d);
-	          // move first node to end
-	          cindex[pn] = cindex[p3];
-	          // move 1st el. to end of Ei
-	          cindex[p3] = cindex[p1];
-	          // add k as 1st element in of Ei
-	          cindex[p1] = k;
-	          // new len of adj. list of node i
-	          W[len + i] = pn - p1 + 1;
-	          // finalize hash of i
-	          h = (h < 0 ? -h : h) % n;
-	          // place i in hash bucket
-	          W[next + i] = W[hhead + h];
-	          W[hhead + h] = i;
-	          // save hash of i in last[i]
-	          last[i] = h;
-	        }
-	      }
-	      // finalize |Lk|
-	      W[degree + k] = dk;
-	      lemax = Math.max(lemax, dk);
-	      // clear w
-	      mark = _wclear(mark + lemax, lemax, w, n);
-	      
-	      // Supernode detection. Supernode detection relies on the hash function h(i) computed for each node i.
-	      // If two nodes have identical adjacency lists, their hash functions wil be identical.
-	      for (pk = pk1; pk < pk2; pk++) {
-	        i = cindex[pk];
-	        // check i is dead, skip it
-	        if (W[nv + i] >= 0) 
-	          continue;
-	        // scan hash bucket of node i
-	        h = last[i];
-	        i = W[hhead + h];
-	        // hash bucket will be empty
-	        W[hhead + h] = -1;
-	        for (; i != -1 && W[next + i] != -1; i = W[next + i], mark++) {
-	          ln = W[len + i];
-	          eln = W[elen + i];
-	          for (p = cptr[i] + 1; p <= cptr[i] + ln - 1; p++) 
-	            W[w + cindex[p]] = mark;
-	          var jlast = i;
-	          // compare i with all j
-	          for (j = W[next + i]; j != -1; ) {
-	            var ok = W[len + j] === ln && W[elen + j] === eln;
-	            for (p = cptr[j] + 1; ok && p <= cptr[j] + ln - 1; p++) {
-	              // compare i and j
-	              if (W[w + cindex[p]] != mark) 
-	                ok = 0;
-	            }
-	            // check i and j are identical
-	            if (ok) {
-	              // absorb j into i
-	              cptr[j] = cs_flip(i);
-	              W[nv + i] += W[nv + j];
-	              W[nv + j] = 0;
-	              // node j is dead
-	              W[elen + j] = -1;
-	              // delete j from hash bucket
-	              j = W[next + j];
-	              W[next + jlast] = j;
-	            }
-	            else {
-	              // j and i are different
-	              jlast = j;
-	              j = W[next + j];
-	            }
-	          }
-	        }
-	      }
-	      
-	      // Finalize new element. The elimination of node k is nearly complete. All nodes i in Lk are scanned one last time.
-	      // Node i is removed from Lk if it is dead. The flagged status of nv[i] is cleared.
-	      for (p = pk1, pk = pk1; pk < pk2; pk++) {
-	        i = cindex[pk];
-	        // check  i is dead, skip it
-	        if ((nvi = -W[nv + i]) <= 0) 
-	          continue;
-	        // restore W[nv + i]
-	        W[nv + i] = nvi;
-	        // compute external degree(i)
-	        d = W[degree + i] + dk - nvi;
-	        d = Math.min(d, n - nel - nvi);
-	        if (W[head + d] != -1) 
-	          last[W[head + d]] = i;
-	        // put i back in degree list
-	        W[next + i] = W[head + d];
-	        last[i] = -1;
-	        W[head + d] = i;
-	        // find new minimum degree
-	        mindeg = Math.min(mindeg, d);
-	        W[degree + i] = d;
-	        // place i in Lk
-	        cindex[p++] = i;
-	      }
-	      // # nodes absorbed into k
-	      W[nv + k] = nvk;
-	      // length of adj list of element k
-	      if ((W[len + k] = p - pk1) === 0) {
-	        // k is a root of the tree
-	        cptr[k] = -1;
-	        // k is now a dead element
-	        W[w + k] = 0;
-	      }
-	      if (elenk !== 0) {
-	        // free unused space in Lk
-	        cnz = p;
-	      }
-	    }
-	    
-	    // Postordering. The elimination is complete, but no permutation has been computed. All that is left 
-	    // of the graph is the assembly tree (ptr) and a set of dead nodes and elements (i is a dead node if
-	    // nv[i] is zero and a dead element if nv[i] > 0). It is from this information only that the final permutation
-	    // is computed. The tree is restored by unflipping all of ptr.
-	    
-	    // fix assembly tree
-	    for (i = 0; i < n; i++) 
-	      cptr[i] = cs_flip(cptr[i]);
-	    for (j = 0; j <= n; j++) 
-	      W[head + j] = -1;
-	    // place unordered nodes in lists
-	    for (j = n; j >= 0; j--) {
-	      // skip if j is an element
-	      if (W[nv + j] > 0)
-	        continue;
-	      // place j in list of its parent
-	      W[next + j] = W[head + cptr[j]];
-	      W[head + cptr[j]] = j;
-	    }
-	    // place elements in lists
-	    for (e = n; e >= 0; e--) {
-	      // skip unless e is an element
-	      if (W[nv + e] <= 0)
-	        continue;
-	      if (cptr[e] != -1) {
-	        // place e in list of its parent
-	        W[next + e] = W[head + cptr[e]];
-	        W[head + cptr[e]] = e;
-	      }
-	    }
-	    // postorder the assembly tree
-	    for (k = 0, i = 0; i <= n; i++) {
-	      if (cptr[i] == -1) 
-	        k = cs_tdfs(i, k, W, head, next, P, w);
-	    }
-	    // remove last item in array
-	    P.splice(P.length - 1, 1);
-	    // return P
-	    return P;
-	  };
-	  
-	  /**
-	   * Creates the matrix that will be used by the approximate minimum degree ordering algorithm. The function accepts the matrix M as input and returns a permutation
-	   * vector P. The amd algorithm operates on a symmetrix matrix, so one of three symmetric matrices is formed.
-	   *
-	   * Order: 0
-	   *   A natural ordering P=null matrix is returned.
-	   *
-	   * Order: 1
-	   *   Matrix must be square. This is appropriate for a Cholesky or LU factorization.
-	   *   P = M + M'
-	   *
-	   * Order: 2
-	   *   Dense columns from M' are dropped, M recreated from M'. This is appropriatefor LU factorization of unsymmetric matrices.
-	   *   P = M' * M
-	   * 
-	   * Order: 3
-	   *   This is best used for QR factorization or LU factorization is matrix M has no dense rows. A dense row is a row with more than 10*sqr(columns) entries.
-	   *   P = M' * M
-	   */
-	  var _createTargetMatrix = function (order, a, m, n, dense) {
-	    // compute A'
-	    var at = transpose(a);
-
-	    // check order = 1, matrix must be square
-	    if (order === 1 && n === m) {
-	      // C = A + A'
-	      return add(a, at);
-	    }
-	    
-	    // check order = 2, drop dense columns from M'
-	    if (order == 2) {
-	      // transpose arrays
-	      var tindex = at._index;
-	      var tptr = at._ptr;
-	      // new column index
-	      var p2 = 0;
-	      // loop A' columns (rows)
-	      for (var j = 0; j < m; j++) {
-	        // column j of AT starts here
-	        var p = tptr[j];
-	        // new column j starts here
-	        tptr[j] = p2;
-	        // skip dense col j
-	        if (tptr[j + 1] - p > dense) 
-	          continue;
-	        // map rows in column j of A
-	        for (var p1 = tptr[j + 1]; p < p1; p++) 
-	          tindex[p2++] = tindex[p];
-	      }
-	      // finalize AT
-	      tptr[m] = p2;
-	      // recreate A from new transpose matrix
-	      a = transpose(at);
-	      // use A' * A
-	      return multiply(at, a);
-	    }
-	    
-	    // use A' * A, square or rectangular matrix
-	    return multiply(at, a);
-	  };
-
-	  /**
-	   * Initialize quotient graph. There are four kind of nodes and elements that must be represented:
-	   *
-	   *  - A live node is a node i (or a supernode) that has not been selected as a pivot nad has not been merged into another supernode.
-	   *  - A dead node i is one that has been removed from the graph, having been absorved into r = flip(ptr[i]).
-	   *  - A live element e is one that is in the graph, having been formed when node e was selected as the pivot.
-	   *  - A dead element e is one that has benn absorved into a subsequent element s = flip(ptr[e]).
-	   */
-	  var _initializeQuotientGraph = function (n, cptr, W, len, head, last, next, hhead, nv, w, elen, degree) {
-	    // Initialize quotient graph
-	    for (var k = 0; k < n; k++) 
-	      W[len + k] = cptr[k + 1] - cptr[k];
-	    W[len + n] = 0;
-	    // initialize workspace
-	    for (var i = 0; i <= n; i++) {
-	      // degree list i is empty
-	      W[head + i] = -1;
-	      last[i] = -1;
-	      W[next + i] = -1;
-	      // hash list i is empty
-	      W[hhead + i] = -1;
-	      // node i is just one node
-	      W[nv + i] = 1;
-	      // node i is alive
-	      W[w + i] = 1;
-	      // Ek of node i is empty
-	      W[elen + i] = 0;
-	      // degree of node i
-	      W[degree + i] = W[len + i];
-	    }
-	    // clear w
-	    var mark = _wclear(0, 0, w, n);
-	    // n is a dead element
-	    W[elen + n] = -2;
-	    // n is a root of assembly tree
-	    cptr[n] = -1;
-	    // n is a dead element
-	    W[w + n] = 0;
-	    // return mark
-	    return mark;
-	  };
-
-	  /**
-	   * Initialize degree lists. Each node is placed in its degree lists. Nodes of zero degree are eliminated immediately. Nodes with 
-	   * degree >= dense are alsol eliminated and merged into a placeholder node n, a dead element. Thes nodes will appera last in the
-	   * output permutation p.
-	   */
-	  var _initializeDegreeLists = function (n, cptr, W, degree, elen, w, dense, nv, head, last, next) {
-	    // result
-	    var nel = 0;
-	    // loop columns
-	    for (var i = 0; i < n; i++) {
-	      // degree @ i
-	      var d = W[degree + i];
-	      // check node i is empty
-	      if (d === 0) {
-	        // element i is dead
-	        W[elen + i] = -2;
-	        nel++;
-	        // i is a root of assembly tree
-	        cptr[i] = -1;
-	        W[w + i] = 0;
-	      }
-	      else if (d > dense) {
-	        // absorb i into element n
-	        W[nv + i] = 0;
-	        // node i is dead
-	        W[elen + i] = -1;
-	        nel++;
-	        cptr[i] = cs_flip(n);
-	        W[nv + n]++;
-	      }
-	      else {
-	        var h = W[head + d];
-	        if (h != -1)
-	          last[h] = i;
-	        // put node i in degree list d
-	        W[next + i] = W[head + d];
-	        W[head + d] = i;
-	      }
-	    }
-	    return nel;
-	  };
-
-	  var _wclear = function(mark, lemax, w, n) {
-	    if (mark < 2 || (mark + lemax < 0)) {
-	      for (var k = 0; k < n; k++) {
-	        if (w[k] !== 0)
-	          w[k] = 1;
-	      }
-	      mark = 2 ;
-	    }
-	    // at this point, w [0..n-1] < mark holds
-	    return mark;
-	  };
-	  
-	  var _diag = function (i, j) { 
-	    return i != j;
-	  };
-	  
-	  return cs_amd;
-	}
-
-	exports.name = 'cs_amd';
-	exports.path = 'sparse';
-	exports.factory = factory;
-
-
-/***/ },
-/* 70 */
-/***/ function(module, exports) {
-
-	'use strict';
-
-	function factory () {
-
-	  /**
-	   * This function "flips" its input about the integer -1.
-	   *
-	   * @param {Number}  i               The value to flip
-	   *
-	   * Reference: http://faculty.cse.tamu.edu/davis/publications.html
-	   */
-	  var cs_flip = function (i) {
-	    // flip the value
-	    return -i - 2;
-	  };
-
-	  return cs_flip;
-	}
-
-	exports.name = 'cs_flip';
-	exports.path = 'sparse';
-	exports.factory = factory;
-
-
-/***/ },
-/* 71 */
-/***/ function(module, exports) {
-
-	'use strict';
-
-	function factory () {
-
-	  /**
-	   * Keeps entries in the matrix when the callback function returns true, removes the entry otherwise
-	   *
-	   * @param {Matrix}   a              The sparse matrix
-	   * @param {function} callback       The callback function, function will be invoked with the following args:
-	   *                                    - The entry row
-	   *                                    - The entry column
-	   *                                    - The entry value
-	   *                                    - The state parameter
-	   * @param {any}      other          The state
-	   *
-	   * @return                          The number of nonzero elements in the matrix
-	   *
-	   * Reference: http://faculty.cse.tamu.edu/davis/publications.html
-	   */
-	  var cs_fkeep = function (a, callback, other) {
-	    // a arrays
-	    var avalues = a._values;
-	    var aindex = a._index;
-	    var aptr = a._ptr;
-	    var asize = a._size;
-	    // columns
-	    var n = asize[1];
-	    // nonzero items
-	    var nz = 0;
-	    // loop columns
-	    for (var j = 0; j < n; j++) {
-	      // get current location of col j
-	      var p = aptr[j];
-	      // record new location of col j
-	      aptr[j] = nz;
-	      for (; p < aptr[j+1]; p++) {
-	        // check we need to keep this item
-	        if (callback(aindex[p], j, avalues ? avalues[p] : 1, other)) {
-	          // keep A(i,j)
-	          aindex[nz] = aindex[p];
-	          // check we need to process values (pattern only)
-	          if (avalues) 
-	            avalues[nz] = avalues[p];
-	          // increment nonzero items
-	          nz++;
-	        }
-	      }
-	    }
-	    // finalize A
-	    aptr[n] = nz;
-	    // trim arrays
-	    aindex.splice(nz, aindex.length - nz);
-	    // check we need to process values (pattern only)
-	    if (avalues)
-	      avalues.splice(nz, avalues.length - nz);    
-	    // return number of nonzero items
-	    return (nz);
-	  };
-	  
-	  return cs_fkeep;
-	}
-
-	exports.name = 'cs_fkeep';
-	exports.path = 'sparse';
-	exports.factory = factory;
-
-
-/***/ },
-/* 72 */
-/***/ function(module, exports) {
-
-	'use strict';
-
-	function factory () {
-
-	  /**
-	   * Depth-first search and postorder of a tree rooted at node j
-	   *
-	   * @param {Number}  j               The tree node
-	   * @param {Number}  k               
-	   * @param {Array}   w               The workspace array
-	   * @param {Number}  head            The index offset within the workspace for the head array
-	   * @param {Number}  next            The index offset within the workspace for the next array
-	   * @param {Array}   post            The post ordering array
-	   * @param {Number}  stack           The index offset within the workspace for the stack array
-	   *
-	   * Reference: http://faculty.cse.tamu.edu/davis/publications.html
-	   */
-	  var cs_tdfs = function (j, k, w, head, next, post, stack) {
-	    // variables
-	    var top = 0;
-	    // place j on the stack
-	    w[stack] = j;
-	    // while (stack is not empty) 
-	    while (top >= 0) {
-	      // p = top of stack
-	      var p = w[stack + top];
-	      // i = youngest child of p
-	      var i = w[head + p];
-	      if (i == -1) {
-	        // p has no unordered children left
-	        top--;
-	        // node p is the kth postordered node
-	        post[k++] = p;
-	      }
-	      else {
-	        // remove i from children of p
-	        w[head + p] = w[next + i];
-	        // increment top
-	        ++top;
-	        // start dfs on child node i
-	        w[stack + top] = i;
-	      }
-	    }
-	    return k;
-	  };
-
-	  return cs_tdfs;
-	}
-
-	exports.name = 'cs_tdfs';
-	exports.path = 'sparse';
-	exports.factory = factory;
-
-
-/***/ },
-/* 73 */
-/***/ function(module, exports) {
-
-	'use strict';
-
-	function factory (type) {
-
-	  var SparseMatrix = type.SparseMatrix;
-
-	  /**
-	   * Permutes a sparse matrix C = P * A * Q
-	   *
-	   * @param {Matrix}  a               The Matrix A
-	   * @param {Array}   pinv            The row permutation vector
-	   * @param {Array}   q               The column permutation vector
-	   * @param {boolean} values          Create a pattern matrix (false), values and pattern otherwise
-	   *
-	   * @return {Matrix}                 C = P * A * Q, null on error
-	   *
-	   * Reference: http://faculty.cse.tamu.edu/davis/publications.html
-	   */
-	  var cs_permute = function (a, pinv, q, values) {
-	    // a arrays
-	    var avalues = a._values;
-	    var aindex = a._index;
-	    var aptr = a._ptr;
-	    var asize = a._size;
-	    var adt = a._datatype;
-	    // rows & columns
-	    var m = asize[0];
-	    var n = asize[1];
-	    // c arrays
-	    var cvalues = values && a._values ? [] : null;
-	    var cindex = []; // (aptr[n]);
-	    var cptr = []; // (n + 1);
-	    // initialize vars
-	    var nz = 0;
-	    // loop columns    
-	    for (var k = 0; k < n; k++) {
-	      // column k of C is column q[k] of A
-	      cptr[k] = nz;
-	      // apply column permutation
-	      var j = q ? (q[k]) : k;
-	      // loop values in column j of A
-	      for (var t0 = aptr[j], t1 = aptr[j + 1], t = t0; t < t1; t++) {
-	        // row i of A is row pinv[i] of C
-	        var r = pinv ? pinv[aindex[t]] : aindex[t];
-	        // index
-	        cindex[nz] = r;
-	        // check we need to populate values
-	        if (cvalues) 
-	          cvalues[nz] = avalues[t];
-	        // increment number of nonzero elements
-	        nz++;
-	      }
-	    }
-	    // finalize the last column of C
-	    cptr[n] = nz;
-	    // return C matrix
-	    return new SparseMatrix({
-	      values: cvalues,
-	      index: cindex,
-	      ptr: cptr,
-	      size: [m, n],
-	      datatype: adt
-	    });
-	  };
-
-	  return cs_permute;
-	}
-
-	exports.name = 'cs_permute';
-	exports.path = 'sparse';
-	exports.factory = factory;
-
-
-/***/ },
-/* 74 */
-/***/ function(module, exports) {
-
-	'use strict';
-
-	function factory () {
-
-	  /**
-	   * Computes the elimination tree of Matrix A (using triu(A)) or the 
-	   * elimination tree of A'A without forming A'A.
-	   *
-	   * @param {Matrix}  a               The A Matrix
-	   * @param {boolean} ata             A value of true the function computes the etree of A'A
-	   *
-	   * Reference: http://faculty.cse.tamu.edu/davis/publications.html
-	   */
-	  var cs_etree = function (a, ata) {
-	    // check inputs
-	    if (!a)
-	      return null;
-	    // a arrays
-	    var aindex = a._index;
-	    var aptr = a._ptr;
-	    var asize = a._size;
-	    // rows & columns
-	    var m = asize[0];
-	    var n = asize[1];
-	    
-	    // allocate result
-	    var parent = []; // (n)
-	    
-	    // allocate workspace
-	    var w = []; // (n + (ata ? m : 0))
-	    var ancestor = 0; // first n entries in w
-	    var prev = n; // last m entries (ata = true)
-	    
-	    var i, inext;
-	    
-	    // check we are calculating A'A
-	    if (ata) {
-	      // initialize workspace
-	      for (i = 0; i < m; i++) 
-	        w[prev + i] = -1;
-	    }
-	    // loop columns
-	    for (var k = 0; k < n; k++) {
-	      // node k has no parent yet
-	      parent[k] = -1;
-	      // nor does k have an ancestor
-	      w[ancestor + k] = -1;
-	      // values in column k
-	      for (var p0 = aptr[k], p1 = aptr[k + 1], p = p0; p < p1; p++) {
-	        // row
-	        var r = aindex[p];
-	        // node
-	        i = ata ? (w[prev + r]) : r;
-	        // traverse from i to k 
-	        for (; i != -1 && i < k; i = inext) {
-	          // inext = ancestor of i
-	          inext = w[ancestor + i];
-	          // path compression
-	          w[ancestor + i] = k;
-	          // check no anc., parent is k
-	          if (inext == -1) 
-	            parent[i] = k;
-	        }
-	        if (ata) 
-	          w[prev + r] = k;
-	      }
-	    }
-	    return parent;
-	  };
-
-	  return cs_etree;
-	}
-
-	exports.name = 'cs_etree';
-	exports.path = 'sparse';
-	exports.factory = factory;
-
-
-/***/ },
-/* 75 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	function factory (type, config, load) {
-
-	  var cs_tdfs = load(__webpack_require__(72));
-
-	  /**
-	   * Post order a tree of forest
-	   *
-	   * @param {Array}   parent          The tree or forest
-	   * @param {Number}  n               Number of columns
-	   *
-	   * Reference: http://faculty.cse.tamu.edu/davis/publications.html
-	   */
-	  var cs_post = function (parent, n) {
-	    // check inputs
-	    if (!parent) 
-	      return null;
-	    // vars 
-	    var k = 0;
-	    var j;
-	    // allocate result
-	    var post = []; // (n);
-	    // workspace, head: first n entries, next: next n entries, stack: last n entries
-	    var w = []; // (3 * n);
-	    var head = 0; 
-	    var next = n; 
-	    var stack = 2 * n;
-	    // initialize workspace
-	    for (j = 0; j < n; j++) {
-	      // empty linked lists
-	      w[head + j] = -1;
-	    }
-	    // traverse nodes in reverse order
-	    for (j = n-1; j >= 0; j--) {
-	      // check j is a root
-	      if (parent[j] == -1) 
-	        continue;
-	      // add j to list of its parent
-	      w[next + j] = w[head + parent[j]];
-	      w[head + parent[j]] = j;
-	    }
-	    // loop nodes
-	    for (j = 0; j < n; j++) {
-	      // skip j if it is not a root
-	      if (parent[j] != -1) 
-	        continue;
-	      // depth-first search
-	      k = cs_tdfs(j, k, w, head, next, post, stack);
-	    }
-	    return post;
-	  };
-
-	  return cs_post;
-	}
-
-	exports.name = 'cs_post';
-	exports.path = 'sparse';
-	exports.factory = factory;
-
-
-/***/ },
-/* 76 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	function factory (type, config, load) {
-
-	  var transpose = load(__webpack_require__(59));
-	  
-	  var cs_leaf = load(__webpack_require__(77));
-
-	  /**
-	   * Computes the column counts using the upper triangular part of A.
-	   * It transposes A internally, none of the input parameters are modified.
-	   *
-	   * @param {Matrix} a           The sparse matrix A
-	   *
-	   * @param {Matrix} ata         Count the columns of A'A instead
-	   *
-	   * @return                     An array of size n of the column counts or null on error
-	   *
-	   * Reference: http://faculty.cse.tamu.edu/davis/publications.html
-	   */
-	  var cs_counts = function (a, parent, post, ata) {
-	    // check inputs
-	    if (!a || !parent || !post) 
-	      return null;
-	    // a matrix arrays
-	    var asize = a._size;
-	    // rows and columns
-	    var m = asize[0];
-	    var n = asize[1];   
-	    // variables
-	    var i, j, k,  J,  p, p0, p1;
-	    
-	    // workspace size
-	    var s = 4 * n + (ata ? (n + m + 1) : 0);
-	    // allocate workspace
-	    var w = []; // (s)
-	    var ancestor = 0; // first n entries
-	    var maxfirst = n; // next n entries
-	    var prevleaf = 2 * n; // next n entries
-	    var first = 3 * n; // next n entries
-	    var head = 4 * n; // next n + 1 entries (used when ata is true)
-	    var next = 5 * n + 1; // last entries in workspace
-	    // clear workspace w[0..s-1]
-	    for (k = 0; k < s; k++) 
-	      w[k] = -1;
-	    
-	    // allocate result
-	    var colcount = []; // (n);
-	    
-	    // AT = A'
-	    var at = transpose(a);
-	    // at arrays
-	    var tindex = at._index;
-	    var tptr = at._ptr;
-
-	    // find w[first + j]
-	    for (k = 0; k < n; k++) {
-	      j = post[k];
-	      // colcount[j]=1 if j is a leaf
-	      colcount[j] = (w[first + j] == -1) ? 1 : 0;
-	      for (; j != -1 && w[first + j] == -1; j = parent[j]) 
-	        w[first + j] = k;
-	    }
-
-	    // initialize ata if needed
-	    if (ata) {
-	      // invert post
-	      for (k = 0; k < n; k++) 
-	        w[post[k]] = k;
-	      // loop rows (columns in AT)
-	      for (i = 0; i < m; i++) {
-	        // values in column i of AT
-	        for (k = n, p0 = tptr[i], p1 = tptr[i + 1], p = p0; p < p1; p++) 
-	          k = Math.min(k, w[tindex[p]]);
-	        // place row i in linked list k
-	        w[next + i] = w[head + k];
-	        w[head + k] = i;
-	      }
-	    }
-	    
-	    // each node in its own set
-	    for (i = 0; i < n; i++) 
-	      w[ancestor + i] = i;
-	    
-	    for (k = 0; k < n; k++) {
-	      // j is the kth node in postordered etree
-	      j = post[k];
-	      // check j is not a root
-	      if (parent[j] != -1) 
-	        colcount[parent[j]]--;
-	      
-	      // J=j for LL'=A case
-	      for (J = (ata ? w[head + k] : j); J != -1; J = (ata ? w[next + J] : -1)) {
-	        for (p = tptr[J]; p < tptr[J+1]; p++) {
-	          i = tindex[p];
-	          var r = cs_leaf(i, j, w, first, maxfirst, prevleaf, ancestor);
-	          // check A(i,j) is in skeleton
-	          if (r.jleaf >= 1) 
-	            colcount[j]++;
-	          // check account for overlap in q
-	          if (r.jleaf == 2) 
-	            colcount[r.q]--;
-	        }
-	      }
-	      if (parent[j] != -1) 
-	        w[ancestor + j] = parent[j];
-	    }
-	    // sum up colcount's of each child
-	    for (j = 0; j < n; j++) {
-	      if (parent[j] != -1) 
-	        colcount[parent[j]] += colcount[j];
-	    }
-	    return colcount;
-	  };
-
-	  return cs_counts;
-	}
-
-	exports.name = 'cs_counts';
-	exports.path = 'sparse';
-	exports.factory = factory;
-
-
-/***/ },
-/* 77 */
-/***/ function(module, exports) {
-
-	'use strict';
-
-	function factory () {
-
-	  /**
-	   * This function determines if j is a leaf of the ith row subtree.
-	   * Consider A(i,j), node j in ith row subtree and return lca(jprev,j)
-	   *
-	   * @param {Number}  i               The ith row subtree
-	   * @param {Number}  j               The node to test
-	   * @param {Array}   w               The workspace array
-	   * @param {Number}  first           The index offset within the workspace for the first array
-	   * @param {Number}  maxfirst        The index offset within the workspace for the maxfirst array
-	   * @param {Number}  prevleaf        The index offset within the workspace for the prevleaf array
-	   * @param {Number}  ancestor        The index offset within the workspace for the ancestor array
-	   *
-	   * @return {Object}
-	   *
-	   * Reference: http://faculty.cse.tamu.edu/davis/publications.html
-	   */
-	  var cs_leaf = function (i, j, w, first, maxfirst, prevleaf, ancestor) {
-	    
-	    var s, sparent, jprev;
-	    
-	    // our result
-	    var jleaf = 0;
-	    var q;
-	    
-	    // check j is a leaf
-	    if (i <= j || w[first + j] <= w[maxfirst + i]) 
-	      return (-1);
-	    // update max first[j] seen so far
-	    w[maxfirst + i] = w[first + j];
-	    // jprev = previous leaf of ith subtree
-	    jprev = w[prevleaf + i];
-	    w[prevleaf + i] = j;
-	    
-	    // check j is first or subsequent leaf
-	    if (jprev === -1) {
-	      // 1st leaf, q = root of ith subtree
-	      jleaf = 1;
-	      q = i;
-	    }
-	    else {
-	      // update jleaf
-	      jleaf = 2;
-	      // q = least common ancester (jprev,j)
-	      for (q = jprev; q != w[ancestor + q]; q = w[ancestor + q]);
-	      for (s = jprev; s != q; s = sparent) {
-	        // path compression
-	        sparent = w[ancestor + s];
-	        w[ancestor + s] = q;
-	      }      
-	    }
-	    return {
-	      jleaf: jleaf,
-	      q: q
-	    };
-	  };
-
-	  return cs_leaf;
-	}
-
-	exports.name = 'cs_leaf';
-	exports.path = 'sparse';
-	exports.factory = factory;
-
-
-/***/ },
-/* 78 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	function factory (type, config, load) {
-
-	  var abs = load(__webpack_require__(63));
-	  var divideScalar = load(__webpack_require__(51));
-	  var multiply = load(__webpack_require__(40));
-	  
-	  var larger = load(__webpack_require__(64));
-	  var largerEq = load(__webpack_require__(79));
-	  
-	  var cs_spsolve = load(__webpack_require__(80));
-
-	  var SparseMatrix = type.SparseMatrix;
-
-	  /**
-	   * Computes the numeric LU factorization of the sparse matrix A. Implements a Left-looking LU factorization
-	   * algorithm that computes L and U one column at a tume. At the kth step, it access columns 1 to k-1 of L 
-	   * and column k of A. Given the fill-reducing column ordering q (see parameter s) computes L, U and pinv so
-	   * L * U = A(p, q), where p is the inverse of pinv.
-	   *
-	   * @param {Matrix}  m               The A Matrix to factorize
-	   * @param {Object}  s               The symbolic analysis from cs_sqr(). Provides the fill-reducing 
-	   *                                  column ordering q
-	   * @param {Number}  tol             Partial pivoting threshold (1 for partial pivoting)
-	   *
-	   * @return {Number}                 The numeric LU factorization of A or null
-	   *
-	   * Reference: http://faculty.cse.tamu.edu/davis/publications.html
-	   */
-	  var cs_lu = function (m, s, tol) {
-	    // validate input
-	    if (!m)
-	      return null;
-	    // m arrays
-	    var size = m._size;
-	    // columns
-	    var n = size[1];
-	    // symbolic analysis result
-	    var q;
-	    var lnz = 100;
-	    var unz = 100;
-	    // update symbolic analysis parameters
-	    if (s) {
-	      q = s.q;
-	      lnz = s.lnz || lnz;
-	      unz = s.unz || unz;
-	    }
-	    // L arrays
-	    var lvalues = []; // (lnz)
-	    var lindex = []; // (lnz);
-	    var lptr = []; // (n + 1);
-	    // L
-	    var L = new SparseMatrix({
-	      values: lvalues,
-	      index: lindex,
-	      ptr: lptr,
-	      size: [n, n]
-	    });
-	    // U arrays
-	    var uvalues = []; // (unz);
-	    var uindex = []; // (unz);
-	    var uptr = []; // (n + 1);
-	    // U
-	    var U = new SparseMatrix({
-	      values: uvalues,
-	      index: uindex,
-	      ptr: uptr,
-	      size: [n, n]
-	    });
-	    // inverse of permutation vector
-	    var pinv = []; // (n);
-	    // vars 
-	    var i, p;
-	    // allocate arrays
-	    var x = []; // (n);
-	    var xi = []; // (2 * n);
-	    // initialize variables
-	    for (i = 0; i < n; i++) {
-	      // clear workspace
-	      x[i] = 0;
-	      // no rows pivotal yet
-	      pinv[i] = -1;
-	      // no cols of L yet
-	      lptr[i + 1] = 0;
-	    }
-	    // reset number of nonzero elements in L and U
-	    lnz = 0;
-	    unz = 0;
-	    // compute L(:,k) and U(:,k)
-	    for (var k = 0; k < n; k++) {
-	      // update ptr
-	      lptr[k] = lnz;
-	      uptr[k] = unz;
-	      // apply column permutations if needed
-	      var col = q ? q[k] : k;
-	      // solve triangular system, x = L\A(:,col)
-	      var top = cs_spsolve(L, m, col, xi, x, pinv, 1);
-	      // find pivot
-	      var ipiv = -1;
-	      var a = -1;
-	      // loop xi[] from top -> n
-	      for (p = top; p < n; p++) {
-	        // x[i] is nonzero
-	        i = xi[p];
-	        // check row i is not yet pivotal
-	        if (pinv[i] < 0) {
-	          // absolute value of x[i]          
-	          var xabs = abs(x[i]);
-	          // check absoulte value is greater than pivot value
-	          if (larger(xabs, a)) {
-	            // largest pivot candidate so far
-	            a = xabs;
-	            ipiv = i;
-	          }
-	        }
-	        else {
-	          // x(i) is the entry U(pinv[i],k)
-	          uindex[unz] = pinv[i];
-	          uvalues[unz++] = x[i];
-	        }
-	      }
-	      // validate we found a valid pivot
-	      if (ipiv == -1 || a <= 0) 
-	        return null;
-	      // update actual pivot column, give preference to diagonal value
-	      if (pinv[col] < 0 && largerEq(abs(x[col]), multiply(a, tol)))
-	        ipiv = col;
-	      // the chosen pivot
-	      var pivot = x[ipiv];
-	      // last entry in U(:,k) is U(k,k)
-	      uindex[unz] = k;
-	      uvalues[unz++] = pivot;
-	      // ipiv is the kth pivot row
-	      pinv[ipiv] = k;
-	      // first entry in L(:,k) is L(k,k) = 1
-	      lindex[lnz] = ipiv;
-	      lvalues[lnz++] = 1;
-	      // L(k+1:n,k) = x / pivot      
-	      for (p = top; p < n; p++) {
-	        // row
-	        i = xi[p];
-	        // check x(i) is an entry in L(:,k)
-	        if (pinv[i] < 0) {
-	          // save unpermuted row in L
-	          lindex[lnz] = i;
-	          // scale pivot column
-	          lvalues[lnz++] = divideScalar(x[i], pivot);
-	        }
-	        // x[0..n-1] = 0 for next k
-	        x[i] = 0;
-	      }
-	    }
-	    // update ptr
-	    lptr[n] = lnz;
-	    uptr[n] = unz;
-	    // fix row indices of L for final pinv
-	    for (p = 0; p < lnz; p++) 
-	      lindex[p] = pinv[lindex[p]];
-	    // trim arrays
-	    lvalues.splice(lnz, lvalues.length - lnz);
-	    lindex.splice(lnz, lindex.length - lnz);
-	    uvalues.splice(unz, uvalues.length - unz);
-	    uindex.splice(unz, uindex.length - unz);    
-	    // return LU factor
-	    return {
-	      L: L,
-	      U: U,
-	      pinv: pinv
-	    };
-	  };
-
-	  return cs_lu;
-	}
-
-	exports.name = 'cs_lu';
-	exports.path = 'sparse';
-	exports.factory = factory;
-
-
-/***/ },
-/* 79 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	var nearlyEqual = __webpack_require__(8).nearlyEqual;
-
-	function factory (type, config, load, typed) {
-	  
-	  var matrix = load(__webpack_require__(23));
-
-	  var algorithm03 = load(__webpack_require__(31));
-	  var algorithm07 = load(__webpack_require__(66));
-	  var algorithm12 = load(__webpack_require__(65));
-	  var algorithm13 = load(__webpack_require__(35));
-	  var algorithm14 = load(__webpack_require__(39));
-
-	  var latex = __webpack_require__(26);
-
-	  /**
-	   * Test whether value x is larger or equal to y.
-	   *
-	   * The function returns true when x is larger than y or the relative
-	   * difference between x and y is smaller than the configured epsilon. The
-	   * function cannot be used to compare values smaller than approximately 2.22e-16.
-	   *
-	   * For matrices, the function is evaluated element wise.
-	   *
-	   * Syntax:
-	   *
-	   *    math.largerEq(x, y)
-	   *
-	   * Examples:
-	   *
-	   *    math.larger(2, 1 + 1);         // returns false
-	   *    math.largerEq(2, 1 + 1);       // returns true
-	   *
-	   * See also:
-	   *
-	   *    equal, unequal, smaller, smallerEq, larger, compare
-	   *
-	   * @param  {number | BigNumber | Fraction | boolean | Unit | string | Array | Matrix} x First value to compare
-	   * @param  {number | BigNumber | Fraction | boolean | Unit | string | Array | Matrix} y Second value to compare
-	   * @return {boolean | Array | Matrix} Returns true when the x is larger or equal to y, else returns false
-	   */
-	  var largerEq = typed('largerEq', {
-
-	    'boolean, boolean': function (x, y) {
-	      return x >= y;
-	    },
-
-	    'number, number': function (x, y) {
-	      return x >= y || nearlyEqual(x, y, config.epsilon);
-	    },
-
-	    'BigNumber, BigNumber': function (x, y) {
-	      return x.gte(y);
-	    },
-
-	    'Fraction, Fraction': function (x, y) {
-	      return x.compare(y) !== -1;
-	    },
-
-	    'Complex, Complex': function () {
-	      throw new TypeError('No ordering relation is defined for complex numbers');
-	    },
-
-	    'Unit, Unit': function (x, y) {
-	      if (!x.equalBase(y)) {
-	        throw new Error('Cannot compare units with different base');
-	      }
-	      return x.value >= y.value || nearlyEqual(x.value, y.value, config.epsilon);
-	    },
-
-	    'string, string': function (x, y) {
-	      return x >= y;
-	    },
-
-	    'Matrix, Matrix': function (x, y) {
-	      // result
-	      var c;
-
-	      // process matrix storage
-	      switch (x.storage()) {
-	        case 'sparse':
-	          switch (y.storage()) {
-	            case 'sparse':
-	              // sparse + sparse
-	              c = algorithm07(x, y, largerEq);
-	              break;
-	            default:
-	              // sparse + dense
-	              c = algorithm03(y, x, largerEq, true);
-	              break;
-	          }
-	          break;
-	        default:
-	          switch (y.storage()) {
-	            case 'sparse':
-	              // dense + sparse
-	              c = algorithm03(x, y, largerEq, false);
-	              break;
-	            default:
-	              // dense + dense
-	              c = algorithm13(x, y, largerEq);
-	              break;
-	          }
-	          break;
-	      }
-	      return c;
-	    },
-
-	    'Array, Array': function (x, y) {
-	      // use matrix implementation
-	      return largerEq(matrix(x), matrix(y)).valueOf();
-	    },
-
-	    'Array, Matrix': function (x, y) {
-	      // use matrix implementation
-	      return largerEq(matrix(x), y);
-	    },
-
-	    'Matrix, Array': function (x, y) {
-	      // use matrix implementation
-	      return largerEq(x, matrix(y));
-	    },
-
-	    'Matrix, any': function (x, y) {
-	      // result
-	      var c;
-	      // check storage format
-	      switch (x.storage()) {
-	        case 'sparse':
-	          c = algorithm12(x, y, largerEq, false);
-	          break;
-	        default:
-	          c = algorithm14(x, y, largerEq, false);
-	          break;
-	      }
-	      return c;
-	    },
-
-	    'any, Matrix': function (x, y) {
-	      // result
-	      var c;
-	      // check storage format
-	      switch (y.storage()) {
-	        case 'sparse':
-	          c = algorithm12(y, x, largerEq, true);
-	          break;
-	        default:
-	          c = algorithm14(y, x, largerEq, true);
-	          break;
-	      }
-	      return c;
-	    },
-
-	    'Array, any': function (x, y) {
-	      // use matrix implementation
-	      return algorithm14(matrix(x), y, largerEq, false).valueOf();
-	    },
-
-	    'any, Array': function (x, y) {
-	      // use matrix implementation
-	      return algorithm14(matrix(y), x, largerEq, true).valueOf();
-	    }
-	  });
-
-	  largerEq.toTex = '\\left(${args[0]}' + latex.operators['largerEq'] + '${args[1]}\\right)';
-
-	  return largerEq;
-	}
-
-	exports.name = 'largerEq';
-	exports.factory = factory;
-
-
-/***/ },
-/* 80 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	function factory (type, config, load) {
-
-	  var divideScalar = load(__webpack_require__(51));
-	  var multiply = load(__webpack_require__(40));
-	  var subtract = load(__webpack_require__(25));
-
-	  var cs_reach = load(__webpack_require__(81));
-
-	  /**
-	   * The function cs_spsolve() computes the solution to G * x = bk, where bk is the
-	   * kth column of B. When lo is true, the function assumes G = L is lower triangular with the
-	   * diagonal entry as the first entry in each column. When lo is true, the function assumes G = U 
-	   * is upper triangular with the diagonal entry as the last entry in each column.
-	   *
-	   * @param {Matrix}  g               The G matrix
-	   * @param {Matrix}  b               The B matrix
-	   * @param {Number}  k               The kth column in B
-	   * @param {Array}   xi              The nonzero pattern xi[top] .. xi[n - 1], an array of size = 2 * n
-	   *                                  The first n entries is the nonzero pattern, the last n entries is the stack
-	   * @param {Array}   x               The soluton to the linear system G * x = b
-	   * @param {Array}   pinv            The inverse row permutation vector, must be null for L * x = b
-	   * @param {boolean} lo              The lower (true) upper triangular (false) flag
-	   *
-	   * @return {Number}                 The index for the nonzero pattern
-	   *
-	   * Reference: http://faculty.cse.tamu.edu/davis/publications.html
-	   */
-	  var cs_spsolve = function (g, b, k, xi, x, pinv, lo) {
-	    // g arrays
-	    var gvalues = g._values;
-	    var gindex = g._index;
-	    var gptr = g._ptr;
-	    var gsize = g._size;
-	    // columns
-	    var n = gsize[1];
-	    // b arrays
-	    var bvalues = b._values;
-	    var bindex = b._index;
-	    var bptr = b._ptr;
-	    // vars
-	    var p, p0, p1, q;
-	    // xi[top..n-1] = cs_reach(B(:,k))
-	    var top = cs_reach(g, b, k, xi, pinv);
-	    // clear x
-	    for (p = top; p < n; p++) 
-	      x[xi[p]] = 0;
-	    // scatter b
-	    for (p0 = bptr[k], p1 = bptr[k + 1], p = p0; p < p1; p++) 
-	      x[bindex[p]] = bvalues[p];
-	    // loop columns
-	    for (var px = top; px < n; px++) {
-	      // x array index for px
-	      var j = xi[px];
-	      // apply permutation vector (U x = b), j maps to column J of G
-	      var J = pinv ? pinv[j] : j;
-	      // check column J is empty
-	      if (J < 0)
-	        continue;
-	      // column value indeces in G, p0 <= p < p1
-	      p0 = gptr[J];
-	      p1 = gptr[J + 1];
-	      // x(j) /= G(j,j)
-	      x[j] = divideScalar(x[j], gvalues[lo ? p0 : (p1 - 1)]);
-	      // first entry L(j,j)
-	      p = lo ? (p0 + 1) : p0;
-	      q = lo ? (p1) : (p1 - 1);
-	      // loop
-	      for ( ; p < q ; p++) {
-	        // row
-	        var i = gindex[p];
-	        // x(i) -= G(i,j) * x(j)
-	        x[i] = subtract(x[i], multiply(gvalues[p], x[j]));
-	      }
-	    }
-	    // return top of stack
-	    return top;
-	  };
-	  
-	  return cs_spsolve;
-	}
-
-	exports.name = 'cs_spsolve';
-	exports.path = 'sparse';
-	exports.factory = factory;
-
-
-/***/ },
-/* 81 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	function factory (type, config, load) {
-
-	  var cs_dfs = load(__webpack_require__(82));
-	  var cs_marked = load(__webpack_require__(83));
-	  var cs_mark = load(__webpack_require__(84));
-
-	  /**
-	   * The cs_reach function computes X = Reach(B), where B is the nonzero pattern of the n-by-1 
-	   * sparse column of vector b. The function returns the set of nodes reachable from any node in B. The
-	   * nonzero pattern xi of the solution x to the sparse linear system Lx=b is given by X=Reach(B).
-	   *
-	   * @param {Matrix}  g               The G matrix
-	   * @param {Matrix}  b               The B matrix
-	   * @param {Number}  k               The kth column in B
-	   * @param {Array}   xi              The nonzero pattern xi[top] .. xi[n - 1], an array of size = 2 * n
-	   *                                  The first n entries is the nonzero pattern, the last n entries is the stack
-	   * @param {Array}   pinv            The inverse row permutation vector
-	   *
-	   * @return {Number}                 The index for the nonzero pattern
-	   *
-	   * Reference: http://faculty.cse.tamu.edu/davis/publications.html
-	   */
-	  var cs_reach = function (g, b, k, xi, pinv) {
-	    // g arrays
-	    var gptr = g._ptr;
-	    var gsize = g._size;
-	    // b arrays
-	    var bindex = b._index;
-	    var bptr = b._ptr;
-	    // columns
-	    var n = gsize[1];
-	    // vars
-	    var p, p0, p1;
-	    // initialize top
-	    var top = n;
-	    // loop column indeces in B
-	    for (p0 = bptr[k], p1 = bptr[k + 1], p = p0; p < p1; p++) {
-	      // node i
-	      var i = bindex[p];
-	      // check node i is marked
-	      if (!cs_marked(gptr, i)) {
-	        // start a dfs at unmarked node i
-	        top = cs_dfs(i, g, top, xi, pinv);
-	      }
-	    }
-	    // loop columns from top -> n - 1
-	    for (p = top; p < n; p++) {
-	      // restore G
-	      cs_mark(gptr, xi[p]);
-	    }
-	    return top;
-	  };
-
-	  return cs_reach;
-	}
-
-	exports.name = 'cs_reach';
-	exports.path = 'sparse';
-	exports.factory = factory;
-
-
-/***/ },
-/* 82 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	function factory (type, config, load) {
-
-	  var cs_marked = load(__webpack_require__(83));
-	  var cs_mark   = load(__webpack_require__(84));
-	  var cs_unflip = load(__webpack_require__(85));
-
-	  /**
-	   * Depth-first search computes the nonzero pattern xi of the directed graph G (Matrix) starting
-	   * at nodes in B (see cs_reach()).
-	   *
-	   * @param {Number}  j               The starting node for the DFS algorithm
-	   * @param {Matrix}  g               The G matrix to search, ptr array modified, then restored
-	   * @param {Number}  top             Start index in stack xi[top..n-1]
-	   * @param {Number}  k               The kth column in B
-	   * @param {Array}   xi              The nonzero pattern xi[top] .. xi[n - 1], an array of size = 2 * n
-	   *                                  The first n entries is the nonzero pattern, the last n entries is the stack
-	   * @param {Array}   pinv            The inverse row permutation vector, must be null for L * x = b
-	   *
-	   * @return {Number}                 New value of top
-	   *
-	   * Reference: http://faculty.cse.tamu.edu/davis/publications.html
-	   */
-	  var cs_dfs = function (j, g, top, xi, pinv) {
-	    // g arrays
-	    var index = g._index;
-	    var ptr = g._ptr;
-	    var size = g._size;
-	    // columns
-	    var n = size[1];
-	    // vars
-	    var i, p, p2;
-	    // initialize head
-	    var head = 0;
-	    // initialize the recursion stack
-	    xi[0] = j;
-	    // loop
-	    while (head >= 0) {
-	      // get j from the top of the recursion stack
-	      j = xi[head];
-	      // apply permutation vector
-	      var jnew = pinv ? pinv[j] : j;
-	      // check node j is marked
-	      if (!cs_marked(ptr, j)) {
-	        // mark node j as visited
-	        cs_mark(ptr, j);
-	        // update stack (last n entries in xi)
-	        xi[n + head] = jnew < 0 ? 0 : cs_unflip(ptr[jnew]);
-	      }
-	      // node j done if no unvisited neighbors
-	      var done = 1;
-	      // examine all neighbors of j, stack (last n entries in xi)
-	      for (p = xi[n + head], p2 = jnew < 0 ? 0 : cs_unflip(ptr[jnew+1]); p < p2; p++) {
-	        // consider neighbor node i
-	        i = index[p];
-	        // check we have visited node i, skip it
-	        if (cs_marked(ptr, i)) 
-	          continue;
-	        // pause depth-first search of node j, update stack (last n entries in xi)
-	        xi[n + head] = p;
-	        // start dfs at node i
-	        xi[++head] = i;
-	        // node j is not done
-	        done = 0;
-	        // break, to start dfs(i)
-	        break;
-	      }
-	      // check depth-first search at node j is done
-	      if (done) {
-	        // remove j from the recursion stack
-	        head--;
-	        // and place in the output stack
-	        xi[--top] = j;
-	      }
-	    }
-	    return top;    
-	  };
-
-	  return cs_dfs;
-	}
-
-	exports.name = 'cs_dfs';
-	exports.path = 'sparse';
-	exports.factory = factory;
-
-
-/***/ },
-/* 83 */
-/***/ function(module, exports) {
-
-	'use strict';
-
-	function factory () {
-
-	  /**
-	   * Checks if the node at w[j] is marked
-	   *
-	   * @param {Array}   w               The array
-	   * @param {Number}  j               The array index
-	   *
-	   * Reference: http://faculty.cse.tamu.edu/davis/publications.html
-	   */
-	  var cs_marked = function (w, j) {
-	    // check node is marked
-	    return w[j] < 0;
-	  };
-
-	  return cs_marked;
-	}
-
-	exports.name = 'cs_marked';
-	exports.path = 'sparse';
-	exports.factory = factory;
-
-
-/***/ },
-/* 84 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	function factory (type, config, load) {
-
-	  var cs_flip = load(__webpack_require__(70));
-
-	  /**
-	   * Marks the node at w[j]
-	   *
-	   * @param {Array}   w               The array
-	   * @param {Number}  j               The array index
-	   *
-	   * Reference: http://faculty.cse.tamu.edu/davis/publications.html
-	   */
-	  var cs_mark = function (w, j) {
-	    // mark w[j]
-	    w[j] = cs_flip(w [j]);
-	  };
-
-	  return cs_mark;
-	}
-
-	exports.name = 'cs_mark';
-	exports.path = 'sparse';
-	exports.factory = factory;
-
-
-/***/ },
-/* 85 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	function factory (type, config, load) {
-
-	  var cs_flip = load(__webpack_require__(70));
-	  
-	  /**
-	   * Flips the value if it is negative of returns the same value otherwise.
-	   *
-	   * @param {Number}  i               The value to flip
-	   *
-	   * Reference: http://faculty.cse.tamu.edu/davis/publications.html
-	   */
-	  var cs_unflip = function (i) {
-	    // flip the value if it is negative
-	    return i < 0 ? cs_flip(i) : i;
-	  };
-
-	  return cs_unflip;
-	}
-
-	exports.name = 'cs_unflip';
-	exports.path = 'sparse';
-	exports.factory = factory;
-
-
-/***/ },
-/* 86 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	function factory (type, config, load, typed) {
-
-	  var matrix = load(__webpack_require__(23));
-	  var divideScalar = load(__webpack_require__(51));
-	  var multiplyScalar = load(__webpack_require__(41));
-	  var subtract = load(__webpack_require__(25));
-	  var equalScalar = load(__webpack_require__(33));
-
-	  var solveValidation = load(__webpack_require__(87));
-
-	  var DenseMatrix = type.DenseMatrix;
-
-	  /** 
-	   * Solves the linear equation system by forwards substitution. Matrix must be a lower triangular matrix.
-	   *
-	   * `L * x = b`
-	   *
-	   * Syntax:
-	   *
-	   *    math.lsolve(L, b);
-	   *
-	   * Examples:
-	   *
-	   *    var a = [[-2, 3], [2, 1]];
-	   *    var b = [11, 9];
-	   *    var x = lsolve(a, b);  // [[-5.5], [20]]
-	   *
-	   * See also:
-	   *
-	   *    lup, slu, usolve, lusolve
-	   *
-	   * @param {Matrix, Array} L       A N x N matrix or array (L)
-	   * @param {Matrix, Array} b       A column vector with the b values
-	   *
-	   * @return {DenseMatrix | Array}  A column vector with the linear system solution (x)
-	   */
-	  var lsolve = typed('lsolve', {
-
-	    'SparseMatrix, Array | Matrix': function (m, b) {
-	      // process matrix
-	      return _sparseForwardSubstitution(m, b);
-	    },
-	    
-	    'DenseMatrix, Array | Matrix': function (m, b) {
-	      // process matrix
-	      return _denseForwardSubstitution(m, b);
-	    },
-	    
-	    'Array, Array | Matrix': function (a, b) {
-	      // create dense matrix from array
-	      var m = matrix(a);
-	      // use matrix implementation
-	      var r = _denseForwardSubstitution(m, b);
-	      // result
-	      return r.valueOf();
-	    }
-	  });
-
-	  var _denseForwardSubstitution = function (m, b) {
-	    // validate matrix and vector, return copy of column vector b
-	    b = solveValidation(m, b, true);
-	    // column vector data
-	    var bdata = b._data;
-	    // rows & columns
-	    var rows = m._size[0];
-	    var columns = m._size[1];
-	    // result
-	    var x = [];
-	    // data
-	    var data = m._data;
-	    // forward solve m * x = b, loop columns
-	    for (var j = 0; j < columns; j++) {
-	      // b[j]
-	      var bj = bdata[j][0] || 0;
-	      // x[j]
-	      var xj;
-	      // forward substitution (outer product) avoids inner looping when bj == 0
-	      if (!equalScalar(bj, 0)) {
-	        // value @ [j, j]
-	        var vjj = data[j][j];
-	        // check vjj
-	        if (equalScalar(vjj, 0)) {
-	          // system cannot be solved
-	          throw new Error('Linear system cannot be solved since matrix is singular');
-	        }
-	        // calculate xj
-	        xj = divideScalar(bj, vjj);
-	        // loop rows
-	        for (var i = j + 1; i < rows; i++) {
-	          // update copy of b
-	          bdata[i] = [subtract(bdata[i][0] || 0, multiplyScalar(xj, data[i][j]))];
-	        }
-	      }
-	      else {
-	        // zero @ j
-	        xj = 0;
-	      }
-	      // update x
-	      x[j] = [xj];
-	    }
-	    // return vector
-	    return new DenseMatrix({
-	      data: x,
-	      size: [rows, 1]
-	    });
-	  };
-
-	  var _sparseForwardSubstitution = function (m, b) {
-	    // validate matrix and vector, return copy of column vector b
-	    b = solveValidation(m, b, true);
-	    // column vector data
-	    var bdata = b._data;
-	    // rows & columns
-	    var rows = m._size[0];
-	    var columns = m._size[1];
-	    // matrix arrays
-	    var values = m._values;
-	    var index = m._index;
-	    var ptr = m._ptr;
-	    // vars
-	    var i, k;
-	    // result
-	    var x = [];
-	    // forward solve m * x = b, loop columns
-	    for (var j = 0; j < columns; j++) {
-	      // b[j]
-	      var bj = bdata[j][0] || 0;
-	      // forward substitution (outer product) avoids inner looping when bj == 0
-	      if (!equalScalar(bj, 0)) {
-	        // value @ [j, j]
-	        var vjj = 0;
-	        // last index in column
-	        var l = ptr[j + 1];
-	        // values in column, find value @ [j, j]
-	        for (k = ptr[j]; k < l; k++) {
-	          // row
-	          i = index[k];
-	          // check row (do not exist when i > j, rows are not sorted!)
-	          if (i === j) {
-	            // update vjj
-	            vjj = values[k];
-	            // exit loop
-	            break;
-	          }
-	        }
-	        // at this point we must have a value @ [j, j]
-	        if (equalScalar(vjj, 0)) {
-	          // system cannot be solved, there is no value @ [j, j]
-	          throw new Error('Linear system cannot be solved since matrix is singular');
-	        }
-	        // calculate xj
-	        var xj = divideScalar(bj, vjj);
-	        // values in column, continue from last loop
-	        for (; k < l; k++) {
-	          // row
-	          i = index[k];
-	          // update copy of b
-	          bdata[i] = [subtract(bdata[i][0] || 0, multiplyScalar(xj, values[k]))];
-	        }
-	        // update x
-	        x[j] = [xj];
-	      }
-	      else {
-	        // update x
-	        x[j] = [0];
-	      }
-	    }
-	    // return vector
-	    return new DenseMatrix({
-	      data: x,
-	      size: [rows, 1]
-	    });
-	  };
-
-	  return lsolve;
-	}
-
-	exports.name = 'lsolve';
-	exports.factory = factory;
-
-
-/***/ },
-/* 87 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	var util = __webpack_require__(36);
-
-	var string = util.string;
-	var array = util.array;
-
-	var isArray = Array.isArray;
-
-	function factory (type) {
-	  
-	  var DenseMatrix = type.DenseMatrix;
-
-	  /**
-	   * Validates matrix and column vector b for backward/forward substitution algorithms.
-	   *
-	   * @param {Matrix} m            An N x N matrix
-	   * @param {Array | Matrix} b    A column vector
-	   * @param {Boolean} copy        Return a copy of vector b
-	   *
-	   * @return {DenseMatrix}        Dense column vector b
-	   */
-	  var solveValidation = function (m, b, copy) {
-	    // matrix size
-	    var size = m.size();
-	    // validate matrix dimensions
-	    if (size.length !== 2)
-	      throw new RangeError('Matrix must be two dimensional (size: ' + string.format(size) + ')');
-	    // rows & columns
-	    var rows = size[0];
-	    var columns = size[1];    
-	    // validate rows & columns
-	    if (rows !== columns) 
-	      throw new RangeError('Matrix must be square (size: ' + string.format(size) + ')');
-	    // vars
-	    var data, i, bdata;
-	    // check b is matrix
-	    if (b && b.isMatrix === true) {
-	      // matrix size
-	      var msize = b.size();
-	      // vector
-	      if (msize.length === 1) {
-	        // check vector length
-	        if (msize[0] !== rows)
-	          throw new RangeError('Dimension mismatch. Matrix columns must match vector length.');
-	        // create data array
-	        data = [];
-	        // matrix data (DenseMatrix)
-	        bdata = b._data;
-	        // loop b data
-	        for (i = 0; i < rows; i++) {
-	          // row array
-	          data[i] = [bdata[i]];
-	        }
-	        // return Dense Matrix
-	        return new DenseMatrix({
-	          data: data,
-	          size: [rows, 1],
-	          datatype: b._datatype
-	        });
-	      }
-	      // two dimensions
-	      if (msize.length === 2) {
-	        // array must be a column vector
-	        if (msize[0] !== rows || msize[1] !== 1)
-	          throw new RangeError('Dimension mismatch. Matrix columns must match vector length.');
-	        // check matrix type
-	        if (b.isDenseMatrix === true) {
-	          // check a copy is needed
-	          if (copy) {
-	            // create data array
-	            data = [];
-	            // matrix data (DenseMatrix)
-	            bdata = b._data;
-	            // loop b data
-	            for (i = 0; i < rows; i++) {
-	              // row array
-	              data[i] = [bdata[i][0]];
-	            }
-	            // return Dense Matrix
-	            return new DenseMatrix({
-	              data: data,
-	              size: [rows, 1],
-	              datatype: b._datatype
-	            });
-	          }
-	          // b is already a column vector
-	          return b;
-	        }
-	        // create data array
-	        data = [];
-	        for (i = 0; i < rows; i++)
-	          data[i] = [0];
-	        // sparse matrix arrays
-	        var values = b._values;
-	        var index = b._index;
-	        var ptr = b._ptr;
-	        // loop values in column 0
-	        for (var k1 = ptr[1], k = ptr[0]; k < k1; k++) {
-	          // row
-	          i = index[k];
-	          // add to data
-	          data[i][0] = values[k]; 
-	        }
-	        // return Dense Matrix
-	        return new DenseMatrix({
-	          data: data,
-	          size: [rows, 1],
-	          datatype: b._datatype
-	        });
-	      }
-	      // throw error
-	      throw new RangeError('Dimension mismatch. Matrix columns must match vector length.');
-	    }
-	    // check b is array
-	    if (isArray(b)) {
-	      // size
-	      var asize = array.size(b);
-	      // check matrix dimensions, vector
-	      if (asize.length === 1) {
-	        // check vector length
-	        if (asize[0] !== rows)
-	          throw new RangeError('Dimension mismatch. Matrix columns must match vector length.');        
-	        // create data array
-	        data = [];
-	        // loop b
-	        for (i = 0; i < rows; i++) {
-	          // row array
-	          data[i] = [b[i]];
-	        }
-	        // return Dense Matrix
-	        return new DenseMatrix({
-	          data: data,
-	          size: [rows, 1]
-	        });
-	      }
-	      if (asize.length === 2) {
-	        // array must be a column vector
-	        if (asize[0] !== rows || asize[1] !== 1)
-	          throw new RangeError('Dimension mismatch. Matrix columns must match vector length.');
-	        // create data array
-	        data = [];
-	        // loop b data
-	        for (i = 0; i < rows; i++) {
-	          // row array
-	          data[i] = [b[i][0]];
-	        }
-	        // return Dense Matrix
-	        return new DenseMatrix({
-	          data: data,
-	          size: [rows, 1]
-	        });
-	      }
-	      // throw error
-	      throw new RangeError('Dimension mismatch. Matrix columns must match vector length.');      
-	    }
-	  };
-	  
-	  return solveValidation;
-	}
-
-	exports.factory = factory;
-
-/***/ },
-/* 88 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	var isArray = Array.isArray;
-
-	function factory (type, config, load, typed) {
-	  
-	  var matrix = load(__webpack_require__(23));
-	  var lup = load(__webpack_require__(62));
-	  var slu = load(__webpack_require__(67));
-	  var cs_ipvec = load(__webpack_require__(89));
-
-	  var solveValidation = load(__webpack_require__(87));
-
-	  var usolve = load(__webpack_require__(90));
-	  var lsolve = load(__webpack_require__(86));
-
-	  /**
-	   * Solves the linear system `A * x = b` where `A` is an [n x n] matrix and `b` is a [n] column vector.
-	   *
-	   * Syntax:
-	   *
-	   *    math.lusolve(A, b)     // returns column vector with the solution to the linear system A * x = b
-	   *    math.lusolve(lup, b)   // returns column vector with the solution to the linear system A * x = b, lup = math.lup(A)
-	   *
-	   * Examples:
-	   *
-	   *    var m = [[1, 0, 0, 0], [0, 2, 0, 0], [0, 0, 3, 0], [0, 0, 0, 4]];
-	   *
-	   *    var x = math.lusolve(m, [-1, -1, -1, -1]);        // x = [[-1], [-0.5], [-1/3], [-0.25]]
-	   *
-	   *    var f = math.lup(m);
-	   *    var x1 = math.lusolve(f, [-1, -1, -1, -1]);       // x1 = [[-1], [-0.5], [-1/3], [-0.25]]
-	   *    var x2 = math.lusolve(f, [1, 2, 1, -1]);          // x2 = [[1], [1], [1/3], [-0.25]]
-	   *
-	   *    var a = [[-2, 3], [2, 1]];
-	   *    var b = [11, 9];
-	   *    var x = lusolve(a, b);  // [[-5.5], [20]]
-	   *
-	   * See also:
-	   *
-	   *    lup, slu, lsolve, usolve
-	   *
-	   * @param {Matrix | Array | Object} A      Invertible Matrix or the Matrix LU decomposition
-	   * @param {Matrix | Array} b               Column Vector
-	   * @param {number} [order]                 The Symbolic Ordering and Analysis order, see slu for details. Matrix must be a SparseMatrix
-	   * @param {Number} [threshold]             Partial pivoting threshold (1 for partial pivoting), see slu for details. Matrix must be a SparseMatrix.
-	   *
-	   * @return {DenseMatrix | Array}           Column vector with the solution to the linear system A * x = b
-	   */
-	  var lusolve = typed('lusolve', {
-	    
-	    'Array, Array | Matrix': function (a, b) {
-	      // convert a to matrix
-	      a = matrix(a);
-	      // matrix lup decomposition
-	      var d = lup(a);
-	      // solve
-	      var x = _lusolve(d.L, d.U, d.p, null, b);
-	      // convert result to array
-	      return x.valueOf();
-	    },
-	    
-	    'DenseMatrix, Array | Matrix': function (a, b) {
-	      // matrix lup decomposition
-	      var d = lup(a);
-	      // solve
-	      return _lusolve(d.L, d.U, d.p, null, b);
-	    },
-	    
-	    'SparseMatrix, Array | Matrix': function (a, b) {
-	      // matrix lup decomposition
-	      var d = lup(a);
-	      // solve
-	      return _lusolve(d.L, d.U, d.p, null, b);
-	    },
-	    
-	    'SparseMatrix, Array | Matrix, number, number': function (a, b, order, threshold) {
-	      // matrix lu decomposition
-	      var d = slu(a, order, threshold);
-	      // solve
-	      return _lusolve(d.L, d.U, d.p, d.q, b);
-	    },
-
-	    'Object, Array | Matrix': function (d, b) {
-	      // solve
-	      return _lusolve(d.L, d.U, d.p, d.q, b);
-	    }
-	  });
-	  
-	  var _toMatrix = function (a) {
-	    // check it is a matrix
-	    if (a && a.isMatrix === true)
-	      return a;
-	    // check array
-	    if (isArray(a))
-	      return matrix(a);
-	    // throw
-	    throw new TypeError('Invalid Matrix LU decomposition');
-	  };
-	  
-	  var _lusolve = function (l, u, p, q, b) {
-	    // verify L, U, P
-	    l = _toMatrix(l);
-	    u = _toMatrix(u);
-	    // validate matrix and vector
-	    b = solveValidation(l, b, false);
-	    // apply row permutations if needed (b is a DenseMatrix)
-	    if (p)
-	      b._data = cs_ipvec(p, b._data);
-	    // use forward substitution to resolve L * y = b
-	    var y = lsolve(l, b);
-	    // use backward substitution to resolve U * x = y
-	    var x = usolve(u, y);
-	    // apply column permutations if needed (x is a DenseMatrix)
-	    if (q)
-	      x._data = cs_ipvec(q, x._data);
-	    // return solution
-	    return x;
-	  };
-
-	  return lusolve;
-	}
-
-	exports.name = 'lusolve';
-	exports.factory = factory;
-
-
-/***/ },
-/* 89 */
-/***/ function(module, exports) {
-
-	'use strict';
-
-	function factory () {
-
-	  /**
-	   * Permutes a vector; x = P'b. In MATLAB notation, x(p)=b.
-	   *
-	   * @param {Array} p           The permutation vector of length n. null value denotes identity
-	   * @param {Array} b           The input vector
-	   *
-	   * @return {Array}            The output vector x = P'b
-	   */
-	  var cs_ipvec = function (p, b, n) {
-	    // vars 
-	    var k;
-	    var n = b.length;
-	    var x = [];
-	    // check permutation vector was provided, p = null denotes identity
-	    if (p) {
-	      // loop vector
-	      for (k = 0; k < n; k++) {
-	        // apply permutation
-	        x[p[k]] = b[k];
-	      }
-	    }
-	    else {
-	      // loop vector
-	      for (k = 0; k < n; k++) {
-	        // x[i] = b[i]
-	        x[k] = b[k];
-	      }
-	    }
-	    return x;
-	  };
-
-	  return cs_ipvec;
-	}
-
-	exports.name = 'cs_ipvec';
-	exports.path = 'sparse';
-	exports.factory = factory;
-
-
-/***/ },
-/* 90 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	function factory (type, config, load, typed) {
-
-	  var matrix = load(__webpack_require__(23));
-	  var divideScalar = load(__webpack_require__(51));
-	  var multiplyScalar = load(__webpack_require__(41));
-	  var subtract = load(__webpack_require__(25));
-	  var equalScalar = load(__webpack_require__(33));
-
-	  var solveValidation = load(__webpack_require__(87));
-	  
-	  var DenseMatrix = type.DenseMatrix;
-
-	  /**
-	   * Solves the linear equation system by backward substitution. Matrix must be an upper triangular matrix.
-	   *
-	   * `U * x = b`
-	   *
-	   * Syntax:
-	   *
-	   *    math.usolve(U, b);
-	   *
-	   * Examples:
-	   *
-	   *    var a = [[-2, 3], [2, 1]];
-	   *    var b = [11, 9];
-	   *    var x = usolve(a, b);  // [[8], [9]]
-	   *
-	   * See also:
-	   *
-	   *    lup, slu, usolve, lusolve
-	   *
-	   * @param {Matrix, Array} U       A N x N matrix or array (U)
-	   * @param {Matrix, Array} b       A column vector with the b values
-	   *
-	   * @return {DenseMatrix | Array}  A column vector with the linear system solution (x)
-	   */
-	  var usolve = typed('usolve', {
-	    
-	    'SparseMatrix, Array | Matrix': function (m, b) {
-	      // process matrix
-	      return _sparseBackwardSubstitution(m, b);
-	    },
-
-	    'DenseMatrix, Array | Matrix': function (m, b) {
-	      // process matrix
-	      return _denseBackwardSubstitution(m, b);
-	    },
-
-	    'Array, Array | Matrix': function (a, b) {
-	      // create dense matrix from array
-	      var m = matrix(a);
-	      // use matrix implementation
-	      var r = _denseBackwardSubstitution(m, b);
-	      // result
-	      return r.valueOf();
-	    }
-	  });
-
-	  var _denseBackwardSubstitution = function (m, b) {
-	    // validate matrix and vector, return copy of column vector b
-	    b = solveValidation(m, b, true);
-	    // column vector data
-	    var bdata = b._data;
-	    // rows & columns
-	    var rows = m._size[0];
-	    var columns = m._size[1];
-	    // result
-	    var x = [];
-	    // arrays
-	    var data = m._data;
-	    // backward solve m * x = b, loop columns (backwards)
-	    for (var j = columns - 1; j >= 0 ; j--) {
-	      // b[j]
-	      var bj = bdata[j][0] || 0;
-	      // x[j]
-	      var xj;
-	      // backward substitution (outer product) avoids inner looping when bj == 0
-	      if (!equalScalar(bj, 0)) {
-	        // value @ [j, j]
-	        var vjj = data[j][j];
-	        // check vjj
-	        if (equalScalar(vjj, 0)) {
-	          // system cannot be solved
-	          throw new Error('Linear system cannot be solved since matrix is singular');
-	        }
-	        // calculate xj
-	        xj = divideScalar(bj, vjj);        
-	        // loop rows
-	        for (var i = j - 1; i >= 0; i--) {
-	          // update copy of b
-	          bdata[i] = [subtract(bdata[i][0] || 0, multiplyScalar(xj, data[i][j]))];
-	        }
-	      }
-	      else {
-	        // zero value @ j
-	        xj = 0;
-	      }
-	      // update x
-	      x[j] = [xj];
-	    }
-	    // return column vector
-	    return new DenseMatrix({
-	      data: x,
-	      size: [rows, 1]
-	    });
-	  };
-	  
-	  var _sparseBackwardSubstitution = function (m, b) {
-	    // validate matrix and vector, return copy of column vector b
-	    b = solveValidation(m, b, true);
-	    // column vector data
-	    var bdata = b._data;
-	    // rows & columns
-	    var rows = m._size[0];
-	    var columns = m._size[1];
-	    // matrix arrays
-	    var values = m._values;
-	    var index = m._index;
-	    var ptr = m._ptr;
-	    // vars
-	    var i, k;
-	    // result
-	    var x = [];
-	    // backward solve m * x = b, loop columns (backwards)
-	    for (var j = columns - 1; j >= 0 ; j--) {
-	      // b[j]
-	      var bj = bdata[j][0] || 0;
-	      // backward substitution (outer product) avoids inner looping when bj == 0
-	      if (!equalScalar(bj, 0)) {
-	        // value @ [j, j]
-	        var vjj = 0;
-	        // first & last indeces in column
-	        var f = ptr[j];
-	        var l = ptr[j + 1];
-	        // values in column, find value @ [j, j], loop backwards
-	        for (k = l - 1; k >= f; k--) {
-	          // row
-	          i = index[k];
-	          // check row
-	          if (i === j) {
-	            // update vjj
-	            vjj = values[k];
-	          }
-	          else if (i < j) {
-	            // exit loop
-	            break;
-	          }
-	        }
-	        // at this point we must have a value @ [j, j]
-	        if (equalScalar(vjj, 0)) {
-	          // system cannot be solved, there is no value @ [j, j]
-	          throw new Error('Linear system cannot be solved since matrix is singular');
-	        }
-	        // calculate xj
-	        var xj = divideScalar(bj, vjj);
-	        // values in column, continue from last loop
-	        for (; k >= f; k--) {
-	          // row
-	          i = index[k];
-	          // update copy of b
-	          bdata[i] = [subtract(bdata[i][0], multiplyScalar(xj, values[k]))];
-	        }
-	        // update x
-	        x[j] = [xj];
-	      }
-	      else {
-	        // update x
-	        x[j] = [0];
-	      }
-	    }
-	    // return vector
-	    return new DenseMatrix({
-	      data: x,
-	      size: [rows, 1]
-	    });
-	  };
-	  
-	  return usolve;
-	}
-
-	exports.name = 'usolve';
-	exports.factory = factory;
-
-
-/***/ },
-/* 91 */
-/***/ function(module, exports, __webpack_require__) {
-
-	module.exports = [
-	  __webpack_require__(63),
-	  __webpack_require__(44),
-	  __webpack_require__(27),
-	  __webpack_require__(92),
-	  __webpack_require__(93),
-	  __webpack_require__(94),
-	  __webpack_require__(95),
-	  __webpack_require__(97),
-	  __webpack_require__(99),
-	  __webpack_require__(101),
-	  __webpack_require__(103),
-	  __webpack_require__(104),
-	  __webpack_require__(105),
-	  __webpack_require__(106),
-	  __webpack_require__(102),
-	  __webpack_require__(109),
-	  __webpack_require__(110),
-	  __webpack_require__(40),
-	  __webpack_require__(111),
-	  __webpack_require__(114),
-	  __webpack_require__(100),
-	  __webpack_require__(115),
-	  __webpack_require__(116),
-	  __webpack_require__(112),
-	  __webpack_require__(117),
-	  __webpack_require__(25),
-	  __webpack_require__(28),
-	  __webpack_require__(118),
-	  __webpack_require__(119)
-	];
-
-
-/***/ },
-/* 92 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	var deepMap = __webpack_require__(29);
-
-	function factory (type, config, load, typed) {
-	  /**
-	   * Round a value towards plus infinity
-	   * If `x` is complex, both real and imaginary part are rounded towards plus infinity.
-	   * For matrices, the function is evaluated element wise.
-	   *
-	   * Syntax:
-	   *
-	   *    math.ceil(x)
-	   *
-	   * Examples:
-	   *
-	   *    math.ceil(3.2);               // returns number 4
-	   *    math.ceil(3.8);               // returns number 4
-	   *    math.ceil(-4.2);              // returns number -4
-	   *    math.ceil(-4.7);              // returns number -4
-	   *
-	   *    var c = math.complex(3.2, -2.7);
-	   *    math.ceil(c);                 // returns Complex 4 - 2i
-	   *
-	   *    math.ceil([3.2, 3.8, -4.7]);  // returns Array [4, 4, -4]
-	   *
-	   * See also:
-	   *
-	   *    floor, fix, round
-	   *
-	   * @param  {number | BigNumber | Fraction | Complex | Array | Matrix} x  Number to be rounded
-	   * @return {number | BigNumber | Fraction | Complex | Array | Matrix} Rounded value
-	   */
-	  var ceil = typed('ceil', {
-	    'number': Math.ceil,
-
-	    'Complex': function (x) {
-	      return new type.Complex(
-	          Math.ceil(x.re),
-	          Math.ceil(x.im)
-	      );
-	    },
-
-	    'BigNumber': function (x) {
-	      return x.ceil();
-	    },
-
-	    'Fraction': function (x) {
-	      return x.ceil();
-	    },
-
-	    'Array | Matrix': function (x) {
-	      // deep map collection, skip zeros since ceil(0) = 0
-	      return deepMap(x, ceil, true);
-	    }
-	  });
-
-	  ceil.toTex = '\\left\\lceil${args[0]}\\right\\rceil';
-
-	  return ceil;
-	}
-
-	exports.name = 'ceil';
-	exports.factory = factory;
-
-
-/***/ },
-/* 93 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	var deepMap = __webpack_require__(29);
-
-	function factory (type, config, load, typed) {
-	  var complexMultiply = typed.find(load(__webpack_require__(41)), ['Complex,Complex']);
-
-	  /**
-	   * Compute the cube of a value, `x * x * x`.
-	   * For matrices, the function is evaluated element wise.
-	   *
-	   * Syntax:
-	   *
-	   *    math.cube(x)
-	   *
-	   * Examples:
-	   *
-	   *    math.cube(2);            // returns number 8
-	   *    math.pow(2, 3);          // returns number 8
-	   *    math.cube(4);            // returns number 64
-	   *    4 * 4 * 4;               // returns number 64
-	   *
-	   *    math.cube([1, 2, 3, 4]); // returns Array [1, 8, 27, 64]
-	   *
-	   * See also:
-	   *
-	   *    multiply, square, pow
-	   *
-	   * @param  {number | BigNumber | Fraction | Complex | Array | Matrix | Unit} x  Number for which to calculate the cube
-	   * @return {number | BigNumber | Fraction | Complex | Array | Matrix | Unit} Cube of x
-	   */
-	  var cube = typed('cube', {
-	    'number': function (x) {
-	      return x * x * x;
-	    },
-
-	    'Complex': function (x) {
-	      return complexMultiply(complexMultiply(x, x), x);
-	    },
-
-	    'BigNumber': function (x) {
-	      return x.times(x).times(x);
-	    },
-
-	    'Fraction': function (x) {
-	      return x.mul(x).mul(x);
-	    },
-
-	    'Array | Matrix': function (x) {
-	      // deep map collection, skip zeros since cube(0) = 0
-	      return deepMap(x, cube, true);
-	    },
-
-	    'Unit': function(x) {
-	      return x.pow(3);
-	    }
-	  });
-
-	  cube.toTex = '\\left(${args[0]}\\right)^3';
-
-	  return cube;
-	}
-
-	exports.name = 'cube';
-	exports.factory = factory;
-
-
-/***/ },
-/* 94 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	var extend = __webpack_require__(5).extend;
-
-	function factory (type, config, load, typed) {
-
-	  var divideScalar = load(__webpack_require__(51));
-	  var multiply     = load(__webpack_require__(40));
-	  var inv          = load(__webpack_require__(50));
-	  var matrix       = load(__webpack_require__(23));
-
-	  var algorithm11 = load(__webpack_require__(42));
-	  var algorithm14 = load(__webpack_require__(39));
-	  
-	  /**
-	   * Divide two values, `x / y`.
-	   * To divide matrices, `x` is multiplied with the inverse of `y`: `x * inv(y)`.
-	   *
-	   * Syntax:
-	   *
-	   *    math.divide(x, y)
-	   *
-	   * Examples:
-	   *
-	   *    math.divide(2, 3);            // returns number 0.6666666666666666
-	   *
-	   *    var a = math.complex(5, 14);
-	   *    var b = math.complex(4, 1);
-	   *    math.divide(a, b);            // returns Complex 2 + 3i
-	   *
-	   *    var c = [[7, -6], [13, -4]];
-	   *    var d = [[1, 2], [4, 3]];
-	   *    math.divide(c, d);            // returns Array [[-9, 4], [-11, 6]]
-	   *
-	   *    var e = math.unit('18 km');
-	   *    math.divide(e, 4.5);          // returns Unit 4 km
-	   *
-	   * See also:
-	   *
-	   *    multiply
-	   *
-	   * @param  {number | BigNumber | Fraction | Complex | Unit | Array | Matrix} x   Numerator
-	   * @param  {number | BigNumber | Fraction | Complex | Array | Matrix} y          Denominator
-	   * @return {number | BigNumber | Fraction | Complex | Unit | Array | Matrix}                      Quotient, `x / y`
-	   */
-	  var divide = typed('divide', extend({
-	    // we extend the signatures of divideScalar with signatures dealing with matrices
-
-	    'Array | Matrix, Array | Matrix': function (x, y) {
-	      // TODO: implement matrix right division using pseudo inverse
-	      // http://www.mathworks.nl/help/matlab/ref/mrdivide.html
-	      // http://www.gnu.org/software/octave/doc/interpreter/Arithmetic-Ops.html
-	      // http://stackoverflow.com/questions/12263932/how-does-gnu-octave-matrix-division-work-getting-unexpected-behaviour
-	      return multiply(x, inv(y));
-	    },
-
-	    'Matrix, any': function (x, y) {
-	      // result
-	      var c;
-
-	      // process storage format
-	      switch (x.storage()) {
-	        case 'sparse':
-	          c = algorithm11(x, y, divideScalar, false);
-	          break;
-	        case 'dense':
-	          c = algorithm14(x, y, divideScalar, false);
-	          break;
-	      }
-	      return c;
-	    },
-	    
-	    'Array, any': function (x, y) {
-	      // use matrix implementation
-	      return algorithm14(matrix(x), y, divideScalar, false).valueOf();
-	    },
-
-	    'any, Array | Matrix': function (x, y) {
-	      return multiply(x, inv(y));
-	    }
-	  }, divideScalar.signatures));
-
-	  divide.toTex = '\\frac{${args[0]}}{${args[1]}}';
-
-	  return divide;
-	}
-
-	exports.name = 'divide';
-	exports.factory = factory;
-
-
-/***/ },
-/* 95 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	function factory (type, config, load, typed) {
-
-	  var matrix = load(__webpack_require__(23));
-	  var divideScalar = load(__webpack_require__(51));
-	  var latex = __webpack_require__(26);
-	  
-	  var algorithm02 = load(__webpack_require__(96));
-	  var algorithm03 = load(__webpack_require__(31));
-	  var algorithm07 = load(__webpack_require__(66));
-	  var algorithm11 = load(__webpack_require__(42));
-	  var algorithm12 = load(__webpack_require__(65));
-	  var algorithm13 = load(__webpack_require__(35));
-	  var algorithm14 = load(__webpack_require__(39));
-
-	  /**
-	   * Divide two matrices element wise. The function accepts both matrices and
-	   * scalar values.
-	   *
-	   * Syntax:
-	   *
-	   *    math.dotDivide(x, y)
-	   *
-	   * Examples:
-	   *
-	   *    math.dotDivide(2, 4);   // returns 0.5
-	   *
-	   *    a = [[9, 5], [6, 1]];
-	   *    b = [[3, 2], [5, 2]];
-	   *
-	   *    math.dotDivide(a, b);   // returns [[3, 2.5], [1.2, 0.5]]
-	   *    math.divide(a, b);      // returns [[1.75, 0.75], [-1.75, 2.25]]
-	   *
-	   * See also:
-	   *
-	   *    divide, multiply, dotMultiply
-	   *
-	   * @param  {number | BigNumber | Fraction | Complex | Unit | Array | Matrix} x Numerator
-	   * @param  {number | BigNumber | Fraction | Complex | Unit | Array | Matrix} y Denominator
-	   * @return {number | BigNumber | Fraction | Complex | Unit | Array | Matrix}                    Quotient, `x ./ y`
-	   */
-	  var dotDivide = typed('dotDivide', {
-	    
-	    'any, any': divideScalar,
-	    
-	    'Matrix, Matrix': function (x, y) {
-	      // result
-	      var c;
-
-	      // process matrix storage
-	      switch (x.storage()) {
-	        case 'sparse':
-	          switch (y.storage()) {
-	            case 'sparse':
-	              // sparse ./ sparse
-	              c = algorithm07(x, y, divideScalar, false);
-	              break;
-	            default:
-	              // sparse ./ dense
-	              c = algorithm02(y, x, divideScalar, true);
-	              break;
-	          }
-	          break;
-	        default:
-	          switch (y.storage()) {
-	            case 'sparse':
-	              // dense ./ sparse
-	              c = algorithm03(x, y, divideScalar, false);
-	              break;
-	            default:
-	              // dense ./ dense
-	              c = algorithm13(x, y, divideScalar);
-	              break;
-	          }
-	          break;
-	      }
-	      return c;
-	    },
-
-	    'Array, Array': function (x, y) {
-	      // use matrix implementation
-	      return dotDivide(matrix(x), matrix(y)).valueOf();
-	    },
-
-	    'Array, Matrix': function (x, y) {
-	      // use matrix implementation
-	      return dotDivide(matrix(x), y);
-	    },
-
-	    'Matrix, Array': function (x, y) {
-	      // use matrix implementation
-	      return dotDivide(x, matrix(y));
-	    },
-
-	    'Matrix, any': function (x, y) {
-	      // result
-	      var c;
-	      // check storage format
-	      switch (x.storage()) {
-	        case 'sparse':
-	          c = algorithm11(x, y, divideScalar, false);
-	          break;
-	        default:
-	          c = algorithm14(x, y, divideScalar, false);
-	          break;
-	      }
-	      return c;
-	    },
-
-	    'any, Matrix': function (x, y) {
-	      // result
-	      var c;
-	      // check storage format
-	      switch (y.storage()) {
-	        case 'sparse':
-	          c = algorithm12(y, x, divideScalar, true);
-	          break;
-	        default:
-	          c = algorithm14(y, x, divideScalar, true);
-	          break;
-	      }
-	      return c;
-	    },
-
-	    'Array, any': function (x, y) {
-	      // use matrix implementation
-	      return algorithm14(matrix(x), y, divideScalar, false).valueOf();
-	    },
-
-	    'any, Array': function (x, y) {
-	      // use matrix implementation
-	      return algorithm14(matrix(y), x, divideScalar, true).valueOf();
-	    }
-	  });
-
-	  dotDivide.toTex = '\\left(${args[0]}' + latex.operators['dotDivide'] + '${args[1]}\\right)';
-	  
-	  return dotDivide;
-	}
-
-	exports.name = 'dotDivide';
-	exports.factory = factory;
-
-
-/***/ },
-/* 96 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	var DimensionError = __webpack_require__(22);
-
-	function factory (type, config, load, typed) {
-
-	  var equalScalar = load(__webpack_require__(33));
-
-	  var SparseMatrix = type.SparseMatrix;
-
-	  /**
-	   * Iterates over SparseMatrix nonzero items and invokes the callback function f(Dij, Sij). 
-	   * Callback function invoked NNZ times (number of nonzero items in SparseMatrix).
-	   *
-	   *
-	   *          ┌  f(Dij, Sij)  ; S(i,j) !== 0
-	   * C(i,j) = ┤
-	   *          └  0            ; otherwise
-	   *
-	   *
-	   * @param {Matrix}   denseMatrix       The DenseMatrix instance (D)
-	   * @param {Matrix}   sparseMatrix      The SparseMatrix instance (S)
-	   * @param {Function} callback          The f(Dij,Sij) operation to invoke, where Dij = DenseMatrix(i,j) and Sij = SparseMatrix(i,j)
-	   * @param {boolean}  inverse           A true value indicates callback should be invoked f(Sij,Dij)
-	   *
-	   * @return {Matrix}                    SparseMatrix (C)
-	   *
-	   * see https://github.com/josdejong/mathjs/pull/346#issuecomment-97477571
-	   */
-	  var algorithm02 = function (denseMatrix, sparseMatrix, callback, inverse) {
-	    // dense matrix arrays
-	    var adata = denseMatrix._data;
-	    var asize = denseMatrix._size;
-	    var adt = denseMatrix._datatype;
-	    // sparse matrix arrays
-	    var bvalues = sparseMatrix._values;
-	    var bindex = sparseMatrix._index;
-	    var bptr = sparseMatrix._ptr;
-	    var bsize = sparseMatrix._size;
-	    var bdt = sparseMatrix._datatype;
-
-	    // validate dimensions
-	    if (asize.length !== bsize.length)
-	      throw new DimensionError(asize.length, bsize.length);
-
-	    // check rows & columns
-	    if (asize[0] !== bsize[0] || asize[1] !== bsize[1])
-	      throw new RangeError('Dimension mismatch. Matrix A (' + asize + ') must match Matrix B (' + bsize + ')');
-
-	    // sparse matrix cannot be a Pattern matrix
-	    if (!bvalues)
-	      throw new Error('Cannot perform operation on Dense Matrix and Pattern Sparse Matrix');
-
-	    // rows & columns
-	    var rows = asize[0];
-	    var columns = asize[1];
-	    
-	    // datatype
-	    var dt;
-	    // equal signature to use
-	    var eq = equalScalar;
-	    // zero value
-	    var zero = 0;
-	    // callback signature to use
-	    var cf = callback;
-
-	    // process data types
-	    if (typeof adt === 'string' && adt === bdt) {
-	      // datatype
-	      dt = adt;
-	      // find signature that matches (dt, dt)
-	      eq = typed.find(equalScalar, [dt, dt]);
-	      // convert 0 to the same datatype
-	      zero = typed.convert(0, dt);
-	      // callback
-	      cf = typed.find(callback, [dt, dt]);
-	    }
-
-	    // result (SparseMatrix)
-	    var cvalues = [];
-	    var cindex = [];
-	    var cptr = [];
-
-	    // loop columns in b
-	    for (var j = 0; j < columns; j++) {
-	      // update cptr
-	      cptr[j] = cindex.length;
-	      // values in column j
-	      for (var k0 = bptr[j], k1 = bptr[j + 1], k = k0; k < k1; k++) {
-	        // row
-	        var i = bindex[k];
-	        // update C(i,j)
-	        var cij = inverse ? cf(bvalues[k], adata[i][j]) : cf(adata[i][j], bvalues[k]);
-	        // check for nonzero
-	        if (!eq(cij, zero)) {
-	          // push i & v
-	          cindex.push(i);
-	          cvalues.push(cij);
-	        }
-	      }
-	    }
-	    // update cptr
-	    cptr[columns] = cindex.length;
-
-	    // return sparse matrix
-	    return new SparseMatrix({
-	      values: cvalues,
-	      index: cindex,
-	      ptr: cptr,
-	      size: [rows, columns],
-	      datatype: dt
-	    });
-	  };
-	  
-	  return algorithm02;
-	}
-
-	exports.name = 'algorithm02';
-	exports.factory = factory;
-
-
-/***/ },
-/* 97 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	function factory (type, config, load, typed) {
-
-	  var matrix = load(__webpack_require__(23));
-	  var multiplyScalar = load(__webpack_require__(41));
-	  var latex = __webpack_require__(26);
-
-	  var algorithm02 = load(__webpack_require__(96));
-	  var algorithm09 = load(__webpack_require__(98));
-	  var algorithm11 = load(__webpack_require__(42));
-	  var algorithm13 = load(__webpack_require__(35));
-	  var algorithm14 = load(__webpack_require__(39));
-
-	  /**
-	   * Multiply two matrices element wise. The function accepts both matrices and
-	   * scalar values.
-	   *
-	   * Syntax:
-	   *
-	   *    math.dotMultiply(x, y)
-	   *
-	   * Examples:
-	   *
-	   *    math.dotMultiply(2, 4); // returns 8
-	   *
-	   *    a = [[9, 5], [6, 1]];
-	   *    b = [[3, 2], [5, 2]];
-	   *
-	   *    math.dotMultiply(a, b); // returns [[27, 10], [30, 2]]
-	   *    math.multiply(a, b);    // returns [[52, 28], [23, 14]]
-	   *
-	   * See also:
-	   *
-	   *    multiply, divide, dotDivide
-	   *
-	   * @param  {number | BigNumber | Fraction | Complex | Unit | Array | Matrix} x Left hand value
-	   * @param  {number | BigNumber | Fraction | Complex | Unit | Array | Matrix} y Right hand value
-	   * @return {number | BigNumber | Fraction | Complex | Unit | Array | Matrix}                    Multiplication of `x` and `y`
-	   */
-	  var dotMultiply = typed('dotMultiply', {
-	    
-	    'any, any': multiplyScalar,
-	    
-	    'Matrix, Matrix': function (x, y) {
-	      // result
-	      var c;
-
-	      // process matrix storage
-	      switch (x.storage()) {
-	        case 'sparse':
-	          switch (y.storage()) {
-	            case 'sparse':
-	              // sparse .* sparse
-	              c = algorithm09(x, y, multiplyScalar, false);
-	              break;
-	            default:
-	              // sparse .* dense
-	              c = algorithm02(y, x, multiplyScalar, true);
-	              break;
-	          }
-	          break;
-	        default:
-	          switch (y.storage()) {
-	            case 'sparse':
-	              // dense .* sparse
-	              c = algorithm02(x, y, multiplyScalar, false);
-	              break;
-	            default:
-	              // dense .* dense
-	              c = algorithm13(x, y, multiplyScalar);
-	              break;
-	          }
-	          break;
-	      }
-	      return c;
-	    },
-	    
-	    'Array, Array': function (x, y) {
-	      // use matrix implementation
-	      return dotMultiply(matrix(x), matrix(y)).valueOf();
-	    },
-	    
-	    'Array, Matrix': function (x, y) {
-	      // use matrix implementation
-	      return dotMultiply(matrix(x), y);
-	    },
-
-	    'Matrix, Array': function (x, y) {
-	      // use matrix implementation
-	      return dotMultiply(x, matrix(y));
-	    },
-
-	    'Matrix, any': function (x, y) {
-	      // result
-	      var c;
-	      // check storage format
-	      switch (x.storage()) {
-	        case 'sparse':
-	          c = algorithm11(x, y, multiplyScalar, false);
-	          break;
-	        default:
-	          c = algorithm14(x, y, multiplyScalar, false);
-	          break;
-	      }
-	      return c;
-	    },
-
-	    'any, Matrix': function (x, y) {
-	      // result
-	      var c;
-	      // check storage format
-	      switch (y.storage()) {
-	        case 'sparse':
-	          c = algorithm11(y, x, multiplyScalar, true);
-	          break;
-	        default:
-	          c = algorithm14(y, x, multiplyScalar, true);
-	          break;
-	      }
-	      return c;
-	    },
-
-	    'Array, any': function (x, y) {
-	      // use matrix implementation
-	      return algorithm14(matrix(x), y, multiplyScalar, false).valueOf();
-	    },
-
-	    'any, Array': function (x, y) {
-	      // use matrix implementation
-	      return algorithm14(matrix(y), x, multiplyScalar, true).valueOf();
-	    }
-	  });
-
-	  dotMultiply.toTex = '\\left(${args[0]}' + latex.operators['dotMultiply'] + '${args[1]}\\right)';
-	  
-	  return dotMultiply;
-	}
-
-	exports.name = 'dotMultiply';
-	exports.factory = factory;
-
-
-/***/ },
-/* 98 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	var DimensionError = __webpack_require__(22);
-
-	function factory (type, config, load, typed) {
-
-	  var equalScalar = load(__webpack_require__(33));
-
-	  var SparseMatrix = type.SparseMatrix;
-
-	  /**
-	   * Iterates over SparseMatrix A and invokes the callback function f(Aij, Bij). 
-	   * Callback function invoked NZA times, number of nonzero elements in A.
-	   *
-	   *
-	   *          ┌  f(Aij, Bij)  ; A(i,j) !== 0
-	   * C(i,j) = ┤  
-	   *          └  0            ; otherwise
-	   *
-	   *
-	   * @param {Matrix}   a                 The SparseMatrix instance (A)
-	   * @param {Matrix}   b                 The SparseMatrix instance (B)
-	   * @param {Function} callback          The f(Aij,Bij) operation to invoke
-	   *
-	   * @return {Matrix}                    SparseMatrix (C)
-	   *
-	   * see https://github.com/josdejong/mathjs/pull/346#issuecomment-97620294
-	   */
-	  var algorithm09 = function (a, b, callback) {
-	    // sparse matrix arrays
-	    var avalues = a._values;
-	    var aindex = a._index;
-	    var aptr = a._ptr;
-	    var asize = a._size;
-	    var adt = a._datatype;
-	    // sparse matrix arrays
-	    var bvalues = b._values;
-	    var bindex = b._index;
-	    var bptr = b._ptr;
-	    var bsize = b._size;
-	    var bdt = b._datatype;
-
-	    // validate dimensions
-	    if (asize.length !== bsize.length)
-	      throw new DimensionError(asize.length, bsize.length);
-
-	    // check rows & columns
-	    if (asize[0] !== bsize[0] || asize[1] !== bsize[1])
-	      throw new RangeError('Dimension mismatch. Matrix A (' + asize + ') must match Matrix B (' + bsize + ')');
-
-	    // rows & columns
-	    var rows = asize[0];
-	    var columns = asize[1];
-
-	    // datatype
-	    var dt;
-	    // equal signature to use
-	    var eq = equalScalar;
-	    // zero value
-	    var zero = 0;
-	    // callback signature to use
-	    var cf = callback;
-
-	    // process data types
-	    if (typeof adt === 'string' && adt === bdt) {
-	      // datatype
-	      dt = adt;
-	      // find signature that matches (dt, dt)
-	      eq = typed.find(equalScalar, [dt, dt]);
-	      // convert 0 to the same datatype
-	      zero = typed.convert(0, dt);
-	      // callback
-	      cf = typed.find(callback, [dt, dt]);
-	    }
-
-	    // result arrays
-	    var cvalues = avalues && bvalues ? [] : undefined;
-	    var cindex = [];
-	    var cptr = [];
-	    // matrix
-	    var c = new SparseMatrix({
-	      values: cvalues,
-	      index: cindex,
-	      ptr: cptr,
-	      size: [rows, columns],
-	      datatype: dt
-	    });
-
-	    // workspaces
-	    var x = cvalues ? [] : undefined;
-	    // marks indicating we have a value in x for a given column
-	    var w = [];
-
-	    // vars
-	    var i, j, k, k0, k1;
-	    
-	    // loop columns
-	    for (j = 0; j < columns; j++) {
-	      // update cptr
-	      cptr[j] = cindex.length;
-	      // column mark
-	      var mark = j + 1;
-	      // check we need to process values
-	      if (x) {
-	        // loop B(:,j)
-	        for (k0 = bptr[j], k1 = bptr[j + 1], k = k0; k < k1; k++) {
-	          // row
-	          i = bindex[k];
-	          // update workspace
-	          w[i] = mark;
-	          x[i] = bvalues[k];
-	        }
-	      }
-	      // loop A(:,j)
-	      for (k0 = aptr[j], k1 = aptr[j + 1], k = k0; k < k1; k++) {
-	        // row
-	        i = aindex[k];
-	        // check we need to process values
-	        if (x) {
-	          // b value @ i,j
-	          var vb = w[i] === mark ? x[i] : zero;
-	          // invoke f
-	          var vc = cf(avalues[k], vb);
-	          // check zero value
-	          if (!eq(vc, zero)) {
-	            // push index
-	            cindex.push(i);
-	            // push value
-	            cvalues.push(vc);
-	          }
-	        }
-	        else {
-	          // push index
-	          cindex.push(i);
-	        }
-	      }
-	    }
-	    // update cptr
-	    cptr[columns] = cindex.length;
-
-	    // return sparse matrix
-	    return c;
-	  };
-
-	  return algorithm09;
-	}
-
-	exports.name = 'algorithm09';
-	exports.factory = factory;
-
-
-/***/ },
-/* 99 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	function factory (type, config, load, typed) {
-
-	  var matrix = load(__webpack_require__(23));
-	  var pow = load(__webpack_require__(100));
-	  var latex = __webpack_require__(26);
-
-	  var algorithm03 = load(__webpack_require__(31));
-	  var algorithm07 = load(__webpack_require__(66));
-	  var algorithm11 = load(__webpack_require__(42));
-	  var algorithm12 = load(__webpack_require__(65));
-	  var algorithm13 = load(__webpack_require__(35));
-	  var algorithm14 = load(__webpack_require__(39));
-
-	  /**
-	   * Calculates the power of x to y element wise.
-	   *
-	   * Syntax:
-	   *
-	   *    math.dotPow(x, y)
-	   *
-	   * Examples:
-	   *
-	   *    math.dotPow(2, 3);            // returns number 8
-	   *
-	   *    var a = [[1, 2], [4, 3]];
-	   *    math.dotPow(a, 2);            // returns Array [[1, 4], [16, 9]]
-	   *    math.pow(a, 2);               // returns Array [[9, 8], [16, 17]]
-	   *
-	   * See also:
-	   *
-	   *    pow, sqrt, multiply
-	   *
-	   * @param  {number | BigNumber | Complex | Unit | Array | Matrix} x  The base
-	   * @param  {number | BigNumber | Complex | Unit | Array | Matrix} y  The exponent
-	   * @return {number | BigNumber | Complex | Unit | Array | Matrix}                     The value of `x` to the power `y`
-	   */
-	  var dotPow = typed('dotPow', {
-	    
-	    'any, any': pow,
-	    
-	    'Matrix, Matrix': function (x, y) {
-	      // result
-	      var c;
-
-	      // process matrix storage
-	      switch (x.storage()) {
-	        case 'sparse':
-	          switch (y.storage()) {
-	            case 'sparse':
-	              // sparse .^ sparse
-	              c = algorithm07(x, y, pow, false);
-	              break;
-	            default:
-	              // sparse .^ dense
-	              c = algorithm03(y, x, pow, true);
-	              break;
-	          }
-	          break;
-	        default:
-	          switch (y.storage()) {
-	            case 'sparse':
-	              // dense .^ sparse
-	              c = algorithm03(x, y, pow, false);
-	              break;
-	            default:
-	              // dense .^ dense
-	              c = algorithm13(x, y, pow);
-	              break;
-	          }
-	          break;
-	      }
-	      return c;
-	    },
-
-	    'Array, Array': function (x, y) {
-	      // use matrix implementation
-	      return dotPow(matrix(x), matrix(y)).valueOf();
-	    },
-
-	    'Array, Matrix': function (x, y) {
-	      // use matrix implementation
-	      return dotPow(matrix(x), y);
-	    },
-
-	    'Matrix, Array': function (x, y) {
-	      // use matrix implementation
-	      return dotPow(x, matrix(y));
-	    },
-
-	    'Matrix, any': function (x, y) {
-	      // result
-	      var c;
-	      // check storage format
-	      switch (x.storage()) {
-	        case 'sparse':
-	          c = algorithm11(x, y, dotPow, false);
-	          break;
-	        default:
-	          c = algorithm14(x, y, dotPow, false);
-	          break;
-	      }
-	      return c;
-	    },
-
-	    'any, Matrix': function (x, y) {
-	      // result
-	      var c;
-	      // check storage format
-	      switch (y.storage()) {
-	        case 'sparse':
-	          c = algorithm12(y, x, dotPow, true);
-	          break;
-	        default:
-	          c = algorithm14(y, x, dotPow, true);
-	          break;
-	      }
-	      return c;
-	    },
-
-	    'Array, any': function (x, y) {
-	      // use matrix implementation
-	      return algorithm14(matrix(x), y, dotPow, false).valueOf();
-	    },
-
-	    'any, Array': function (x, y) {
-	      // use matrix implementation
-	      return algorithm14(matrix(y), x, dotPow, true).valueOf();
-	    }
-	  });
-
-	  dotPow.toTex = '\\left(${args[0]}' + latex.operators['dotPow'] + '${args[1]}\\right)';
-	  
-	  return dotPow;
-	}
-
-	exports.name = 'dotPow';
-	exports.factory = factory;
-
-
-/***/ },
-/* 100 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	var isInteger = __webpack_require__(8).isInteger;
-	var size = __webpack_require__(18).size;
-
-	function factory (type, config, load, typed) {
-	  var latex = __webpack_require__(26);
-	  var exp = load(__webpack_require__(101));
-	  var eye = load(__webpack_require__(48));
-	  var log = load(__webpack_require__(102));
-	  var multiply = load(__webpack_require__(40));
-	  var matrix = load(__webpack_require__(23));
-
-	  /**
-	   * Calculates the power of x to y, `x ^ y`.
-	   * Matrix exponentiation is supported for square matrices `x`, and positive
-	   * integer exponents `y`.
-	   *
-	   * Syntax:
-	   *
-	   *    math.pow(x, y)
-	   *
-	   * Examples:
-	   *
-	   *    math.pow(2, 3);               // returns number 8
-	   *
-	   *    var a = math.complex(2, 3);
-	   *    math.pow(a, 2)                // returns Complex -5 + 12i
-	   *
-	   *    var b = [[1, 2], [4, 3]];
-	   *    math.pow(b, 2);               // returns Array [[9, 8], [16, 17]]
-	   *
-	   * See also:
-	   *
-	   *    multiply, sqrt
-	   *
-	   * @param  {number | BigNumber | Complex | Array | Matrix} x  The base
-	   * @param  {number | BigNumber | Complex} y                   The exponent
-	   * @return {number | BigNumber | Complex | Array | Matrix} The value of `x` to the power `y`
-	   */
-	  var pow = typed('pow', {
-	    'number, number': _pow,
-
-	    'Complex, Complex': _powComplex,
-
-	    'BigNumber, BigNumber': function (x, y) {
-	      if (y.isInteger() || x >= 0 || config.predictable) {
-	        return x.pow(y);
-	      }
-	      else {
-	        return _powComplex(new type.Complex(x.toNumber(), 0), new type.Complex(y.toNumber(), 0));
-	      }
-	    },
-
-	    'Fraction, Fraction': function (x, y) {
-	      if (y.d !== 1) {
-	        if (config.predictable) {
-	          throw new Error('Function pow does not support non-integer exponents for fractions.');
-	        }
-	        else {
-	          return _pow(x.valueOf(), y.valueOf());
-	        }
-	      }
-	      else {
-	        return x.pow(y);
-	     }
-	    },
-
-	    'Array, number': _powArray,
-
-	    'Array, BigNumber': function (x, y) {
-	      return _powArray(x, y.toNumber());
-	    },
-
-	    'Matrix, number': _powMatrix,
-
-	    'Matrix, BigNumber': function (x, y) {
-	      return _powMatrix(x, y.toNumber());
-	    },
-
-	    'Unit, number': function (x, y) {
-	      return x.pow(y);
-	    }
-
-	  });
-
-	  /**
-	   * Calculates the power of x to y, x^y, for two numbers.
-	   * @param {number} x
-	   * @param {number} y
-	   * @return {number | Complex} res
-	   * @private
-	   */
-	  function _pow(x, y) {
-	    if (isInteger(y) || x >= 0 || config.predictable) {
-	      return Math.pow(x, y);
-	    }
-	    else {
-	      return _powComplex(new type.Complex(x, 0), new type.Complex(y, 0));
-	    }
-	  }
-
-	  /**
-	   * Calculates the power of x to y, x^y, for two complex numbers.
-	   * @param {Complex} x
-	   * @param {Complex} y
-	   * @return {Complex} res
-	   * @private
-	   */
-	  function _powComplex (x, y) {
-	    // complex computation
-	    // x^y = exp(log(x)*y) = exp((abs(x)+i*arg(x))*y)
-	    // TODO: we can optimize this as we know x and y are Complex
-	    //   expComplex      = exp.signatures['Complex,Complex']
-	    //   multiplyComplex = multiply.signatures['Complex,Complex']
-	    //   logComplex      = log.signatures['Complex,Complex']
-	    //   return expComplex(multiplyComplex(logComplex(x), y));
-	    return exp(multiply(log(x), y));
-	  }
-
-	  /**
-	   * Calculate the power of a 2d array
-	   * @param {Array} x     must be a 2 dimensional, square matrix
-	   * @param {number} y    a positive, integer value
-	   * @returns {Array}
-	   * @private
-	   */
-	  function _powArray(x, y) {
-	    if (!isInteger(y) || y < 0) {
-	      throw new TypeError('For A^b, b must be a positive integer (value is ' + y + ')');
-	    }
-	    // verify that A is a 2 dimensional square matrix
-	    var s = size(x);
-	    if (s.length != 2) {
-	      throw new Error('For A^b, A must be 2 dimensional (A has ' + s.length + ' dimensions)');
-	    }
-	    if (s[0] != s[1]) {
-	      throw new Error('For A^b, A must be square (size is ' + s[0] + 'x' + s[1] + ')');
-	    }
-
-	    var res = eye(s[0]).valueOf();
-	    var px = x;
-	    while (y >= 1) {
-	      if ((y & 1) == 1) {
-	        res = multiply(px, res);
-	      }
-	      y >>= 1;
-	      px = multiply(px, px);
-	    }
-	    return res;
-	  }
-
-	  /**
-	   * Calculate the power of a 2d matrix
-	   * @param {Matrix} x     must be a 2 dimensional, square matrix
-	   * @param {number} y    a positive, integer value
-	   * @returns {Matrix}
-	   * @private
-	   */
-	  function _powMatrix (x, y) {
-	    return matrix(_powArray(x.valueOf(), y));
-	  }
-
-
-
-	  pow.toTex = '\\left(${args[0]}\\right)' + latex.operators['pow'] + '{${args[1]}}';
-
-	  return pow;
-	}
-
-	exports.name = 'pow';
-	exports.factory = factory;
-
-
-/***/ },
-/* 101 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	var deepMap = __webpack_require__(29);
-
-	function factory (type, config, load, typed) {
-	  /**
-	   * Calculate the exponent of a value.
-	   * For matrices, the function is evaluated element wise.
-	   *
-	   * Syntax:
-	   *
-	   *    math.exp(x)
-	   *
-	   * Examples:
-	   *
-	   *    math.exp(2);                  // returns number 7.3890560989306495
-	   *    math.pow(math.e, 2);          // returns number 7.3890560989306495
-	   *    math.log(math.exp(2));        // returns number 2
-	   *
-	   *    math.exp([1, 2, 3]);
-	   *    // returns Array [
-	   *    //   2.718281828459045,
-	   *    //   7.3890560989306495,
-	   *    //   20.085536923187668
-	   *    // ]
-	   *
-	   * See also:
-	   *
-	   *    log, pow
-	   *
-	   * @param {number | BigNumber | Complex | Array | Matrix} x  A number or matrix to exponentiate
-	   * @return {number | BigNumber | Complex | Array | Matrix} Exponent of `x`
-	   */
-	  var exp = typed('exp', {
-	    'number': Math.exp,
-
-	    'Complex': function (x) {
-	      var r = Math.exp(x.re);
-	      return new type.Complex(
-	          r * Math.cos(x.im),
-	          r * Math.sin(x.im)
-	      );
-	    },
-
-	    'BigNumber': function (x) {
-	      return x.exp();
-	    },
-
-	    'Array | Matrix': function (x) {
-	      // TODO: exp(sparse) should return a dense matrix since exp(0)==1
-	      return deepMap(x, exp);
-	    }
-	  });
-
-	  exp.toTex = '\\exp\\left(${args[0]}\\right)';
-
-	  return exp;
-	}
-
-	exports.name = 'exp';
-	exports.factory = factory;
-
-
-/***/ },
-/* 102 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	var deepMap = __webpack_require__(29);
-
-	function factory (type, config, load, typed) {
-	  var divideScalar = load(__webpack_require__(51));
-
-	  /**
-	   * Calculate the logarithm of a value.
-	   *
-	   * For matrices, the function is evaluated element wise.
-	   *
-	   * Syntax:
-	   *
-	   *    math.log(x)
-	   *    math.log(x, base)
-	   *
-	   * Examples:
-	   *
-	   *    math.log(3.5);                  // returns 1.252762968495368
-	   *    math.exp(math.log(2.4));        // returns 2.4
-	   *
-	   *    math.pow(10, 4);                // returns 10000
-	   *    math.log(10000, 10);            // returns 4
-	   *    math.log(10000) / math.log(10); // returns 4
-	   *
-	   *    math.log(1024, 2);              // returns 10
-	   *    math.pow(2, 10);                // returns 1024
-	   *
-	   * See also:
-	   *
-	   *    exp, log10
-	   *
-	   * @param {number | BigNumber | Complex | Array | Matrix} x
-	   *            Value for which to calculate the logarithm.
-	   * @param {number | BigNumber | Complex} [base=e]
-	   *            Optional base for the logarithm. If not provided, the natural
-	   *            logarithm of `x` is calculated.
-	   * @return {number | BigNumber | Complex | Array | Matrix}
-	   *            Returns the logarithm of `x`
-	   */
-	  var log = typed('log', {
-	    'number': _logNumber,
-
-	    'Complex': _logComplex,
-
-	    'BigNumber': function (x) {
-	      if (!x.isNegative() || config.predictable) {
-	        return x.ln();
-	      }
-	      else {
-	        // downgrade to number, return Complex valued result
-	        return _logComplex(new type.Complex(x.toNumber(), 0));
-	      }
-	    },
-
-	    'Array | Matrix': function (x) {
-	      return deepMap(x, log);
-	    },
-
-	    'any, any': function (x, base) {
-	      // calculate logarithm for a specified base, log(x, base)
-	      return divideScalar(log(x), log(base));
-	    }
-	  });
-
-	  /**
-	   * Calculate the natural logarithm of a number
-	   * @param {number} x
-	   * @returns {number | Complex}
-	   * @private
-	   */
-	  function _logNumber(x) {
-	    if (x >= 0 || config.predictable) {
-	      return Math.log(x);
-	    }
-	    else {
-	      // negative value -> complex value computation
-	      return log(new type.Complex(x, 0));
-	    }
-	  }
-
-	  /**
-	   * Calculate the natural logarithm of a complex number
-	   * @param {Complex} x
-	   * @returns {Complex}
-	   * @private
-	   */
-	  function _logComplex(x) {
-	    return new type.Complex (
-	        Math.log(Math.sqrt(x.re * x.re + x.im * x.im)),
-	        Math.atan2(x.im, x.re)
-	    );
-	  }
-
-	  log.toTex = {
-	    1: '\\ln\\left(${args[0]}\\right)',
-	    2: '\\log_{${args[1]}}\\left(${args[0]}\\right)'
-	  };
-
-	  return log;
-	}
-
-	exports.name = 'log';
-	exports.factory = factory;
-
-
-/***/ },
-/* 103 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	var deepMap = __webpack_require__(29);
-
-	function factory (type, config, load, typed) {
-	  /**
-	   * Round a value towards zero.
-	   * For matrices, the function is evaluated element wise.
-	   *
-	   * Syntax:
-	   *
-	   *    math.fix(x)
-	   *
-	   * Examples:
-	   *
-	   *    math.fix(3.2);                // returns number 3
-	   *    math.fix(3.8);                // returns number 3
-	   *    math.fix(-4.2);               // returns number -4
-	   *    math.fix(-4.7);               // returns number -4
-	   *
-	   *    var c = math.complex(3.2, -2.7);
-	   *    math.fix(c);                  // returns Complex 3 - 2i
-	   *
-	   *    math.fix([3.2, 3.8, -4.7]);   // returns Array [3, 3, -4]
-	   *
-	   * See also:
-	   *
-	   *    ceil, floor, round
-	   *
-	   * @param {number | BigNumber | Fraction | Complex | Array | Matrix} x Number to be rounded
-	   * @return {number | BigNumber | Fraction | Complex | Array | Matrix}            Rounded value
-	   */
-	  var fix = typed('fix', {
-	    'number': function (x) {
-	      return (x > 0) ? Math.floor(x) : Math.ceil(x);
-	    },
-
-	    'Complex': function (x) {
-	      return new type.Complex(
-	          (x.re > 0) ? Math.floor(x.re) : Math.ceil(x.re),
-	          (x.im > 0) ? Math.floor(x.im) : Math.ceil(x.im)
-	      );
-	    },
-
-	    'BigNumber': function (x) {
-	      return x.isNegative() ? x.ceil() : x.floor();
-	    },
-
-	    'Fraction': function (x) {
-	      return x.s < 0 ? x.ceil() : x.floor();
-	    },
-
-	    'Array | Matrix': function (x) {
-	      // deep map collection, skip zeros since fix(0) = 0
-	      return deepMap(x, fix, true);
-	    }
-	  });
-
-	  fix.toTex = '\\mathrm{${name}}\\left(${args}\\right)';
-
-	  return fix;
-	}
-
-	exports.name = 'fix';
-	exports.factory = factory;
-
-
-/***/ },
-/* 104 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	var deepMap = __webpack_require__(29);
-
-	function factory (type, config, load, typed) {
-	  /**
-	   * Round a value towards minus infinity.
-	   * For matrices, the function is evaluated element wise.
-	   *
-	   * Syntax:
-	   *
-	   *    math.floor(x)
-	   *
-	   * Examples:
-	   *
-	   *    math.floor(3.2);              // returns number 3
-	   *    math.floor(3.8);              // returns number 3
-	   *    math.floor(-4.2);             // returns number -5
-	   *    math.floor(-4.7);             // returns number -5
-	   *
-	   *    var c = math.complex(3.2, -2.7);
-	   *    math.floor(c);                // returns Complex 3 - 3i
-	   *
-	   *    math.floor([3.2, 3.8, -4.7]); // returns Array [3, 3, -5]
-	   *
-	   * See also:
-	   *
-	   *    ceil, fix, round
-	   *
-	   * @param  {number | BigNumber | Fraction | Complex | Array | Matrix} x  Number to be rounded
-	   * @return {number | BigNumber | Fraction | Complex | Array | Matrix} Rounded value
-	   */
-	  var floor = typed('floor', {
-	    'number': Math.floor,
-
-	    'Complex': function (x) {
-	      return new type.Complex(
-	          Math.floor(x.re),
-	          Math.floor(x.im)
-	      );
-	    },
-
-	    'BigNumber': function (x) {
-	      return x.floor();
-	    },
-
-	    'Fraction': function (x) {
-	      return x.floor();
-	    },
-
-	    'Array | Matrix': function (x) {
-	      // deep map collection, skip zeros since floor(0) = 0
-	      return deepMap(x, floor, true);
-	    }
-	  });
-
-	  floor.toTex = '\\left\\lfloor${args[0]}\\right\\rfloor';
-
-	  return floor;
-	}
-
-	exports.name = 'floor';
-	exports.factory = factory;
-
-
-/***/ },
-/* 105 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	var isInteger = __webpack_require__(8).isInteger;
-
-	function factory (type, config, load, typed) {
-
-	  var matrix = load(__webpack_require__(23));
-
-	  var algorithm01 = load(__webpack_require__(30));
-	  var algorithm04 = load(__webpack_require__(45));
-	  var algorithm10 = load(__webpack_require__(34));
-	  var algorithm13 = load(__webpack_require__(35));
-	  var algorithm14 = load(__webpack_require__(39));
-
-	  /**
-	   * Calculate the greatest common divisor for two or more values or arrays.
-	   *
-	   * For matrices, the function is evaluated element wise.
-	   *
-	   * Syntax:
-	   *
-	   *    math.gcd(a, b)
-	   *    math.gcd(a, b, c, ...)
-	   *
-	   * Examples:
-	   *
-	   *    math.gcd(8, 12);              // returns 4
-	   *    math.gcd(-4, 6);              // returns 2
-	   *    math.gcd(25, 15, -10);        // returns 5
-	   *
-	   *    math.gcd([8, -4], [12, 6]);   // returns [4, 2]
-	   *
-	   * See also:
-	   *
-	   *    lcm, xgcd
-	   *
-	   * @param {... number | BigNumber | Fraction | Array | Matrix} args  Two or more integer numbers
-	   * @return {number | BigNumber | Fraction | Array | Matrix}                           The greatest common divisor
-	   */
-	  var gcd = typed('gcd', {
-
-	    'number, number': _gcd,
-
-	    'BigNumber, BigNumber': _gcdBigNumber,
-
-	    'Fraction, Fraction': function (x, y) {
-	      return x.gcd(y);
-	    },
-
-	    'Matrix, Matrix': function (x, y) {
-	      // result
-	      var c;
-
-	      // process matrix storage
-	      switch (x.storage()) {
-	        case 'sparse':
-	          switch (y.storage()) {
-	            case 'sparse':
-	              // sparse + sparse
-	              c = algorithm04(x, y, gcd);
-	              break;
-	            default:
-	              // sparse + dense
-	              c = algorithm01(y, x, gcd, true);
-	              break;
-	          }
-	          break;
-	        default:
-	          switch (y.storage()) {
-	            case 'sparse':
-	              // dense + sparse
-	              c = algorithm01(x, y, gcd, false);
-	              break;
-	            default:
-	              // dense + dense
-	              c = algorithm13(x, y, gcd);
-	              break;
-	          }
-	          break;
-	      }
-	      return c;
-	    },
-
-	    'Array, Array': function (x, y) {
-	      // use matrix implementation
-	      return gcd(matrix(x), matrix(y)).valueOf();
-	    },
-
-	    'Array, Matrix': function (x, y) {
-	      // use matrix implementation
-	      return gcd(matrix(x), y);
-	    },
-
-	    'Matrix, Array': function (x, y) {
-	      // use matrix implementation
-	      return gcd(x, matrix(y));
-	    },
-	    
-	    'Matrix, number | BigNumber': function (x, y) {
-	      // result
-	      var c;
-	      // check storage format
-	      switch (x.storage()) {
-	        case 'sparse':
-	          c = algorithm10(x, y, gcd, false);
-	          break;
-	        default:
-	          c = algorithm14(x, y, gcd, false);
-	          break;
-	      }
-	      return c;
-	    },
-
-	    'number | BigNumber, Matrix': function (x, y) {
-	      // result
-	      var c;
-	      // check storage format
-	      switch (y.storage()) {
-	        case 'sparse':
-	          c = algorithm10(y, x, gcd, true);
-	          break;
-	        default:
-	          c = algorithm14(y, x, gcd, true);
-	          break;
-	      }
-	      return c;
-	    },
-
-	    'Array, number | BigNumber': function (x, y) {
-	      // use matrix implementation
-	      return algorithm14(matrix(x), y, gcd, false).valueOf();
-	    },
-
-	    'number | BigNumber, Array': function (x, y) {
-	      // use matrix implementation
-	      return algorithm14(matrix(y), x, gcd, true).valueOf();
-	    },
-
-	    // TODO: need a smarter notation here
-	    'Array | Matrix | number | BigNumber, Array | Matrix | number | BigNumber, ...Array | Matrix | number | BigNumber': function (a, b, args) {
-	      var res = gcd(a, b);
-	      for (var i = 0; i < args.length; i++) {
-	        res = gcd(res, args[i]);
-	      }
-	      return res;
-	    }
-	  });
-
-	  gcd.toTex = '\\gcd\\left(${args}\\right)';
-
-	  return gcd;
-
-	  /**
-	   * Calculate gcd for BigNumbers
-	   * @param {BigNumber} a
-	   * @param {BigNumber} b
-	   * @returns {BigNumber} Returns greatest common denominator of a and b
-	   * @private
-	   */
-	  function _gcdBigNumber(a, b) {
-	    if (!a.isInt() || !b.isInt()) {
-	      throw new Error('Parameters in function gcd must be integer numbers');
-	    }
-
-	    // http://en.wikipedia.org/wiki/Euclidean_algorithm
-	    var zero = new type.BigNumber(0);
-	    while (!b.isZero()) {
-	      var r = a.mod(b);
-	      a = b;
-	      b = r;
-	    }
-	    return a.lt(zero) ? a.neg() : a;
-	  }
-	}
-
-	/**
-	 * Calculate gcd for numbers
-	 * @param {number} a
-	 * @param {number} b
-	 * @returns {number} Returns the greatest common denominator of a and b
-	 * @private
-	 */
-	function _gcd(a, b) {
-	  if (!isInteger(a) || !isInteger(b)) {
-	    throw new Error('Parameters in function gcd must be integer numbers');
-	  }
-
-	  // http://en.wikipedia.org/wiki/Euclidean_algorithm
-	  var r;
-	  while (b != 0) {
-	    r = a % b;
-	    a = b;
-	    b = r;
-	  }
-	  return (a < 0) ? -a : a;
-	}
-
-	exports.name = 'gcd';
-	exports.factory = factory;
-
-
-/***/ },
-/* 106 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	var isInteger = __webpack_require__(8).isInteger;
-
-	function factory (type, config, load, typed) {
-	  
-	  var matrix = load(__webpack_require__(23));
-
-	  var algorithm02 = load(__webpack_require__(96));
-	  var algorithm06 = load(__webpack_require__(107));
-	  var algorithm11 = load(__webpack_require__(42));
-	  var algorithm13 = load(__webpack_require__(35));
-	  var algorithm14 = load(__webpack_require__(39));
-
-	  /**
-	   * Calculate the least common multiple for two or more values or arrays.
-	   *
-	   * lcm is defined as:
-	   *
-	   *     lcm(a, b) = abs(a * b) / gcd(a, b)
-	   *
-	   * For matrices, the function is evaluated element wise.
-	   *
-	   * Syntax:
-	   *
-	   *    math.lcm(a, b)
-	   *    math.lcm(a, b, c, ...)
-	   *
-	   * Examples:
-	   *
-	   *    math.lcm(4, 6);               // returns 12
-	   *    math.lcm(6, 21);              // returns 42
-	   *    math.lcm(6, 21, 5);           // returns 210
-	   *
-	   *    math.lcm([4, 6], [6, 21]);    // returns [12, 42]
-	   *
-	   * See also:
-	   *
-	   *    gcd, xgcd
-	   *
-	   * @param {... number | BigNumber | Array | Matrix} args  Two or more integer numbers
-	   * @return {number | BigNumber | Array | Matrix}                           The least common multiple
-	   */
-	  var lcm = typed('lcm', {
-	    'number, number': _lcm,
-
-	    'BigNumber, BigNumber': _lcmBigNumber,
-
-	    // TODO: implement support for Fraction
-
-	    'Matrix, Matrix': function (x, y) {
-	      // result
-	      var c;
-
-	      // process matrix storage
-	      switch (x.storage()) {
-	        case 'sparse':
-	          switch (y.storage()) {
-	            case 'sparse':
-	              // sparse + sparse
-	              c = algorithm06(x, y, lcm);
-	              break;
-	            default:
-	              // sparse + dense
-	              c = algorithm02(y, x, lcm, true);
-	              break;
-	          }
-	          break;
-	        default:
-	          switch (y.storage()) {
-	            case 'sparse':
-	              // dense + sparse
-	              c = algorithm02(x, y, lcm, false);
-	              break;
-	            default:
-	              // dense + dense
-	              c = algorithm13(x, y, lcm);
-	              break;
-	          }
-	          break;
-	      }
-	      return c;
-	    },
-
-	    'Array, Array': function (x, y) {
-	      // use matrix implementation
-	      return lcm(matrix(x), matrix(y)).valueOf();
-	    },
-
-	    'Array, Matrix': function (x, y) {
-	      // use matrix implementation
-	      return lcm(matrix(x), y);
-	    },
-
-	    'Matrix, Array': function (x, y) {
-	      // use matrix implementation
-	      return lcm(x, matrix(y));
-	    },
-
-	    'Matrix, number | BigNumber': function (x, y) {
-	      // result
-	      var c;
-	      // check storage format
-	      switch (x.storage()) {
-	        case 'sparse':
-	          c = algorithm11(x, y, lcm, false);
-	          break;
-	        default:
-	          c = algorithm14(x, y, lcm, false);
-	          break;
-	      }
-	      return c;
-	    },
-
-	    'number | BigNumber, Matrix': function (x, y) {
-	      // result
-	      var c;
-	      // check storage format
-	      switch (y.storage()) {
-	        case 'sparse':
-	          c = algorithm11(y, x, lcm, true);
-	          break;
-	        default:
-	          c = algorithm14(y, x, lcm, true);
-	          break;
-	      }
-	      return c;
-	    },
-
-	    'Array, number | BigNumber': function (x, y) {
-	      // use matrix implementation
-	      return algorithm14(matrix(x), y, lcm, false).valueOf();
-	    },
-
-	    'number | BigNumber, Array': function (x, y) {
-	      // use matrix implementation
-	      return algorithm14(matrix(y), x, lcm, true).valueOf();
-	    },
-
-	    // TODO: need a smarter notation here
-	    'Array | Matrix | number | BigNumber, Array | Matrix | number | BigNumber, ...Array | Matrix | number | BigNumber': function (a, b, args) {
-	      var res = lcm(a, b);
-	      for (var i = 0; i < args.length; i++) {
-	        res = lcm(res, args[i]);
-	      }
-	      return res;
-	    }
-	  });
-
-	  lcm.toTex = '\\mathrm{${name}}\\left(${args}\\right)';
-
-	  return lcm;
-
-	  /**
-	   * Calculate lcm for two BigNumbers
-	   * @param {BigNumber} a
-	   * @param {BigNumber} b
-	   * @returns {BigNumber} Returns the least common multiple of a and b
-	   * @private
-	   */
-	  function _lcmBigNumber(a, b) {
-	    if (!a.isInt() || !b.isInt()) {
-	      throw new Error('Parameters in function lcm must be integer numbers');
-	    }
-
-	    if (a.isZero() || b.isZero()) {
-	      return new type.BigNumber(0);
-	    }
-
-	    // http://en.wikipedia.org/wiki/Euclidean_algorithm
-	    // evaluate lcm here inline to reduce overhead
-	    var prod = a.times(b);
-	    while (!b.isZero()) {
-	      var t = b;
-	      b = a.mod(t);
-	      a = t;
-	    }
-	    return prod.div(a).abs();
-	  }
-	}
-
-	/**
-	 * Calculate lcm for two numbers
-	 * @param {number} a
-	 * @param {number} b
-	 * @returns {number} Returns the least common multiple of a and b
-	 * @private
-	 */
-	function _lcm (a, b) {
-	  if (!isInteger(a) || !isInteger(b)) {
-	    throw new Error('Parameters in function lcm must be integer numbers');
-	  }
-
-	  if (a == 0 || b == 0) {
-	    return 0;
-	  }
-
-	  // http://en.wikipedia.org/wiki/Euclidean_algorithm
-	  // evaluate lcm here inline to reduce overhead
-	  var t;
-	  var prod = a * b;
-	  while (b != 0) {
-	    t = b;
-	    b = a % t;
-	    a = t;
-	  }
-	  return Math.abs(prod / a);
-	}
-
-	exports.name = 'lcm';
-	exports.factory = factory;
-
-
-/***/ },
-/* 107 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	var scatter = __webpack_require__(108);
-	var DimensionError = __webpack_require__(22);
-
-	function factory (type, config, load, typed) {
-
-	  var equalScalar = load(__webpack_require__(33));
-
-	  var SparseMatrix = type.SparseMatrix;
-
-	  /**
-	   * Iterates over SparseMatrix A and SparseMatrix B nonzero items and invokes the callback function f(Aij, Bij). 
-	   * Callback function invoked (Anz U Bnz) times, where Anz and Bnz are the nonzero elements in both matrices.
-	   *
-	   *
-	   *          ┌  f(Aij, Bij)  ; A(i,j) !== 0 && B(i,j) !== 0
-	   * C(i,j) = ┤  
-	   *          └  0            ; otherwise
-	   *
-	   *
-	   * @param {Matrix}   a                 The SparseMatrix instance (A)
-	   * @param {Matrix}   b                 The SparseMatrix instance (B)
-	   * @param {Function} callback          The f(Aij,Bij) operation to invoke
-	   *
-	   * @return {Matrix}                    SparseMatrix (C)
-	   *
-	   * see https://github.com/josdejong/mathjs/pull/346#issuecomment-97620294
-	   */
-	  var algorithm06 = function (a, b, callback) {
-	    // sparse matrix arrays
-	    var avalues = a._values;
-	    var asize = a._size;
-	    var adt = a._datatype;
-	    // sparse matrix arrays
-	    var bvalues = b._values;
-	    var bsize = b._size;
-	    var bdt = b._datatype;
-
-	    // validate dimensions
-	    if (asize.length !== bsize.length)
-	      throw new DimensionError(asize.length, bsize.length);
-
-	    // check rows & columns
-	    if (asize[0] !== bsize[0] || asize[1] !== bsize[1])
-	      throw new RangeError('Dimension mismatch. Matrix A (' + asize + ') must match Matrix B (' + bsize + ')');
-
-	    // rows & columns
-	    var rows = asize[0];
-	    var columns = asize[1];
-
-	    // datatype
-	    var dt;
-	    // equal signature to use
-	    var eq = equalScalar;
-	    // zero value
-	    var zero = 0;
-	    // callback signature to use
-	    var cf = callback;
-
-	    // process data types
-	    if (typeof adt === 'string' && adt === bdt) {
-	      // datatype
-	      dt = adt;
-	      // find signature that matches (dt, dt)
-	      eq = typed.find(equalScalar, [dt, dt]);
-	      // convert 0 to the same datatype
-	      zero = typed.convert(0, dt);
-	      // callback
-	      cf = typed.find(callback, [dt, dt]);
-	    }
-
-	    // result arrays
-	    var cvalues = avalues && bvalues ? [] : undefined;
-	    var cindex = [];
-	    var cptr = [];
-	    // matrix
-	    var c = new SparseMatrix({
-	      values: cvalues,
-	      index: cindex,
-	      ptr: cptr,
-	      size: [rows, columns],
-	      datatype: dt
-	    });
-
-	    // workspaces
-	    var x = cvalues ? [] : undefined;
-	    // marks indicating we have a value in x for a given column
-	    var w = [];
-	    // marks indicating value in a given row has been updated
-	    var u = [];
-
-	    // loop columns
-	    for (var j = 0; j < columns; j++) {
-	      // update cptr
-	      cptr[j] = cindex.length;
-	      // columns mark
-	      var mark = j + 1;
-	      // scatter the values of A(:,j) into workspace
-	      scatter(a, j, w, x, u, mark, c, cf);
-	      // scatter the values of B(:,j) into workspace
-	      scatter(b, j, w, x, u, mark, c, cf);
-	      // check we need to process values (non pattern matrix)
-	      if (x) {
-	        // initialize first index in j
-	        var k = cptr[j];
-	        // loop index in j
-	        while (k < cindex.length) {
-	          // row
-	          var i = cindex[k];
-	          // check function was invoked on current row (Aij !=0 && Bij != 0)
-	          if (u[i] === mark) {
-	            // value @ i
-	            var v = x[i];
-	            // check for zero value
-	            if (!eq(v, zero)) {
-	              // push value
-	              cvalues.push(v);
-	              // increment pointer
-	              k++;
-	            }
-	            else {
-	              // remove value @ i, do not increment pointer
-	              cindex.splice(k, 1);
-	            }
-	          }
-	          else {
-	            // remove value @ i, do not increment pointer
-	            cindex.splice(k, 1);
-	          }
-	        }
-	      }
-	      else {
-	        // initialize first index in j
-	        var p = cptr[j];
-	        // loop index in j
-	        while (p < cindex.length) {
-	          // row
-	          var r = cindex[p];
-	          // check function was invoked on current row (Aij !=0 && Bij != 0)
-	          if (u[r] !== mark) {
-	            // remove value @ i, do not increment pointer
-	            cindex.splice(p, 1);
-	          }
-	          else {
-	            // increment pointer
-	            p++;
-	          }
-	        }
-	      }
-	    }
-	    // update cptr
-	    cptr[columns] = cindex.length;
-
-	    // return sparse matrix
-	    return c;
-	  };
-	  
-	  return algorithm06;
-	}
-
-	exports.name = 'algorithm06';
-	exports.factory = factory;
-
-
-/***/ },
-/* 108 */
-/***/ function(module, exports) {
-
-	'use strict';
-
-	module.exports = function scatter(a, j, w, x, u, mark, c, f, inverse, update, value) {
-	  // a arrays
-	  var avalues = a._values;
-	  var aindex = a._index;
-	  var aptr = a._ptr;
-	  // c arrays
-	  var cindex = c._index;
-
-	  // vars
-	  var k, k0, k1, i;
-
-	  // check we need to process values (pattern matrix)
-	  if (x) {
-	    // values in j
-	    for (k0 = aptr[j], k1 = aptr[j + 1], k = k0; k < k1; k++) {
-	      // row
-	      i = aindex[k];
-	      // check value exists in current j
-	      if (w[i] !== mark) {
-	        // i is new entry in j
-	        w[i] = mark;
-	        // add i to pattern of C
-	        cindex.push(i);
-	        // x(i) = A, check we need to call function this time
-	        if (update) {
-	          // copy value to workspace calling callback function
-	          x[i] = inverse ? f(avalues[k], value) : f(value, avalues[k]);
-	          // function was called on current row
-	          u[i] = mark;
-	        }
-	        else {
-	          // copy value to workspace
-	          x[i] = avalues[k];
-	        }
-	      }
-	      else {
-	        // i exists in C already
-	        x[i] = inverse ? f(avalues[k], x[i]) : f(x[i], avalues[k]);
-	        // function was called on current row
-	        u[i] = mark;
-	      }
-	    }
-	  }
-	  else {
-	    // values in j
-	    for (k0 = aptr[j], k1 = aptr[j + 1], k = k0; k < k1; k++) {
-	      // row
-	      i = aindex[k];
-	      // check value exists in current j
-	      if (w[i] !== mark) {
-	        // i is new entry in j
-	        w[i] = mark;
-	        // add i to pattern of C
-	        cindex.push(i);
-	      }
-	      else {
-	        // indicate function was called on current row
-	        u[i] = mark;
-	      }
-	    }
-	  }
-	};
-
-
-/***/ },
-/* 109 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	var deepMap = __webpack_require__(29);
-
-	function factory (type, config, load, typed) {
-	  /**
-	   * Calculate the 10-base of a value. This is the same as calculating `log(x, 10)`.
-	   *
-	   * For matrices, the function is evaluated element wise.
-	   *
-	   * Syntax:
-	   *
-	   *    math.log10(x)
-	   *
-	   * Examples:
-	   *
-	   *    math.log10(0.00001);            // returns -5
-	   *    math.log10(10000);              // returns 4
-	   *    math.log(10000) / math.log(10); // returns 4
-	   *    math.pow(10, 4);                // returns 10000
-	   *
-	   * See also:
-	   *
-	   *    exp, log
-	   *
-	   * @param {number | BigNumber | Complex | Array | Matrix} x
-	   *            Value for which to calculate the logarithm.
-	   * @return {number | BigNumber | Complex | Array | Matrix}
-	   *            Returns the 10-base logarithm of `x`
-	   */
-	  var log10 = typed('log10', {
-	    'number': function (x) {
-	      if (x >= 0 || config.predictable) {
-	        return Math.log(x) / Math.LN10;
-	      }
-	      else {
-	        // negative value -> complex value computation
-	        return log10(new type.Complex(x, 0));
-	      }
-	    },
-
-	    'Complex': _log10Complex,
-
-	    'BigNumber': function (x) {
-	      if (!x.isNegative() || config.predictable) {
-	        return x.log();
-	      }
-	      else {
-	        // downgrade to number, return Complex valued result
-	        return _log10Complex(new type.Complex(x.toNumber(), 0));
-	      }
-	    },
-
-	    'Array | Matrix': function (x) {
-	      return deepMap(x, log10);
-	    }
-	  });
-
-	  log10.toTex = '\\log_{10}\\left(${args[0]}\\right)';
-
-	  return log10;
-
-	  /**
-	   * Calculate log10 for a complex value
-	   * @param {Complex} x
-	   * @returns {Complex}
-	   * @private
-	   */
-	  function _log10Complex(x) {
-	    return new type.Complex (
-	        Math.log(Math.sqrt(x.re * x.re + x.im * x.im)) / Math.LN10,
-	        Math.atan2(x.im, x.re) / Math.LN10
-	    );
-	  }
-	}
-
-	exports.name = 'log10';
-	exports.factory = factory;
-
-
-
-/***/ },
-/* 110 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	function factory (type, config, load, typed) {
-
-	  var matrix = load(__webpack_require__(23));
-	  var latex = __webpack_require__(26);
-
-	  var algorithm02 = load(__webpack_require__(96));
-	  var algorithm03 = load(__webpack_require__(31));
-	  var algorithm05 = load(__webpack_require__(32));
-	  var algorithm11 = load(__webpack_require__(42));
-	  var algorithm12 = load(__webpack_require__(65));
-	  var algorithm13 = load(__webpack_require__(35));
-	  var algorithm14 = load(__webpack_require__(39));
-	  
-	  /**
-	   * Calculates the modulus, the remainder of an integer division.
-	   *
-	   * For matrices, the function is evaluated element wise.
-	   *
-	   * The modulus is defined as:
-	   *
-	   *     x - y * floor(x / y)
-	   *
-	   * See http://en.wikipedia.org/wiki/Modulo_operation.
-	   *
-	   * Syntax:
-	   *
-	   *    math.mod(x, y)
-	   *
-	   * Examples:
-	   *
-	   *    math.mod(8, 3);                // returns 2
-	   *    math.mod(11, 2);               // returns 1
-	   *
-	   *    function isOdd(x) {
-	   *      return math.mod(x, 2) != 0;
-	   *    }
-	   *
-	   *    isOdd(2);                      // returns false
-	   *    isOdd(3);                      // returns true
-	   *
-	   * See also:
-	   *
-	   *    divide
-	   *
-	   * @param  {number | BigNumber | Fraction | Array | Matrix} x Dividend
-	   * @param  {number | BigNumber | Fraction | Array | Matrix} y Divisor
-	   * @return {number | BigNumber | Fraction | Array | Matrix} Returns the remainder of `x` divided by `y`.
-	   */
-	  var mod = typed('mod', {
-
-	    'number, number': _mod,
-
-	    'BigNumber, BigNumber': function (x, y) {
-	      return y.isZero() ? x : x.mod(y);
-	    },
-
-	    'Fraction, Fraction': function (x, y) {
-	      return x.mod(y);
-	    },
-
-	    'Matrix, Matrix': function (x, y) {
-	      // result
-	      var c;
-
-	      // process matrix storage
-	      switch (x.storage()) {
-	        case 'sparse':
-	          switch (y.storage()) {
-	            case 'sparse':
-	              // mod(sparse, sparse)
-	              c = algorithm05(x, y, mod, false);
-	              break;
-	            default:
-	              // mod(sparse, dense)
-	              c = algorithm02(y, x, mod, true);
-	              break;
-	          }
-	          break;
-	        default:
-	          switch (y.storage()) {
-	            case 'sparse':
-	              // mod(dense, sparse)
-	              c = algorithm03(x, y, mod, false);
-	              break;
-	            default:
-	              // mod(dense, dense)
-	              c = algorithm13(x, y, mod);
-	              break;
-	          }
-	          break;
-	      }
-	      return c;
-	    },
-	    
-	    'Array, Array': function (x, y) {
-	      // use matrix implementation
-	      return mod(matrix(x), matrix(y)).valueOf();
-	    },
-
-	    'Array, Matrix': function (x, y) {
-	      // use matrix implementation
-	      return mod(matrix(x), y);
-	    },
-
-	    'Matrix, Array': function (x, y) {
-	      // use matrix implementation
-	      return mod(x, matrix(y));
-	    },
-
-	    'Matrix, any': function (x, y) {
-	      // result
-	      var c;
-	      // check storage format
-	      switch (x.storage()) {
-	        case 'sparse':
-	          c = algorithm11(x, y, mod, false);
-	          break;
-	        default:
-	          c = algorithm14(x, y, mod, false);
-	          break;
-	      }
-	      return c;
-	    },
-
-	    'any, Matrix': function (x, y) {
-	      // result
-	      var c;
-	      // check storage format
-	      switch (y.storage()) {
-	        case 'sparse':
-	          c = algorithm12(y, x, mod, true);
-	          break;
-	        default:
-	          c = algorithm14(y, x, mod, true);
-	          break;
-	      }
-	      return c;
-	    },
-
-	    'Array, any': function (x, y) {
-	      // use matrix implementation
-	      return algorithm14(matrix(x), y, mod, false).valueOf();
-	    },
-
-	    'any, Array': function (x, y) {
-	      // use matrix implementation
-	      return algorithm14(matrix(y), x, mod, true).valueOf();
-	    }
-	  });
-
-	  mod.toTex = '\\left(${args[0]}' + latex.operators['mod'] + '${args[1]}\\right)';
-
-	  return mod;
-
-	  /**
-	   * Calculate the modulus of two numbers
-	   * @param {number} x
-	   * @param {number} y
-	   * @returns {number} res
-	   * @private
-	   */
-	  function _mod(x, y) {
-	    if (y > 0) {
-	      // We don't use JavaScript's % operator here as this doesn't work
-	      // correctly for x < 0 and x == 0
-	      // see http://en.wikipedia.org/wiki/Modulo_operation
-	      return x - y * Math.floor(x / y);
-	    }
-	    else if (y === 0) {
-	      return x;
-	    }
-	    else { // y < 0
-	      // TODO: implement mod for a negative divisor
-	      throw new Error('Cannot calculate mod for a negative divisor');
-	    }
-	  }
-	}
-
-	exports.name = 'mod';
-	exports.factory = factory;
-
-
-/***/ },
-/* 111 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	function factory (type, config, load, typed) {
-	  
-	  var abs         = load(__webpack_require__(63));
-	  var add         = load(__webpack_require__(44));
-	  var pow         = load(__webpack_require__(100));
-	  var sqrt        = load(__webpack_require__(112));
-	  var multiply    = load(__webpack_require__(40));
-	  var equalScalar = load(__webpack_require__(33));
-	  var larger      = load(__webpack_require__(64));
-	  var smaller     = load(__webpack_require__(113));
-	  var matrix      = load(__webpack_require__(23));
-	  var trace       = load(__webpack_require__(58));
-	  var transpose   = load(__webpack_require__(59));
-	  
-	  var complexAbs = typed.find(abs, ['Complex']);
-
-	  /**
-	   * Calculate the norm of a number, vector or matrix.
-	   *
-	   * The second parameter p is optional. If not provided, it defaults to 2.
-	   *
-	   * Syntax:
-	   *
-	   *    math.norm(x)
-	   *    math.norm(x, p)
-	   *
-	   * Examples:
-	   *
-	   *    math.abs(-3.5);                         // returns 3.5
-	   *    math.norm(-3.5);                        // returns 3.5
-	   *
-	   *    math.norm(math.complex(3, -4));         // returns 5
-	   *
-	   *    math.norm([1, 2, -3], Infinity);        // returns 3
-	   *    math.norm([1, 2, -3], -Infinity);       // returns 1
-	   *
-	   *    math.norm([3, 4], 2);                   // returns 5
-	   *
-	   *    math.norm([[1, 2], [3, 4]], 1)          // returns 6
-	   *    math.norm([[1, 2], [3, 4]], 'inf');     // returns 7
-	   *    math.norm([[1, 2], [3, 4]], 'fro');     // returns 5.477225575051661
-	   *
-	   * See also:
-	   *
-	   *    abs
-	   *
-	   * @param  {number | BigNumber | Complex | Array | Matrix} x
-	   *            Value for which to calculate the norm
-	   * @param  {number | BigNumber | string} [p=2]
-	   *            Vector space.
-	   *            Supported numbers include Infinity and -Infinity.
-	   *            Supported strings are: 'inf', '-inf', and 'fro' (The Frobenius norm)
-	   * @return {number | BigNumber} the p-norm
-	   */
-	  var norm = typed('norm', {
-	    'number': Math.abs,
-
-	    'Complex': complexAbs,
-
-	    'BigNumber': function (x) {
-	      // norm(x) = abs(x)
-	      return x.abs();
-	    },
-	    
-	    'boolean | null' : function (x) {
-	      // norm(x) = abs(x)
-	      return Math.abs(x);
-	    },
-
-	    'Array': function (x) {
-	      return _norm(matrix(x), 2);
-	    },
-	    
-	    'Matrix': function (x) {
-	      return _norm(x, 2);
-	    },
-
-	    'number | Complex | BigNumber | boolean | null, number | BigNumber | string': function (x) {
-	      // ignore second parameter, TODO: remove the option of second parameter for these types
-	      return norm(x);
-	    },
-
-	    'Array, number | BigNumber | string': function (x, p) {
-	      return _norm(matrix(x), p);
-	    },
-	    
-	    'Matrix, number | BigNumber | string': function (x, p) {
-	      return _norm(x, p);
-	    }
-	  });
-
-	  /**
-	   * Calculate the norm for an array
-	   * @param {Array} x
-	   * @param {number | string} p
-	   * @returns {number} Returns the norm
-	   * @private
-	   */
-	  function _norm (x, p) {
-	    // size
-	    var sizeX = x.size();
-	    
-	    // check if it is a vector
-	    if (sizeX.length == 1) {
-	      // check p
-	      if (p === Number.POSITIVE_INFINITY || p === 'inf') {
-	        // norm(x, Infinity) = max(abs(x))
-	        var pinf = 0;
-	        // skip zeros since abs(0) == 0
-	        x.forEach(
-	          function (value) {
-	            var v = abs(value);
-	            if (larger(v, pinf))
-	              pinf = v;
-	          },
-	          true);
-	        return pinf;
-	      }
-	      if (p === Number.NEGATIVE_INFINITY || p === '-inf') {
-	        // norm(x, -Infinity) = min(abs(x))
-	        var ninf;
-	        // skip zeros since abs(0) == 0
-	        x.forEach(
-	          function (value) {
-	            var v = abs(value);
-	            if (!ninf || smaller(v, ninf))
-	              ninf = v;
-	          },
-	          true);
-	        return ninf || 0;
-	      }
-	      if (p === 'fro') {
-	        return _norm(x, 2);
-	      }
-	      if (typeof p === 'number' && !isNaN(p)) {
-	        // check p != 0
-	        if (!equalScalar(p, 0)) {
-	          // norm(x, p) = sum(abs(xi) ^ p) ^ 1/p
-	          var n = 0;
-	          // skip zeros since abs(0) == 0
-	          x.forEach(
-	            function (value) {
-	              n = add(pow(abs(value), p), n);
-	            },
-	            true);
-	          return pow(n, 1 / p);
-	        }
-	        return Number.POSITIVE_INFINITY;
-	      }
-	      // invalid parameter value
-	      throw new Error('Unsupported parameter value');
-	    }
-	    // MxN matrix
-	    if (sizeX.length == 2) {
-	      // check p
-	      if (p === 1) {
-	        // norm(x) = the largest column sum
-	        var c = [];
-	        // result
-	        var maxc = 0;
-	        // skip zeros since abs(0) == 0
-	        x.forEach(
-	          function (value, index) {
-	            var j = index[1];
-	            var cj = add(c[j] || 0, abs(value));
-	            if (larger(cj, maxc))
-	              maxc = cj;
-	            c[j] = cj;
-	          },
-	          true);
-	        return maxc;
-	      }
-	      if (p === Number.POSITIVE_INFINITY || p === 'inf') {
-	        // norm(x) = the largest row sum
-	        var r = [];
-	        // result
-	        var maxr = 0;
-	        // skip zeros since abs(0) == 0
-	        x.forEach(
-	          function (value, index) {
-	            var i = index[0];
-	            var ri = add(r[i] || 0, abs(value));
-	            if (larger(ri, maxr))
-	              maxr = ri;
-	            r[i] = ri;
-	          },
-	          true);
-	        return maxr;
-	      }
-	      if (p === 'fro') {
-	        // norm(x) = sqrt(sum(diag(x'x)))
-	        return sqrt(trace(multiply(transpose(x), x)));
-	      }
-	      if (p === 2) {
-	        // not implemented
-	        throw new Error('Unsupported parameter value, missing implementation of matrix singular value decomposition');
-	      }
-	      // invalid parameter value
-	      throw new Error('Unsupported parameter value');
-	    }
-	  }
-
-	  norm.toTex = {
-	    1: '\\left\\|${args[0]}\\right\\|',
-	    2: '\\mathrm{${name}}\\left(${args}\\right)'
-	  };
-
-	  return norm;
-	}
-
-	exports.name = 'norm';
-	exports.factory = factory;
-
-
-/***/ },
-/* 112 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	var deepMap = __webpack_require__(29);
-
-	function factory (type, config, load, typed) {
-	  /**
-	   * Calculate the square root of a value.
-	   *
-	   * For matrices, the function is evaluated element wise.
-	   *
-	   * Syntax:
-	   *
-	   *    math.sqrt(x)
-	   *
-	   * Examples:
-	   *
-	   *    math.sqrt(25);                // returns 5
-	   *    math.square(5);               // returns 25
-	   *    math.sqrt(-4);                // returns Complex 2i
-	   *
-	   * See also:
-	   *
-	   *    square, multiply
-	   *
-	   * @param {number | BigNumber | Complex | Array | Matrix | Unit} x
-	   *            Value for which to calculate the square root.
-	   * @return {number | BigNumber | Complex | Array | Matrix | Unit}
-	   *            Returns the square root of `x`
-	   */
-	  var sqrt = typed('sqrt', {
-	    'number': _sqrtNumber,
-
-	    'Complex': _sqrtComplex,
-
-	    'BigNumber': function (x) {
-	      if (!x.isNegative() || config.predictable) {
-	        return x.sqrt();
-	      }
-	      else {
-	        // negative value -> downgrade to number to do complex value computation
-	        return _sqrtNumber(x.toNumber());
-	      }
-	    },
-
-	    'Array | Matrix': function (x) {
-	      // deep map collection, skip zeros since sqrt(0) = 0
-	      return deepMap(x, sqrt, true);
-	    },
-
-	    'Unit': function (x) {
-	      // Someday will work for complex units when they are implemented
-	      return x.pow(0.5);
-	    }
-
-	  });
-
-	  /**
-	   * Calculate sqrt for a number
-	   * @param {number} x
-	   * @returns {number | Complex} Returns the square root of x
-	   * @private
-	   */
-	  function _sqrtNumber(x) {
-	    if (x >= 0 || config.predictable) {
-	      return Math.sqrt(x);
-	    }
-	    else {
-	      return _sqrtComplex(new type.Complex(x, 0));
-	    }
-	  }
-
-	  /**
-	   * Calculate sqrt for a complex number
-	   * @param {Complex} x
-	   * @returns {Complex} Returns the square root of x
-	   * @private
-	   */
-	  function _sqrtComplex(x) {
-	    var r = Math.sqrt(x.re * x.re + x.im * x.im);
-
-	    var re, im;
-
-	    if (x.re >= 0) {
-	      re = 0.5 * Math.sqrt(2.0 * (r + x.re));
-	    }
-	    else {
-	      re = Math.abs(x.im) / Math.sqrt(2 * (r - x.re));
-	    }
-
-	    if (x.re <= 0) {
-	      im = 0.5 * Math.sqrt(2.0 * (r - x.re));
-	    }
-	    else {
-	      im = Math.abs(x.im) / Math.sqrt(2 * (r + x.re));
-	    }
-
-	    if (x.im >= 0) {
-	      return new type.Complex(re, im);
-	    }
-	    else {
-	      return new type.Complex(re, -im);
-	    }
-	  }
-
-	  sqrt.toTex = '\\sqrt{${args[0]}}';
-
-	  return sqrt;
-	}
-
-	exports.name = 'sqrt';
-	exports.factory = factory;
-
-
-/***/ },
-/* 113 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	var nearlyEqual = __webpack_require__(8).nearlyEqual;
-
-	function factory (type, config, load, typed) {
-
-	  var matrix = load(__webpack_require__(23));
-
-	  var algorithm03 = load(__webpack_require__(31));
-	  var algorithm07 = load(__webpack_require__(66));
-	  var algorithm12 = load(__webpack_require__(65));
-	  var algorithm13 = load(__webpack_require__(35));
-	  var algorithm14 = load(__webpack_require__(39));
-
-	  var latex = __webpack_require__(26);
-
-	  /**
-	   * Test whether value x is smaller than y.
-	   *
-	   * The function returns true when x is smaller than y and the relative
-	   * difference between x and y is smaller than the configured epsilon. The
-	   * function cannot be used to compare values smaller than approximately 2.22e-16.
-	   *
-	   * For matrices, the function is evaluated element wise.
-	   *
-	   * Syntax:
-	   *
-	   *    math.smaller(x, y)
-	   *
-	   * Examples:
-	   *
-	   *    math.smaller(2, 3);            // returns true
-	   *    math.smaller(5, 2 * 2);        // returns false
-	   *
-	   *    var a = math.unit('5 cm');
-	   *    var b = math.unit('2 inch');
-	   *    math.smaller(a, b);            // returns true
-	   *
-	   * See also:
-	   *
-	   *    equal, unequal, smallerEq, smaller, smallerEq, compare
-	   *
-	   * @param  {number | BigNumber | Fraction | boolean | Unit | string | Array | Matrix} x First value to compare
-	   * @param  {number | BigNumber | Fraction | boolean | Unit | string | Array | Matrix} y Second value to compare
-	   * @return {boolean | Array | Matrix} Returns true when the x is smaller than y, else returns false
-	   */
-	  var smaller = typed('smaller', {
-
-	    'boolean, boolean': function (x, y) {
-	      return x < y;
-	    },
-
-	    'number, number': function (x, y) {
-	      return x < y && !nearlyEqual(x, y, config.epsilon);
-	    },
-
-	    'BigNumber, BigNumber': function (x, y) {
-	      return x.lt(y);
-	    },
-
-	    'Fraction, Fraction': function (x, y) {
-	      return x.compare(y) === -1;
-	    },
-
-	    'Complex, Complex': function (x, y) {
-	      throw new TypeError('No ordering relation is defined for complex numbers');
-	    },
-
-	    'Unit, Unit': function (x, y) {
-	      if (!x.equalBase(y)) {
-	        throw new Error('Cannot compare units with different base');
-	      }
-	      return x.value < y.value && !nearlyEqual(x.value, y.value, config.epsilon);
-	    },
-
-	    'string, string': function (x, y) {
-	      return x < y;
-	    },
-
-	    'Matrix, Matrix': function (x, y) {
-	      // result
-	      var c;
-
-	      // process matrix storage
-	      switch (x.storage()) {
-	        case 'sparse':
-	          switch (y.storage()) {
-	            case 'sparse':
-	              // sparse + sparse
-	              c = algorithm07(x, y, smaller);
-	              break;
-	            default:
-	              // sparse + dense
-	              c = algorithm03(y, x, smaller, true);
-	              break;
-	          }
-	          break;
-	        default:
-	          switch (y.storage()) {
-	            case 'sparse':
-	              // dense + sparse
-	              c = algorithm03(x, y, smaller, false);
-	              break;
-	            default:
-	              // dense + dense
-	              c = algorithm13(x, y, smaller);
-	              break;
-	          }
-	          break;
-	      }
-	      return c;
-	    },
-
-	    'Array, Array': function (x, y) {
-	      // use matrix implementation
-	      return smaller(matrix(x), matrix(y)).valueOf();
-	    },
-
-	    'Array, Matrix': function (x, y) {
-	      // use matrix implementation
-	      return smaller(matrix(x), y);
-	    },
-
-	    'Matrix, Array': function (x, y) {
-	      // use matrix implementation
-	      return smaller(x, matrix(y));
-	    },
-
-	    'Matrix, any': function (x, y) {
-	      // result
-	      var c;
-	      // check storage format
-	      switch (x.storage()) {
-	        case 'sparse':
-	          c = algorithm12(x, y, smaller, false);
-	          break;
-	        default:
-	          c = algorithm14(x, y, smaller, false);
-	          break;
-	      }
-	      return c;
-	    },
-
-	    'any, Matrix': function (x, y) {
-	      // result
-	      var c;
-	      // check storage format
-	      switch (y.storage()) {
-	        case 'sparse':
-	          c = algorithm12(y, x, smaller, true);
-	          break;
-	        default:
-	          c = algorithm14(y, x, smaller, true);
-	          break;
-	      }
-	      return c;
-	    },
-
-	    'Array, any': function (x, y) {
-	      // use matrix implementation
-	      return algorithm14(matrix(x), y, smaller, false).valueOf();
-	    },
-
-	    'any, Array': function (x, y) {
-	      // use matrix implementation
-	      return algorithm14(matrix(y), x, smaller, true).valueOf();
-	    }
-	  });
-
-	  smaller.toTex = '\\left(${args[0]}' + latex.operators['smaller'] + '${args[1]}\\right)';
-
-	  return smaller;
-	}
-
-	exports.name = 'smaller';
-	exports.factory = factory;
-
-
-/***/ },
-/* 114 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	function factory (type, config, load, typed) {
-
-	  var matrix = load(__webpack_require__(23));
-
-	  var algorithm01 = load(__webpack_require__(30));
-	  var algorithm02 = load(__webpack_require__(96));
-	  var algorithm06 = load(__webpack_require__(107));
-	  var algorithm11 = load(__webpack_require__(42));
-	  var algorithm13 = load(__webpack_require__(35));
-	  var algorithm14 = load(__webpack_require__(39));
-
-	  /**
-	   * Calculate the nth root of a value.
-	   * The principal nth root of a positive real number A, is the positive real
-	   * solution of the equation
-	   *
-	   *     x^root = A
-	   *
-	   * For matrices, the function is evaluated element wise.
-	   *
-	   * Syntax:
-	   *
-	   *     math.nthRoot(a)
-	   *     math.nthRoot(a, root)
-	   *
-	   * Examples:
-	   *
-	   *     math.nthRoot(9, 2);    // returns 3, as 3^2 == 9
-	   *     math.sqrt(9);          // returns 3, as 3^2 == 9
-	   *     math.nthRoot(64, 3);   // returns 4, as 4^3 == 64
-	   *
-	   * See also:
-	   *
-	   *     sqrt, pow
-	   *
-	   * @param {number | BigNumber | Array | Matrix | Complex} a
-	   *              Value for which to calculate the nth root
-	   * @param {number | BigNumber} [root=2]    The root.
-	   * @return {number | Complex | Array | Matrix} Returns the nth root of `a`
-	   */
-	  var nthRoot = typed('nthRoot', {
-	    
-	    'number': function (x) {
-	      return _nthRoot(x, 2);
-	    },
-	    'number, number': _nthRoot,
-
-	    'BigNumber': function (x) {
-	      return _bigNthRoot(x, new type.BigNumber(2));
-	    },
-	    'Complex' : function(x) {
-	      return _nthComplexRoot(x, 2);
-	    }, 
-	    'Complex, number' : _nthComplexRoot,
-	    'BigNumber, BigNumber': _bigNthRoot,
-
-	    'Array | Matrix': function (x) {
-	      return nthRoot(x, 2);
-	    },
-	    
-	    'Matrix, Matrix': function (x, y) {
-	      // result
-	      var c;
-
-	      // process matrix storage
-	      switch (x.storage()) {
-	        case 'sparse':
-	          switch (y.storage()) {
-	            case 'sparse':
-	              // density must be one (no zeros in matrix)
-	              if (y.density() === 1) {
-	                // sparse + sparse
-	                c = algorithm06(x, y, nthRoot);
-	              }
-	              else {
-	                // throw exception
-	                throw new Error('Root must be non-zero');
-	              }
-	              break;
-	            default:
-	              // sparse + dense
-	              c = algorithm02(y, x, nthRoot, true);
-	              break;
-	          }
-	          break;
-	        default:
-	          switch (y.storage()) {
-	            case 'sparse':
-	              // density must be one (no zeros in matrix)
-	              if (y.density() === 1) {
-	                // dense + sparse
-	                c = algorithm01(x, y, nthRoot, false);
-	              }
-	              else {
-	                // throw exception
-	                throw new Error('Root must be non-zero');
-	              }
-	              break;
-	            default:
-	              // dense + dense
-	              c = algorithm13(x, y, nthRoot);
-	              break;
-	          }
-	          break;
-	      }
-	      return c;
-	    },
-
-	    'Array, Array': function (x, y) {
-	      // use matrix implementation
-	      return nthRoot(matrix(x), matrix(y)).valueOf();
-	    },
-
-	    'Array, Matrix': function (x, y) {
-	      // use matrix implementation
-	      return nthRoot(matrix(x), y);
-	    },
-
-	    'Matrix, Array': function (x, y) {
-	      // use matrix implementation
-	      return nthRoot(x, matrix(y));
-	    },
-	    
-	    'Matrix, number | BigNumber': function (x, y) {
-	      // result
-	      var c;
-	      // check storage format
-	      switch (x.storage()) {
-	        case 'sparse':
-	          c = algorithm11(x, y, nthRoot, false);
-	          break;
-	        default:
-	          c = algorithm14(x, y, nthRoot, false);
-	          break;
-	      }
-	      return c;
-	    },
-
-	    'number | BigNumber, Matrix': function (x, y) {
-	      // result
-	      var c;
-	      // check storage format
-	      switch (y.storage()) {
-	        case 'sparse':
-	          // density must be one (no zeros in matrix)
-	          if (y.density() === 1) {
-	            // sparse - scalar
-	            c = algorithm11(y, x, nthRoot, true);
-	          }
-	          else {
-	            // throw exception
-	            throw new Error('Root must be non-zero');
-	          }
-	          break;
-	        default:
-	          c = algorithm14(y, x, nthRoot, true);
-	          break;
-	      }
-	      return c;
-	    },
-
-	    'Array, number | BigNumber': function (x, y) {
-	      // use matrix implementation
-	      return nthRoot(matrix(x), y).valueOf();
-	    },
-
-	    'number | BigNumber, Array': function (x, y) {
-	      // use matrix implementation
-	      return nthRoot(x, matrix(y)).valueOf();
-	    }
-	  });
-
-	  nthRoot.toTex = '\\sqrt[${args[1]}]{${args[0]}}';
-
-	  return nthRoot;
-
-	  /**
-	   * Calculate the nth root of a for BigNumbers, solve x^root == a
-	   * http://rosettacode.org/wiki/Nth_root#JavaScript
-	   * @param {BigNumber} a
-	   * @param {BigNumber} root
-	   * @private
-	   */
-	  function _bigNthRoot(a, root) {
-	    var zero = new type.BigNumber(0);
-	    var one = new type.BigNumber(1);
-	    var inv = root.isNegative();
-	    if (inv) root = root.negated();
-
-	    if (root.isZero()) throw new Error('Root must be non-zero');
-	    if (a.isNegative() && !root.abs().mod(2).equals(1)) throw new Error('Root must be odd when a is negative.');
-
-	    // edge cases zero and infinity
-	    if (a.isZero()) return zero;
-	    if (!a.isFinite())
-	    {
-	      return inv ? zero : a;
-	    }
-
-	    var x = one; // Initial guess
-	    var i = 0;
-	    var iMax = 10000;
-	    do {
-	      var xPrev = x;
-	      var delta = a.div(x.pow(root.minus(1))).minus(x).div(root);
-	      x = x.plus(delta);
-	      i++;
-	    }
-	    while (!x.equals(xPrev) && i < iMax);
-
-	    if (!x.equals(xPrev)) {
-	      throw new Error('Function nthRoot failed to converge');
-	    }
-
-	    return inv ? one.div(x) : x;
-	  }
-	}
-
-	/**
-	 * Calculate the nth root of a, solve x^root == a
-	 * http://rosettacode.org/wiki/Nth_root#JavaScript
-	 * @param {number} a
-	 * @param {number} root
-	 * @private
-	 */
-	function _nthRoot(a, root) {
-	  var inv = root < 0;
-	  if (inv) root = -root;
-
-	  if (root === 0) throw new Error('Root must be non-zero');
-	  if (a < 0 && (Math.abs(root) % 2 != 1)) throw new Error('Root must be odd when a is negative.');
-
-	  // edge cases zero and infinity
-	  if (a == 0) return 0;
-	  if (!Number.isFinite(a)) {
-	    return inv ? 0 : a;
-	  }
-
-	  var x = 1; // Initial guess
-	  var xPrev = 1;
-	  var i = 0;
-	  var iMax = 10000;
-	  do {
-	    var delta = (a / Math.pow(x, root - 1) - x) / root;
-	    xPrev = x;
-	    x = x + delta;
-	    i++;
-	  }
-	  while (xPrev !== x && i < iMax);
-
-	  if (xPrev !== x) {
-	    throw new Error('Function nthRoot failed to converge');
-	  }
-
-	  return inv ? 1 / x : x;
-	}
-
-	/**
-	 * Calculate the nth root of a Complex Number a using De Moviers Theorem.
-	 * @param  {Complex} a
-	 * @param  {number} root
-	 * @return {Array} array or n Complex Roots in Polar Form.
-	 */
-	function _nthComplexRoot(a, root) {
-	  if (root < 0) throw new Error('Root must be greater than zero');
-	  if (root === 0) throw new Error('Root must be non-zero');
-	  if (root % 1 !== 0) throw new Error('Root must be an integer');  
-	  var polar = a.toPolar();
-	  var roots = [];
-	  var r = Math.pow(polar.r, 1/root);
-	  for(var k = 0; k < root; k++) {
-	    roots.push({r: r, phi: (polar.phi + 2 * Math.PI * k)/root});
-	  }
-	  return roots;
-	}
-
-	exports.name = 'nthRoot';
-	exports.factory = factory;
-
-
-/***/ },
-/* 115 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	var isInteger = __webpack_require__(8).isInteger;
-	var toFixed = __webpack_require__(8).toFixed;
-	var deepMap = __webpack_require__(29);
-
-	var NO_INT = 'Number of decimals in function round must be an integer';
-
-	function factory (type, config, load, typed) {
-	  var matrix = load(__webpack_require__(23));
-	  var equalScalar = load(__webpack_require__(33));
-	  var zeros = load(__webpack_require__(60));
-
-	  var algorithm11 = load(__webpack_require__(42));
-	  var algorithm12 = load(__webpack_require__(65));
-	  var algorithm14 = load(__webpack_require__(39));
-	  
-	  /**
-	   * Round a value towards the nearest integer.
-	   * For matrices, the function is evaluated element wise.
-	   *
-	   * Syntax:
-	   *
-	   *    math.round(x)
-	   *    math.round(x, n)
-	   *
-	   * Examples:
-	   *
-	   *    math.round(3.2);              // returns number 3
-	   *    math.round(3.8);              // returns number 4
-	   *    math.round(-4.2);             // returns number -4
-	   *    math.round(-4.7);             // returns number -5
-	   *    math.round(math.pi, 3);       // returns number 3.142
-	   *    math.round(123.45678, 2);     // returns number 123.46
-	   *
-	   *    var c = math.complex(3.2, -2.7);
-	   *    math.round(c);                // returns Complex 3 - 3i
-	   *
-	   *    math.round([3.2, 3.8, -4.7]); // returns Array [3, 4, -5]
-	   *
-	   * See also:
-	   *
-	   *    ceil, fix, floor
-	   *
-	   * @param  {number | BigNumber | Fraction | Complex | Array | Matrix} x  Number to be rounded
-	   * @param  {number | BigNumber | Array} [n=0]                            Number of decimals
-	   * @return {number | BigNumber | Fraction | Complex | Array | Matrix} Rounded value
-	   */
-	  var round = typed('round', {
-
-	    'number': Math.round,
-
-	    'number, number': function (x, n) {
-	      if (!isInteger(n))   {throw new TypeError(NO_INT);}
-	      if (n < 0 || n > 15) {throw new Error('Number of decimals in function round must be in te range of 0-15');}
-
-	      return _round(x, n);
-	    },
-
-	    'Complex': function (x) {
-	      return new type.Complex (
-	          Math.round(x.re),
-	          Math.round(x.im)
-	      );
-	    },
-
-	    'Complex, number': function (x, n) {
-	      return new type.Complex (
-	          _round(x.re, n),
-	          _round(x.im, n)
-	      );
-	    },
-
-	    'Complex, BigNumber': function (x, n) {
-	      if (!n.isInteger()) {throw new TypeError(NO_INT);}
-
-	      var _n = n.toNumber();
-	      return new type.Complex (
-	          _round(x.re, _n),
-	          _round(x.im, _n)
-	      );
-	    },
-
-	    'number, BigNumber': function (x, n) {
-	      if (!n.isInteger()) {throw new TypeError(NO_INT);}
-
-	      return new type.BigNumber(x).toDecimalPlaces(n.toNumber());
-	    },
-
-	    'BigNumber': function (x) {
-	      return x.toDecimalPlaces(0);
-	    },
-
-	    'BigNumber, BigNumber': function (x, n) {
-	      if (!n.isInteger()) {throw new TypeError(NO_INT);}
-
-	      return x.toDecimalPlaces(n.toNumber());
-	    },
-
-	    'Fraction': function (x) {
-	      return x.round();
-	    },
-	    // TODO: add support for math.round(Fraction, Fraction | number)
-
-	    'Array | Matrix': function (x) {
-	      // deep map collection, skip zeros since round(0) = 0
-	      return deepMap(x, round, true);
-	    },
-
-	    'Matrix, number | BigNumber': function (x, y) {
-	      // result
-	      var c;
-	      // check storage format
-	      switch (x.storage()) {
-	        case 'sparse':
-	          c = algorithm11(x, y, round, false);
-	          break;
-	        default:
-	          c = algorithm14(x, y, round, false);
-	          break;
-	      }
-	      return c;
-	    },
-
-	    'number | Complex | BigNumber, Matrix': function (x, y) {
-	      // check scalar is zero
-	      if (!equalScalar(x, 0)) {
-	        // result
-	        var c;
-	        // check storage format
-	        switch (y.storage()) {
-	          case 'sparse':
-	            c = algorithm12(y, x, round, true);
-	            break;
-	          default:
-	            c = algorithm14(y, x, round, true);
-	            break;
-	        }
-	        return c;
-	      }
-	      // do not execute algorithm, result will be a zero matrix
-	      return zeros(y.size(), y.storage());
-	    },
-
-	    'Array, number | BigNumber': function (x, y) {
-	      // use matrix implementation
-	      return algorithm14(matrix(x), y, round, false).valueOf();
-	    },
-
-	    'number | Complex | BigNumber, Array': function (x, y) {
-	      // use matrix implementation
-	      return algorithm14(matrix(y), x, round, true).valueOf();
-	    }
-	  });
-
-	  round.toTex = {
-	    1: '\\left\\lfloor${args[0]}\\right\\rceil',
-	    2: '\\mathrm{${name}}\\left(${args}\\right)'
-	  };
-
-	  return round;
-	}
-
-	/**
-	 * round a number to the given number of decimals, or to zero if decimals is
-	 * not provided
-	 * @param {number} value
-	 * @param {number} decimals       number of decimals, between 0 and 15 (0 by default)
-	 * @return {number} roundedValue
-	 * @private
-	 */
-	function _round (value, decimals) {
-	  return parseFloat(toFixed(value, decimals));
-	}
-
-	exports.name = 'round';
-	exports.factory = factory;
-
-
-/***/ },
-/* 116 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	var number = __webpack_require__(8);
-	var deepMap = __webpack_require__(29);
-
-	function factory (type, config, load, typed) {
-	  /**
-	   * Compute the sign of a value. The sign of a value x is:
-	   *
-	   * -  1 when x > 1
-	   * - -1 when x < 0
-	   * -  0 when x == 0
-	   *
-	   * For matrices, the function is evaluated element wise.
-	   *
-	   * Syntax:
-	   *
-	   *    math.sign(x)
-	   *
-	   * Examples:
-	   *
-	   *    math.sign(3.5);               // returns 1
-	   *    math.sign(-4.2);              // returns -1
-	   *    math.sign(0);                 // returns 0
-	   *
-	   *    math.sign([3, 5, -2, 0, 2]);  // returns [1, 1, -1, 0, 1]
-	   *
-	   * See also:
-	   *
-	   *    abs
-	   *
-	   * @param  {number | BigNumber | Fraction | Complex | Array | Matrix | Unit} x
-	   *            The number for which to determine the sign
-	   * @return {number | BigNumber | Fraction | Complex | Array | Matrix | Unit}e
-	   *            The sign of `x`
-	   */
-	  var sign = typed('sign', {
-	    'number': number.sign,
-
-	    'Complex': function (x) {
-	      var abs = Math.sqrt(x.re * x.re + x.im * x.im);
-	      return new type.Complex(x.re / abs, x.im / abs);
-	    },
-
-	    'BigNumber': function (x) {
-	      return new type.BigNumber(x.cmp(0));
-	    },
-
-	    'Fraction': function (x) {
-	      return new type.Fraction(x.s);
-	    },
-
-	    'Array | Matrix': function (x) {
-	      // deep map collection, skip zeros since sign(0) = 0
-	      return deepMap(x, sign, true);
-	    },
-
-	    'Unit': function(x) {
-	      return number.sign(x.value);
-	    }
-	  });
-
-	  sign.toTex = '\\mathrm{${name}}\\left(${args}\\right)';
-
-	  return sign;
-	}
-
-	exports.name = 'sign';
-	exports.factory = factory;
-
-
-
-/***/ },
-/* 117 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	var deepMap = __webpack_require__(29);
-
-	function factory (type, config, load, typed) {
-	  /**
-	   * Compute the square of a value, `x * x`.
-	   * For matrices, the function is evaluated element wise.
-	   *
-	   * Syntax:
-	   *
-	   *    math.square(x)
-	   *
-	   * Examples:
-	   *
-	   *    math.square(2);           // returns number 4
-	   *    math.square(3);           // returns number 9
-	   *    math.pow(3, 2);           // returns number 9
-	   *    math.multiply(3, 3);      // returns number 9
-	   *
-	   *    math.square([1, 2, 3, 4]);  // returns Array [1, 4, 9, 16]
-	   *
-	   * See also:
-	   *
-	   *    multiply, cube, sqrt, pow
-	   *
-	   * @param  {number | BigNumber | Fraction | Complex | Array | Matrix | Unit} x
-	   *            Number for which to calculate the square
-	   * @return {number | BigNumber | Fraction | Complex | Array | Matrix | Unit}
-	   *            Squared value
-	   */
-	  var square = typed('square', {
-	    'number': function (x) {
-	      return x * x;
-	    },
-
-	    'Complex': function (x) {
-	      return new type.Complex(
-	          x.re * x.re - x.im * x.im,
-	          x.re * x.im + x.im * x.re
-	      );
-	    },
-
-	    'BigNumber': function (x) {
-	      return x.times(x);
-	    },
-
-	    'Fraction': function (x) {
-	      return x.clone().mul(x);
-	    },
-
-	    'Array | Matrix': function (x) {
-	      // deep map collection, skip zeros since square(0) = 0
-	      return deepMap(x, square, true);
-	    },
-
-	    'Unit': function(x) {
-	      return x.pow(2);
-	    }
-	  });
-
-	  square.toTex = '\\left(${args[0]}\\right)^2';
-
-	  return square;
-	}
-
-	exports.name = 'square';
-	exports.factory = factory;
-
-
-/***/ },
-/* 118 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	var deepMap = __webpack_require__(29);
-
-	function factory (type, config, load, typed) {
-	  var latex = __webpack_require__(26);
-
-	  /**
-	   * Unary plus operation.
-	   * Boolean values and strings will be converted to a number, numeric values will be returned as is.
-	   *
-	   * For matrices, the function is evaluated element wise.
-	   *
-	   * Syntax:
-	   *
-	   *    math.unaryPlus(x)
-	   *
-	   * Examples:
-	   *
-	   *    math.unaryPlus(3.5);      // returns 3.5
-	   *    math.unaryPlus(1);     // returns 1
-	   *
-	   * See also:
-	   *
-	   *    unaryMinus, add, subtract
-	   *
-	   * @param  {number | BigNumber | Fraction | string | Complex | Unit | Array | Matrix} x
-	   *            Input value
-	   * @return {number | BigNumber | Fraction | Complex | Unit | Array | Matrix}
-	   *            Returns the input value when numeric, converts to a number when input is non-numeric.
-	   */
-	  var unaryPlus = typed('unaryPlus', {
-	    'number': function (x) {
-	      return x;
-	    },
-
-	    'Complex': function (x) {
-	      return x.clone();
-	    },
-
-	    'BigNumber': function (x) {
-	      return x; // bignumbers are immutable
-	    },
-
-	    'Fraction': function (x) {
-	      return x; // fractions are immutable
-	    },
-
-	    'Unit': function (x) {
-	      return x.clone();
-	    },
-
-	    'Array | Matrix': function (x) {
-	      // deep map collection, skip zeros since unaryPlus(0) = 0
-	      return deepMap(x, unaryPlus, true);
-	    },
-
-	    'boolean | string | null': function (x) {
-	      // convert to a number or bignumber
-	      return (config.number == 'bignumber') ? new type.BigNumber(+x): +x;
-	    }
-	  });
-
-	  unaryPlus.toTex = latex.operators['unaryPlus'] + '\\left(${args[0]}\\right)'
-
-	  return unaryPlus;
-	}
-
-	exports.name = 'unaryPlus';
-	exports.factory = factory;
-
-
-/***/ },
-/* 119 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	var isInteger = __webpack_require__(8).isInteger;
-
-	function factory (type, config, load, typed) {
-	  var matrix = load(__webpack_require__(23));
-
-	  /**
-	   * Calculate the extended greatest common divisor for two values.
-	   * See http://en.wikipedia.org/wiki/Extended_Euclidean_algorithm.
-	   *
-	   * Syntax:
-	   *
-	   *    math.xgcd(a, b)
-	   *
-	   * Examples:
-	   *
-	   *    math.xgcd(8, 12);             // returns [4, -1, 1]
-	   *    math.gcd(8, 12);              // returns 4
-	   *    math.xgcd(36163, 21199);      // returns [1247, -7, 12]
-	   *
-	   * See also:
-	   *
-	   *    gcd, lcm
-	   *
-	   * @param {number | BigNumber} a  An integer number
-	   * @param {number | BigNumber} b  An integer number
-	   * @return {Array}              Returns an array containing 3 integers `[div, m, n]`
-	   *                              where `div = gcd(a, b)` and `a*m + b*n = div`
-	   */
-	  var xgcd = typed('xgcd', {
-	    'number, number': _xgcd,
-	    'BigNumber, BigNumber': _xgcdBigNumber
-	    // TODO: implement support for Fraction
-	  });
-
-	  xgcd.toTex = '\\mathrm{${name}}\\left(${args}\\right)';
-
-	  return xgcd;
-
-	  /**
-	   * Calculate xgcd for two numbers
-	   * @param {number} a
-	   * @param {number} b
-	   * @return {number} result
-	   * @private
-	   */
-	  function _xgcd (a, b) {
-	    // source: http://en.wikipedia.org/wiki/Extended_Euclidean_algorithm
-	    var t, // used to swap two variables
-	        q, // quotient
-	        r, // remainder
-	        x = 0, lastx = 1,
-	        y = 1, lasty = 0;
-
-	    if (!isInteger(a) || !isInteger(b)) {
-	      throw new Error('Parameters in function xgcd must be integer numbers');
-	    }
-
-	    while (b) {
-	      q = Math.floor(a / b);
-	      r = a % b;
-
-	      t = x;
-	      x = lastx - q * x;
-	      lastx = t;
-
-	      t = y;
-	      y = lasty - q * y;
-	      lasty = t;
-
-	      a = b;
-	      b = r;
-	    }
-
-	    var res;
-	    if (a < 0) {
-	      res = [-a, -lastx, -lasty];
-	    }
-	    else {
-	      res = [a, a ? lastx : 0, lasty];
-	    }
-	    return (config.matrix === 'array') ? res : matrix(res);
-	  }
-
-	  /**
-	   * Calculate xgcd for two BigNumbers
-	   * @param {BigNumber} a
-	   * @param {BigNumber} b
-	   * @return {BigNumber[]} result
-	   * @private
-	   */
-	  function _xgcdBigNumber(a, b) {
-	    // source: http://en.wikipedia.org/wiki/Extended_Euclidean_algorithm
-	    var t, // used to swap two variables
-	        q, // quotient
-	        r, // remainder
-	        zero = new type.BigNumber(0),
-	        x = new type.BigNumber(0), lastx = new type.BigNumber(1),
-	        y = new type.BigNumber(1), lasty = new type.BigNumber(0);
-
-	    if (!a.isInt() || !b.isInt()) {
-	      throw new Error('Parameters in function xgcd must be integer numbers');
-	    }
-
-	    while (!b.isZero()) {
-	      q = a.div(b).floor();
-	      r = a.mod(b);
-
-	      t = x;
-	      x = lastx.minus(q.times(x));
-	      lastx = t;
-
-	      t = y;
-	      y = lasty.minus(q.times(y));
-	      lasty = t;
-
-	      a = b;
-	      b = r;
-	    }
-
-	    var res;
-	    if (a.lt(zero)) {
-	      res = [a.neg(), lastx.neg(), lasty.neg()];
-	    }
-	    else {
-	      res = [a, !a.isZero() ? lastx : 0, lasty];
-	    }
-	    return (config.matrix === 'array') ? res : matrix(res);
-	  }
-	}
-
-	exports.name = 'xgcd';
-	exports.factory = factory;
-
-
-/***/ },
-/* 120 */
-/***/ function(module, exports, __webpack_require__) {
-
-	module.exports = [
-	  __webpack_require__(121),
-	  __webpack_require__(125),
-	  __webpack_require__(126),
-	  __webpack_require__(128),
-	  __webpack_require__(130),
-	  __webpack_require__(133),
-	  __webpack_require__(135)
-	];
-
-
-/***/ },
-/* 121 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	var isInteger = __webpack_require__(8).isInteger;
-	var bigBitAnd = __webpack_require__(122);
-
-	function factory (type, config, load, typed) {
-	  var latex = __webpack_require__(26);
-
-	  var matrix = load(__webpack_require__(23));
-
-	  var algorithm02 = load(__webpack_require__(96));
-	  var algorithm06 = load(__webpack_require__(107));
-	  var algorithm11 = load(__webpack_require__(42));
-	  var algorithm13 = load(__webpack_require__(35));
-	  var algorithm14 = load(__webpack_require__(39));
-	  
-	  /**
-	   * Bitwise AND two values, `x & y`.
-	   * For matrices, the function is evaluated element wise.
-	   *
-	   * Syntax:
-	   *
-	   *    math.bitAnd(x, y)
-	   *
-	   * Examples:
-	   *
-	   *    math.bitAnd(53, 131);               // returns number 1
-	   *
-	   *    math.bitAnd([1, 12, 31], 42);       // returns Array [0, 8, 10]
-	   *
-	   * See also:
-	   *
-	   *    bitNot, bitOr, bitXor, leftShift, rightArithShift, rightLogShift
-	   *
-	   * @param  {number | BigNumber | Array | Matrix} x First value to and
-	   * @param  {number | BigNumber | Array | Matrix} y Second value to and
-	   * @return {number | BigNumber | Array | Matrix} AND of `x` and `y`
-	   */
-	  var bitAnd = typed('bitAnd', {
-
-	    'number, number': function (x, y) {
-	      if (!isInteger(x) || !isInteger(y)) {
-	        throw new Error('Integers expected in function bitAnd');
-	      }
-
-	      return x & y;
-	    },
-
-	    'BigNumber, BigNumber': bigBitAnd,
-
-	    'Matrix, Matrix': function (x, y) {
-	      // result
-	      var c;
-
-	      // process matrix storage
-	      switch (x.storage()) {
-	        case 'sparse':
-	          switch (y.storage()) {
-	            case 'sparse':
-	              // sparse & sparse
-	              c = algorithm06(x, y, bitAnd, false);
-	              break;
-	            default:
-	              // sparse & dense
-	              c = algorithm02(y, x, bitAnd, true);
-	              break;
-	          }
-	          break;
-	        default:
-	          switch (y.storage()) {
-	            case 'sparse':
-	              // dense & sparse
-	              c = algorithm02(x, y, bitAnd, false);
-	              break;
-	            default:
-	              // dense & dense
-	              c = algorithm13(x, y, bitAnd);
-	              break;
-	          }
-	          break;
-	      }
-	      return c;
-	    },
-	    
-	    'Array, Array': function (x, y) {
-	      // use matrix implementation
-	      return bitAnd(matrix(x), matrix(y)).valueOf();
-	    },
-
-	    'Array, Matrix': function (x, y) {
-	      // use matrix implementation
-	      return bitAnd(matrix(x), y);
-	    },
-
-	    'Matrix, Array': function (x, y) {
-	      // use matrix implementation
-	      return bitAnd(x, matrix(y));
-	    },
-	    
-	    'Matrix, any': function (x, y) {
-	      // result
-	      var c;
-	      // check storage format
-	      switch (x.storage()) {
-	        case 'sparse':
-	          c = algorithm11(x, y, bitAnd, false);
-	          break;
-	        default:
-	          c = algorithm14(x, y, bitAnd, false);
-	          break;
-	      }
-	      return c;
-	    },
-
-	    'any, Matrix': function (x, y) {
-	      // result
-	      var c;
-	      // check storage format
-	      switch (y.storage()) {
-	        case 'sparse':
-	          c = algorithm11(y, x, bitAnd, true);
-	          break;
-	        default:
-	          c = algorithm14(y, x, bitAnd, true);
-	          break;
-	      }
-	      return c;
-	    },
-
-	    'Array, any': function (x, y) {
-	      // use matrix implementation
-	      return algorithm14(matrix(x), y, bitAnd, false).valueOf();
-	    },
-
-	    'any, Array': function (x, y) {
-	      // use matrix implementation
-	      return algorithm14(matrix(y), x, bitAnd, true).valueOf();
-	    }
-	  });
-
-	  bitAnd.toTex = '\\left(${args[0]}' + latex.operators['bitAnd'] + '${args[1]}\\right)';
-
-	  return bitAnd;
-	}
-
-	exports.name = 'bitAnd';
-	exports.factory = factory;
-
-
-/***/ },
-/* 122 */
-/***/ function(module, exports, __webpack_require__) {
-
-	var bitwise = __webpack_require__(123);
-
-	/**
-	 * Bitwise and for Bignumbers
-	 *
-	 * Special Cases:
-	 *   N &  n =  N
-	 *   n &  0 =  0
-	 *   n & -1 =  n
-	 *   n &  n =  n
-	 *   I &  I =  I
-	 *  -I & -I = -I
-	 *   I & -I =  0
-	 *   I &  n =  n
-	 *   I & -n =  I
-	 *  -I &  n =  0
-	 *  -I & -n = -I
-	 *
-	 * @param {BigNumber} x
-	 * @param {BigNumber} y
-	 * @return {BigNumber} Result of `x` & `y`, is fully precise
-	 * @private
-	 */
-	module.exports = function bitAnd(x, y) {
-	  if ((x.isFinite() && !x.isInteger()) || (y.isFinite() && !y.isInteger())) {
-	    throw new Error('Integers expected in function bitAnd');
-	  }
-
-	  var BigNumber = x.constructor;
-	  if (x.isNaN() || y.isNaN()) {
-	    return new BigNumber(NaN);
-	  }
-
-	  if (x.isZero() || y.eq(-1) || x.eq(y)) {
-	    return x;
-	  }
-	  if (y.isZero() || x.eq(-1)) {
-	    return y;
-	  }
-
-	  if (!x.isFinite() || !y.isFinite()) {
-	    if (!x.isFinite() && !y.isFinite()) {
-	      if (x.isNegative() == y.isNegative()) {
-	        return x;
-	      }
-	      return new BigNumber(0);
-	    }
-	    if (!x.isFinite()) {
-	      if (y.isNegative()) {
-	        return x;
-	      }
-	      if (x.isNegative()) {
-	        return new BigNumber(0);
-	      }
-	      return y;
-	    }
-	    if (!y.isFinite()) {
-	      if (x.isNegative()) {
-	        return y;
-	      }
-	      if (y.isNegative()) {
-	        return new BigNumber(0);
-	      }
-	      return x;
-	    }
-	  }
-	  return bitwise(x, y, function (a, b) { return a & b });
-	};
-
-
-/***/ },
-/* 123 */
-/***/ function(module, exports, __webpack_require__) {
-
-	var bitNot = __webpack_require__(124);
-
-	/**
-	 * Applies bitwise function to numbers
-	 * @param {BigNumber} x
-	 * @param {BigNumber} y
-	 * @param {function (a, b)} func
-	 * @return {BigNumber}
-	 */
-	module.exports = function bitwise(x, y, func) {
-	  var BigNumber = x.constructor;
-
-	  var xBits, yBits;
-	  var xSign = +(x.s < 0);
-	  var ySign = +(y.s < 0);
-	  if (xSign) {
-	    xBits = decCoefficientToBinaryString(bitNot(x));
-	    for (var i = 0; i < xBits.length; ++i) {
-	      xBits[i] ^= 1;
-	    }
-	  } else {
-	    xBits = decCoefficientToBinaryString(x);
-	  }
-	  if (ySign) {
-	    yBits = decCoefficientToBinaryString(bitNot(y));
-	    for (var i = 0; i < yBits.length; ++i) {
-	      yBits[i] ^= 1;
-	    }
-	  } else {
-	    yBits = decCoefficientToBinaryString(y);
-	  }
-
-	  var minBits, maxBits, minSign;
-	  if (xBits.length <= yBits.length) {
-	    minBits = xBits;
-	    maxBits = yBits;
-	    minSign = xSign;
-	  } else {
-	    minBits = yBits;
-	    maxBits = xBits;
-	    minSign = ySign;
-	  }
-
-	  var shortLen = minBits.length;
-	  var longLen = maxBits.length;
-	  var expFuncVal = func(xSign, ySign) ^ 1;
-	  var outVal = new BigNumber(expFuncVal ^ 1);
-	  var twoPower = BigNumber.ONE;
-	  var two = new BigNumber(2);
-
-	  var prevPrec = BigNumber.precision;
-	  BigNumber.config({precision: 1E9});
-
-	  while (shortLen > 0) {
-	    if (func(minBits[--shortLen], maxBits[--longLen]) == expFuncVal) {
-	      outVal = outVal.plus(twoPower);
-	    }
-	    twoPower = twoPower.times(two);
-	  }
-	  while (longLen > 0) {
-	    if (func(minSign, maxBits[--longLen]) == expFuncVal) {
-	      outVal = outVal.plus(twoPower);
-	    }
-	    twoPower = twoPower.times(two);
-	  }
-
-	  BigNumber.config({precision: prevPrec});
-
-	  if (expFuncVal == 0) {
-	    outVal.s = -outVal.s;
-	  }
-	  return outVal;
-	};
-
-	/* Extracted from decimal.js, and edited to specialize. */
-	function decCoefficientToBinaryString (x) {
-	  // Convert to string
-	  var a = x.c;
-	  var r = a[0] + '';
-
-	  for (var i = 1; i < a.length; ++i) {
-	    var s = a[i] + '';
-	    for (var z = 7 - s.length; z--; ) {
-	      s = '0' + s;
-	    }
-
-	    r += s;
-	  }
-
-	  var j;
-	  for (j = r.length - 1; r.charAt(j) == '0'; --j);
-
-	  var xe = x.e;
-	  var str = r.slice(0, j + 1 || 1);
-	  var strL = str.length;
-	  if (xe > 0) {
-	    if (++xe > strL) {
-	      // Append zeros.
-	      for (xe -= strL; xe--; str += '0');
-	    } else if (xe < strL) {
-	      str = str.slice(0, xe) + '.' + str.slice(xe);
-	    }
-	  }
-
-	  // Convert from base 10 (decimal) to base 2
-	  var arr = [0];
-	  for (var i = 0; i < str.length; ) {
-	    for (var arrL = arr.length; arrL--; arr[arrL] *= 10);
-
-	    arr[0] += str.charAt(i++) << 0;  // convert to int
-	    for (var j = 0; j < arr.length; ++j) {
-	      if (arr[j] > 1) {
-	        if (arr[j + 1] == null) {
-	          arr[j + 1] = 0;
-	        }
-
-	        arr[j + 1] += arr[j] >> 1;
-	        arr[j] &= 1;
-	      }
-	    }
-	  }
-
-	  return arr.reverse();
-	}
-
-
-/***/ },
-/* 124 */
-/***/ function(module, exports) {
-
-	/**
-	 * Bitwise not
-	 * @param {BigNumber} value
-	 * @return {BigNumber} Result of ~`x`, fully precise
-	 *
-	 */
-	module.exports = function bitNot (x) {
-	  if (x.isFinite() && !x.isInteger()) {
-	    throw new Error('Integer expected in function bitNot');
-	  }
-
-	  var BigNumber = x.constructor;
-	  var prevPrec = BigNumber.precision;
-	  BigNumber.config({precision: 1E9});
-
-	  var x = x.plus(BigNumber.ONE);
-	  x.s = -x.s || null;
-
-	  BigNumber.config({precision: prevPrec});
-	  return x;
-	};
-
-
-/***/ },
-/* 125 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	var deepMap = __webpack_require__(29);
-	var bigBitNot = __webpack_require__(124);
-	var isInteger = __webpack_require__(8).isInteger;
-
-	function factory (type, config, load, typed) {
-	  var latex = __webpack_require__(26);
-
-	  /**
-	   * Bitwise NOT value, `~x`.
-	   * For matrices, the function is evaluated element wise.
-	   * For units, the function is evaluated on the best prefix base.
-	   *
-	   * Syntax:
-	   *
-	   *    math.bitNot(x)
-	   *
-	   * Examples:
-	   *
-	   *    math.bitNot(1);               // returns number -2
-	   *
-	   *    math.bitNot([2, -3, 4]);      // returns Array [-3, 2, 5]
-	   *
-	   * See also:
-	   *
-	   *    bitAnd, bitOr, bitXor, leftShift, rightArithShift, rightLogShift
-	   *
-	   * @param  {number | BigNumber | Array | Matrix} x Value to not
-	   * @return {number | BigNumber | Array | Matrix} NOT of `x`
-	   */
-	  var bitNot = typed('bitNot', {
-	    'number': function (x) {
-	      if (!isInteger(x)) {
-	        throw new Error('Integer expected in function bitNot');
-	      }
-
-	      return ~x;
-	    },
-
-	    'BigNumber': bigBitNot,
-
-	    'Array | Matrix': function (x) {
-	      return deepMap(x, bitNot);
-	    }
-	  });
-
-	  bitNot.toTex = latex.operators['bitNot'] + '\\left(${args[0]}\\right)';
-
-	  return bitNot;
-	}
-
-	exports.name = 'bitNot';
-	exports.factory = factory;
-
-
-/***/ },
-/* 126 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	var isInteger = __webpack_require__(8).isInteger;
-	var bigBitOr = __webpack_require__(127);
-
-	function factory (type, config, load, typed) {
-	  var latex = __webpack_require__(26);
-
-	  var matrix = load(__webpack_require__(23));
-
-	  var algorithm01 = load(__webpack_require__(30));
-	  var algorithm04 = load(__webpack_require__(45));
-	  var algorithm10 = load(__webpack_require__(34));
-	  var algorithm13 = load(__webpack_require__(35));
-	  var algorithm14 = load(__webpack_require__(39));
-	  
-	  /**
-	   * Bitwise OR two values, `x | y`.
-	   * For matrices, the function is evaluated element wise.
-	   * For units, the function is evaluated on the lowest print base.
-	   *
-	   * Syntax:
-	   *
-	   *    math.bitOr(x, y)
-	   *
-	   * Examples:
-	   *
-	   *    math.bitOr(1, 2);               // returns number 3
-	   *
-	   *    math.bitOr([1, 2, 3], 4);       // returns Array [5, 6, 7]
-	   *
-	   * See also:
-	   *
-	   *    bitAnd, bitNot, bitXor, leftShift, rightArithShift, rightLogShift
-	   *
-	   * @param  {number | BigNumber | Array | Matrix} x First value to or
-	   * @param  {number | BigNumber | Array | Matrix} y Second value to or
-	   * @return {number | BigNumber | Array | Matrix} OR of `x` and `y`
-	   */
-	  var bitOr = typed('bitOr', {
-
-	    'number, number': function (x, y) {
-	      if (!isInteger(x) || !isInteger(y)) {
-	        throw new Error('Integers expected in function bitOr');
-	      }
-
-	      return x | y;
-	    },
-
-	    'BigNumber, BigNumber': bigBitOr,
-
-	    'Matrix, Matrix': function (x, y) {
-	      // result
-	      var c;
-
-	      // process matrix storage
-	      switch (x.storage()) {
-	        case 'sparse':
-	          switch (y.storage()) {
-	            case 'sparse':
-	              // sparse + sparse
-	              c = algorithm04(x, y, bitOr);
-	              break;
-	            default:
-	              // sparse + dense
-	              c = algorithm01(y, x, bitOr, true);
-	              break;
-	          }
-	          break;
-	        default:
-	          switch (y.storage()) {
-	            case 'sparse':
-	              // dense + sparse
-	              c = algorithm01(x, y, bitOr, false);
-	              break;
-	            default:
-	              c = algorithm13(x, y, bitOr);
-	              break;
-	          }
-	          break;
-	      }
-	      return c;
-	    },
-
-	    'Array, Array': function (x, y) {
-	      // use matrix implementation
-	      return bitOr(matrix(x), matrix(y)).valueOf();
-	    },
-
-	    'Array, Matrix': function (x, y) {
-	      // use matrix implementation
-	      return bitOr(matrix(x), y);
-	    },
-
-	    'Matrix, Array': function (x, y) {
-	      // use matrix implementation
-	      return bitOr(x, matrix(y));
-	    },
-
-	    'Matrix, any': function (x, y) {
-	      // result
-	      var c;
-	      // check storage format
-	      switch (x.storage()) {
-	        case 'sparse':
-	          c = algorithm10(x, y, bitOr, false);
-	          break;
-	        default:
-	          c = algorithm14(x, y, bitOr, false);
-	          break;
-	      }
-	      return c;
-	    },
-
-	    'any, Matrix': function (x, y) {
-	      // result
-	      var c;
-	      // check storage format
-	      switch (y.storage()) {
-	        case 'sparse':
-	          c = algorithm10(y, x, bitOr, true);
-	          break;
-	        default:
-	          c = algorithm14(y, x, bitOr, true);
-	          break;
-	      }
-	      return c;
-	    },
-
-	    'Array, any': function (x, y) {
-	      // use matrix implementation
-	      return algorithm14(matrix(x), y, bitOr, false).valueOf();
-	    },
-
-	    'any, Array': function (x, y) {
-	      // use matrix implementation
-	      return algorithm14(matrix(y), x, bitOr, true).valueOf();
-	    }
-	  });
-
-	  bitOr.toTex = '\\left(${args[0]}' + latex.operators['bitOr'] + '${args[1]}\\right)';
-
-	  return bitOr;
-	}
-
-	exports.name = 'bitOr';
-	exports.factory = factory;
-
-
-/***/ },
-/* 127 */
-/***/ function(module, exports, __webpack_require__) {
-
-	var bitwise = __webpack_require__(123);
-
-	/**
-	 * Bitwise OR for BigNumbers
-	 *
-	 * Special Cases:
-	 *   N |  n =  N
-	 *   n |  0 =  n
-	 *   n | -1 = -1
-	 *   n |  n =  n
-	 *   I |  I =  I
-	 *  -I | -I = -I
-	 *   I | -n = -1
-	 *   I | -I = -1
-	 *   I |  n =  I
-	 *  -I |  n = -I
-	 *  -I | -n = -n
-	 *
-	 * @param {BigNumber} x
-	 * @param {BigNumber} y
-	 * @return {BigNumber} Result of `x` | `y`, fully precise
-	 */
-	module.exports = function bitOr (x, y) {
-	  if ((x.isFinite() && !x.isInteger()) || (y.isFinite() && !y.isInteger())) {
-	    throw new Error('Integers expected in function bitOr');
-	  }
-
-	  var BigNumber = x.constructor;
-	  if (x.isNaN() || y.isNaN()) {
-	    return new BigNumber(NaN);
-	  }
-
-	  var negOne = new BigNumber(-1);
-	  if (x.isZero() || y.eq(negOne) || x.eq(y)) {
-	    return y;
-	  }
-	  if (y.isZero() || x.eq(negOne)) {
-	    return x;
-	  }
-
-	  if (!x.isFinite() || !y.isFinite()) {
-	    if ((!x.isFinite() && !x.isNegative() && y.isNegative()) ||
-	        (x.isNegative() && !y.isNegative() && !y.isFinite())) {
-	      return negOne;
-	    }
-	    if (x.isNegative() && y.isNegative()) {
-	      return x.isFinite() ? x : y;
-	    }
-	    return x.isFinite() ? y : x;
-	  }
-
-	  return bitwise(x, y, function (a, b) { return a | b });
-	};
-
-
-/***/ },
-/* 128 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	var isInteger = __webpack_require__(8).isInteger;
-	var bigBitXor = __webpack_require__(129);
-
-	function factory (type, config, load, typed) {
-	  var latex = __webpack_require__(26);
-
-	  var matrix = load(__webpack_require__(23));
-
-	  var algorithm03 = load(__webpack_require__(31));
-	  var algorithm07 = load(__webpack_require__(66));
-	  var algorithm12 = load(__webpack_require__(65));
-	  var algorithm13 = load(__webpack_require__(35));
-	  var algorithm14 = load(__webpack_require__(39));
-
-	  /**
-	   * Bitwise XOR two values, `x ^ y`.
-	   * For matrices, the function is evaluated element wise.
-	   *
-	   * Syntax:
-	   *
-	   *    math.bitXor(x, y)
-	   *
-	   * Examples:
-	   *
-	   *    math.bitXor(1, 2);               // returns number 3
-	   *
-	   *    math.bitXor([2, 3, 4], 4);       // returns Array [6, 7, 0]
-	   *
-	   * See also:
-	   *
-	   *    bitAnd, bitNot, bitOr, leftShift, rightArithShift, rightLogShift
-	   *
-	   * @param  {number | BigNumber | Array | Matrix} x First value to xor
-	   * @param  {number | BigNumber | Array | Matrix} y Second value to xor
-	   * @return {number | BigNumber | Array | Matrix} XOR of `x` and `y`
-	   */
-	  var bitXor = typed('bitXor', {
-
-	    'number, number': function (x, y) {
-	      if (!isInteger(x) || !isInteger(y)) {
-	        throw new Error('Integers expected in function bitXor');
-	      }
-
-	      return x ^ y;
-	    },
-
-	    'BigNumber, BigNumber': bigBitXor,
-
-	    'Matrix, Matrix': function (x, y) {
-	      // result
-	      var c;
-
-	      // process matrix storage
-	      switch (x.storage()) {
-	        case 'sparse':
-	          switch (y.storage()) {
-	            case 'sparse':
-	              // sparse + sparse
-	              c = algorithm07(x, y, bitXor);
-	              break;
-	            default:
-	              // sparse + dense
-	              c = algorithm03(y, x, bitXor, true);
-	              break;
-	          }
-	          break;
-	        default:
-	          switch (y.storage()) {
-	            case 'sparse':
-	              // dense + sparse
-	              c = algorithm03(x, y, bitXor, false);
-	              break;
-	            default:
-	              // dense + dense
-	              c = algorithm13(x, y, bitXor);
-	              break;
-	          }
-	          break;
-	      }
-	      return c;
-	    },
-
-	    'Array, Array': function (x, y) {
-	      // use matrix implementation
-	      return bitXor(matrix(x), matrix(y)).valueOf();
-	    },
-
-	    'Array, Matrix': function (x, y) {
-	      // use matrix implementation
-	      return bitXor(matrix(x), y);
-	    },
-
-	    'Matrix, Array': function (x, y) {
-	      // use matrix implementation
-	      return bitXor(x, matrix(y));
-	    },
-
-	    'Matrix, any': function (x, y) {
-	      // result
-	      var c;
-	      // check storage format
-	      switch (x.storage()) {
-	        case 'sparse':
-	          c = algorithm12(x, y, bitXor, false);
-	          break;
-	        default:
-	          c = algorithm14(x, y, bitXor, false);
-	          break;
-	      }
-	      return c;
-	    },
-
-	    'any, Matrix': function (x, y) {
-	      // result
-	      var c;
-	      // check storage format
-	      switch (y.storage()) {
-	        case 'sparse':
-	          c = algorithm12(y, x, bitXor, true);
-	          break;
-	        default:
-	          c = algorithm14(y, x, bitXor, true);
-	          break;
-	      }
-	      return c;
-	    },
-
-	    'Array, any': function (x, y) {
-	      // use matrix implementation
-	      return algorithm14(matrix(x), y, bitXor, false).valueOf();
-	    },
-
-	    'any, Array': function (x, y) {
-	      // use matrix implementation
-	      return algorithm14(matrix(y), x, bitXor, true).valueOf();
-	    }
-	  });
-
-	  bitXor.toTex = '\\left(${args[0]}' + latex.operators['bitXor'] + '${args[1]}\\right)';
-
-	  return bitXor;
-	}
-
-	exports.name = 'bitXor';
-	exports.factory = factory;
-
-
-/***/ },
-/* 129 */
-/***/ function(module, exports, __webpack_require__) {
-
-	var bitwise = __webpack_require__(123);
-	var bitNot = __webpack_require__(124);
-
-	/**
-	 * Bitwise XOR for BigNumbers
-	 *
-	 * Special Cases:
-	 *   N ^  n =  N
-	 *   n ^  0 =  n
-	 *   n ^  n =  0
-	 *   n ^ -1 = ~n
-	 *   I ^  n =  I
-	 *   I ^ -n = -I
-	 *   I ^ -I = -1
-	 *  -I ^  n = -I
-	 *  -I ^ -n =  I
-	 *
-	 * @param {BigNumber} x
-	 * @param {BigNumber} y
-	 * @return {BigNumber} Result of `x` ^ `y`, fully precise
-	 *
-	 */
-	module.exports = function bitXor(x, y) {
-	  if ((x.isFinite() && !x.isInteger()) || (y.isFinite() && !y.isInteger())) {
-	    throw new Error('Integers expected in function bitXor');
-	  }
-
-	  var BigNumber = x.constructor;
-	  if (x.isNaN() || y.isNaN()) {
-	    return new BigNumber(NaN);
-	  }
-	  if (x.isZero()) {
-	    return y;
-	  }
-	  if (y.isZero()) {
-	    return x;
-	  }
-
-	  if (x.eq(y)) {
-	    return new BigNumber(0);
-	  }
-
-	  var negOne = new BigNumber(-1);
-	  if (x.eq(negOne)) {
-	    return bitNot(y);
-	  }
-	  if (y.eq(negOne)) {
-	    return bitNot(x);
-	  }
-
-	  if (!x.isFinite() || !y.isFinite()) {
-	    if (!x.isFinite() && !y.isFinite()) {
-	      return negOne;
-	    }
-	    return new BigNumber(x.isNegative() == y.isNegative()
-	        ?  Infinity
-	        : -Infinity);
-	  }
-	  return bitwise(x, y, function (a, b) { return a ^ b });
-	};
-
-
-/***/ },
-/* 130 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	var isInteger = __webpack_require__(8).isInteger;
-	var bigLeftShift = __webpack_require__(131);
-
-	function factory (type, config, load, typed) {
-	  var latex = __webpack_require__(26);
-
-	  var matrix = load(__webpack_require__(23));
-	  var equalScalar = load(__webpack_require__(33));
-	  var zeros = load(__webpack_require__(60));
-
-	  var algorithm01 = load(__webpack_require__(30));
-	  var algorithm02 = load(__webpack_require__(96));
-	  var algorithm08 = load(__webpack_require__(132));
-	  var algorithm10 = load(__webpack_require__(34));
-	  var algorithm11 = load(__webpack_require__(42));
-	  var algorithm13 = load(__webpack_require__(35));
-	  var algorithm14 = load(__webpack_require__(39));
-
-	  /**
-	   * Bitwise left logical shift of a value x by y number of bits, `x << y`.
-	   * For matrices, the function is evaluated element wise.
-	   * For units, the function is evaluated on the best prefix base.
-	   *
-	   * Syntax:
-	   *
-	   *    math.leftShift(x, y)
-	   *
-	   * Examples:
-	   *
-	   *    math.leftShift(1, 2);               // returns number 4
-	   *
-	   *    math.leftShift([1, 2, 3], 4);       // returns Array [16, 32, 64]
-	   *
-	   * See also:
-	   *
-	   *    leftShift, bitNot, bitOr, bitXor, rightArithShift, rightLogShift
-	   *
-	   * @param  {number | BigNumber | Array | Matrix} x Value to be shifted
-	   * @param  {number | BigNumber} y Amount of shifts
-	   * @return {number | BigNumber | Array | Matrix} `x` shifted left `y` times
-	   */
-	  var leftShift = typed('leftShift', {
-	    
-	    'number, number': function (x, y) {
-	      if (!isInteger(x) || !isInteger(y)) {
-	        throw new Error('Integers expected in function leftShift');
-	      }
-
-	      return x << y;
-	    },
-
-	    'BigNumber, BigNumber': bigLeftShift,
-
-	    'Matrix, Matrix': function (x, y) {
-	      // result
-	      var c;
-
-	      // process matrix storage
-	      switch (x.storage()) {
-	        case 'sparse':
-	          switch (y.storage()) {
-	            case 'sparse':
-	              // sparse & sparse
-	              c = algorithm08(x, y, leftShift, false);
-	              break;
-	            default:
-	              // sparse & dense
-	              c = algorithm02(y, x, leftShift, true);
-	              break;
-	          }
-	          break;
-	        default:
-	          switch (y.storage()) {
-	            case 'sparse':
-	              // dense & sparse
-	              c = algorithm01(x, y, leftShift, false);
-	              break;
-	            default:
-	              // dense & dense
-	              c = algorithm13(x, y, leftShift);
-	              break;
-	          }
-	          break;
-	      }
-	      return c;
-	    },
-
-	    'Array, Array': function (x, y) {
-	      // use matrix implementation
-	      return leftShift(matrix(x), matrix(y)).valueOf();
-	    },
-
-	    'Array, Matrix': function (x, y) {
-	      // use matrix implementation
-	      return leftShift(matrix(x), y);
-	    },
-
-	    'Matrix, Array': function (x, y) {
-	      // use matrix implementation
-	      return leftShift(x, matrix(y));
-	    },
-
-	    'Matrix, number | BigNumber': function (x, y) {
-	      // check scalar
-	      if (!equalScalar(y, 0)) {
-	        // result
-	        var c;
-	        // check storage format
-	        switch (x.storage()) {
-	          case 'sparse':
-	            c = algorithm11(x, y, leftShift, false);
-	            break;
-	          default:
-	            c = algorithm14(x, y, leftShift, false);
-	            break;
-	        }
-	        return c;
-	      }
-	      return x.clone();
-	    },
-
-	    'number | BigNumber, Matrix': function (x, y) {
-	      // check scalar
-	      if (!equalScalar(x, 0)) {
-	        // result
-	        var c;
-	        // check storage format
-	        switch (y.storage()) {
-	          case 'sparse':
-	            c = algorithm10(y, x, leftShift, true);
-	            break;
-	          default:
-	            c = algorithm14(y, x, leftShift, true);
-	            break;
-	        }
-	        return c;
-	      }
-	      return zeros(y.size(), y.storage());
-	    },
-
-	    'Array, number | BigNumber': function (x, y) {
-	      // use matrix implementation
-	      return leftShift(matrix(x), y).valueOf();
-	    },
-
-	    'number | BigNumber, Array': function (x, y) {
-	      // use matrix implementation
-	      return leftShift(x, matrix(y)).valueOf();
-	    }
-	  });
-
-	  leftShift.toTex = '\\left(${args[0]}' + latex.operators['leftShift'] + '${args[1]}\\right)';
-
-	  return leftShift;
-	}
-
-	exports.name = 'leftShift';
-	exports.factory = factory;
-
-
-/***/ },
-/* 131 */
-/***/ function(module, exports) {
-
-	
-	/**
-	 * Bitwise left shift
-	 *
-	 * Special Cases:
-	 *  n << -n = N
-	 *  n <<  N = N
-	 *  N <<  n = N
-	 *  n <<  0 = n
-	 *  0 <<  n = 0
-	 *  I <<  I = N
-	 *  I <<  n = I
-	 *  n <<  I = I
-	 *
-	 * @param {BigNumber} x
-	 * @param {BigNumber} y
-	 * @return {BigNumber} Result of `x` << `y`
-	 *
-	 */
-	module.exports = function leftShift (x, y) {
-	  if ((x.isFinite() && !x.isInteger()) || (y.isFinite() && !y.isInteger())) {
-	    throw new Error('Integers expected in function leftShift');
-	  }
-
-	  var BigNumber = x.constructor;
-	  if (x.isNaN() || y.isNaN() || (y.isNegative() && !y.isZero())) {
-	    return new BigNumber(NaN);
-	  }
-	  if (x.isZero() || y.isZero()) {
-	    return x;
-	  }
-	  if (!x.isFinite() && !y.isFinite()) {
-	    return new BigNumber(NaN);
-	  }
-
-	  // Math.pow(2, y) is fully precise for y < 55, and fast
-	  if (y.lt(55)) {
-	    return x.times(Math.pow(2, y.toNumber()) + '');
-	  }
-	  return x.times(new BigNumber(2).pow(y));
-	};
-
-
-/***/ },
-/* 132 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	var DimensionError = __webpack_require__(22);
-
-	function factory (type, config, load, typed) {
-
-	  var equalScalar = load(__webpack_require__(33));
-
-	  var SparseMatrix = type.SparseMatrix;
-
-	  /**
-	   * Iterates over SparseMatrix A and SparseMatrix B nonzero items and invokes the callback function f(Aij, Bij). 
-	   * Callback function invoked MAX(NNZA, NNZB) times
-	   *
-	   *
-	   *          ┌  f(Aij, Bij)  ; A(i,j) !== 0 && B(i,j) !== 0
-	   * C(i,j) = ┤  A(i,j)       ; A(i,j) !== 0
-	   *          └  0            ; otherwise
-	   *
-	   *
-	   * @param {Matrix}   a                 The SparseMatrix instance (A)
-	   * @param {Matrix}   b                 The SparseMatrix instance (B)
-	   * @param {Function} callback          The f(Aij,Bij) operation to invoke
-	   *
-	   * @return {Matrix}                    SparseMatrix (C)
-	   *
-	   * see https://github.com/josdejong/mathjs/pull/346#issuecomment-97620294
-	   */
-	  var algorithm08 = function (a, b, callback) {
-	    // sparse matrix arrays
-	    var avalues = a._values;
-	    var aindex = a._index;
-	    var aptr = a._ptr;
-	    var asize = a._size;
-	    var adt = a._datatype;
-	    // sparse matrix arrays
-	    var bvalues = b._values;
-	    var bindex = b._index;
-	    var bptr = b._ptr;
-	    var bsize = b._size;
-	    var bdt = b._datatype;
-
-	    // validate dimensions
-	    if (asize.length !== bsize.length)
-	      throw new DimensionError(asize.length, bsize.length);
-
-	    // check rows & columns
-	    if (asize[0] !== bsize[0] || asize[1] !== bsize[1])
-	      throw new RangeError('Dimension mismatch. Matrix A (' + asize + ') must match Matrix B (' + bsize + ')');
-
-	    // sparse matrix cannot be a Pattern matrix
-	    if (!avalues || !bvalues)
-	      throw new Error('Cannot perform operation on Pattern Sparse Matrices');
-
-	    // rows & columns
-	    var rows = asize[0];
-	    var columns = asize[1];
-
-	    // datatype
-	    var dt;
-	    // equal signature to use
-	    var eq = equalScalar;
-	    // zero value
-	    var zero = 0;
-	    // callback signature to use
-	    var cf = callback;
-
-	    // process data types
-	    if (typeof adt === 'string' && adt === bdt) {
-	      // datatype
-	      dt = adt;
-	      // find signature that matches (dt, dt)
-	      eq = typed.find(equalScalar, [dt, dt]);
-	      // convert 0 to the same datatype
-	      zero = typed.convert(0, dt);
-	      // callback
-	      cf = typed.find(callback, [dt, dt]);
-	    }
-
-	    // result arrays
-	    var cvalues = [];
-	    var cindex = [];
-	    var cptr = [];
-	    // matrix
-	    var c = new SparseMatrix({
-	      values: cvalues,
-	      index: cindex,
-	      ptr: cptr,
-	      size: [rows, columns],
-	      datatype: dt
-	    });
-
-	    // workspace
-	    var x = [];
-	    // marks indicating we have a value in x for a given column
-	    var w = [];
-
-	    // vars
-	    var k, k0, k1, i;
-
-	    // loop columns
-	    for (var j = 0; j < columns; j++) {
-	      // update cptr
-	      cptr[j] = cindex.length;
-	      // columns mark
-	      var mark = j + 1;
-	      // loop values in a
-	      for (k0 = aptr[j], k1 = aptr[j + 1], k = k0; k < k1; k++) {
-	        // row
-	        i = aindex[k];
-	        // mark workspace
-	        w[i] = mark;
-	        // set value
-	        x[i] = avalues[k];
-	        // add index
-	        cindex.push(i);
-	      }
-	      // loop values in b
-	      for (k0 = bptr[j], k1 = bptr[j + 1], k = k0; k < k1; k++) {
-	        // row
-	        i = bindex[k];
-	        // check value exists in workspace
-	        if (w[i] === mark) {
-	          // evaluate callback
-	          x[i] = cf(x[i], bvalues[k]);
-	        }
-	      }
-	      // initialize first index in j
-	      k = cptr[j];
-	      // loop index in j
-	      while (k < cindex.length) {
-	        // row
-	        i = cindex[k];
-	        // value @ i
-	        var v = x[i];
-	        // check for zero value
-	        if (!eq(v, zero)) {
-	          // push value
-	          cvalues.push(v);
-	          // increment pointer
-	          k++;
-	        }
-	        else {
-	          // remove value @ i, do not increment pointer
-	          cindex.splice(k, 1);
-	        }
-	      }      
-	    }
-	    // update cptr
-	    cptr[columns] = cindex.length;
-
-	    // return sparse matrix
-	    return c;
-	  };
-
-	  return algorithm08;
-	}
-
-	exports.name = 'algorithm08';
-	exports.factory = factory;
-
-
-/***/ },
-/* 133 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	var isInteger = __webpack_require__(8).isInteger;
-	var bigRightArithShift = __webpack_require__(134);
-
-	function factory (type, config, load, typed) {
-	  var latex = __webpack_require__(26);
-	  
-	  var matrix = load(__webpack_require__(23));
-	  var equalScalar = load(__webpack_require__(33));
-	  var zeros = load(__webpack_require__(60));
-
-	  var algorithm01 = load(__webpack_require__(30));
-	  var algorithm02 = load(__webpack_require__(96));
-	  var algorithm08 = load(__webpack_require__(132));
-	  var algorithm10 = load(__webpack_require__(34));
-	  var algorithm11 = load(__webpack_require__(42));
-	  var algorithm13 = load(__webpack_require__(35));
-	  var algorithm14 = load(__webpack_require__(39));
-
-	  /**
-	   * Bitwise right arithmetic shift of a value x by y number of bits, `x >> y`.
-	   * For matrices, the function is evaluated element wise.
-	   * For units, the function is evaluated on the best prefix base.
-	   *
-	   * Syntax:
-	   *
-	   *    math.rightArithShift(x, y)
-	   *
-	   * Examples:
-	   *
-	   *    math.rightArithShift(4, 2);               // returns number 1
-	   *
-	   *    math.rightArithShift([16, -32, 64], 4);   // returns Array [1, -2, 3]
-	   *
-	   * See also:
-	   *
-	   *    bitAnd, bitNot, bitOr, bitXor, rightArithShift, rightLogShift
-	   *
-	   * @param  {number | BigNumber | Array | Matrix} x Value to be shifted
-	   * @param  {number | BigNumber} y Amount of shifts
-	   * @return {number | BigNumber | Array | Matrix} `x` sign-filled shifted right `y` times
-	   */
-	  var rightArithShift = typed('rightArithShift', {
-
-	    'number, number': function (x, y) {
-	      if (!isInteger(x) || !isInteger(y)) {
-	        throw new Error('Integers expected in function rightArithShift');
-	      }
-
-	      return x >> y;
-	    },
-
-	    'BigNumber, BigNumber': bigRightArithShift,
-
-	    'Matrix, Matrix': function (x, y) {
-	      // result
-	      var c;
-
-	      // process matrix storage
-	      switch (x.storage()) {
-	        case 'sparse':
-	          switch (y.storage()) {
-	            case 'sparse':
-	              // sparse & sparse
-	              c = algorithm08(x, y, rightArithShift, false);
-	              break;
-	            default:
-	              // sparse & dense
-	              c = algorithm02(y, x, rightArithShift, true);
-	              break;
-	          }
-	          break;
-	        default:
-	          switch (y.storage()) {
-	            case 'sparse':
-	              // dense & sparse
-	              c = algorithm01(x, y, rightArithShift, false);
-	              break;
-	            default:
-	              // dense & dense
-	              c = algorithm13(x, y, rightArithShift);
-	              break;
-	          }
-	          break;
-	      }
-	      return c;
-	    },
-
-	    'Array, Array': function (x, y) {
-	      // use matrix implementation
-	      return rightArithShift(matrix(x), matrix(y)).valueOf();
-	    },
-
-	    'Array, Matrix': function (x, y) {
-	      // use matrix implementation
-	      return rightArithShift(matrix(x), y);
-	    },
-
-	    'Matrix, Array': function (x, y) {
-	      // use matrix implementation
-	      return rightArithShift(x, matrix(y));
-	    },
-
-	    'Matrix, number | BigNumber': function (x, y) {
-	      // check scalar
-	      if (!equalScalar(y, 0)) {
-	        // result
-	        var c;
-	        // check storage format
-	        switch (x.storage()) {
-	          case 'sparse':
-	            c = algorithm11(x, y, rightArithShift, false);
-	            break;
-	          default:
-	            c = algorithm14(x, y, rightArithShift, false);
-	            break;
-	        }
-	        return c;
-	      }
-	      return x.clone();
-	    },
-
-	    'number | BigNumber, Matrix': function (x, y) {
-	      // check scalar
-	      if (!equalScalar(x, 0)) {
-	        // result
-	        var c;
-	        // check storage format
-	        switch (y.storage()) {
-	          case 'sparse':
-	            c = algorithm10(y, x, rightArithShift, true);
-	            break;
-	          default:
-	            c = algorithm14(y, x, rightArithShift, true);
-	            break;
-	        }
-	        return c;
-	      }
-	      return zeros(y.size(), y.storage());
-	    },
-
-	    'Array, number | BigNumber': function (x, y) {
-	      // use matrix implementation
-	      return rightArithShift(matrix(x), y).valueOf();
-	    },
-
-	    'number | BigNumber, Array': function (x, y) {
-	      // use matrix implementation
-	      return rightArithShift(x, matrix(y)).valueOf();
-	    }
-	  });
-
-	  rightArithShift.toTex = '\\left(${args[0]}' + latex.operators['rightArithShift'] + '${args[1]}\\right)';
-
-	  return rightArithShift;
-	}
-
-	exports.name = 'rightArithShift';
-	exports.factory = factory;
-
-
-/***/ },
-/* 134 */
-/***/ function(module, exports) {
-
-	/*
-	 * Special Cases:
-	 *   n >> -n =  N
-	 *   n >>  N =  N
-	 *   N >>  n =  N
-	 *   I >>  I =  N
-	 *   n >>  0 =  n
-	 *   I >>  n =  I
-	 *  -I >>  n = -I
-	 *  -I >>  I = -I
-	 *   n >>  I =  I
-	 *  -n >>  I = -1
-	 *   0 >>  n =  0
-	 *
-	 * @param {BigNumber} value
-	 * @param {BigNumber} value
-	 * @return {BigNumber} Result of `x` >> `y`
-	 *
-	 */
-	module.exports = function rightArithShift (x, y) {
-	  if ((x.isFinite() && !x.isInteger()) || (y.isFinite() && !y.isInteger())) {
-	    throw new Error('Integers expected in function rightArithShift');
-	  }
-
-	  var BigNumber = x.constructor;
-	  if (x.isNaN() || y.isNaN() || (y.isNegative() && !y.isZero())) {
-	    return new BigNumber(NaN);
-	  }
-	  if (x.isZero() || y.isZero()) {
-	    return x;
-	  }
-	  if (!y.isFinite()) {
-	    if (x.isNegative()) {
-	      return new BigNumber(-1);
-	    }
-	    if (!x.isFinite()) {
-	      return new BigNumber(NaN);
-	    }
-	    return new BigNumber(0);
-	  }
-
-	  // Math.pow(2, y) is fully precise for y < 55, and fast
-	  if (y.lt(55)) {
-	    return x.div(Math.pow(2, y.toNumber()) + '').floor();
-	  }
-	  return x.div(new BigNumber(2).pow(y)).floor();
-	};
-
-
-/***/ },
-/* 135 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	var isInteger = __webpack_require__(8).isInteger;
-
-	function factory (type, config, load, typed) {
-	  var latex = __webpack_require__(26);
-
-	  var matrix = load(__webpack_require__(23));
-	  var equalScalar = load(__webpack_require__(33));
-	  var zeros = load(__webpack_require__(60));
-
-	  var algorithm01 = load(__webpack_require__(30));
-	  var algorithm02 = load(__webpack_require__(96));
-	  var algorithm08 = load(__webpack_require__(132));
-	  var algorithm10 = load(__webpack_require__(34));
-	  var algorithm11 = load(__webpack_require__(42));
-	  var algorithm13 = load(__webpack_require__(35));
-	  var algorithm14 = load(__webpack_require__(39));
-	  
-	  /**
-	   * Bitwise right logical shift of value x by y number of bits, `x >>> y`.
-	   * For matrices, the function is evaluated element wise.
-	   * For units, the function is evaluated on the best prefix base.
-	   *
-	   * Syntax:
-	   *
-	   *    math.rightLogShift(x, y)
-	   *
-	   * Examples:
-	   *
-	   *    math.rightLogShift(4, 2);               // returns number 1
-	   *
-	   *    math.rightLogShift([16, -32, 64], 4);   // returns Array [1, 2, 3]
-	   *
-	   * See also:
-	   *
-	   *    bitAnd, bitNot, bitOr, bitXor, leftShift, rightLogShift
-	   *
-	   * @param  {number | Array | Matrix} x Value to be shifted
-	   * @param  {number} y Amount of shifts
-	   * @return {number | Array | Matrix} `x` zero-filled shifted right `y` times
-	   */
-
-	  var rightLogShift = typed('rightLogShift', {
-
-	    'number, number': function (x, y) {
-	      if (!isInteger(x) || !isInteger(y)) {
-	        throw new Error('Integers expected in function rightLogShift');
-	      }
-
-	      return x >>> y;
-	    },
-
-	    // 'BigNumber, BigNumber': ..., // TODO: implement BigNumber support for rightLogShift
-
-	    'Matrix, Matrix': function (x, y) {
-	      // result
-	      var c;
-
-	      // process matrix storage
-	      switch (x.storage()) {
-	        case 'sparse':
-	          switch (y.storage()) {
-	            case 'sparse':
-	              // sparse & sparse
-	              c = algorithm08(x, y, rightLogShift, false);
-	              break;
-	            default:
-	              // sparse & dense
-	              c = algorithm02(y, x, rightLogShift, true);
-	              break;
-	          }
-	          break;
-	        default:
-	          switch (y.storage()) {
-	            case 'sparse':
-	              // dense & sparse
-	              c = algorithm01(x, y, rightLogShift, false);
-	              break;
-	            default:
-	              // dense & dense
-	              c = algorithm13(x, y, rightLogShift);
-	              break;
-	          }
-	          break;
-	      }
-	      return c;
-	    },
-
-	    'Array, Array': function (x, y) {
-	      // use matrix implementation
-	      return rightLogShift(matrix(x), matrix(y)).valueOf();
-	    },
-
-	    'Array, Matrix': function (x, y) {
-	      // use matrix implementation
-	      return rightLogShift(matrix(x), y);
-	    },
-
-	    'Matrix, Array': function (x, y) {
-	      // use matrix implementation
-	      return rightLogShift(x, matrix(y));
-	    },
-
-	    'Matrix, number | BigNumber': function (x, y) {
-	      // check scalar
-	      if (!equalScalar(y, 0)) {
-	        // result
-	        var c;
-	        // check storage format
-	        switch (x.storage()) {
-	          case 'sparse':
-	            c = algorithm11(x, y, rightLogShift, false);
-	            break;
-	          default:
-	            c = algorithm14(x, y, rightLogShift, false);
-	            break;
-	        }
-	        return c;
-	      }
-	      return x.clone();
-	    },
-
-	    'number | BigNumber, Matrix': function (x, y) {
-	      // check scalar
-	      if (!equalScalar(x, 0)) {
-	        // result
-	        var c;
-	        // check storage format
-	        switch (y.storage()) {
-	          case 'sparse':
-	            c = algorithm10(y, x, rightLogShift, true);
-	            break;
-	          default:
-	            c = algorithm14(y, x, rightLogShift, true);
-	            break;
-	        }
-	        return c;
-	      }
-	      return zeros(y.size(), y.storage());
-	    },
-
-	    'Array, number | BigNumber': function (x, y) {
-	      // use matrix implementation
-	      return rightLogShift(matrix(x), y).valueOf();
-	    },
-
-	    'number | BigNumber, Array': function (x, y) {
-	      // use matrix implementation
-	      return rightLogShift(x, matrix(y)).valueOf();
-	    }
-	  });
-
-	  rightLogShift.toTex = '\\left(${args[0]}' + latex.operators['rightLogShift'] + '${args[1]}\\right)';
-
-	  return rightLogShift;
-	}
-
-	exports.name = 'rightLogShift';
-	exports.factory = factory;
-
-
-/***/ },
-/* 136 */
-/***/ function(module, exports, __webpack_require__) {
-
-	module.exports = [
-	  __webpack_require__(137),
-	  __webpack_require__(146),
-	  __webpack_require__(138),
-	  __webpack_require__(148)
-	];
-
-
-/***/ },
-/* 137 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	function factory (type, config, load, typed) {
-	  var add = load(__webpack_require__(44));
-	  var stirlingS2 = load(__webpack_require__(138));
-	  var isNegative = load(__webpack_require__(144));
-	  var isInteger = load(__webpack_require__(145));
-
-	  /**
-	   * The Bell Numbers count the number of partitions of a set. A partition is a pairwise disjoint subset of S whose union is S.
-	   * bellNumbers only takes integer arguments.
-	   * The following condition must be enforced: n >= 0
-	   *
-	   * Syntax:
-	   *
-	   *   math.bellNumbers(n)
-	   *
-	   * Examples:
-	   *
-	   *    math.bellNumbers(3); // returns 5;
-	   *    math.bellNumbers(8); // returns 4140;
-	   *
-	   * See also:
-	   *
-	   *    stirlingS2
-	   *
-	   * @param {Number | BigNumber} n    Total number of objects in the set
-	   * @return {Number | BigNumber}     B(n)
-	   */
-	  var bellNumbers = typed('bellNumbers', {
-	    'number | BigNumber': function (n) {
-
-	      if (!isInteger(n) || isNegative(n)) {
-	        throw new TypeError('Non-negative integer value expected in function bellNumbers');
-	      }
-
-	      // Sum (k=0, n) S(n,k).
-	      var result = 0;
-	      for(var i = 0; i <= n; i++) {
-	        result = add(result, stirlingS2(n, i));
-	      }
-
-	      return result;
-	    }
-	  });
-
-	  bellNumbers.toTex = '\\mathrm{B}_{${args[0]}}';
-
-	  return bellNumbers;
-	}
-
-	exports.name = 'bellNumbers';
-	exports.factory = factory;
-
-
-/***/ },
-/* 138 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	function factory (type, config, load, typed) {
-	  var add = load(__webpack_require__(44));
-	  var subtract = load(__webpack_require__(25));
-	  var multiply = load(__webpack_require__(40));
-	  var divide = load(__webpack_require__(94));
-	  var pow = load(__webpack_require__(100));
-	  var factorial = load(__webpack_require__(139));
-	  var combinations = load(__webpack_require__(143));
-	  var isNegative = load(__webpack_require__(144));
-	  var isInteger = load(__webpack_require__(145));
-	  var larger = load(__webpack_require__(64));
-
-	  /**
-	   * The Stirling numbers of the second kind, counts the number of ways to partition
-	   * a set of n labelled objects into k nonempty unlabelled subsets.
-	   * stirlingS2 only takes integer arguments.
-	   * The following condition must be enforced: k <= n.
-	   *
-	   *  If n = k or k = 1, then s(n,k) = 1
-	   *
-	   * Syntax:
-	   *
-	   *   math.stirlingS2(n, k)
-	   *
-	   * Examples:
-	   *
-	   *    math.stirlingS2(5, 3); //returns 25
-	   *
-	   * See also:
-	   *
-	   *    Bell numbers
-	   *
-	   * @param {Number | BigNumber} n    Total number of objects in the set
-	   * @param {Number | BigNumber} k    Number of objects in the subset
-	   * @return {Number | BigNumber}     S(n,k)
-	   */
-	  var stirlingS2 = typed('stirlingS2', {
-	    'number | BigNumber, number | BigNumber': function (n, k) {
-	      if (!isInteger(n) || isNegative(n) || !isInteger(k) || isNegative(k)) {
-	        throw new TypeError('Non-negative integer value expected in function stirlingS2');
-	      }
-	      else if (larger(k, n)) {
-	        throw new TypeError('k must be less than or equal to n in function stirlingS2');
-	      }
-
-	      // 1/k! Sum(i=0 -> k) [(-1)^(k-i)*C(k,j)* i^n]
-	      var kFactorial = factorial(k);
-	      var result = 0;
-	      for(var i = 0; i <= k; i++) {
-	        var negativeOne = pow(-1, subtract(k,i));
-	        var kChooseI = combinations(k,i);
-	        var iPower = pow(i,n);
-
-	        result = add(result, multiply(multiply(kChooseI, iPower), negativeOne));
-	      }
-
-	      return divide(result, kFactorial);
-	    }
-	  });
-
-	  stirlingS2.toTex = '\\mathrm{S}\\left(${args[0]},${args[1]}\\right)';
-
-	  return stirlingS2;
-	}
-
-	exports.name = 'stirlingS2';
-	exports.factory = factory;
-
-
-/***/ },
-/* 139 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	var deepMap = __webpack_require__(29);
-	var constants = __webpack_require__(140);
-
-	function factory (type, config, load, typed) {
-	  var gamma = load(__webpack_require__(142));
-	  var latex = __webpack_require__(26);
-
-	  /**
-	   * Compute the factorial of a value
-	   *
-	   * Factorial only supports an integer value as argument.
-	   * For matrices, the function is evaluated element wise.
-	   *
-	   * Syntax:
-	   *
-	   *    math.factorial(n)
-	   *
-	   * Examples:
-	   *
-	   *    math.factorial(5);    // returns 120
-	   *    math.factorial(3);    // returns 6
-	   *
-	   * See also:
-	   *
-	   *    combinations, gamma, permutations
-	   *
-	   * @param {number | BigNumber | Array | Matrix} n   An integer number
-	   * @return {number | BigNumber | Array | Matrix}    The factorial of `n`
-	   */
-	  var factorial = typed('factorial', {
-	    'number': function (n) {
-	      if (n === Number.POSITIVE_INFINITY) {
-	       return Math.sqrt(2 * Math.PI);
-	      }
-
-	      return gamma(n + 1);
-	    },
-
-	    'BigNumber': function (n) {
-	      if (!n.isFinite() && !n.isNegative()) {
-	        return constants.tau(type.BigNumber).sqrt();
-	      }
-
-	      return gamma(n.plus(1));
-	    },
-
-	    'Array | Matrix': function (n) {
-	      return deepMap(n, factorial);
-	    }
-	  });
-
-	  factorial.toTex = '\\left(${args[0]}\\right)' + latex.operators['factorial'];
-
-	  return factorial;
-	}
-
-	exports.name = 'factorial';
-	exports.factory = factory;
-
-
-/***/ },
-/* 140 */
-/***/ function(module, exports, __webpack_require__) {
-
-	var memoize = __webpack_require__(38).memoize;
-	var atan = __webpack_require__(141);
-
-	/**
-	 * Calculate BigNumber e
-	 * @param {function} BigNumber   BigNumber constructor
-	 * @returns {BigNumber} Returns e
-	 */
-	exports.e = memoize(function (BigNumber) {
-	  return new BigNumber(1).exp();
-	}, hasher);
-
-	/**
-	 * Calculate BigNumber golden ratio, phi = (1+sqrt(5))/2
-	 * @param {function} BigNumber   BigNumber constructor
-	 * @returns {BigNumber} Returns phi
-	 */
-	exports.phi = memoize(function (BigNumber) {
-	  return new BigNumber(1).plus(new BigNumber(5).sqrt()).div(2);
-	}, hasher);
-
-	/**
-	 * Calculate BigNumber pi.
-	 *
-	 * Uses Machin's formula: pi / 4 = 4 * arctan(1 / 5) - arctan(1 / 239)
-	 * http://milan.milanovic.org/math/english/pi/machin.html
-	 * @param {function} BigNumber   BigNumber constructor
-	 * @returns {BigNumber} Returns pi
-	 */
-	exports.pi = memoize(function (BigNumber) {
-	  // we calculate pi with a few decimal places extra to prevent round off issues
-	  var Big = BigNumber.constructor({precision: BigNumber.precision + 4});
-	  var pi4th = new Big(4).times(atan(new Big(1).div(5)))
-	      .minus(atan(new Big(1).div(239)));
-
-	  // the final pi has the requested number of decimals
-	  return new BigNumber(4).times(pi4th);
-	}, hasher);
-
-	/**
-	 * Calculate BigNumber tau, tau = 2 * pi
-	 * @param {function} BigNumber   BigNumber constructor
-	 * @returns {BigNumber} Returns tau
-	 */
-	exports.tau = memoize(function (BigNumber) {
-	  // we calculate pi at a slightly higher precision than configured to prevent round off errors
-	  // when multiplying by two in the end
-
-	  var pi = exports.pi(BigNumber.constructor({precision: BigNumber.precision + 2}));
-
-	  return new BigNumber(2).times(pi);
-	}, hasher);
-
-	/**
-	 * Create a hash for a BigNumber constructor function. The created has is
-	 * the configured precision
-	 * @param {Array} args         Supposed to contain a single entry with
-	 *                             a BigNumber constructor
-	 * @return {number} precision
-	 * @private
-	 */
-	function hasher (args) {
-	  return args[0].precision;
-	}
-
-
-/***/ },
-/* 141 */
-/***/ function(module, exports) {
-
-	/**
-	 * Calculate the arc tangent of x using a Taylor expansion
-	 *
-	 * arctan(x) = x - x^3/3 + x^5/5 - x^7/7 + x^9/9 - ...
-	 *           = x - x^2*x^1/3 + x^2*x^3/5 - x^2*x^5/7 + x^2*x^7/9 - ...
-	 *
-	 * @param {BigNumber} x
-	 * @returns {BigNumber} arc tangent of x
-	 */
-	module.exports = function atan(x) {
-	  var y = x;
-	  var yPrev = NaN;
-	  var x2 = x.times(x);
-	  var num = x;
-	  var add = true;
-
-	  for (var k = 3; !y.equals(yPrev); k += 2) {
-	    num = num.times(x2);
-
-	    yPrev = y;
-	    add = !add;
-	    y = (add) ? y.plus(num.div(k)) : y.minus(num.div(k));
-	  }
-
-	  return y;
-	};
-
-
-/***/ },
-/* 142 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	var deepMap = __webpack_require__(29);
-	var isInteger = __webpack_require__(8).isInteger;
-
-	function factory (type, config, load, typed) {
-	  var multiply = load(__webpack_require__(40));
-	  var pow = load(__webpack_require__(100));
-
-	  /**
-	   * Compute the gamma function of a value using Lanczos approximation for
-	   * small values, and an extended Stirling approximation for large values.
-	   *
-	   * For matrices, the function is evaluated element wise.
-	   *
-	   * Syntax:
-	   *
-	   *    math.gamma(n)
-	   *
-	   * Examples:
-	   *
-	   *    math.gamma(5);       // returns 24
-	   *    math.gamma(-0.5);    // returns -3.5449077018110335
-	   *    math.gamma(math.i);  // returns -0.15494982830180973 - 0.49801566811835596i
-	   *
-	   * See also:
-	   *
-	   *    combinations, factorial, permutations
-	   *
-	   * @param {number | Array | Matrix} n   A real or complex number
-	   * @return {number | Array | Matrix}    The gamma of `n`
-	   */
-	  var gamma = typed('gamma', {
-	    'number': function (n) {
-	      var t, x;
-
-	      if (isInteger(n)) {
-	        if (n <= 0) {
-	          return isFinite(n) ? Infinity : NaN;
-	        }
-
-	        if (n > 171) {
-	          return Infinity;                  // Will overflow
-	        }
-
-	        var value = n - 2;
-	        var res = n - 1;
-	        while (value > 1) {
-	          res *= value;
-	          value--;
-	        }
-
-	        if (res == 0) {
-	          res = 1;                          // 0! is per definition 1
-	        }
-
-	        return res;
-	      }
-
-	      if (n < 0.5) {
-	        return Math.PI / (Math.sin(Math.PI * n) * gamma(1-n));
-	      }
-
-	      if (n >= 171.35) {
-	        return Infinity;                    // will overflow
-	      }
-
-	      if (n > 85.0) {                       // Extended Stirling Approx
-	        var twoN = n*n;
-	        var threeN = twoN*n;
-	        var fourN = threeN*n;
-	        var fiveN = fourN*n;
-	        return Math.sqrt(2*Math.PI/n) * Math.pow((n/Math.E), n) *
-	            (1 + 1/(12*n) + 1/(288*twoN) - 139/(51840*threeN) -
-	            571/(2488320*fourN) + 163879/(209018880*fiveN) +
-	            5246819/(75246796800*fiveN*n));
-	      }
-
-	      --n;
-	      x = p[0];
-	      for (var i = 1; i < p.length; ++i) {
-	        x += p[i] / (n+i);
-	      }
-
-	      t = n + g + 0.5;
-	      return Math.sqrt(2*Math.PI) * Math.pow(t, n+0.5) * Math.exp(-t) * x;
-	    },
-
-	    'Complex': function (n) {
-	      var t, x;
-
-	      if (n.im == 0) {
-	        return gamma(n.re);
-	      }
-
-	      n = new type.Complex(n.re - 1, n.im);
-	      x = new type.Complex(p[0], 0);
-	      for (var i = 1; i < p.length; ++i) {
-	        var real = n.re + i;                // x += p[i]/(n+i)
-	        var den = real*real + n.im*n.im;
-	        if (den != 0) {
-	          x.re += p[i] * real / den;
-	          x.im += -(p[i] * n.im) / den;
-	        } else {
-	          x.re = p[i] < 0
-	              ? -Infinity
-	              :  Infinity;
-	        }
-	      }
-
-	      t = new type.Complex(n.re + g + 0.5, n.im);
-	      var twoPiSqrt = Math.sqrt(2*Math.PI);
-
-	      n.re += 0.5;
-	      var result = pow(t, n);
-	      if (result.im == 0) {                 // sqrt(2*PI)*result
-	        result.re *= twoPiSqrt;
-	      } else if (result.re == 0) {
-	        result.im *= twoPiSqrt;
-	      } else {
-	        result.re *= twoPiSqrt;
-	        result.im *= twoPiSqrt;
-	      }
-
-	      var r = Math.exp(-t.re);              // exp(-t)
-	      t.re = r * Math.cos(-t.im);
-	      t.im = r * Math.sin(-t.im);
-
-	      return multiply(multiply(result, t), x);
-	    },
-
-	    'BigNumber': function (n) {
-	      if (n.isInteger()) {
-	        return (n.isNegative() || n.isZero())
-	            ? new type.BigNumber(Infinity)
-	            : bigFactorial(n.minus(1));
-	      }
-
-	      if (!n.isFinite()) {
-	        return new type.BigNumber(n.isNegative() ? NaN : Infinity);
-	      }
-
-	      throw new Error('Integer BigNumber expected');
-	    },
-
-	    'Array | Matrix': function (n) {
-	      return deepMap(n, gamma);
-	    }
-	  });
-
-	  /**
-	   * Calculate factorial for a BigNumber
-	   * @param {BigNumber} n
-	   * @returns {BigNumber} Returns the factorial of n
-	   */
-	  function bigFactorial(n) {
-	    var value, res, preciseFacs;
-
-	    var num = n.toNumber();   // should definitely be below Number.MAX_VALUE
-	    if (num < smallBigFacs.length) {
-	      return new type.BigNumber(smallBigFacs[num]).toSD(config.precision);
-	    }
-
-	    // be wary of round-off errors
-	    var precision = config.precision + (Math.log(num) | 0);
-	    var Big = type.BigNumber.constructor({precision: precision});
-
-	    // adjust n do align with the precision specific tables
-	    num -= smallBigFacs.length;
-	    if (preciseFacs = bigBigFacs[precision]) {
-	      if (preciseFacs[num]) {
-	        return new type.BigNumber(preciseFacs[num].toPrecision(config.precision));
-	      }
-	      res = preciseFacs[preciseFacs.length-1];
-	    } else {
-	      preciseFacs = bigBigFacs[precision] = [];
-	      res = new Big(smallBigFacs[smallBigFacs.length-1])
-	          .toSD(precision);
-	    }
-
-	    var one = new Big(1);
-	    value = new Big(preciseFacs.length + smallBigFacs.length);
-	    for (var i = preciseFacs.length; i < num; ++i) {
-	      preciseFacs[i] = res = res.times(value);
-	      value = value.plus(one);
-	    }
-
-	    preciseFacs[num] = res.times(value);
-	    return new type.BigNumber(preciseFacs[num].toPrecision(config.precision));
-	  }
-
-	  gamma.toTex = '\\Gamma\\left(${args[0]}\\right)';
-
-	  return gamma;
-	}
-
-	// TODO: comment on the variables g and p
-
-	var g = 4.7421875;
-
-	var p = [
-	  0.99999999999999709182,
-	  57.156235665862923517,
-	  -59.597960355475491248,
-	  14.136097974741747174,
-	  -0.49191381609762019978,
-	  0.33994649984811888699e-4,
-	  0.46523628927048575665e-4,
-	  -0.98374475304879564677e-4,
-	  0.15808870322491248884e-3,
-	  -0.21026444172410488319e-3,
-	  0.21743961811521264320e-3,
-	  -0.16431810653676389022e-3,
-	  0.84418223983852743293e-4,
-	  -0.26190838401581408670e-4,
-	  0.36899182659531622704e-5
-	];
-
-	// 21! >= values for each precision
-	var bigBigFacs = [];
-
-	// 0-20! values
-	var smallBigFacs = [
-	  1,
-	  1,
-	  2,
-	  6,
-	  24,
-	  120,
-	  720,
-	  5040,
-	  40320,
-	  362880,
-	  3628800,
-	  39916800,
-	  479001600,
-	  6227020800,
-	  87178291200,
-	  1307674368000,
-	  20922789888000,
-	  355687428096000,
-	  6402373705728000,
-	  121645100408832000,
-	  2432902008176640000
-	];
-
-	exports.name = 'gamma';
-	exports.factory = factory;
-
-
-/***/ },
-/* 143 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	var isInteger = __webpack_require__(8).isInteger;
-
-	function factory (type, config, load, typed) {
-	  /**
-	   * Compute the number of ways of picking `k` unordered outcomes from `n`
-	   * possibilities.
-	   *
-	   * Combinations only takes integer arguments.
-	   * The following condition must be enforced: k <= n.
-	   *
-	   * Syntax:
-	   *
-	   *     math.combinations(n, k)
-	   *
-	   * Examples:
-	   *
-	   *    math.combinations(7, 5); // returns 21
-	   *
-	   * See also:
-	   *
-	   *    permutations, factorial
-	   *
-	   * @param {number | BigNumber} n    Total number of objects in the set
-	   * @param {number | BigNumber} k    Number of objects in the subset
-	   * @return {number | BigNumber}     Number of possible combinations.
-	   */
-	  var combinations = typed('combinations', {
-	    'number, number': function (n, k) {
-	      var max, result, i;
-
-	      if (!isInteger(n) || n < 0) {
-	        throw new TypeError('Positive integer value expected in function combinations');
-	      }
-	      if (k > n) {
-	        throw new TypeError('k must be less than or equal to n');
-	      }
-
-	      max = Math.max(k, n - k);
-	      result = 1;
-	      for (i = 1; i <= n - max; i++) {
-	        result = result * (max + i) / i;
-	      }
-
-	      return result;
-	    },
-
-	    'BigNumber, BigNumber': function (n, k) {
-	      var max, result, i, ii;
-	      var one = new type.BigNumber(1);
-
-	      if (!isPositiveInteger(n) || !isPositiveInteger(k)) {
-	        throw new TypeError('Positive integer value expected in function combinations');
-	      }
-	      if (k.gt(n)) {
-	        throw new TypeError('k must be less than n in function combinations');
-	      }
-
-	      max = n.minus(k);
-	      if (k.lt(max)) max = k;
-	      result = one;
-	      for (i = one, ii = n.minus(max); i.lte(ii); i = i.plus(1)) {
-	        result = result.times(max.plus(i)).dividedBy(i);
-	      }
-
-	      return result;
-	    }
-
-	    // TODO: implement support for collection in combinations
-	  });
-
-	  combinations.toTex = '\\binom{${args[0]}}{${args[1]}}';
-
-	  return combinations;
-	}
-
-	/**
-	 * Test whether BigNumber n is a positive integer
-	 * @param {BigNumber} n
-	 * @returns {boolean} isPositiveInteger
-	 */
-	function isPositiveInteger(n) {
-	  return n.isInteger() && n.gte(0);
-	}
-
-	exports.name = 'combinations';
-	exports.factory = factory;
-
-
-/***/ },
-/* 144 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	var deepMap = __webpack_require__(29);
-	var number = __webpack_require__(8);
-
-	function factory (type, config, load, typed) {
-	  /**
-	   * Test whether a value is negative: smaller than zero.
-	   * The function supports types `number`, `BigNumber`, `Fraction`, and `Unit`.
-	   *
-	   * The function is evaluated element-wise in case of Array or Matrix input.
-	   *
-	   * Syntax:
-	   *
-	   *     math.isNegative(x)
-	   *
-	   * Examples:
-	   *
-	   *    math.isNegative(3);                     // returns false
-	   *    math.isNegative(-2);                    // returns true
-	   *    math.isNegative(0);                     // returns false
-	   *    math.isNegative(-0);                    // returns false
-	   *    math.isNegative(math.bignumber(2));     // returns false
-	   *    math.isNegative(math.fraction(-2, 5));  // returns true
-	   *    math.isNegative('-2');                  // returns true
-	   *    math.isNegative([2, 0, -3]');           // returns [false, false, true]
-	   *
-	   * See also:
-	   *
-	   *    isNumeric, isPositive, isZero, isInteger
-	   *
-	   * @param {number | BigNumber | Fraction | Unit | Array | Matrix} x  Value to be tested
-	   * @return {boolean}  Returns true when `x` is larger than zero.
-	   *                    Throws an error in case of an unknown data type.
-	   */
-	  var isNegative = typed('isNegative', {
-	    'number': function (x) {
-	      return x < 0;
-	    },
-
-	    'BigNumber': function (x) {
-	      return x.isNeg() && !x.isZero() && !x.isNaN();
-	    },
-
-	    'Fraction': function (x) {
-	      return x.s < 0 && x.n > 0;
-	    },
-
-	    'Unit': function (x) {
-	      return x.value < 0;
-	    },
-
-	    'Array | Matrix': function (x) {
-	      return deepMap(x, isNegative);
-	    }
-	  });
-
-	  return isNegative;
-	}
-
-	exports.name = 'isNegative';
-	exports.factory = factory;
-
-
-/***/ },
-/* 145 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	var deepMap = __webpack_require__(29);
-	var number = __webpack_require__(8);
-
-	function factory (type, config, load, typed) {
-	  /**
-	   * Test whether a value is an integer number.
-	   * The function supports `number`, `BigNumber`, and `Fraction`.
-	   *
-	   * The function is evaluated element-wise in case of Array or Matrix input.
-	   *
-	   * Syntax:
-	   *
-	   *     math.isInteger(x)
-	   *
-	   * Examples:
-	   *
-	   *    math.isInteger(2);                     // returns true
-	   *    math.isInteger(0);                     // returns true
-	   *    math.isInteger(0.5);                   // returns false
-	   *    math.isInteger(math.bignumber(500));   // returns true
-	   *    math.isInteger(math.fraction(4));      // returns true
-	   *    math.isInteger('3');                   // returns true
-	   *    math.isInteger([3, 0.5, -2]);          // returns [true, false, true]
-	   *    math.isInteger(math.complex('2 - 4i'); // throws an error
-	   *
-	   * See also:
-	   *
-	   *    isNumeric, isPositive, isNegative, isZero
-	   *
-	   * @param {number | BigNumber | Fraction | Array | Matrix} x   Value to be tested
-	   * @return {boolean}  Returns true when `x` contains a numeric, integer value.
-	   *                    Throws an error in case of an unknown data type.
-	   */
-	  var isInteger = typed('isInteger', {
-	    'number': number.isInteger, // TODO: what to do with isInteger(add(0.1, 0.2))  ?
-
-	    'BigNumber': function (x) {
-	      return x.isInt();
-	    },
-
-	    'Fraction': function (x) {
-	      return x.d === 1 && isFinite(x.n);
-	    },
-
-	    'Array | Matrix': function (x) {
-	      return deepMap(x, isInteger);
-	    }
-	  });
-
-	  return isInteger;
-	}
-
-	exports.name = 'isInteger';
-	exports.factory = factory;
-
-
-/***/ },
-/* 146 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	function factory (type, config, load, typed) {
-	  var combinations = load(__webpack_require__(143));
-	  var add = load(__webpack_require__(27));
-	  var isPositive = load(__webpack_require__(147));
-	  var isInteger = load(__webpack_require__(145));
-	  var larger = load(__webpack_require__(64));
-
-	  /**
-	   * The composition counts of n into k parts.
-	   *
-	   * composition only takes integer arguments.
-	   * The following condition must be enforced: k <= n.
-	   *
-	   * Syntax:
-	   *
-	   *   math.composition(n, k)
-	   *
-	   * Examples:
-	   *
-	   *    math.composition(5, 3); // returns 6
-	   *
-	   * See also:
-	   *
-	   *    combinations
-	   *
-	   * @param {Number | BigNumber} n    Total number of objects in the set
-	   * @param {Number | BigNumber} k    Number of objects in the subset
-	   * @return {Number | BigNumber}     Returns the composition counts of n into k parts.
-	   */
-	  var composition =  typed('composition', {
-	    'number | BigNumber, number | BigNumber': function (n, k) {
-	      if (!isInteger(n) || !isPositive(n) || !isInteger(k) || !isPositive(k)) {
-	        throw new TypeError('Positive integer value expected in function composition');
-	      }
-	      else if (larger(k, n)) {
-	        throw new TypeError('k must be less than or equal to n in function composition');
-	      }
-
-	      return combinations(add(n, -1), add(k, -1));
-	    }
-	  });
-
-	  composition.toTex = '\\mathrm{${name}}\\left(${args}\\right)';
-
-	  return composition;
-	}
-
-	exports.name = 'composition';
-	exports.factory = factory;
-
-
-/***/ },
-/* 147 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	var deepMap = __webpack_require__(29);
-	var number = __webpack_require__(8);
-
-	function factory (type, config, load, typed) {
-	  /**
-	   * Test whether a value is positive: larger than zero.
-	   * The function supports types `number`, `BigNumber`, `Fraction`, and `Unit`.
-	   *
-	   * The function is evaluated element-wise in case of Array or Matrix input.
-	   *
-	   * Syntax:
-	   *
-	   *     math.isPositive(x)
-	   *
-	   * Examples:
-	   *
-	   *    math.isPositive(3);                     // returns true
-	   *    math.isPositive(-2);                    // returns false
-	   *    math.isPositive(0);                     // returns false
-	   *    math.isPositive(-0);                    // returns false
-	   *    math.isPositive(0.5);                   // returns true
-	   *    math.isPositive(math.bignumber(2));     // returns true
-	   *    math.isPositive(math.fraction(-2, 5));  // returns false
-	   *    math.isPositive(math.fraction(1,3));    // returns false
-	   *    math.isPositive('2');                   // returns true
-	   *    math.isPositive([2, 0, -3]');           // returns [true, false, false]
-	   *
-	   * See also:
-	   *
-	   *    isNumeric, isZero, isNegative, isInteger
-	   *
-	   * @param {number | BigNumber | Fraction | Unit | Array | Matrix} x  Value to be tested
-	   * @return {boolean}  Returns true when `x` is larger than zero.
-	   *                    Throws an error in case of an unknown data type.
-	   */
-	  var isPositive = typed('isPositive', {
-	    'number': function (x) {
-	      return x > 0;
-	    },
-
-	    'BigNumber': function (x) {
-	      return !x.isNeg() && !x.isZero() && !x.isNaN();
-	    },
-
-	    'Fraction': function (x) {
-	      return x.s > 0 && x.n > 0;
-	    },
-
-	    'Unit': function (x) {
-	      return x.value > 0;
-	    },
-
-	    'Array | Matrix': function (x) {
-	      return deepMap(x, isPositive);
-	    }
-	  });
-
-	  return isPositive;
-	}
-
-	exports.name = 'isPositive';
-	exports.factory = factory;
-
-
-/***/ },
-/* 148 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	function factory (type, config, load, typed) {
-	  var add = load(__webpack_require__(44));
-	  var divide = load(__webpack_require__(94));
-	  var multiply = load(__webpack_require__(40));
-	  var combinations = load(__webpack_require__(143));
-	  var isNegative = load(__webpack_require__(144));
-	  var isInteger = load(__webpack_require__(145));
-
-
-	  /**
-	   * The Catalan Numbers enumerate combinatorial structures of many different types.
-	   * catalan only takes integer arguments.
-	   * The following condition must be enforced: n >= 0
-	   *
-	   * Syntax:
-	   *
-	   *   math.catalan(n)
-	   *
-	   * Examples:
-	   *
-	   *    math.catalan(3); // returns 5;
-	   *    math.catalan(8); // returns 1430;
-	   *
-	   * See also:
-	   *
-	   *    bellNumbers
-	   *
-	   * @param {Number | BigNumber} n    nth Catalan number
-	   * @return {Number | BigNumber}     Cn(n)
-	   */
-	  var catalan = typed('catalan', {
-	    'number | BigNumber': function (n) {
-
-	      if (!isInteger(n) || isNegative(n)) {
-	        throw new TypeError('Non-negative integer value expected in function catalan');
-	      }
-	       
-	      return divide(combinations(multiply(n,2), n), add(n,1));
-
-	    }
-	  });
-
-	  catalan.toTex = '\\mathrm{C}_{${args[0]}}';
-
-	  return catalan;
-	}
-
-	exports.name = 'catalan';
-	exports.factory = factory;
-
-
-/***/ },
-/* 149 */
-/***/ function(module, exports, __webpack_require__) {
-
-	module.exports = [
-	  __webpack_require__(150),
-	  __webpack_require__(151),
-	  __webpack_require__(152),
-	  __webpack_require__(153)
-	];
-
-
-/***/ },
-/* 150 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	var deepMap = __webpack_require__(29);
-
-	function factory (type, config, load, typed) {
-	  /**
-	   * Compute the argument of a complex value.
-	   * For a complex number `a + bi`, the argument is computed as `atan2(b, a)`.
-	   *
-	   * For matrices, the function is evaluated element wise.
-	   *
-	   * Syntax:
-	   *
-	   *    math.arg(x)
-	   *
-	   * Examples:
-	   *
-	   *    var a = math.complex(2, 2);
-	   *    math.arg(a) / math.pi;          // returns number 0.25
-	   *
-	   *    var b = math.complex('2 + 3i');
-	   *    math.arg(b);                    // returns number 0.982793723247329
-	   *    math.atan2(3, 2);               // returns number 0.982793723247329
-	   *
-	   * See also:
-	   *
-	   *    re, im, conj, abs
-	   *
-	   * @param {number | Complex | Array | Matrix} x
-	   *            A complex number or array with complex numbers
-	   * @return {number | Array | Matrix} The argument of x
-	   */
-	  var arg = typed('arg', {
-	    'number': function (x) {
-	      return Math.atan2(0, x);
-	    },
-
-	    'Complex': function (x) {
-	      return Math.atan2(x.im, x.re);
-	    },
-
-	    // TODO: implement BigNumber support for function arg
-
-	    'Array | Matrix': function (x) {
-	      return deepMap(x, arg);
-	    }
-	  });
-
-	  arg.toTex = '\\arg\\left(${args[0]}\\right)';
-
-	  return arg;
-	}
-
-	exports.name = 'arg';
-	exports.factory = factory;
-
-
-/***/ },
-/* 151 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	var deepMap = __webpack_require__(29);
-
-	function factory (type, config, load, typed) {
-	  /**
-	   * Compute the complex conjugate of a complex value.
-	   * If `x = a+bi`, the complex conjugate of `x` is `a - bi`.
-	   *
-	   * For matrices, the function is evaluated element wise.
-	   *
-	   * Syntax:
-	   *
-	   *    math.conj(x)
-	   *
-	   * Examples:
-	   *
-	   *    math.conj(math.complex('2 + 3i'));  // returns Complex 2 - 3i
-	   *    math.conj(math.complex('2 - 3i'));  // returns Complex 2 + 3i
-	   *    math.conj(math.complex('-5.2i'));  // returns Complex 5.2i
-	   *
-	   * See also:
-	   *
-	   *    re, im, arg, abs
-	   *
-	   * @param {number | BigNumber | Complex | Array | Matrix} x
-	   *            A complex number or array with complex numbers
-	   * @return {number | BigNumber | Complex | Array | Matrix}
-	   *            The complex conjugate of x
-	   */
-	  var conj = typed('conj', {
-	    'number': function (x) {
-	      return x;
-	    },
-
-	    'BigNumber': function (x) {
-	      return x;
-	    },
-
-	    'Complex': function (x) {
-	      return new type.Complex(x.re, -x.im);
-	    },
-
-	    'Array | Matrix': function (x) {
-	      return deepMap(x, conj);
-	    }
-	  });
-
-	  conj.toTex = '\\left(${args[0]}\\right)^*';
-
-	  return conj;
-	}
-
-	exports.name = 'conj';
-	exports.factory = factory;
-
-
-/***/ },
-/* 152 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	var deepMap = __webpack_require__(29);
-
-	function factory (type, config, load, typed) {
-	  /**
-	   * Get the imaginary part of a complex number.
-	   * For a complex number `a + bi`, the function returns `b`.
-	   *
-	   * For matrices, the function is evaluated element wise.
-	   *
-	   * Syntax:
-	   *
-	   *    math.im(x)
-	   *
-	   * Examples:
-	   *
-	   *    var a = math.complex(2, 3);
-	   *    math.re(a);                     // returns number 2
-	   *    math.im(a);                     // returns number 3
-	   *
-	   *    math.re(math.complex('-5.2i')); // returns number -5.2
-	   *    math.re(math.complex(2.4));     // returns number 0
-	   *
-	   * See also:
-	   *
-	   *    re, conj, abs, arg
-	   *
-	   * @param {number | BigNumber | Complex | Array | Matrix} x
-	   *            A complex number or array with complex numbers
-	   * @return {number | BigNumber | Array | Matrix} The imaginary part of x
-	   */
-	  var im = typed('im', {
-	    'number': function (x) {
-	      return 0;
-	    },
-
-	    'BigNumber': function (x) {
-	      return new type.BigNumber(0);
-	    },
-
-	    'Complex': function (x) {
-	      return x.im;
-	    },
-
-	    'Array | Matrix': function (x) {
-	      return deepMap(x, im);
-	    }
-	  });
-
-	  im.toTex = '\\Im\\left\\lbrace${args[0]}\\right\\rbrace';
-
-	  return im;
-	}
-
-	exports.name = 'im';
-	exports.factory = factory;
-
-
-/***/ },
-/* 153 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	var deepMap = __webpack_require__(29);
-
-	function factory (type, config, load, typed) {
-	  /**
-	   * Get the real part of a complex number.
-	   * For a complex number `a + bi`, the function returns `a`.
-	   *
-	   * For matrices, the function is evaluated element wise.
-	   *
-	   * Syntax:
-	   *
-	   *    math.re(x)
-	   *
-	   * Examples:
-	   *
-	   *    var a = math.complex(2, 3);
-	   *    math.re(a);                     // returns number 2
-	   *    math.im(a);                     // returns number 3
-	   *
-	   *    math.re(math.complex('-5.2i')); // returns number 0
-	   *    math.re(math.complex(2.4));     // returns number 2.4
-	   *
-	   * See also:
-	   *
-	   *    im, conj, abs, arg
-	   *
-	   * @param {number | BigNumber | Complex | Array | Matrix} x
-	   *            A complex number or array with complex numbers
-	   * @return {number | BigNumber | Array | Matrix} The real part of x
-	   */
-	  var re = typed('re', {
-	    'number': function (x) {
-	      return x;
-	    },
-
-	    'BigNumber': function (x) {
-	      return x;
-	    },
-
-	    'Complex': function (x) {
-	      return x.re;
-	    },
-
-	    'Array | Matrix': function (x) {
-	      return deepMap(x, re);
-	    }
-	  });
-
-	  re.toTex = '\\Re\\left\\lbrace${args[0]}\\right\\rbrace';
-
-	  return re;
-	}
-
-	exports.name = 're';
-	exports.factory = factory;
-
-
-/***/ },
-/* 154 */
-/***/ function(module, exports, __webpack_require__) {
-
-	module.exports = [
-	  __webpack_require__(155)
-	];
-
-
-/***/ },
-/* 155 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	function factory (type, config, load, typed) {
-	  var matrix = load(__webpack_require__(23));
-
-	  /**
-	   * Calculates the point of intersection of two lines in two or three dimensions
-	   * and of a line and a plane in three dimensions. The inputs are in the form of
-	   * arrays or 1 dimensional matrices. The line intersection functions return null
-	   * if the lines do not meet.
-	   *
-	   * Note: Fill the plane coefficients as `x + y + z = c` and not as `x + y + z + c = 0`.
-	   *
-	   * Syntax:
-	   *
-	   *    math.intersect(endPoint1Line1, endPoint2Line1, endPoint1Line2, endPoint2Line2)
-	   *    math.intersect(endPoint1, endPoint2, planeCoefficients)
-	   *
-	   * Examples:
-	   *
-	   *    math.intersect([0, 0], [10, 10], [10, 0], [0, 10]);              // Returns [5, 5]
-	   *    math.intersect([0, 0, 0], [10, 10, 0], [10, 0, 0], [0, 10, 0]);  // Returns [5, 5, 0]
-	   *    math.intersect([1, 0, 1],  [4, -2, 2], [1, 1, 1, 6]);            // Returns [7, -4, 3]
-	   *
-	   * @param  {Array | Matrix} w   Co-ordinates of first end-point of first line
-	   * @param  {Array | Matrix} x   Co-ordinates of second end-point of first line
-	   * @param  {Array | Matrix} y   Co-ordinates of first end-point of second line
-	   *                              OR Co-efficients of the plane's equation
-	   * @param  {Array | Matrix} z   Co-ordinates of second end-point of second line
-	   *                              OR null if the calculation is for line and plane
-	   * @return {Array}              Returns the point of intersection of lines/lines-planes
-	   */
-	  var intersect = typed('intersect', {
-	    'Array, Array, Array': function (x, y, plane) {
-	      if (!_3d(x)) { throw new TypeError('Array with 3 numbers expected for first argument'); }
-	      if (!_3d(y)) { throw new TypeError('Array with 3 numbers expected for second argument'); }
-	      if (!_4d(plane)) { throw new TypeError('Array with 4 numbers expected as third argument'); }
-
-	      return _intersectLinePlane(x[0], x[1], x[2], y[0], y[1], y[2], plane[0], plane[1], plane[2], plane[3]);
-	    },
-
-	    'Array, Array, Array, Array': function (w, x, y, z) {
-	      if (w.length === 2) {
-	        if (!_2d(w)) { throw new TypeError('Array with 2 numbers expected for first argument'); }
-	        if (!_2d(x)) { throw new TypeError('Array with 2 numbers expected for second argument'); }
-	        if (!_2d(y)) { throw new TypeError('Array with 2 numbers expected for third argument'); }
-	        if (!_2d(z)) { throw new TypeError('Array with 2 numbers expected for fourth argument'); }
-
-	        return _intersect2d(w[0], w[1], x[0], x[1], y[0], y[1], z[0], z[1]);
-	      }
-	      else if (w.length === 3) {
-	        if (!_3d(w)) { throw new TypeError('Array with 3 numbers expected for first argument'); }
-	        if (!_3d(x)) { throw new TypeError('Array with 3 numbers expected for second argument'); }
-	        if (!_3d(y)) { throw new TypeError('Array with 3 numbers expected for third argument'); }
-	        if (!_3d(z)) { throw new TypeError('Array with 3 numbers expected for fourth argument'); }
-
-	        return _intersect3d(w[0], w[1], w[2], x[0], x[1], x[2], y[0], y[1], y[2], z[0], z[1], z[2]);
-	      }
-	      else {
-	        throw new TypeError('Arrays with two or thee dimensional points expected');
-	      }
-	    },
-
-	    'Matrix, Matrix, Matrix': function (x, y, plane) {
-	      return matrix(intersect(x.valueOf(), y.valueOf(), plane.valueOf()));
-	    },
-
-	    'Matrix, Matrix, Matrix, Matrix': function (w, x, y, z) {
-	      // TODO: output matrix type should match input matrix type
-	      return matrix(intersect(w.valueOf(), x.valueOf(), y.valueOf(), z.valueOf()));
-	    }
-	  });
-
-	  return intersect;
-	}
-
-	function _2d(x) {
-	  return x.length === 2 && typeof x[0] === 'number' && typeof x[1] === 'number';
-	}
-
-	function _3d(x) {
-	  return x.length === 3 && typeof x[0] === 'number' && typeof x[1] === 'number' && typeof x[2] === 'number';
-	}
-
-	function _4d(x) {
-	  return x.length === 4 && typeof x[0] === 'number' && typeof x[1] === 'number' && typeof x[2] === 'number' && typeof x[3] === 'number';
-	}
-
-	function _intersect2d(x1, y1, x2, y2, x3, y3, x4, y4){
-	  var d1343 = (x1 - x3)*(x4 - x3) + (y1 - y3)*(y4 - y3);
-	  var d4321 = (x4 - x3)*(x2 - x1) + (y4 - y3)*(y2 - y1);
-	  var d1321 = (x1 - x3)*(x2 - x1) + (y1 - y3)*(y2 - y1);
-	  var d4343 = (x4 - x3)*(x4 - x3) + (y4 - y3)*(y4 - y3);
-	  var d2121 = (x2 - x1)*(x2 - x1) + (y2 - y1)*(y2 - y1);
-	  var ta = ( d1343*d4321 - d1321*d4343 ) / ( d2121*d4343 - d4321*d4321 );
-	  var tb = ( d1343 + ta * d4321 ) / (d4343);
-
-	  var pax = x1 + ta * (x2 - x1);
-	  var pay = y1 + ta * (y2 - y1);
-	  var pbx = x3 + tb * (x4 - x3);
-	  var pby = y3 + tb * (y4 - y3);
-	  if (pax === pbx && pay === pby){
-	    return [pax, pay];
-	  }
-	  else{
-	    return null;
-	  }
-	}
-
-	function _intersect3d(x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4){
-	  var d1343 = (x1 - x3)*(x4 - x3) + (y1 - y3)*(y4 - y3) + (z1 - z3)*(z4 - z3);
-	  var d4321 = (x4 - x3)*(x2 - x1) + (y4 - y3)*(y2 - y1) + (z4 - z3)*(z2 - z1);
-	  var d1321 = (x1 - x3)*(x2 - x1) + (y1 - y3)*(y2 - y1) + (z1 - z3)*(z2 - z1);
-	  var d4343 = (x4 - x3)*(x4 - x3) + (y4 - y3)*(y4 - y3) + (z4 - z3)*(z4 - z3);
-	  var d2121 = (x2 - x1)*(x2 - x1) + (y2 - y1)*(y2 - y1) + (z2 - z1)*(z2 - z1);
-	  var ta = ( d1343*d4321 - d1321*d4343 ) / ( d2121*d4343 - d4321*d4321 );
-	  var tb = ( d1343 + ta * d4321 ) / (d4343);
-
-	  var pax = x1 + ta * (x2 - x1);
-	  var pay = y1 + ta * (y2 - y1);
-	  var paz = z1 + ta * (z2 - z1);
-	  var pbx = x3 + tb * (x4 - x3);
-	  var pby = y3 + tb * (y4 - y3);
-	  var pbz = z3 + tb * (z4 - z3);
-	  if (pax === pbx && pay === pby && paz === pbz){
-	    return [pax, pay, paz];
-	  }
-	  else{
-	    return null;
-	  }
-	}
-
-	function _intersectLinePlane(x1, y1, z1, x2, y2, z2, x, y, z, c){
-	  var t = (c - x1*x - y1*y - z1*z)/(x2*x + y2*y + z2*z - x1 - y1 - z1);
-	  var px = x1 + t * (x2 - x1);
-	  var py = y1 + t * (y2 - y1);
-	  var pz = z1 + t * (z2 - z1);
-	  return [px, py, pz];
-	  // TODO: Add cases when line is parallel to the plane:
-	  //       (a) no intersection,
-	  //       (b) line contained in plane
-	}
-
-	exports.name = 'intersect';
-	exports.factory = factory;
-
-
-/***/ },
-/* 156 */
-/***/ function(module, exports, __webpack_require__) {
-
-	module.exports = [
-	  __webpack_require__(157),
-	  __webpack_require__(158),
-	  __webpack_require__(159),
-	  __webpack_require__(160)
-	];
-
-
-/***/ },
-/* 157 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	function factory (type, config, load, typed) {
-	  var latex = __webpack_require__(26);
-
-	  var matrix = load(__webpack_require__(23));
-	  var zeros = load(__webpack_require__(60));
-	  var not = load(__webpack_require__(158));
-
-	  var algorithm02 = load(__webpack_require__(96));
-	  var algorithm06 = load(__webpack_require__(107));
-	  var algorithm11 = load(__webpack_require__(42));
-	  var algorithm13 = load(__webpack_require__(35));
-	  var algorithm14 = load(__webpack_require__(39));
-
-	  /**
-	   * Logical `and`. Test whether two values are both defined with a nonzero/nonempty value.
-	   * For matrices, the function is evaluated element wise.
-	   *
-	   * Syntax:
-	   *
-	   *    math.and(x, y)
-	   *
-	   * Examples:
-	   *
-	   *    math.and(2, 4);   // returns true
-	   *
-	   *    a = [2, 0, 0];
-	   *    b = [3, 7, 0];
-	   *    c = 0;
-	   *
-	   *    math.and(a, b);   // returns [true, false, false]
-	   *    math.and(a, c);   // returns [false, false, false]
-	   *
-	   * See also:
-	   *
-	   *    not, or, xor
-	   *
-	   * @param  {number | BigNumber | Complex | Unit | Array | Matrix} x First value to check
-	   * @param  {number | BigNumber | Complex | Unit | Array | Matrix} y Second value to check
-	   * @return {boolean | Array | Matrix}
-	   *            Returns true when both inputs are defined with a nonzero/nonempty value.
-	   */
-	  var and = typed('and', {
-
-	    'number, number': function (x, y) {
-	      return !!(x && y);
-	    },
-
-	    'Complex, Complex': function (x, y) {
-	      return (x.re !== 0 || x.im !== 0) && (y.re !== 0 || y.im !== 0);
-	    },
-
-	    'BigNumber, BigNumber': function (x, y) {
-	      return !x.isZero() && !y.isZero() && !x.isNaN() && !y.isNaN();
-	    },
-
-	    'Unit, Unit': function (x, y) {
-	      return (x.value !== 0 && x.value !== null) && (y.value !== 0 && y.value !== null);
-	    },
-	    
-	    'Matrix, Matrix': function (x, y) {
-	      // result
-	      var c;
-
-	      // process matrix storage
-	      switch (x.storage()) {
-	        case 'sparse':
-	          switch (y.storage()) {
-	            case 'sparse':
-	              // sparse & sparse
-	              c = algorithm06(x, y, and, false);
-	              break;
-	            default:
-	              // sparse & dense
-	              c = algorithm02(y, x, and, true);
-	              break;
-	          }
-	          break;
-	        default:
-	          switch (y.storage()) {
-	            case 'sparse':
-	              // dense & sparse
-	              c = algorithm02(x, y, and, false);
-	              break;
-	            default:
-	              // dense & dense
-	              c = algorithm13(x, y, and);
-	              break;
-	          }
-	          break;
-	      }
-	      return c;
-	    },
-
-	    'Array, Array': function (x, y) {
-	      // use matrix implementation
-	      return and(matrix(x), matrix(y)).valueOf();
-	    },
-
-	    'Array, Matrix': function (x, y) {
-	      // use matrix implementation
-	      return and(matrix(x), y);
-	    },
-
-	    'Matrix, Array': function (x, y) {
-	      // use matrix implementation
-	      return and(x, matrix(y));
-	    },
-
-	    'Matrix, any': function (x, y) {
-	      // check scalar
-	      if (not(y)) {
-	        // return zero matrix
-	        return zeros(x.size(), x.storage());
-	      }
-	      // result
-	      var c;
-	      // check storage format
-	      switch (x.storage()) {
-	        case 'sparse':
-	          c = algorithm11(x, y, and, false);
-	          break;
-	        default:
-	          c = algorithm14(x, y, and, false);
-	          break;
-	      }
-	      return c;
-	    },
-
-	    'any, Matrix': function (x, y) {
-	      // check scalar
-	      if (not(x)) {
-	        // return zero matrix
-	        return zeros(x.size(), x.storage());
-	      }
-	      // result
-	      var c;
-	      // check storage format
-	      switch (y.storage()) {
-	        case 'sparse':
-	          c = algorithm11(y, x, and, true);
-	          break;
-	        default:
-	          c = algorithm14(y, x, and, true);
-	          break;
-	      }
-	      return c;
-	    },
-
-	    'Array, any': function (x, y) {
-	      // use matrix implementation
-	      return and(matrix(x), y).valueOf();
-	    },
-
-	    'any, Array': function (x, y) {
-	      // use matrix implementation
-	      return and(x, matrix(y)).valueOf();
-	    }
-	  });
-
-	  and.toTex = '\\left(${args[0]}' + latex.operators['and'] + '${args[1]}\\right)';
-
-	  return and;
-	}
-
-	exports.name = 'and';
-	exports.factory = factory;
-
-
-/***/ },
-/* 158 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	var deepMap = __webpack_require__(29);
-
-	function factory (type, config, load, typed) {
-	  var latex = __webpack_require__(26);
-
-	  /**
-	   * Logical `not`. Flips boolean value of a given parameter.
-	   * For matrices, the function is evaluated element wise.
-	   *
-	   * Syntax:
-	   *
-	   *    math.not(x)
-	   *
-	   * Examples:
-	   *
-	   *    math.not(2);      // returns false
-	   *    math.not(0);      // returns true
-	   *    math.not(true);   // returns false
-	   *
-	   *    a = [2, -7, 0];
-	   *    math.not(a);      // returns [false, false, true]
-	   *
-	   * See also:
-	   *
-	   *    and, or, xor
-	   *
-	   * @param  {number | BigNumber | Complex | Unit | Array | Matrix} x First value to check
-	   * @return {boolean | Array | Matrix}
-	   *            Returns true when input is a zero or empty value.
-	   */
-	  var not = typed('not', {
-	    'number': function (x) {
-	      return !x;
-	    },
-
-	    'Complex': function (x) {
-	      return x.re === 0 && x.im === 0;
-	    },
-
-	    'BigNumber': function (x) {
-	      return x.isZero() || x.isNaN();
-	    },
-
-	    'Unit': function (x) {
-	      return x.value === null || x.value == 0;
-	    },
-
-	    'Array | Matrix': function (x) {
-	      return deepMap(x, not);
-	    }
-	  });
-
-	  not.toTex = latex.operators['not'] + '\\left(${args[0]}\\right)';
-
-	  return not;
-	}
-
-	exports.name = 'not';
-	exports.factory = factory;
-
-
-/***/ },
-/* 159 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	function factory (type, config, load, typed) {
-	  var latex = __webpack_require__(26);
-
-	  var matrix = load(__webpack_require__(23));
-
-	  var algorithm03 = load(__webpack_require__(31));
-	  var algorithm05 = load(__webpack_require__(32));
-	  var algorithm12 = load(__webpack_require__(65));
-	  var algorithm13 = load(__webpack_require__(35));
-	  var algorithm14 = load(__webpack_require__(39));
-	  
-	  /**
-	   * Logical `or`. Test if at least one value is defined with a nonzero/nonempty value.
-	   * For matrices, the function is evaluated element wise.
-	   *
-	   * Syntax:
-	   *
-	   *    math.or(x, y)
-	   *
-	   * Examples:
-	   *
-	   *    math.or(2, 4);   // returns true
-	   *
-	   *    a = [2, 5, 0];
-	   *    b = [0, 22, 0];
-	   *    c = 0;
-	   *
-	   *    math.or(a, b);   // returns [true, true, false]
-	   *    math.or(b, c);   // returns [false, true, false]
-	   *
-	   * See also:
-	   *
-	   *    and, not, xor
-	   *
-	   * @param  {number | BigNumber | Complex | Unit | Array | Matrix} x First value to check
-	   * @param  {number | BigNumber | Complex | Unit | Array | Matrix} y Second value to check
-	   * @return {boolean | Array | Matrix}
-	   *            Returns true when one of the inputs is defined with a nonzero/nonempty value.
-	   */
-	  var or = typed('or', {
-
-	    'number, number': function (x, y) {
-	      return !!(x || y);
-	    },
-
-	    'Complex, Complex': function (x, y) {
-	      return (x.re !== 0 || x.im !== 0) || (y.re !== 0 || y.im !== 0);
-	    },
-
-	    'BigNumber, BigNumber': function (x, y) {
-	      return (!x.isZero() && !x.isNaN()) || (!y.isZero() && !y.isNaN());
-	    },
-
-	    'Unit, Unit': function (x, y) {
-	      return (x.value !== 0 && x.value !== null) || (y.value !== 0 && y.value !== null);
-	    },
-
-	    'Matrix, Matrix': function (x, y) {
-	      // result
-	      var c;
-
-	      // process matrix storage
-	      switch (x.storage()) {
-	        case 'sparse':
-	          switch (y.storage()) {
-	            case 'sparse':
-	              // sparse + sparse
-	              c = algorithm05(x, y, or);
-	              break;
-	            default:
-	              // sparse + dense
-	              c = algorithm03(y, x, or, true);
-	              break;
-	          }
-	          break;
-	        default:
-	          switch (y.storage()) {
-	            case 'sparse':
-	              // dense + sparse
-	              c = algorithm03(x, y, or, false);
-	              break;
-	            default:
-	              // dense + dense
-	              c = algorithm13(x, y, or);
-	              break;
-	          }
-	          break;
-	      }
-	      return c;
-	    },
-
-	    'Array, Array': function (x, y) {
-	      // use matrix implementation
-	      return or(matrix(x), matrix(y)).valueOf();
-	    },
-
-	    'Array, Matrix': function (x, y) {
-	      // use matrix implementation
-	      return or(matrix(x), y);
-	    },
-
-	    'Matrix, Array': function (x, y) {
-	      // use matrix implementation
-	      return or(x, matrix(y));
-	    },
-
-	    'Matrix, any': function (x, y) {
-	      // result
-	      var c;
-	      // check storage format
-	      switch (x.storage()) {
-	        case 'sparse':
-	          c = algorithm12(x, y, or, false);
-	          break;
-	        default:
-	          c = algorithm14(x, y, or, false);
-	          break;
-	      }
-	      return c;
-	    },
-
-	    'any, Matrix': function (x, y) {
-	      // result
-	      var c;
-	      // check storage format
-	      switch (y.storage()) {
-	        case 'sparse':
-	          c = algorithm12(y, x, or, true);
-	          break;
-	        default:
-	          c = algorithm14(y, x, or, true);
-	          break;
-	      }
-	      return c;
-	    },
-
-	    'Array, any': function (x, y) {
-	      // use matrix implementation
-	      return algorithm14(matrix(x), y, or, false).valueOf();
-	    },
-
-	    'any, Array': function (x, y) {
-	      // use matrix implementation
-	      return algorithm14(matrix(y), x, or, true).valueOf();
-	    }
-	  });
-
-	  or.toTex = '\\left(${args[0]}' + latex.operators['or'] + '${args[1]}\\right)';
-
-	  return or;
-	}
-
-	exports.name = 'or';
-	exports.factory = factory;
-
-
-/***/ },
-/* 160 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	function factory (type, config, load, typed) {
-	  var latex = __webpack_require__(26);
-
-	  var matrix = load(__webpack_require__(23));
-
-	  var algorithm03 = load(__webpack_require__(31));
-	  var algorithm07 = load(__webpack_require__(66));
-	  var algorithm12 = load(__webpack_require__(65));
-	  var algorithm13 = load(__webpack_require__(35));
-	  var algorithm14 = load(__webpack_require__(39));
-	  
-	  /**
-	   * Logical `xor`. Test whether one and only one value is defined with a nonzero/nonempty value.
-	   * For matrices, the function is evaluated element wise.
-	   *
-	   * Syntax:
-	   *
-	   *    math.xor(x, y)
-	   *
-	   * Examples:
-	   *
-	   *    math.xor(2, 4);   // returns false
-	   *
-	   *    a = [2, 0, 0];
-	   *    b = [2, 7, 0];
-	   *    c = 0;
-	   *
-	   *    math.xor(a, b);   // returns [false, true, false]
-	   *    math.xor(a, c);   // returns [true, false, false]
-	   *
-	   * See also:
-	   *
-	   *    and, not, or
-	   *
-	   * @param  {number | BigNumber | Complex | Unit | Array | Matrix} x First value to check
-	   * @param  {number | BigNumber | Complex | Unit | Array | Matrix} y Second value to check
-	   * @return {boolean | Array | Matrix}
-	   *            Returns true when one and only one input is defined with a nonzero/nonempty value.
-	   */
-	  var xor = typed('xor', {
-	 
-	    'number, number': function (x, y) {
-	      return !!(!!x ^ !!y);
-	    },
-
-	    'Complex, Complex': function (x, y) {
-	      return !!((x.re !== 0 || x.im !== 0) ^ (y.re !== 0 || y.im !== 0));
-	    },
-
-	    'BigNumber, BigNumber': function (x, y) {
-	      return !!((!x.isZero() && !x.isNaN()) ^ (!y.isZero() && !y.isNaN()));
-	    },
-
-	    'Unit, Unit': function (x, y) {
-	      return !!((x.value !== 0 && x.value !== null) ^ (y.value !== 0 && y.value !== null));
-	    },
-
-	    'Matrix, Matrix': function (x, y) {
-	      // result
-	      var c;
-
-	      // process matrix storage
-	      switch (x.storage()) {
-	        case 'sparse':
-	          switch (y.storage()) {
-	            case 'sparse':
-	              // sparse + sparse
-	              c = algorithm07(x, y, xor);
-	              break;
-	            default:
-	              // sparse + dense
-	              c = algorithm03(y, x, xor, true);
-	              break;
-	          }
-	          break;
-	        default:
-	          switch (y.storage()) {
-	            case 'sparse':
-	              // dense + sparse
-	              c = algorithm03(x, y, xor, false);
-	              break;
-	            default:
-	              // dense + dense
-	              c = algorithm13(x, y, xor);
-	              break;
-	          }
-	          break;
-	      }
-	      return c;
-	    },
-
-	    'Array, Array': function (x, y) {
-	      // use matrix implementation
-	      return xor(matrix(x), matrix(y)).valueOf();
-	    },
-
-	    'Array, Matrix': function (x, y) {
-	      // use matrix implementation
-	      return xor(matrix(x), y);
-	    },
-
-	    'Matrix, Array': function (x, y) {
-	      // use matrix implementation
-	      return xor(x, matrix(y));
-	    },
-
-	    'Matrix, any': function (x, y) {
-	      // result
-	      var c;
-	      // check storage format
-	      switch (x.storage()) {
-	        case 'sparse':
-	          c = algorithm12(x, y, xor, false);
-	          break;
-	        default:
-	          c = algorithm14(x, y, xor, false);
-	          break;
-	      }
-	      return c;
-	    },
-
-	    'any, Matrix': function (x, y) {
-	      // result
-	      var c;
-	      // check storage format
-	      switch (y.storage()) {
-	        case 'sparse':
-	          c = algorithm12(y, x, xor, true);
-	          break;
-	        default:
-	          c = algorithm14(y, x, xor, true);
-	          break;
-	      }
-	      return c;
-	    },
-
-	    'Array, any': function (x, y) {
-	      // use matrix implementation
-	      return algorithm14(matrix(x), y, xor, false).valueOf();
-	    },
-
-	    'any, Array': function (x, y) {
-	      // use matrix implementation
-	      return algorithm14(matrix(y), x, xor, true).valueOf();
-	    }
-	  });
-
-	  xor.toTex = '\\left(${args[0]}' + latex.operators['xor'] + '${args[1]}\\right)';
-
-	  return xor;
-	}
-
-	exports.name = 'xor';
-	exports.factory = factory;
-
-
-/***/ },
-/* 161 */
-/***/ function(module, exports, __webpack_require__) {
-
-	module.exports = [
-	  //require('./distribution'), // TODO: rethink math.distribution
-	  __webpack_require__(143),
-	  __webpack_require__(139),
-	  __webpack_require__(142),
-	  __webpack_require__(162),
-	  __webpack_require__(166),
-	  __webpack_require__(167),
-	  __webpack_require__(168),
-	  __webpack_require__(171),
-	  __webpack_require__(172)
-	];
-
-
-/***/ },
-/* 162 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-
-	function factory(type, config, load, typed) {
-	    var matrix = load(__webpack_require__(23));
-	    var divide = load(__webpack_require__(94));
-	    var sum = load(__webpack_require__(163));
-	    var multiply = load(__webpack_require__(40));
-	    var dotDivide = load(__webpack_require__(95));
-	    var log = load(__webpack_require__(102));
-	    var isNumeric = load(__webpack_require__(165));
-
-	    /**
-	     * Calculate the Kullback-Leibler (KL) divergence  between two distributions
-	     *
-	     * Syntax:
-	     *
-	     *     math.kldivergence(x, y)
-	     *
-	     * Examples:
-	     *
-	     *     math.kldivergence([0.7,0.5,0.4], [0.2,0.9,0.5]);   //returns 0.24376698773121153
-	     *
-	     *
-	     * @param  {Array | Matrix} q    First vector
-	     * @param  {Array | Matrix} p    Second vector
-	     * @return {number}              Returns distance between q and p
-	     */
-	    var kldivergence = typed('kldivergence', {
-	        'Array, Array': function(q, p) {
-	            return _kldiv(matrix(q), matrix(p));
-	        },
-
-	        'Matrix, Array': function(q, p) {
-	            return _kldiv(q, matrix(p));
-	        },
-
-	        'Array, Matrix': function(q, p){
-	            return _kldiv(matrix(q), p);
-	        },
-
-	        'Matrix, Matrix': function(q, p){
-	            return _kldiv(q, p);
-	        }
-
-	    });
-
-	    function _kldiv(q, p) {
-	        var plength = p.size().length;
-	        var qlength = q.size().length;
-	        if (plength > 1) {
-	            throw new Error('first object must be one dimensional');
-	        }
-	        
-	        if (qlength > 1) {
-	            throw new Error('second object must be one dimensional');
-	        }
-	        
-	        if(plength !== qlength){
-	            throw new Error("Length of two vectors must be equal");
-	        }
-	        
-	        //Before calculation, apply normalization
-	        var sumq = sum(q);
-	        if (sumq === 0) {
-	            throw new Error("Sum of elements in first object must be non zero");
-	        }
-
-	        var sump = sum(p);
-	        if (sump === 0) {
-	            throw new Error("Sum of elements in second object must be non zero");
-	        }
-	        var qnorm = divide(q, sum(q));
-	        var pnorm = divide(p, sum(p));
-
-	        var result = sum(multiply(qnorm, log(dotDivide(qnorm, pnorm))));
-	        if (isNumeric(result)) {
-	            return result;
-	        }
-	        else {
-	            return Number.NaN;
-	        }
-	    }
-
-	    return kldivergence;
-	}
-
-
-	exports.name = 'kldivergence';
-	exports.factory = factory;
-	 
-
-
-/***/ },
-/* 163 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	var deepForEach = __webpack_require__(164);
-
-	function factory (type, config, load, typed) {
-	  var add = load(__webpack_require__(27));
-
-	  /**
-	   * Compute the sum of a matrix or a list with values.
-	   * In case of a (multi dimensional) array or matrix, the sum of all
-	   * elements will be calculated.
-	   *
-	   * Syntax:
-	   *
-	   *     math.sum(a, b, c, ...)
-	   *     math.sum(A)
-	   *
-	   * Examples:
-	   *
-	   *     math.sum(2, 1, 4, 3);               // returns 10
-	   *     math.sum([2, 1, 4, 3]);             // returns 10
-	   *     math.sum([[2, 5], [4, 3], [1, 7]]); // returns 22
-	   *
-	   * See also:
-	   *
-	   *    mean, median, min, max, prod, std, var
-	   *
-	   * @param {... *} args  A single matrix or or multiple scalar values
-	   * @return {*} The sum of all values
-	   */
-	  var sum = typed('sum', {
-	    'Array | Matrix': function (args) {
-	      // sum([a, b, c, d, ...])
-	      return _sum(args);
-	    },
-
-	    'Array | Matrix, number | BigNumber': function () {
-	      // sum([a, b, c, d, ...], dim)
-	      // TODO: implement sum(A, dim)
-	      throw new Error('sum(A, dim) is not yet supported');
-	    },
-
-	    '...': function () {
-	      // sum(a, b, c, d, ...)
-	      return _sum(arguments);
-	    }
-	  });
-
-	  sum.toTex = '\\mathrm{${name}}\\left(${args}\\right)';
-
-	  return sum;
-
-	  /**
-	   * Recursively calculate the sum of an n-dimensional array
-	   * @param {Array} array
-	   * @return {number} sum
-	   * @private
-	   */
-	  function _sum(array) {
-	    var sum = undefined;
-
-	    deepForEach(array, function (value) {
-	      sum = (sum === undefined) ? value : add(sum, value);
-	    });
-
-	    if (sum === undefined) {
-	      switch (config.number) {
-	        case 'number':
-	          return 0;
-	        case 'bignumber':
-	          return new type.BigNumber(0);
-	        case 'fraction':
-	          return new type.Fraction(0);
-	        default:
-	          return 0;
-	      }
-	    }
-
-	    return sum;
-	  }
-	}
-
-	exports.name = 'sum';
-	exports.factory = factory;
-
-
-/***/ },
-/* 164 */
-/***/ function(module, exports) {
-
-	'use strict';
-
-	/**
-	 * Recursively loop over all elements in a given multi dimensional array
-	 * and invoke the callback on each of the elements.
-	 * @param {Array | Matrix} array
-	 * @param {Function} callback     The callback method is invoked with one
-	 *                                parameter: the current element in the array
-	 */
-	module.exports = function deepForEach (array, callback) {
-	  if (array && array.isMatrix === true) {
-	    array = array.valueOf();
-	  }
-
-	  for (var i = 0, ii = array.length; i < ii; i++) {
-	    var value = array[i];
-
-	    if (Array.isArray(value)) {
-	      deepForEach(value, callback);
-	    }
-	    else {
-	      callback(value);
-	    }
-	  }
-	};
-
-
-/***/ },
-/* 165 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	var deepMap = __webpack_require__(29);
-	var number = __webpack_require__(8);
-
-	function factory (type, config, load, typed) {
-	  /**
-	   * Test whether a value is an numeric value.
-	   *
-	   * The function is evaluated element-wise in case of Array or Matrix input.
-	   *
-	   * Syntax:
-	   *
-	   *     math.isNumeric(x)
-	   *
-	   * Examples:
-	   *
-	   *    math.isNumeric(2);                     // returns true
-	   *    math.isNumeric(0);                     // returns true
-	   *    math.isNumeric(math.bignumber(500));   // returns true
-	   *    math.isNumeric(math.fraction(4));      // returns true
-	   *    math.isNumeric(math.complex('2 - 4i'); // returns false
-	   *    math.isNumeric('3');                   // returns false
-	   *    math.isNumeric([2.3, 'foo', false]);   // returns [true, false, true]
-	   *
-	   * See also:
-	   *
-	   *    isZero, isPositive, isNegative, isInteger
-	   *
-	   * @param {*} x       Value to be tested
-	   * @return {boolean}  Returns true when `x` is a `number`, `BigNumber`,
-	   *                    `Fraction`, or `boolean`. Returns false for other types.
-	   *                    Throws an error in case of unknown types.
-	   */
-	  var isNumeric = typed('isNumeric', {
-	    'number | BigNumber | Fraction | boolean': function () {
-	      return true;
-	    },
-
-	    'Complex | Unit | string': function () {
-	      return false;
-	    },
-
-	    'Array | Matrix': function (x) {
-	      return deepMap(x, isNumeric);
-	    }
-	  });
-
-	  return isNumeric;
-	}
-
-	exports.name = 'isNumeric';
-	exports.factory = factory;
-
-
-/***/ },
-/* 166 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	var deepForEach = __webpack_require__(164);
-
-	function factory (type, config, load, typed) {
-	  var add = load(__webpack_require__(44));
-	  var multiply = load(__webpack_require__(40));
-	  var divide = load(__webpack_require__(94));
-	  var factorial = load(__webpack_require__(139));
-	  var isInteger = load(__webpack_require__(145));
-	  var isPositive = load(__webpack_require__(147));
-
-	  /**
-	   * Multinomial Coefficients compute the number of ways of picking a1, a2, ..., ai unordered outcomes from `n` possibilities.
-	   *
-	   * multinomial takes one array of integers as an argument.
-	   * The following condition must be enforced: every ai <= 0
-	   *
-	   * Syntax:
-	   *
-	   *     math.multinomial(a) // a is an array type
-	   *
-	   * Examples:
-	   *
-	   *    math.multinomial([1,2,1]); // returns 12
-	   *
-	   * See also:
-	   *
-	   *    combinations, factorial
-	   *
-	   * @param {number[] | BigNumber[]} a    Integer numbers of objects in the subset
-	   * @return {Number | BigNumber}         Multinomial coefficient.
-	   */
-	  return typed('multinomial', {
-	    'Array | Matrix': function (a) {
-	      var sum = 0;
-	      var denom = 1;
-
-	      deepForEach(a, function(ai) {
-	        if(!isInteger(ai) || !isPositive(ai)) {
-	          throw new TypeError('Positive integer value expected in function multinomial');
-	        }
-	        sum = add(sum, ai);
-	        denom = multiply(denom, factorial(ai));
-	      });
-
-	      return divide(factorial(sum), denom);
-	    }
-	  });
-	}
-
-	exports.name = 'multinomial';
-	exports.factory = factory;
-
-
-/***/ },
-/* 167 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	var isInteger = __webpack_require__(8).isInteger;
-
-	function factory (type, config, load, typed) {
-	  var factorial = load(__webpack_require__(139));
-
-	  /**
-	   * Compute the number of ways of obtaining an ordered subset of `k` elements
-	   * from a set of `n` elements.
-	   *
-	   * Permutations only takes integer arguments.
-	   * The following condition must be enforced: k <= n.
-	   *
-	   * Syntax:
-	   *
-	   *     math.permutations(n)
-	   *     math.permutations(n, k)
-	   *
-	   * Examples:
-	   *
-	   *    math.permutations(5);     // 120
-	   *    math.permutations(5, 3);  // 60
-	   *
-	   * See also:
-	   *
-	   *    combinations, factorial
-	   *
-	   * @param {number | BigNumber} n   The number of objects in total
-	   * @param {number | BigNumber} [k] The number of objects in the subset
-	   * @return {number | BigNumber}    The number of permutations
-	   */
-	  var permutations = typed('permutations', {
-	    'number | BigNumber': factorial,
-
-	    'number, number': function (n, k) {
-	      var result, i;
-
-	      if (!isInteger(n) || n < 0) {
-	        throw new TypeError('Positive integer value expected in function permutations');
-	      }
-	      if (!isInteger(k) || k < 0) {
-	        throw new TypeError('Positive integer value expected in function permutations');
-	      }
-	      if (k > n) {
-	        throw new TypeError('second argument k must be less than or equal to first argument n');
-	      }
-
-	      // Permute n objects, k at a time
-	      result = 1;
-	      for (i = n - k + 1; i <= n; i++) {
-	        result = result * i;
-	      }
-
-	      return result;
-	    },
-
-	    'BigNumber, BigNumber': function (n, k) {
-	      var result, i;
-
-	      if (!isPositiveInteger(n) || !isPositiveInteger(k)) {
-	        throw new TypeError('Positive integer value expected in function permutations');
-	      }
-	      if (k.gt(n)) {
-	        throw new TypeError('second argument k must be less than or equal to first argument n');
-	      }
-
-	      result = new type.BigNumber(1);
-	      for (i = n.minus(k).plus(1); i.lte(n); i = i.plus(1)) {
-	        result = result.times(i);
-	      }
-
-	      return result;
-	    }
-
-	    // TODO: implement support for collection in permutations
-	  });
-
-	  permutations.toTex = '\\mathrm{${name}}\\left(${args}\\right)';
-
-	  return permutations;
-	}
-
-	/**
-	 * Test whether BigNumber n is a positive integer
-	 * @param {BigNumber} n
-	 * @returns {boolean} isPositiveInteger
-	 */
-	function isPositiveInteger(n) {
-	  return n.isInteger() && n.gte(0);
-	}
-
-	exports.name = 'permutations';
-	exports.factory = factory;
-
-
-/***/ },
-/* 168 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	function factory (type, config, load, typed) {
-	  var distribution = load(__webpack_require__(169));
-
-	  /**
-	   * Random pick a value from a one dimensional array.
-	   * Array element is picked using a random function with uniform distribution.
-	   *
-	   * Syntax:
-	   *
-	   *     math.pickRandom(array)
-	   *
-	   * Examples:
-	   *
-	   *     math.pickRandom([3, 6, 12, 2]);       // returns one of the values in the array
-	   *
-	   * See also:
-	   *
-	   *     random, randomInt
-	   *
-	   * @param {Array} array     A one dimensional array
-	   * @return {number} One of the elements of the provided input array
-	   */
-	  // TODO: rework pickRandom to a typed-function
-	  var pickRandom =  distribution('uniform').pickRandom;
-
-	  pickRandom.toTex = '\\mathrm{${name}}\\left(${args}\\right)';
-
-	  return pickRandom;
-	}
-
-	exports.name = 'pickRandom';
-	exports.factory = factory;
-
-
-/***/ },
-/* 169 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	var ArgumentsError = __webpack_require__(11);
-	var isCollection = __webpack_require__(170);
-
-	// TODO: rethink math.distribution
-	// TODO: rework to a typed function
-	function factory (type, config, load, typed) {
-	  var matrix = load(__webpack_require__(23));
-	  var array = __webpack_require__(18);
-
-	  /**
-	   * Create a distribution object with a set of random functions for given
-	   * random distribution.
-	   *
-	   * Syntax:
-	   *
-	   *     math.distribution(name)
-	   *
-	   * Examples:
-	   *
-	   *     var normalDist = math.distribution('normal'); // create a normal distribution
-	   *     normalDist.random(0, 10);                     // get a random value between 0 and 10
-	   *
-	   * See also:
-	   *
-	   *     random, randomInt, pickRandom
-	   *
-	   * @param {string} name   Name of a distribution. Choose from 'uniform', 'normal'.
-	   * @return {Object}       Returns a distribution object containing functions:
-	   *                        `random([size] [, min] [, max])`,
-	   *                        `randomInt([min] [, max])`,
-	   *                        `pickRandom(array)`
-	   */
-	  function distribution(name) {
-	    if (!distributions.hasOwnProperty(name))
-	      throw new Error('Unknown distribution ' + name);
-
-	    var args = Array.prototype.slice.call(arguments, 1),
-	        distribution = distributions[name].apply(this, args);
-
-	    return (function(distribution) {
-
-	      // This is the public API for all distributions
-	      var randFunctions = {
-
-	        random: function(arg1, arg2, arg3) {
-	          var size, min, max;
-	          if (arguments.length > 3) {
-	            throw new ArgumentsError('random', arguments.length, 0, 3);
-
-	          // `random(max)` or `random(size)`
-	          } else if (arguments.length === 1) {
-	            if (isCollection(arg1)) {
-	              size = arg1;
-	            }
-	            else {
-	              max = arg1;
-	            }
-	          // `random(min, max)` or `random(size, max)`
-	          } else if (arguments.length === 2) {
-	            if (isCollection(arg1)) {
-	              size = arg1;
-	              max = arg2;
-	            }
-	            else {
-	              min = arg1;
-	              max = arg2;
-	            }
-	          // `random(size, min, max)`
-	          } else {
-	            size = arg1;
-	            min = arg2;
-	            max = arg3;
-	          }
-
-	          // TODO: validate type of min, max, and size
-
-	          if (max === undefined) max = 1;
-	          if (min === undefined) min = 0;
-	          if (size !== undefined) {
-	            var res = _randomDataForMatrix(size.valueOf(), min, max, _random);
-	            return (size && size.isMatrix === true) ? matrix(res) : res;
-	          }
-	          else return _random(min, max);
-	        },
-
-	        randomInt: function(arg1, arg2, arg3) {
-	          var size, min, max;
-	          if (arguments.length > 3 || arguments.length < 1)
-	            throw new ArgumentsError('randomInt', arguments.length, 1, 3);
-
-	          // `random(max)` or `random(size)`
-	          else if (arguments.length === 1)
-	            if (isCollection(arg1)) {
-	              size = arg1;
-	            }
-	            else {
-	              max = arg1;
-	            }
-	          // `randomInt(min, max)` or `randomInt(size, max)`
-	          else if (arguments.length === 2) {
-	            if (isCollection(arg1)) {
-	              size = arg1;
-	              max = arg2;
-	            }
-	            else {
-	              min = arg1;
-	              max = arg2;
-	            }
-	          // `randomInt(size, min, max)`
-	          } else {
-	            size = arg1;
-	            min = arg2;
-	            max = arg3;
-	          }
-
-	          // TODO: validate type of min, max, and size
-
-	          if (min === undefined) min = 0;
-	          if (size !== undefined) {
-	            var res = _randomDataForMatrix(size.valueOf(), min, max, _randomInt);
-	            return (size && size.isMatrix === true) ? matrix(res) : res;
-	          }
-	          else return _randomInt(min, max);
-	        },
-
-	        pickRandom: function(possibles) {
-	          if (arguments.length !== 1) {
-	            throw new ArgumentsError('pickRandom', arguments.length, 1);
-	          }
-	          if (possibles && possibles.isMatrix === true) {
-	            possibles = possibles.valueOf(); // get Array
-	          }
-	          else if (!Array.isArray(possibles)) {
-	            throw new TypeError('Unsupported type of value in function pickRandom');
-	          }
-
-	          if (array.size(possibles).length > 1) {
-	            throw new Error('Only one dimensional vectors supported');
-	          }
-
-	          // TODO: add support for multi dimensional matrices
-	          return possibles[Math.floor(Math.random() * possibles.length)];
-	        }
-
-	      };
-
-	      var _random = function(min, max) {
-	        return min + distribution() * (max - min);
-	      };
-
-	      var _randomInt = function(min, max) {
-	        return Math.floor(min + distribution() * (max - min));
-	      };
-
-	      // This is a function for generating a random matrix recursively.
-	      var _randomDataForMatrix = function(size, min, max, randFunc) {
-	        var data = [], length, i;
-	        size = size.slice(0);
-
-	        if (size.length > 1) {
-	          for (i = 0, length = size.shift(); i < length; i++)
-	            data.push(_randomDataForMatrix(size, min, max, randFunc));
-	        } else {
-	          for (i = 0, length = size.shift(); i < length; i++)
-	            data.push(randFunc(min, max));
-	        }
-
-	        return data;
-	      };
-
-	      return randFunctions;
-
-	    })(distribution);
-	  }
-
-	  // Each distribution is a function that takes no argument and when called returns
-	  // a number between 0 and 1.
-	  var distributions = {
-
-	    uniform: function() {
-	      return Math.random;
-	    },
-
-	    // Implementation of normal distribution using Box-Muller transform
-	    // ref : http://en.wikipedia.org/wiki/Box%E2%80%93Muller_transform
-	    // We take : mean = 0.5, standard deviation = 1/6
-	    // so that 99.7% values are in [0, 1].
-	    normal: function() {
-	      return function() {
-	        var u1, u2,
-	            picked = -1;
-	        // We reject values outside of the interval [0, 1]
-	        // TODO: check if it is ok to do that?
-	        while (picked < 0 || picked > 1) {
-	          u1 = Math.random();
-	          u2 = Math.random();
-	          picked = 1/6 * Math.pow(-2 * Math.log(u1), 0.5) * Math.cos(2 * Math.PI * u2) + 0.5;
-	        }
-	        return picked;
-	      }
-	    }
-	  };
-
-	  distribution.toTex = '\\mathrm{${name}}\\left(${args}\\right)';
-
-	  return distribution;
-	}
-
-	exports.name = 'distribution';
-	exports.factory = factory;
-
-
-/***/ },
-/* 170 */
-/***/ function(module, exports) {
-
-	'use strict';
-
-	/**
-	 * Test whether a value is a collection: an Array or Matrix
-	 * @param {*} x
-	 * @returns {boolean} isCollection
-	 */
-	module.exports = function isCollection (x) {
-	  return (Array.isArray(x) || (x && x.isMatrix === true));
-	};
-
-
-/***/ },
-/* 171 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	function factory (type, config, load, typed) {
-	  var distribution = load(__webpack_require__(169));
-
-	  /**
-	   * Return a random number larger or equal to `min` and smaller than `max`
-	   * using a uniform distribution.
-	   *
-	   * Syntax:
-	   *
-	   *     math.random()                // generate a random number between 0 and 1
-	   *     math.random(max)             // generate a random number between 0 and max
-	   *     math.random(min, max)        // generate a random number between min

Follow ups