mathjs
Version:
Math.js is an extensive math library for JavaScript and Node.js. It features a flexible expression parser and offers an integrated solution to work with numbers, big numbers, complex numbers, units, and matrices.
1,577 lines (1,364 loc) • 1.04 MB
JavaScript
/**
* math.js
* https://github.com/josdejong/mathjs
*
* Math.js is an extensive math library for JavaScript and Node.js,
* It features real and complex numbers, units, matrices, a large set of
* mathematical functions, and a flexible expression parser.
*
* @version 1.7.0
* @date 2015-05-31
*
* @license
* Copyright (C) 2013-2015 Jos de Jong <wjosdejong@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory();
else if(typeof define === 'function' && define.amd)
define(factory);
else if(typeof exports === 'object')
exports["math"] = factory();
else
root["math"] = factory();
})(this, function() {
return /******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId])
/******/ return installedModules[moduleId].exports;
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ exports: {},
/******/ id: moduleId,
/******/ loaded: false
/******/ };
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/ // Flag the module as loaded
/******/ module.loaded = true;
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/ // Load entry module and return exports
/******/ return __webpack_require__(0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ function(module, exports, __webpack_require__) {
module.exports = __webpack_require__(1);
/***/ },
/* 1 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var object = __webpack_require__(12);
var digits = __webpack_require__(5).digits;
/**
* math.js factory function.
*
* @param {Object} [config] Available configuration options:
* {String} matrix
* A string 'matrix' (default) or 'array'.
* {String} number
* A string 'number' (default) or 'bignumber'
* {Number} precision
* The number of significant digits for BigNumbers.
* Not applicable for Numbers.
*/
function create (config) {
// simple test for ES5 support
if (typeof Object.create !== 'function') {
throw new Error('ES5 not supported by this JavaScript engine. ' +
'Please load the es5-shim and es5-sham library for compatibility.');
}
// create namespace
var math = {};
// create configuration options. These are private
var _config = {
// type of default matrix output. Choose 'matrix' (default) or 'array'
matrix: 'matrix',
// type of default number output. Choose 'number' (default) or 'bignumber'
number: 'number',
// number of significant digits in BigNumbers
precision: 64,
// minimum relative difference between two compared values,
// used by all comparison functions
epsilon: 1e-14
};
/**
* Set configuration options for math.js, and get current options
* @param {Object} [options] Available options:
* {String} matrix
* A string 'matrix' (default) or 'array'.
* {String} number
* A string 'number' (default) or 'bignumber'
* {Number} precision
* The number of significant digits for BigNumbers.
* Not applicable for Numbers.
* @return {Object} Returns the current configuration
*/
math.config = function(options) {
if (options) {
// merge options
object.deepExtend(_config, options);
if (options.precision) {
math.type.BigNumber.config({
precision: options.precision
});
}
// reload the constants (they depend on option number and precision)
// this must be done after math.type.BigNumber.config is applied
__webpack_require__(15)(math, _config);
// TODO: remove deprecated setting some day (deprecated since version 0.17.0)
if (options.number && options.number.defaultType) {
throw new Error('setting `number.defaultType` is deprecated. Use `number` instead.');
}
// TODO: remove deprecated setting some day (deprecated since version 0.17.0)
if (options.number && options.number.precision) {
throw new Error('setting `number.precision` is deprecated. Use `precision` instead.');
}
// TODO: remove deprecated setting some day (deprecated since version 0.17.0)
if (options.matrix && options.matrix.defaultType) {
throw new Error('setting `matrix.defaultType` is deprecated. Use `matrix` instead.');
}
// TODO: remove deprecated setting some day (deprecated since version 0.15.0)
if (options.matrix && options.matrix['default']) {
throw new Error('setting `matrix.default` is deprecated. Use `matrix` instead.');
}
// TODO: remove deprecated setting some day (deprecated since version 0.20.0)
if (options.decimals) {
throw new Error('setting `decimals` is deprecated. Use `precision` instead.');
}
}
// return a clone of the settings
return object.clone(_config);
};
/**
* math.js factory function. Creates a new instance of math.js
*
* @param {Object} [config] Available configuration options:
* {String} matrix
* A string 'matrix' (default) or 'array'.
* {String} number
* A string 'number' (default) or 'bignumber'
* {Number} precision
* The number of significant digits for BigNumbers.
* Not applicable for Numbers.
*/
math.create = create;
// create a new BigNumber factory for this instance of math.js
var BigNumber = __webpack_require__(7).constructor();
/**
* Get a JSON representation of a BigNumber containing
* type information
* @returns {Object} Returns a JSON object structured as:
* `{"mathjs": "BigNumber", "value": "0.2"}`
*/
BigNumber.prototype.toJSON = function () {
return {
mathjs: 'BigNumber',
value: this.toString()
};
};
/**
* Instantiate a BigNumber from a JSON object
* @param {Object} json a JSON object structured as:
* `{"mathjs": "BigNumber", "value": "0.2"}`
* @return {BigNumber}
*/
BigNumber.fromJSON = function (json) {
return new BigNumber(json.value);
};
// extend BigNumber with a function clone
if (typeof BigNumber.prototype.clone !== 'function') {
/**
* Clone a bignumber
* @return {BigNumber} clone
*/
BigNumber.prototype.clone = function() {
return this; // just return itself (a BigNumber is immutable)
};
}
// extend BigNumber with a function convert
if (typeof BigNumber.convert !== 'function') {
/**
* Try to convert a Number in to a BigNumber.
* If the number has 15 or more significant digits, the Number cannot be
* converted to BigNumber and will return the original number.
* @param {Number} number
* @return {BigNumber | Number} bignumber
*/
BigNumber.convert = function(number) {
if (digits(number) > 15) {
return number;
}
else {
return new BigNumber(number);
}
};
}
else {
throw new Error('Cannot add function convert to BigNumber: function already exists');
}
// errors
math.error = __webpack_require__(21);
// types (Matrix, Complex, Unit, ...)
math.type = {};
math.type.Complex = __webpack_require__(16);
math.type.Range = __webpack_require__(24);
math.type.Index = __webpack_require__(25);
math.type.Matrix = __webpack_require__(26)(_config);
math.type.Unit = __webpack_require__(19);
math.type.Help = __webpack_require__(27);
math.type.ResultSet = __webpack_require__(28);
math.type.BigNumber = BigNumber;
math.collection = __webpack_require__(29)(math, _config);
// matrix storage formats
math.type.CcsMatrix = __webpack_require__(30)(math, _config);
math.type.CrsMatrix = __webpack_require__(31)(math, _config);
math.type.DenseMatrix = __webpack_require__(32)(math, _config);
// matrix storage format registry
math.type.Matrix._storage.ccs = math.type.CcsMatrix;
math.type.Matrix._storage.crs = math.type.CrsMatrix;
math.type.Matrix._storage.dense = math.type.DenseMatrix;
math.type.Matrix._storage['default'] = math.type.DenseMatrix;
// expression (parse, Parser, nodes, docs)
math.expression = {};
math.expression.node = __webpack_require__(33);
math.expression.parse = __webpack_require__(50)(math, _config);
math.expression.Parser = __webpack_require__(51)(math, _config);
math.expression.docs = __webpack_require__(52);
// serialization utilities
math.json = {
reviver: __webpack_require__(203)(math, _config)
};
// functions - construction (must be defined before the rest of functions)
__webpack_require__(204)(math, _config);
__webpack_require__(205)(math, _config);
__webpack_require__(206)(math, _config);
__webpack_require__(207)(math, _config);
__webpack_require__(208)(math, _config);
__webpack_require__(209)(math, _config);
__webpack_require__(210)(math, _config);
__webpack_require__(211)(math, _config);
__webpack_require__(212)(math, _config);
__webpack_require__(213)(math, _config);
// expression parser
__webpack_require__(214)(math, _config);
__webpack_require__(215)(math, _config);
__webpack_require__(216)(math, _config);
__webpack_require__(217)(math, _config);
// functions - arithmetic
__webpack_require__(218)(math, _config);
__webpack_require__(219)(math, _config);
__webpack_require__(220)(math, _config);
__webpack_require__(221)(math, _config);
__webpack_require__(222)(math, _config);
__webpack_require__(223)(math, _config);
__webpack_require__(224)(math, _config);
__webpack_require__(225)(math, _config);
__webpack_require__(226)(math, _config);
__webpack_require__(227)(math, _config);
__webpack_require__(228)(math, _config);
__webpack_require__(229)(math, _config);
__webpack_require__(230)(math, _config);
__webpack_require__(231)(math, _config);
__webpack_require__(232)(math, _config);
__webpack_require__(233)(math, _config);
__webpack_require__(234)(math, _config);
__webpack_require__(235)(math, _config);
__webpack_require__(236)(math, _config);
__webpack_require__(237)(math, _config);
__webpack_require__(238)(math, _config);
__webpack_require__(239)(math, _config);
__webpack_require__(240)(math, _config);
__webpack_require__(241)(math, _config);
__webpack_require__(242)(math, _config);
__webpack_require__(243)(math, _config);
__webpack_require__(244)(math, _config);
__webpack_require__(245)(math, _config);
__webpack_require__(246)(math, _config);
// functions - bitwise
__webpack_require__(247)(math, _config);
__webpack_require__(248)(math, _config);
__webpack_require__(249)(math, _config);
__webpack_require__(250)(math, _config);
__webpack_require__(251)(math, _config);
__webpack_require__(252)(math, _config);
__webpack_require__(253)(math, _config);
//functions - combinatorics
__webpack_require__(254)(math, _config);
__webpack_require__(255)(math, _config);
__webpack_require__(256)(math, _config);
// functions - complex
__webpack_require__(257)(math, _config);
__webpack_require__(258)(math, _config);
__webpack_require__(259)(math, _config);
__webpack_require__(260)(math, _config);
// functions - logical
__webpack_require__(261)(math, _config);
__webpack_require__(262)(math, _config);
__webpack_require__(263)(math, _config);
__webpack_require__(264)(math, _config);
// functions - matrix
__webpack_require__(265)(math, _config);
__webpack_require__(266)(math, _config);
__webpack_require__(267)(math, _config);
__webpack_require__(268)(math, _config);
__webpack_require__(2)(math, _config);
__webpack_require__(269)(math, _config);
__webpack_require__(270)(math, _config);
__webpack_require__(271)(math, _config);
__webpack_require__(272)(math, _config);
__webpack_require__(273)(math, _config);
__webpack_require__(274)(math, _config);
__webpack_require__(275)(math, _config);
__webpack_require__(276)(math, _config);
__webpack_require__(277)(math, _config);
__webpack_require__(278)(math, _config);
__webpack_require__(279)(math, _config);
__webpack_require__(280)(math, _config);
// functions - probability
//require('./function/probability/distribution')(math, _config); // TODO: rethink math.distribution
__webpack_require__(281)(math, _config);
__webpack_require__(282)(math, _config);
__webpack_require__(283)(math, _config);
__webpack_require__(285)(math, _config);
__webpack_require__(286)(math, _config);
__webpack_require__(287)(math, _config);
__webpack_require__(288)(math, _config);
__webpack_require__(289)(math, _config);
// functions - relational
__webpack_require__(290)(math, _config);
__webpack_require__(291)(math, _config);
__webpack_require__(292)(math, _config);
__webpack_require__(293)(math, _config);
__webpack_require__(294)(math, _config);
__webpack_require__(295)(math, _config);
__webpack_require__(296)(math, _config);
__webpack_require__(297)(math, _config);
// functions - statistics
__webpack_require__(298)(math, _config);
__webpack_require__(299)(math, _config);
__webpack_require__(300)(math, _config);
__webpack_require__(301)(math, _config);
__webpack_require__(302)(math, _config);
__webpack_require__(303)(math, _config);
__webpack_require__(304)(math, _config);
__webpack_require__(305)(math, _config);
__webpack_require__(306)(math, _config);
// functions - trigonometry
__webpack_require__(307)(math, _config);
__webpack_require__(308)(math, _config);
__webpack_require__(309)(math, _config);
__webpack_require__(310)(math, _config);
__webpack_require__(311)(math, _config);
__webpack_require__(312)(math, _config);
__webpack_require__(313)(math, _config);
__webpack_require__(314)(math, _config);
__webpack_require__(315)(math, _config);
__webpack_require__(316)(math, _config);
__webpack_require__(317)(math, _config);
__webpack_require__(318)(math, _config);
__webpack_require__(319)(math, _config);
__webpack_require__(320)(math, _config);
__webpack_require__(321)(math, _config);
__webpack_require__(322)(math, _config);
__webpack_require__(323)(math, _config);
__webpack_require__(324)(math, _config);
__webpack_require__(325)(math, _config);
__webpack_require__(326)(math, _config);
__webpack_require__(327)(math, _config);
__webpack_require__(328)(math, _config);
__webpack_require__(329)(math, _config);
__webpack_require__(330)(math, _config);
__webpack_require__(331)(math, _config);
// functions - units
__webpack_require__(332)(math, _config);
// functions - utils
__webpack_require__(333)(math, _config);
__webpack_require__(334)(math, _config);
__webpack_require__(335)(math, _config);
__webpack_require__(336)(math, _config);
__webpack_require__(339)(math, _config);
__webpack_require__(340)(math, _config);
__webpack_require__(341)(math, _config);
__webpack_require__(342)(math, _config);
__webpack_require__(343)(math, _config);
__webpack_require__(338)(math, _config);
// TODO: deprecated since version 0.25.0, remove some day.
math.ifElse = function () {
throw new Error('Function ifElse is deprecated. Use the conditional operator instead.');
};
// constants
__webpack_require__(15)(math, _config);
// attach transform functions (for converting one-based indices to zero-based)
math.expression.transform = {
concat: __webpack_require__(344)(math, _config),
filter: __webpack_require__(346)(math, _config),
forEach:__webpack_require__(347)(math, _config),
index: __webpack_require__(348)(math, _config),
map: __webpack_require__(349)(math, _config),
max: __webpack_require__(350)(math, _config),
mean: __webpack_require__(351)(math, _config),
min: __webpack_require__(352)(math, _config),
range: __webpack_require__(353)(math, _config),
subset: __webpack_require__(354)(math, _config)
};
// selector (we initialize after all functions are loaded)
math.chaining = {};
math.chaining.Chain = __webpack_require__(355)(math, _config);
math.chaining.Selector = math.chaining.Chain; // TODO: deprecate in v2.0
// apply provided configuration options
math.config(_config); // apply the default options
math.config(config); // apply custom options
// return the new instance
return math;
}
// create a default instance of math.js
var math = create();
if (typeof window !== 'undefined') {
window.mathjs = math; // TODO: deprecate the mathjs namespace some day (replaced with 'math' since version 0.25.0)
}
// export the default instance
module.exports = math;
/***/ },
/* 2 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
module.exports = function(math) {
var array = __webpack_require__(3);
var Matrix = math.type.Matrix;
/**
* 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`
*/
math.dot = function dot(x, y) {
if (x instanceof Matrix) {
if (y instanceof Matrix) {
return _dot(x.toArray(), y.toArray());
}
else if (Array.isArray(y)) {
return _dot(x.toArray(), y);
}
}
else if (Array.isArray(x)) {
if (y instanceof Matrix) {
return _dot(x, y.toArray());
}
else if (Array.isArray(y)) {
return _dot(x, y);
}
}
throw new math.error.UnsupportedTypeError('dot', math['typeof'](x), math['typeof'](y));
};
/**
* 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= array.size(x);
var ySize = array.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 = math.add(prod, math.multiply(x[i], y[i]));
}
return prod;
}
};
/***/ },
/* 3 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var number = __webpack_require__(5),
string = __webpack_require__(9),
object = __webpack_require__(12),
types = __webpack_require__(4),
DimensionError = __webpack_require__(13),
IndexError = __webpack_require__(14),
isArray = Array.isArray;
/**
* Calculate the size of a multi dimensional array.
* @param {Array} x
* @Return {Number[]} size
* @private
*/
function _size(x) {
var size = [];
while (isArray(x)) {
size.push(x.length);
x = x[0];
}
return size;
}
/**
* Calculate the size of a multi dimensional array.
* All elements in the array are checked for matching dimensions using the
* method validate
* @param {Array} x
* @Return {Number[]} size
* @throws RangeError
*/
exports.size = function(x) {
// calculate the size
var s = _size(x);
// verify the size
exports.validate(x, s);
// TODO: don't validate here? only in a Matrix constructor?
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 (!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 (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 (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 (!isArray(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 (!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 (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
* @private
*/
exports.squeeze = function(array, size) {
var s = size || exports.size(array);
// squeeze outer dimensions
while (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 (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 (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)
* @private
*/
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;
};
/**
* Convert function arguments to an array.
* @param {Arguments} args
* @returns {Array} array
*/
exports.argsToArray = function(args) {
var array = [];
for (var i = 0, len = args.length; i < len; i++) {
array[i] = args[i];
}
return array;
};
/**
* Test whether an object is an array
* @param {*} value
* @return {Boolean} isArray
*/
exports.isArray = isArray;
/***/ },
/* 4 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
/**
* Determine the type of a variable
*
* type(x)
*
* @param {*} x
* @return {String} type Lower case type, 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 Function)return 'function';
if (x instanceof RegExp) return 'regexp';
}
return type;
};
/***/ },
/* 5 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var NumberFormatter = __webpack_require__(6);
/**
* Test whether value is a Number
* @param {*} value
* @return {Boolean} isNumber
*/
exports.isNumber = function(value) {
return (value instanceof Number) || (typeof value == 'number');
};
/**
* Check if a number is integer
* @param {Number | Boolean} value
* @return {Boolean} isInteger
*/
exports.isInteger = function(value) {
return (value == Math.round(value));
// Note: we use ==, not ===, as we can have Booleans as well
};
/**
* Calculate the sign of a number
* @param {Number} x
* @returns {*}
*/
exports.sign = function(x) {
if (x > 0) {
return 1;
}
else if (x < 0) {
return -1;
}
else {
return 0;
}
};
/**
* Convert a number 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 {Number} 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 === Infinity) {
return 'Infinity';
}
else if (value === -Infinity) {
return '-Infinity';
}
else if (isNaN(value)) {
return 'NaN';
}
// default values for options
var notation = 'auto';
var precision = undefined;
if (options) {
// determine notation from options
if (options.notation) {
notation = options.notation;
}
// determine precision from options
if (exports.isNumber(options)) {
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':
return exports
.toPrecision(value, precision, options && options.exponential)
// remove trailing zeros after the decimal point
.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 {Number} 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) {
return new NumberFormatter(value).toExponential(precision);
};
/**
* Format a number with fixed notation.
* @param {Number} value
* @param {Number} [precision=0] Optional number of decimals after the
* decimal point. Zero by default.
*/
exports.toFixed = function(value, precision) {
return new NumberFormatter(value).toFixed(precision);
};
/**
* Format a number with a certain precision
* @param {Number} value
* @param {Number} [precision=undefined] Optional number of digits.
* @param {{lower: number, upper: number}} [options] By default:
* lower = 1e-3 (excl)
* upper = 1e+5 (incl)
* @return {string}
*/
exports.toPrecision = function(value, precision, options) {
return new NumberFormatter(value).toPrecision(precision, options);
};
/**
* Count the number of significant digits of a number.
*
* For example:
* 2.34 returns 3
* 0.0034 returns 2
* 120.5e+30 returns 4
*
* @param {Number} value
* @return {Number} digits Number of significant digits
*/
exports.digits = function(value) {
return value
.toExponential()
.replace(/e.*$/, '') // remove exponential notation
.replace( /^0\.?0*|\./, '') // remove decimal point and leading zeros
.length
};
/**
* Minimum number added to one that makes the result different than one
*/
exports.DBL_EPSILON = Number.EPSILON || 2.2204460492503130808472633361816E-16;
/**
* Compares two floating point numbers.
* @param {Number} x First value to compare
* @param {Number} y Second value to compare
* @param {Number} [epsilon] The maximum relative difference between x and y
* If epsilon is undefined or null, the function will
* test whether x and y are exactly equal.
* @return {boolean} whether the two numbers are equal
*/
exports.nearlyEqual = function(x, y, epsilon) {
// if epsilon is null or undefined, test whether x and y are exactly equal
if (epsilon == null) return x == y;
// use "==" operator, handles infinities
if (x == y) return true;
// NaN
if (isNaN(x) || isNaN(y)) return false;
// at this point x and y should be finite
if(isFinite(x) && isFinite(y)) {
// check numbers are very close, needed when comparing numbers near zero
var diff = Math.abs(x - y);
if (diff < exports.DBL_EPSILON) {
return true;
}
else {
// use relative error
return diff <= Math.max(Math.abs(x), Math.abs(y)) * epsilon;
}
}
// Infinite and Number or negative Infinite and positive Infinite cases
return false;
};
/**
* Determines if n is a positive integer
* @param {Number} n Value to determine if it is a positive integer
* @return {Boolean} Whether the number is positive
*/
exports.isPositiveInteger = function(n) {
var BigNumber = __webpack_require__(7);
if (exports.isNumber(n) && exports.isInteger(n) && n >= 0) {
return true;
}
if (n instanceof BigNumber && n.isInteger() && n.gte(0)) {
return true;
}
return false;
};
/***/ },
/* 6 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
/**
* Format a number using methods toPrecision, toFixed, toExponential.
* @param {number | string} value
* @constructor
*/
function NumberFormatter (value) {
// parse the input value
var match = String(value).toLowerCase().match(/^0*?(-?)(\d+\.?\d*)(e([+-]?\d+))?$/);
if (!match) {
throw new SyntaxError('Invalid number');
}
var sign = match[1];
var coefficients = match[2];
var exponent = parseFloat(match[4] || '0');
var dot = coefficients.indexOf('.');
exponent += (dot !== -1) ? (dot - 1) : (coefficients.length - 1);
this.sign = sign;
this.coefficients = coefficients
.replace('.', '') // remove the dot (must be removed before removing leading zeros)
.replace(/^0*/, function (zeros) {
// remove leading zeros, add their count to the exponent
exponent -= zeros.length;
return '';
})
.replace(/0*$/, '') // remove trailing zeros
.split('')
.map(function (d) {
return parseInt(d);
});
if (this.coefficients.length === 0) {
this.coefficients.push(0);
exponent++;
}
this.exponent = exponent;
}
/**
* Format a number with fixed notation.
* @param {Number} [precision=0] Optional number of decimals after the
* decimal point. Zero by default.
*/
NumberFormatter.prototype.toFixed = function (precision) {
var rounded = this.roundDigits(this.exponent + 1 + (precision || 0));
var c = rounded.coefficients;
var p = rounded.exponent + 1; // exponent may have changed
// append zeros if needed
var pp = p + (precision || 0);
if (c.length < pp) {
c = c.concat(zeros(pp - c.length));
}
// prepend zeros if needed
if (p < 0) {
c = zeros(-p + 1).concat(c);
p = 1;
}
// insert a dot if needed
if (precision) {
c.splice(p, 0, (p === 0) ? '0.' : '.');
}
return this.sign + c.join('');
};
/**
* Format a number in exponential notation. Like '1.23e+5', '2.3e+0', '3.500e-3'
* @param {Number} [precision] Number of digits in formatted output.
* If not provided, the maximum available digits
* is used.
*/
NumberFormatter.prototype.toExponential = function (precision) {
// round if needed, else create a clone
var rounded = precision ? this.roundDigits(precision) : this.clone();
var c = rounded.coefficients;
var e = rounded.exponent;
// append zeros if needed
if (c.length < precision) {
c = c.concat(zeros(precision - c.length));
}
// format as `C.CCCe+EEE` or `C.CCCe-EEE`
var first = c.shift();
return this.sign + first + (c.length > 0 ? ('.' + c.join('')) : '') +
'e' + (e >= 0 ? '+' : '') + e;
};
/**
* Format a number with a certain precision
* @param {Number} [precision=undefined] Optional number of digits.
* @param {{lower: number | undefined, upper: number | undefined}} [options]
* By default:
* lower = 1e-3 (excl)
* upper = 1e+5 (incl)
* @return {string}
*/
NumberFormatter.prototype.toPrecision = function(precision, options) {
// determine lower and upper bound for exponential notation.
var lower = (options && options.lower !== undefined) ? options.lower : 1e-3;
var upper = (options && options.upper !== undefined) ? options.upper : 1e+5;
var abs = Math.abs(Math.pow(10, this.exponent));
if (abs < lower || abs >= upper) {
// exponential notation
return this.toExponential(precision);
}
else {
var rounded = precision ? this.roundDigits(precision) : this.clone();
var c = rounded.coefficients;
var e = rounded.exponent;
// append trailing zeros
if (c.length < precision) {
c = c.concat(zeros(precision - c.length));
}
// append trailing zeros
// TODO: simplify the next statement
c = c.concat(zeros(e - c.length + 1 +
(c.length < precision ? precision - c.length : 0)));
// prepend zeros
c = zeros(-e).concat(c);
var dot = e > 0 ? e : 0;
if (dot < c.length - 1) {
c.splice(dot + 1, 0, '.');
}
return this.sign + c.join('');
}
};
/**
* Crete a clone of the NumberFormatter
* @return {NumberFormatter} Returns a clone of the NumberFormatter
*/
NumberFormatter.prototype.clone = function () {
var clone = new NumberFormatter('0');
clone.sign = this.sign;
clone.coefficients = this.coefficients.slice(0);
clone.exponent = this.exponent;
return clone;
};
/**
* Round the number of digits of a number *
* @param {number} precision A positive integer
* @return {NumberFormatter} Returns a new NumberFormatter with the rounded
* digits
*/
NumberFormatter.prototype.roundDigits = function (precision) {
var rounded = this.clone();
var c = rounded.coefficients;
// prepend zeros if needed
while (precision <= 0) {
c.unshift(0);
rounded.exponent++;
precision++;
}
if (c.length > precision) {
var removed = c.splice(precision);
if (removed[0] >= 5) {
var i = precision - 1;
c[i]++;
while (c[i] === 10) {
c.pop();
if (i === 0) {
c.unshift(0);
rounded.exponent++;
i++;
}
i--;
c[i]++;
}
}
}
return rounded;
};
/**
* Create an array filled with zeros.
* @param {number} length
* @return {Array}
*/
function zeros(length) {
var arr = [];
for (var i = 0; i < length; i++) {
arr.push(0);
}
return arr;
}
module.exports = NumberFormatter;
/***/ },
/* 7 */
/***/ function(module, exports, __webpack_require__) {
var BigNumber = __webpack_require__(8);
// FIXME: replace all require('decimal.js') with require('./BigNumber').
module.exports = BigNumber;
/***/ },
/* 8 */
/***/ function(module, exports, __webpack_require__) {
var __WEBPACK_AMD_DEFINE_RESULT__;/*! decimal.js v4.0.2 https://github.com/MikeMcl/decimal.js/LICENCE */
;(function (global) {
'use strict';
/*
* decimal.js v4.0.2
* An arbitrary-precision Decimal type for JavaScript.
* https://github.com/MikeMcl/decimal.js
* Copyright (c) 2014 Michael Mclaughlin <M8ch88l@gmail.com>
* MIT Expat Licence
*/
var convertBase, decimal, noConflict,
crypto = global['crypto'],
external = true,
id = 0,
mathfloor = Math.floor,
mathpow = Math.pow,
outOfRange,
toString = Object.prototype.toString,
BASE = 1e7,
LOGBASE = 7,
NUMERALS = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_',
P = {},
/*
The maximum exponent magnitude.
The limit on the value of toExpNeg, toExpPos, minE and maxE.
*/
EXP_LIMIT = 9e15, // 0 to 9e15
/*
The limit on the value of precision, and on the argument to toDecimalPlaces,
toExponential, toFixed, toFormat, toPrecision and toSignificantDigits.
*/
MAX_DIGITS = 1E9, // 0 to 1e+9
/*
To decide whether or not to calculate x.pow(integer y) using the 'exponentiation by
squaring' algorithm or by exp(y*ln(x)), the number of significant digits of x is multiplied
by y. If this number is less than INT_POW_LIMIT then the former algorithm is used.
*/
INT_POW_LIMIT = 3000, // 0 to 5000
// The natural logarithm of 10 (1025 digits).
LN10 = '2.30258509299404568401799145468436420760110148862877297603332790096757260967735248023599720508959829834196778404228624863340952546508280675666628736909878168948290720832555468084379989482623319852839350530896537773262884616336622228769821988674654366747440424327436515504893431493939147961940440022210510171417480036880840126470806855677432162283552201148046637156591213734507478569476834636167921018064450706480002775026849167465505868569356734206705811364292245544057589257242082413146956890167589402567763113569192920333765871416602301057030896345720754403708474699401682692828084811842893148485249486448719278096762712757753970276686059524967166741834857044225071979650047149510504922147765676369386629769795221107182645497347726624257094293225827985025855097852653832076067263171643095059950878075237103331011978575473315414218084275438635917781170543098274823850