UNPKG

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,715 lines (1,513 loc) 749 kB
/** * 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.0.1 * @date 2014-09-12 * * @license * Copyright (C) 2013-2014 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__(3); var digits = __webpack_require__(4).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__(2)(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__(139).constructor(); // extend BigNumber with a function clone if (typeof BigNumber.prototype.clone !== 'function') { /** * Clone a bignumber * @return {BigNumber} clone */ BigNumber.prototype.clone = function() { return new BigNumber(this); }; } // 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 mor 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__(5); // types (Matrix, Complex, Unit, ...) math.type = {}; math.type.Complex = __webpack_require__(6); math.type.Range = __webpack_require__(7); math.type.Index = __webpack_require__(8); math.type.Matrix = __webpack_require__(9); math.type.Unit = __webpack_require__(10); math.type.Help = __webpack_require__(11); math.type.ResultSet = __webpack_require__(12); math.type.BigNumber = BigNumber; math.collection = __webpack_require__(13); // expression (parse, Parser, nodes, docs) math.expression = {}; math.expression.node = __webpack_require__(16); math.expression.parse = __webpack_require__(14); math.expression.Parser = __webpack_require__(15); math.expression.docs = __webpack_require__(17); // expression parser __webpack_require__(29)(math, _config); __webpack_require__(30)(math, _config); __webpack_require__(31)(math, _config); __webpack_require__(32)(math, _config); // functions - arithmetic __webpack_require__(33)(math, _config); __webpack_require__(34)(math, _config); __webpack_require__(35)(math, _config); __webpack_require__(36)(math, _config); __webpack_require__(37)(math, _config); __webpack_require__(38)(math, _config); __webpack_require__(39)(math, _config); __webpack_require__(40)(math, _config); __webpack_require__(41)(math, _config); __webpack_require__(42)(math, _config); __webpack_require__(43)(math, _config); __webpack_require__(44)(math, _config); __webpack_require__(45)(math, _config); __webpack_require__(46)(math, _config); __webpack_require__(47)(math, _config); __webpack_require__(48)(math, _config); __webpack_require__(49)(math, _config); __webpack_require__(50)(math, _config); __webpack_require__(51)(math, _config); __webpack_require__(52)(math, _config); __webpack_require__(53)(math, _config); __webpack_require__(54)(math, _config); __webpack_require__(55)(math, _config); __webpack_require__(56)(math, _config); __webpack_require__(57)(math, _config); __webpack_require__(58)(math, _config); __webpack_require__(59)(math, _config); // functions - relational __webpack_require__(60)(math, _config); __webpack_require__(61)(math, _config); __webpack_require__(62)(math, _config); __webpack_require__(63)(math, _config); __webpack_require__(64)(math, _config); __webpack_require__(65)(math, _config); __webpack_require__(66)(math, _config); __webpack_require__(67)(math, _config); // functions - complex __webpack_require__(68)(math, _config); __webpack_require__(69)(math, _config); __webpack_require__(70)(math, _config); __webpack_require__(71)(math, _config); // functions - construction __webpack_require__(72)(math, _config); __webpack_require__(73)(math, _config); __webpack_require__(74)(math, _config); __webpack_require__(75)(math, _config); __webpack_require__(76)(math, _config); __webpack_require__(77)(math, _config); __webpack_require__(78)(math, _config); __webpack_require__(79)(math, _config); __webpack_require__(80)(math, _config); __webpack_require__(81)(math, _config); // functions - matrix __webpack_require__(82)(math, _config); __webpack_require__(83)(math, _config); __webpack_require__(84)(math, _config); __webpack_require__(85)(math, _config); __webpack_require__(86)(math, _config); __webpack_require__(87)(math, _config); __webpack_require__(88)(math, _config); __webpack_require__(89)(math, _config); __webpack_require__(90)(math, _config); __webpack_require__(91)(math, _config); __webpack_require__(92)(math, _config); __webpack_require__(93)(math, _config); __webpack_require__(94)(math, _config); __webpack_require__(95)(math, _config); // functions - probability //require('./function/probability/distribution')(math, _config); // TODO: rethink math.distribution __webpack_require__(96)(math, _config); __webpack_require__(97)(math, _config); __webpack_require__(98)(math, _config); __webpack_require__(99)(math, _config); __webpack_require__(100)(math, _config); __webpack_require__(101)(math, _config); // functions - statistics __webpack_require__(102)(math, _config); __webpack_require__(103)(math, _config); __webpack_require__(104)(math, _config); __webpack_require__(105)(math, _config); __webpack_require__(106)(math, _config); __webpack_require__(107)(math, _config); __webpack_require__(108)(math, _config); __webpack_require__(109)(math, _config); // functions - trigonometry __webpack_require__(110)(math, _config); __webpack_require__(111)(math, _config); __webpack_require__(112)(math, _config); __webpack_require__(113)(math, _config); __webpack_require__(114)(math, _config); __webpack_require__(115)(math, _config); __webpack_require__(116)(math, _config); __webpack_require__(117)(math, _config); __webpack_require__(118)(math, _config); __webpack_require__(119)(math, _config); __webpack_require__(120)(math, _config); __webpack_require__(121)(math, _config); __webpack_require__(122)(math, _config); __webpack_require__(123)(math, _config); __webpack_require__(124)(math, _config); __webpack_require__(125)(math, _config); // functions - units __webpack_require__(126)(math, _config); // functions - utils __webpack_require__(127)(math, _config); __webpack_require__(128)(math, _config); __webpack_require__(129)(math, _config); __webpack_require__(130)(math, _config); __webpack_require__(131)(math, _config); __webpack_require__(132)(math, _config); __webpack_require__(133)(math, _config); __webpack_require__(134)(math, _config); __webpack_require__(135)(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__(2)(math, _config); // attach transform functions (for converting one-based indices to zero-based) __webpack_require__(18)(math, _config); __webpack_require__(19)(math, _config); __webpack_require__(20)(math, _config); __webpack_require__(21)(math, _config); __webpack_require__(22)(math, _config); __webpack_require__(23)(math, _config); __webpack_require__(24)(math, _config); __webpack_require__(25)(math, _config); __webpack_require__(26)(math, _config); __webpack_require__(27)(math, _config); // selector (we initialize after all functions are loaded) math.chaining = {}; math.chaining.Selector = __webpack_require__(28)(math, _config); // 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, config) { var bignumber = __webpack_require__(136); var Complex = __webpack_require__(6); var BigNumber = math.type.BigNumber; /** * Calculate BigNumber e * @returns {BigNumber} Returns e */ function bigE() { return new BigNumber(1).exp(); } /** * Calculate BigNumber golden ratio, phi = (1+sqrt(5))/2 * @returns {BigNumber} Returns phi */ function bigPhi() { return new BigNumber(1).plus(new BigNumber(5).sqrt()).div(2); } /** * 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 */ function arctan(x) { var y = x; var yPrev = NaN; var x2 = x.times(x); var num = x; var sign = -1; for (var k = 3; !y.equals(yPrev); k += 2) { num = num.times(x2); yPrev = y; y = (sign > 0) ? y.plus(num.div(k)) : y.minus(num.div(k)); sign = -sign; } return y; } /** * 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 * @returns {BigNumber} Returns pi */ function bigPi() { // 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(arctan(new Big(1).div(5))) .minus(arctan(new Big(1).div(239))); // the final pi has the requested number of decimals return new BigNumber(4).times(pi4th); } /** * Calculate BigNumber tau, tau = 2 * pi * @returns {BigNumber} Returns tau */ function bigTau() { // we calculate pi at a slightly higher precision than configured to prevent round off errors // when multiplying by two in the end BigNumber.config({precision: config.precision + 2}); var pi = bigPi(); BigNumber.config({precision: config.precision}); return new BigNumber(2).times(pi); } var big = config.number === 'bignumber'; // TODO: in case of support for defineProperty, we can lazy evaluate the BigNumber constants by creating them as properties (calculation of PI is slow for example) math.pi = big ? bigPi() : Math.PI; math.tau = big ? bigTau() : Math.PI * 2; math.e = big ? bigE() : Math.E; math.phi = big ? bigPhi() : 1.61803398874989484820458683436563811772030917980576286213545; // golden ratio, (1+sqrt(5))/2 math.i = new Complex(0, 1); math['Infinity'] = Infinity; math['NaN'] = NaN; math['true'] = true; math['false'] = false; math['null'] = null; math['uninitialized'] = __webpack_require__(137).UNINITIALIZED; // uppercase constants (for compatibility with built-in Math) math.E = math.e; math.LN2 = big ? new BigNumber(2).ln() : Math.LN2; math.LN10 = big ? new BigNumber(10).ln() : Math.LN10; math.LOG2E = big ? new BigNumber(1).div(new BigNumber(2).ln()) : Math.LOG2E; math.LOG10E = big ? new BigNumber(1).div(new BigNumber(10).ln()) : Math.LOG10E; math.PI = math.pi; math.SQRT1_2 = big ? new BigNumber(0.5).sqrt() : Math.SQRT1_2; math.SQRT2 = big ? new BigNumber(2).sqrt() : Math.SQRT2; // meta information math.version = __webpack_require__(138); }; /***/ }, /* 3 */ /***/ function(module, exports, __webpack_require__) { 'use strict'; /** * Clone an object * * clone(x) * * Can clone any primitive type, array, and object. * If x has a function clone, this function will be invoked to clone the object. * * @param {*} x * @return {*} clone */ exports.clone = function clone(x) { var type = typeof x; // immutable primitive types if (type === 'number' || type === 'string' || type === 'boolean' || x === null || x === undefined) { return x; } // use clone function of the object when available if (typeof x.clone === 'function') { return x.clone(); } // array if (Array.isArray(x)) { return x.map(function (value) { return clone(value); }); } if (x instanceof Number) return new Number(x.valueOf()); if (x instanceof String) return new String(x.valueOf()); if (x instanceof Boolean) return new Boolean(x.valueOf()); if (x instanceof Date) return new Date(x.valueOf()); if (x instanceof RegExp) throw new TypeError('Cannot clone ' + x); // TODO: clone a RegExp // object var m = {}; for (var key in x) { if (x.hasOwnProperty(key)) { m[key] = clone(x[key]); } } return m; }; /** * Extend object a with the properties of object b * @param {Object} a * @param {Object} b * @return {Object} a */ exports.extend = function(a, b) { for (var prop in b) { if (b.hasOwnProperty(prop)) { a[prop] = b[prop]; } } return a; }; /** * Deep extend an object a with the properties of object b * @param {Object} a * @param {Object} b * @returns {Object} */ exports.deepExtend = function deepExtend (a, b) { // TODO: add support for Arrays to deepExtend if (Array.isArray(b)) { throw new TypeError('Arrays are not supported by deepExtend'); } for (var prop in b) { if (b.hasOwnProperty(prop)) { if (b[prop] && b[prop].constructor === Object) { if (a[prop] === undefined) { a[prop] = {}; } if (a[prop].constructor === Object) { deepExtend(a[prop], b[prop]); } else { a[prop] = b[prop]; } } else if (Array.isArray(b[prop])) { throw new TypeError('Arrays are not supported by deepExtend'); } else { a[prop] = b[prop]; } } } return a; }; /** * Deep test equality of all fields in two pairs of arrays or objects. * @param {Array | Object} a * @param {Array | Object} b * @returns {boolean} */ exports.deepEqual = function deepEqual (a, b) { var prop, i, len; if (Array.isArray(a)) { if (!Array.isArray(b)) { return false; } if (a.length != b.length) { return false; } for (i = 0, len = a.length; i < len; i++) { if (!exports.deepEqual(a[i], b[i])) { return false; } } return true; } else if (a instanceof Object) { if (Array.isArray(b) || !(b instanceof Object)) { return false; } for (prop in a) { //noinspection JSUnfilteredForInLoop if (!exports.deepEqual(a[prop], b[prop])) { return false; } } for (prop in b) { //noinspection JSUnfilteredForInLoop if (!exports.deepEqual(a[prop], b[prop])) { return false; } } return true; } else { return (typeof a === typeof b) && (a == b); } }; /***/ }, /* 4 */ /***/ function(module, exports, __webpack_require__) { 'use strict'; /** * 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': // 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; } } // handle special case zero if (value === 0) return '0'; // determine whether or not to output exponential notation var str; var abs = Math.abs(value); if (abs >= lower && abs < upper) { // normal number notation // Note: IE7 does not allow value.toPrecision(undefined) var valueStr = precision ? value.toPrecision(Math.min(precision, 21)) : value.toPrecision(); str = parseFloat(valueStr) + ''; } 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 {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) { if (precision !== undefined) { return value.toExponential(Math.min(precision - 1, 20)); } else { return value.toExponential(); } }; /** * 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 value.toFixed(Math.min(precision, 20)); }; /** * 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; }; /***/ }, /* 5 */ /***/ function(module, exports, __webpack_require__) { 'use strict'; exports.ArgumentsError = __webpack_require__(140); exports.DimensionError = __webpack_require__(141); exports.IndexError = __webpack_require__(142); exports.UnsupportedTypeError = __webpack_require__(143); // TODO: implement an InvalidValueError? /***/ }, /* 6 */ /***/ function(module, exports, __webpack_require__) { 'use strict'; var util = __webpack_require__(144), Unit = __webpack_require__(10), number = util.number, isNumber = util.number.isNumber, isUnit = Unit.isUnit, isString = util.string.isString; /** * @constructor Complex * * A complex value can be constructed in the following ways: * var a = new Complex(); * var b = new Complex(re, im); * var c = Complex.parse(str); * * Example usage: * var a = new Complex(3, -4); // 3 - 4i * a.re = 5; // a = 5 - 4i * var i = a.im; // -4; * var b = Complex.parse('2 + 6i'); // 2 + 6i * var c = new Complex(); // 0 + 0i * var d = math.add(a, b); // 5 + 2i * * @param {Number} re The real part of the complex value * @param {Number} [im] The imaginary part of the complex value */ function Complex(re, im) { if (!(this instanceof Complex)) { throw new SyntaxError('Constructor must be called with the new operator'); } switch (arguments.length) { case 0: this.re = 0; this.im = 0; break; case 1: var arg = arguments[0]; if (typeof arg === 'object') { if('re' in arg && 'im' in arg) { var construct = new Complex(arg.re, arg.im); // pass on input validation this.re = construct.re; this.im = construct.im; break; } else if ('r' in arg && 'phi' in arg) { var construct = Complex.fromPolar(arg.r, arg.phi); this.re = construct.re; this.im = construct.im; break; } } throw new SyntaxError('Object with the re and im or r and phi properties expected.'); case 2: if (!isNumber(re) || !isNumber(im)) { throw new TypeError('Two numbers expected in Complex constructor'); } this.re = re; this.im = im; break; default: throw new SyntaxError('One, two or three arguments expected in Complex constructor'); } } /** * Test whether value is a Complex value * @param {*} value * @return {Boolean} isComplex */ Complex.isComplex = function (value) { return (value instanceof Complex); }; // private variables and functions for the parser var text, index, c; function skipWhitespace() { while (c == ' ' || c == '\t') { next(); } } function isDigitDot (c) { return ((c >= '0' && c <= '9') || c == '.'); } function isDigit (c) { return ((c >= '0' && c <= '9')); } function next() { index++; c = text.charAt(index); } function revert(oldIndex) { index = oldIndex; c = text.charAt(index); } function parseNumber () { var number = ''; var oldIndex; oldIndex = index; if (c == '+') { next(); } else if (c == '-') { number += c; next(); } if (!isDigitDot(c)) { // a + or - must be followed by a digit revert(oldIndex); return null; } // get number, can have a single dot if (c == '.') { number += c; next(); if (!isDigit(c)) { // this is no legal number, it is just a dot revert(oldIndex); return null; } } else { while (isDigit(c)) { number += c; next(); } if (c == '.') { number += c; next(); } } while (isDigit(c)) { number += c; next(); } // check for exponential notation like "2.3e-4" or "1.23e50" if (c == 'E' || c == 'e') { number += c; next(); if (c == '+' || c == '-') { number += c; next(); } // Scientific notation MUST be followed by an exponent if (!isDigit(c)) { // this is no legal number, exponent is missing. revert(oldIndex); return null; } while (isDigit(c)) { number += c; next(); } } return number; } function parseComplex () { // check for 'i', '-i', '+i' var cnext = text.charAt(index + 1); if (c == 'I' || c == 'i') { next(); return '1'; } else if ((c == '+' || c == '-') && (cnext == 'I' || cnext == 'i')) { var number = (c == '+') ? '1' : '-1'; next(); next(); return number; } return null; } /** * Parse a complex number from a string. For example Complex.parse("2 + 3i") * will return a Complex value where re = 2, im = 3. * Returns null if provided string does not contain a valid complex number. * @param {String} str * @returns {Complex | null} complex */ Complex.parse = function (str) { text = str; index = -1; c = ''; if (!isString(text)) { return null; } next(); skipWhitespace(); var first = parseNumber(); if (first) { if (c == 'I' || c == 'i') { // pure imaginary number next(); skipWhitespace(); if (c) { // garbage at the end. not good. return null; } return new Complex(0, Number(first)); } else { // complex and real part skipWhitespace(); var separator = c; if (separator != '+' && separator != '-') { // pure real number skipWhitespace(); if (c) { // garbage at the end. not good. return null; } return new Complex(Number(first), 0); } else { // complex and real part next(); skipWhitespace(); var second = parseNumber(); if (second) { if (c != 'I' && c != 'i') { // 'i' missing at the end of the complex number return null; } next(); } else { second = parseComplex(); if (!second) { // imaginary number missing after separator return null; } } if (separator == '-') { if (second[0] == '-') { second = '+' + second.substring(1); } else { second = '-' + second; } } next(); skipWhitespace(); if (c) { // garbage at the end. not good. return null; } return new Complex(Number(first), Number(second)); } } } else { // check for 'i', '-i', '+i' first = parseComplex(); if (first) { skipWhitespace(); if (c) { // garbage at the end. not good. return null; } return new Complex(0, Number(first)); } } return null; }; /** * Create a complex number from polar coordinates * * Usage: * * Complex.fromPolar(r: Number, phi: Number) : Complex * Complex.fromPolar({r: Number, phi: Number}) : Complex * * @param {*} args... * @return {Complex} */ Complex.fromPolar = function (args) { switch (arguments.length) { case 1: var arg = arguments[0]; if(typeof arg === 'object') { return Complex.fromPolar(arg.r, arg.phi); } throw new TypeError('Input has to be an object with r and phi keys.'); case 2: var r = arguments[0], phi = arguments[1]; if(isNumber(r)) { if (isUnit(phi) && phi.hasBase(Unit.BASE_UNITS.ANGLE)) { // convert unit to a number in radians phi = phi.toNumber('rad'); } if(isNumber(phi)) { return new Complex(r * Math.cos(phi), r * Math.sin(phi)); } throw new TypeError('Phi is not a number nor an angle unit.'); } else { throw new TypeError('Radius r is not a number.'); } default: throw new SyntaxError('Wrong number of arguments in function fromPolar'); } }; /* * Return the value of the complex number in polar notation * The angle phi will be set in the interval of [-pi, pi]. * @return {{r: number, phi: number}} Returns and object with properties r and phi. */ Complex.prototype.toPolar = function() { return { r: Math.sqrt(this.re * this.re + this.im * this.im), phi: Math.atan2(this.im, this.re) }; }; /** * Create a copy of the complex value * @return {Complex} clone */ Complex.prototype.clone = function () { return new Complex(this.re, this.im); }; /** * Test whether this complex number equals an other complex value. * Two complex numbers are equal when both their real and imaginary parts * are equal. * @param {Complex} other * @return {boolean} isEqual */ Complex.prototype.equals = function (other) { return (this.re === other.re) && (this.im === other.im); }; /** * Get a string representation of the complex number, * with optional formatting options. * @param {Object | Number | Function} [options] Formatting options. See * lib/util/number:format for a * description of the available * options. * @return {String} str */ Complex.prototype.format = function (options) { var str = '', strRe = number.format(this.re, options), strIm = number.format(this.im, options); if (this.im == 0) { // real value str = strRe; } else if (this.re == 0) { // purely complex value if (this.im == 1) { str = 'i'; } else if (this.im == -1) { str = '-i'; } else { str = strIm + 'i'; } } else { // complex value if (this.im > 0) { if (this.im == 1) { str = strRe + ' + i'; } else { str = strRe + ' + ' + strIm + 'i'; } } else { if (this.im == -1) { str = strRe + ' - i'; } else { str = strRe + ' - ' + strIm.substring(1) + 'i'; } } } return str; }; /** * Get a string representation of the complex number. * @return {String} str */ Complex.prototype.toString = function () { return this.format(); }; /** * Returns a string representation of the complex number. * @return {String} str */ Complex.prototype.valueOf = Complex.prototype.toString; // exports module.exports = Complex; /***/ }, /* 7 */ /***/ function(module, exports, __webpack_require__) { 'use strict'; var util = __webpack_require__(144); var number = util.number; var string = util.string; var array = util.array; /** * @constructor Range * Create a range. A range has a start, step, and end, and contains functions * to iterate over the range. * * A range can be constructed as: * var range = new Range(start, end); * var range = new Range(start, end, step); * * To get the result of the range: * range.forEach(function (x) { * console.log(x); * }); * range.map(function (x) { * return math.sin(x); * }); * range.toArray(); * * Example usage: * var c = new Range(2, 6); // 2:1:5 * c.toArray(); // [2, 3, 4, 5] * var d = new Range(2, -3, -1); // 2:-1:-2 * d.toArray(); // [2, 1, 0, -1, -2] * * @param {Number} start included lower bound * @param {Number} end excluded upper bound * @param {Number} [step] step size, default value is 1 */ function Range(start, end, step) { if (!(this instanceof Range)) { throw new SyntaxError('Constructor must be called with the new operator'); } if (start != null && !number.isNumber(start)) { throw new TypeError('Parameter start must be a number'); } if (end != null && !number.isNumber(end)) { throw new TypeError('Parameter end must be a number'); } if (step != null && !number.isNumber(step)) { throw new TypeError('Parameter step must be a number'); } this.start = (start != null) ? parseFloat(start) : 0; this.end = (end != null) ? parseFloat(end) : 0; this.step = (step != null) ? parseFloat(step) : 1; } /** * 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 {Range | null} range */ Range.parse = function (str) { if (!string.isString(str)) { return null; } var args = str.split(':'); var nums = args.map(function (arg) { return parseFloat(arg); }); var invalid = nums.some(function (num) { return isNaN(num); }); if(invalid) { return null; } switch (nums.length) { case 2: return new Range(nums[0], nums[1]); case 3: return new Range(nums[0], nums[2], nums[1]); default: return null; } }; /** * Create a clone of the range * @return {Range} clone */ Range.prototype.clone = function () { return new Range(this.start, this.end, this.step); }; /** * Test whether an object is a Range * @param {*} object * @return {Boolean} isRange */ Range.isRange = function (object) { return (object instanceof Range); }; /** * Retrieve the size of the range. * Returns an array containing one number, the number of elements in the range. * @returns {Number[]} size */ Range.prototype.size = function () { var len = 0, start = this.start, step = this.step, end = this.end, diff = end - start; if (number.sign(step) == number.sign(diff)) { len = Math.ceil((diff) / step); } else if (diff == 0) { len = 0; } if (isNaN(len)) { len = 0; } return [len]; }; /** * Calculate the minimum value in the range * @return {Number | undefined} min */ Range.prototype.min = function () { var size = this.size()[0]; if (size > 0) { if (this.step > 0) { // positive step return this.start; } else { // negative step return this.start + (size - 1) * this.step; } } else { return undefined; } }; /** * Calculate the maximum value in the range * @return {Number | undefined} max */ Range.prototype.max = function () { var size = this.size()[0]; if (size > 0) { if (this.step > 0) { // positive step return this.start + (size - 1) * this.step; } else { // negative step return this.start; } } else { return undefined; } }; /** * Execute a callback function for each value in the range. * @param {function} callback The callback method is invoked with three * parameters: the value of the element, the index * of the element, and the Matrix being traversed. */ Range.prototype.forEach = function (callback) { var x = this.start; var step = this.step; var end = this.end; var i = 0; if (step > 0) { while (x < end) { callback(x, i, this); x += step; i++; } } else if (step < 0) { while (x > end) { callback(x, i, this); x += step; i++; } } }; /** * Execute a callback function for each value in the Range, and return the * results as an array * @param {function} callback The callback method is invoked with three * parameters: the value of the element, the index * of the element, and the Matrix being traversed. * @returns {Array} array */ Range.prototype.map = function (callback) { var array = []; this.forEach(function (value, index, obj) { array[index] = callback(value, index, obj); }); return array; }; /** * Create an Array with a copy of the Ranges data * @returns {Array} array */ Range.prototype.toArray = function () { var array = []; this.forEach(function (value, index) { array[index] = value; }); return array; }; /** * Get the primitive value of the Range, a one dimensional array * @returns {Array} array */ Range.prototype.valueOf = function () { // TODO: implement a caching mechanism for range.valueOf() return this.toArray(); }; /** * Get a string representation of the range, with optional formatting options. * Output is formatted as 'start:step:end', for example '2:6' or '0:0.2:11' * @param {Object | Number | Function} [options] Formatting options. See * lib/util/number:format for a * description of the available * options. * @returns {String} str */ Range.prototype.format = function (options) { var str = number.format(this.start, options); if (this.step != 1) { str += ':' + number.format(this.step, options); } str += ':' + number.format(this.end, options); return str; }; /** * Get a string representation of the range. * @returns {String} */ Rang