UNPKG

mathjs

Version:

Math.js is an extensive math library for JavaScript and Node.js. It features a flexible expression parser with support for symbolic computation, comes with a large set of built-in functions and constants, and offers an integrated solution to work with dif

1,783 lines (1,548 loc) 1.57 MB
/** * 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 3.12.3 * @date 2017-05-05 * * @license * Copyright (C) 2013-2017 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] = { /******/ i: moduleId, /******/ l: false, /******/ exports: {} /******/ }; /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ // Flag the module as loaded /******/ module.l = 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; /******/ // identity function for calling harmony imports with the correct context /******/ __webpack_require__.i = function(value) { return value; }; /******/ // define getter function for harmony exports /******/ __webpack_require__.d = function(exports, name, getter) { /******/ if(!__webpack_require__.o(exports, name)) { /******/ Object.defineProperty(exports, name, { /******/ configurable: false, /******/ enumerable: true, /******/ get: getter /******/ }); /******/ } /******/ }; /******/ // getDefaultExport function for compatibility with non-harmony modules /******/ __webpack_require__.n = function(module) { /******/ var getter = module && module.__esModule ? /******/ function getDefault() { return module['default']; } : /******/ function getModuleExports() { return module; }; /******/ __webpack_require__.d(getter, 'a', getter); /******/ return getter; /******/ }; /******/ // Object.prototype.hasOwnProperty.call /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; /******/ // __webpack_public_path__ /******/ __webpack_require__.p = ""; /******/ // Load entry module and return exports /******/ return __webpack_require__(__webpack_require__.s = 519); /******/ }) /************************************************************************/ /******/ ([ /* 0 */ /***/ (function(module, exports, __webpack_require__) { "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; /***/ }), /* 1 */ /***/ (function(module, exports, __webpack_require__) { "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); } }; /***/ }), /* 2 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /** * @typedef {{sign: '+' | '-' | '', coefficients: number[], exponent: number}} SplitValue */ /** * Test whether value is a number * @param {*} value * @return {boolean} isNumber */ exports.isNumber = function(value) { return typeof value === 'number'; }; /** * Check if a number is integer * @param {number | boolean} value * @return {boolean} isInteger */ exports.isInteger = function(value) { return isFinite(value) ? (value == Math.round(value)) : false; // Note: we use ==, not ===, as we can have Booleans as well }; /** * Calculate the sign of a number * @param {number} x * @returns {*} */ exports.sign = Math.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' * 'engineering' Always use engineering notation. * For example '123.4e+0' and '14.0e+6' * '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' * format(12345678, {notation: 'engineering'}); // '12.345678e+6' * * @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 'engineering': return exports.toEngineering(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".'); } }; /** * Split a number into sign, coefficients, and exponent * @param {number | string} value * @return {SplitValue} * Returns an object containing sign, coefficients, and exponent */ exports.splitNumber = function (value) { // parse the input value var match = String(value).toLowerCase().match(/^0*?(-?)(\d+\.?\d*)(e([+-]?\d+))?$/); if (!match) { throw new SyntaxError('Invalid number ' + value); } var sign = match[1]; var digits = match[2]; var exponent = parseFloat(match[4] || '0'); var dot = digits.indexOf('.'); exponent += (dot !== -1) ? (dot - 1) : (digits.length - 1); var coefficients = digits .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 (coefficients.length === 0) { coefficients.push(0); exponent++; } return { sign: sign, coefficients: coefficients, exponent: exponent }; }; /** * Format a number in engineering notation. Like '1.23e+6', '2.3e+0', '3.500e-3' * @param {number | string} value * @param {number} [precision=0] Optional number of decimals after the * decimal point. Zero by default. */ exports.toEngineering = function (value, precision) { if (isNaN(value) || !isFinite(value)) { return String(value); } var rounded = exports.roundDigits(exports.splitNumber(value), precision); var e = rounded.exponent; var c = rounded.coefficients; // find nearest lower multiple of 3 for exponent var newExp = e % 3 === 0 ? e : (e < 0 ? (e - 3) - (e % 3) : e - (e % 3)); // concatenate coefficients with necessary zeros var significandsDiff = e >= 0 ? e : Math.abs(newExp); // add zeros if necessary (for ex: 1e+8) if (c.length - 1 < significandsDiff) c = c.concat(zeros(significandsDiff - (c.length - 1))); // find difference in exponents var expDiff = Math.abs(e - newExp); var decimalIdx = 1; // push decimal index over by expDiff times while (--expDiff >= 0) decimalIdx++; // if all coefficient values are zero after the decimal point, don't add a decimal value. // otherwise concat with the rest of the coefficients var decimals = c.slice(decimalIdx).join(''); var decimalVal = decimals.match(/[1-9]/) ? ('.' + decimals) : ''; var str = c.slice(0, decimalIdx).join('') + decimalVal + 'e' + (e >= 0 ? '+' : '') + newExp.toString(); return rounded.sign + str; }; /** * Format a number with fixed notation. * @param {number | string} value * @param {number} [precision=0] Optional number of decimals after the * decimal point. Zero by default. */ exports.toFixed = function (value, precision) { if (isNaN(value) || !isFinite(value)) { return String(value); } var splitValue = exports.splitNumber(value) var rounded = exports.roundDigits(splitValue, splitValue.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 rounded.sign + c.join(''); }; /** * Format a number in exponential notation. Like '1.23e+5', '2.3e+0', '3.500e-3' * @param {number | string} value * @param {number} [precision] Number of digits in formatted output. * If not provided, the maximum available digits * is used. */ exports.toExponential = function (value, precision) { if (isNaN(value) || !isFinite(value)) { return String(value); } // round if needed, else create a clone var split = exports.splitNumber(value) var rounded = precision ? exports.roundDigits(split, precision) : split; 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 rounded.sign + first + (c.length > 0 ? ('.' + c.join('')) : '') + 'e' + (e >= 0 ? '+' : '') + e; } /** * Format a number with a certain precision * @param {number | string} value * @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} */ exports.toPrecision = function (value, precision, options) { if (isNaN(value) || !isFinite(value)) { return String(value); } // 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 split = exports.splitNumber(value) var abs = Math.abs(Math.pow(10, split.exponent)); if (abs < lower || abs >= upper) { // exponential notation return exports.toExponential(value, precision); } else { var rounded = precision ? exports.roundDigits(split, precision) : split; 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 rounded.sign + c.join(''); } } /** * Round the number of digits of a number * * @param {SplitValue} split A value split with .splitNumber(value) * @param {number} precision A positive integer * @return {SplitValue} * Returns an object containing sign, coefficients, and exponent * with rounded digits */ exports.roundDigits = function (split, precision) { // create a clone var rounded = { sign: split.sign, coefficients: split.coefficients, exponent: split.exponent } 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, c.length - 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; } /** * 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 nearly 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; }; /***/ }), /* 3 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var number = __webpack_require__(2); var string = __webpack_require__(11); var object = __webpack_require__(5); var types = __webpack_require__(63); var DimensionError = __webpack_require__(9); var IndexError = __webpack_require__(44); /** * 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 * when length is provided * @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 || (typeof length === 'number' && 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] = defaultValue; } } } } /** * Re-shape a multi dimensional array to fit the specified dimensions * @param {Array} array Array to be reshaped * @param {Array.<number>} sizes List of sizes for each dimension * @returns {Array} Array whose data has been formatted to fit the * specified dimensions * * @throws {DimensionError} If the product of the new dimension sizes does * not equal that of the old ones */ exports.reshape = function(array, sizes) { var flatArray = exports.flatten(array); var newArray; var product = function (arr) { return arr.reduce(function (prev, curr) { return prev * curr; }); }; if (!Array.isArray(array) || !Array.isArray(sizes)) { throw new TypeError('Array expected'); } if (sizes.length === 0) { throw new DimensionError(0, product(exports.size(array)), '!='); } try { newArray = _reshape(flatArray, sizes); } catch (e) { if (e instanceof DimensionError) { throw new DimensionError( product(sizes), product(exports.size(array)), '!=' ); } throw e; } if (flatArray.length > 0) { throw new DimensionError( product(sizes), product(exports.size(array)), '!=' ); } return newArray; }; /** * Recursively re-shape a multi dimensional array to fit the specified dimensions * @param {Array} array Array to be reshaped * @param {Array.<number>} sizes List of sizes for each dimension * @returns {Array} Array whose data has been formatted to fit the * specified dimensions * * @throws {DimensionError} If the product of the new dimension sizes does * not equal that of the old ones */ function _reshape(array, sizes) { var accumulator = []; var i; if (sizes.length === 0) { if (array.length === 0) { throw new DimensionError(null, null, '!='); } return array.shift(); } for (i = 0; i < sizes[0]; i += 1) { accumulator.push(_reshape(array, sizes.slice(1))); } return accumulator; } /** * 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 * * Paramter `size` will be mutated to match the new, unqueezed matrix size. * * @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; }; /** * A safe map * @param {Array} array * @param {function} callback */ exports.map = function (array, callback) { return Array.prototype.map.call(array, callback); } /** * A safe forEach * @param {Array} array * @param {function} callback */ exports.forEach = function (array, callback) { Array.prototype.forEach.call(array, callback); } /** * A safe join * @param {Array} array * @param {string} separator */ exports.join = function (array, separator) { return Array.prototype.join.call(array, separator); } /** * Test whether an object is an array * @param {*} value * @return {boolean} isArray */ exports.isArray = Array.isArray; /***/ }), /* 4 */ /***/ (function(module, exports, __webpack_require__) { "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; }; /***/ }), /* 5 */ /***/ (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 && x.isBigNumber === true) return x; // bignumbers are immutable if (x instanceof RegExp) throw new TypeError('Cannot clone ' + x); // TODO: clone a RegExp // object return exports.map(x, clone); }; /** * Apply map to all properties of an object * @param {Object} object * @param {function} callback * @return {Object} Returns a copy of the object with mapped properties */ exports.map = function(object, callback) { var clone = {}; for (var key in object) { if (Object.hasOwnProperty.call(object, key)) { clone[key] = callback(object[key]); } } return clone; } /** * 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 (Object.hasOwnProperty.call(b, 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 (Object.hasOwnProperty.call(b, 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); } }; /** * Test whether the current JavaScript engine supports Object.defineProperty * @returns {boolean} returns true if supported */ exports.canDefineProperty = function () { // test needed for broken IE8 implementation try { if (Object.defineProperty) { Object.defineProperty({}, 'x', { get: function () {} }); return true; } } catch (e) {} return false; }; /** * Attach a lazy loading property to a constant. * The given function `fn` is called once when the property is first requested. * On older browsers (<IE8), the function will fall back to direct evaluation * of the properties value. * @param {Object} object Object where to add the property * @param {string} prop Property name * @param {Function} fn Function returning the property value. Called * without arguments. */ exports.lazy = function (object, prop, fn) { if (exports.canDefineProperty()) { var _uninitialized = true; var _value; Object.defineProperty(object, prop, { get: function () { if (_uninitialized) { _value = fn(); _uninitialized = false; } return _value; }, set: function (value) { _value = value; _uninitialized = false; }, configurable: true, enumerable: true }); } else { // fall back to immediate evaluation object[prop] = fn(); } }; /** * Traverse a path into an object. * When a namespace is missing, it will be created * @param {Object} object * @param {string} path A dot separated string like 'name.space' * @return {Object} Returns the object at the end of the path */ exports.traverse = function(object, path) { var obj = object; if (path) { var names = path.split('.'); for (var i = 0; i < names.length; i++) { var name = names[i]; if (!(name in obj)) { obj[name] = {}; } obj = obj[name]; } } return obj; }; /** * A safe hasOwnProperty * @param {Object} object * @param {string} property */ exports.hasOwnProperty = function (object, property) { return object && Object.hasOwnProperty.call(object, property); } /** * Test whether an object is a factory. a factory has fields: * * - factory: function (type: Object, config: Object, load: function, typed: function [, math: Object]) (required) * - name: string (optional) * - path: string A dot separated path (optional) * - math: boolean If true (false by default), the math namespace is passed * as fifth argument of the factory function * * @param {*} object * @returns {boolean} */ exports.isFactory = function (object) { return object && typeof object.factory === 'function'; }; /***/ }), /* 6 */ /***/ (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; /***/ }), /* 7 */ /***/ (function(module, exports, __webpack_require__) { // the compile functions which compile a Node into JavaScript are not // exposed as class methods for security reasons to prevent being able to // override them or create fake Nodes. Instead, only compile functions of // registered nodes can be executed var hasOwnProperty = __webpack_require__(5).hasOwnProperty; function factory () { // map with node type as key and compile functions as value var compileFunctions = {} /** * Register a compile function for a node * @param {string} type * @param {function} compileFunction * The compile function, invoked as * compileFunction(node, defs, args) */ function register(type, compileFunction) { if (compileFunctions[type] === undefined) { compileFunctions[type] = compileFunction; } else { throw new Error('Cannot register type "' + type + '": already exists'); } } /** * Compile a Node into JavaScript * @param {Node} node * @param {Object} defs Object which can be used to define functions * or constants globally available for the compiled * expression * @param {Object} args Object with local function arguments, the key is * the name of the argument, and the value is `true`. * The object may not be mutated, but must be * extended instead. * @return {string} Returns JavaScript code */ function compile (node, defs, args) { if (hasOwnProperty(compileFunctions, node.type)) { var compileFunction = compileFunctions[node.type]; return compileFunction(node, defs, args); } else if (typeof node._compile === 'function' && !hasOwnProperty(node, '_compile')) { // Compatibility for CustomNodes // TODO: this is a security risk, change it such that you have to register CustomNodes separately in math.js, like math.expression.node.register(MyCustomNode) return node._compile(defs, args); } else { throw new Error('Cannot compile node: unknown type "' + node.type + '"'); } } return { register: register, compile: compile } } exports.factory = factory; /***/ }), /* 8 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var util = __webpack_require__(25); var DimensionError = __webpack_require__(9); 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 array