ubuntu-touch-coreapps-reviewers team mailing list archive
-
ubuntu-touch-coreapps-reviewers team
-
Mailing list archive
-
Message #04268
[Merge] lp:~gang65/ubuntu-calculator-app/ubuntu-calculator-app-mathjs-2-upgrade into lp:ubuntu-calculator-app
Bartosz Kosiorek has proposed merging lp:~gang65/ubuntu-calculator-app/ubuntu-calculator-app-mathjs-2-upgrade into lp:ubuntu-calculator-app.
Commit message:
Upgrade math.js to 2.1.1 to improve performance (LP: #1484851)
Requested reviews:
Ubuntu Calculator Developers (ubuntu-calculator-dev)
For more details, see:
https://code.launchpad.net/~gang65/ubuntu-calculator-app/ubuntu-calculator-app-mathjs-2-upgrade/+merge/268046
Upgrade math.js to 2.1.1 to improve performance (LP: #1484851)
--
The attached diff has been truncated due to its size.
Your team Ubuntu Calculator Developers is requested to review the proposed merge of lp:~gang65/ubuntu-calculator-app/ubuntu-calculator-app-mathjs-2-upgrade into lp:ubuntu-calculator-app.
=== modified file 'app/engine/math.js'
--- app/engine/math.js 2015-04-29 19:37:47 +0000
+++ app/engine/math.js 2015-08-14 09:10:33 +0000
@@ -14,8 +14,8 @@
* It features real and complex numbers, units, matrices, a large set of
* mathematical functions, and a flexible expression parser.
*
- * @version 1.5.2
- * @date 2015-04-09
+ * @version 2.1.1
+ * @date 2015-08-12
*
* @license
* Copyright (C) 2013-2015 Jos de Jong <wjosdejong@xxxxxxxxx>
@@ -35,7 +35,8 @@
(function webpackUniversalModuleDefinition(root, factory) {
// UCA: we delete all exports, we don't need them, and we keep only our var
- mathJs = factory();})(this, function() {
+ mathJs = factory();
+})(this, function() {
return /******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
@@ -82,42 +83,117 @@
/* 0 */
/***/ function(module, exports, __webpack_require__) {
- module.exports = __webpack_require__(1);
-
-
-/***/ },
-/* 1 */
-/***/ function(module, exports, __webpack_require__) {
-
- 'use strict';
-
- var object = __webpack_require__(2);
- var digits = __webpack_require__(3).digits;
+ var core = __webpack_require__(1);
/**
- * math.js factory function.
+ * math.js factory function. Creates a new instance of math.js
*
* @param {Object} [config] Available configuration options:
- * {String} matrix
+ * {number} epsilon
+ * Minimum relative difference between two
+ * compared values, used by all comparison functions.
+ * {string} matrix
* A string 'matrix' (default) or 'array'.
- * {String} number
- * A string 'number' (default) or 'bignumber'
- * {Number} precision
+ * {string} number
+ * A string 'number' (default), 'bignumber', or
+ * 'fraction'
+ * {number} precision
* The number of significant digits for BigNumbers.
* Not applicable for Numbers.
+ * {boolean} predictable
+ * Predictable output type of functions. When true,
+ * output type depends only on the input types. When
+ * false (default), output type can vary depending
+ * on input values. For example `math.sqrt(-2)`
+ * returns `NaN` when predictable is false, and
+ * returns `complex('2i')` when true.
*/
function create (config) {
+ // create a new math.js instance
+ var math = core.create(config);
+ math.create = create;
+
+ // import data types, functions, constants, expression parser, etc.
+ math.import(__webpack_require__(13));
+
+ return math;
+ }
+
+ // return a new instance of math.js
+ module.exports = create();
+
+
+/***/ },
+/* 1 */
+/***/ function(module, exports, __webpack_require__) {
+
+ module.exports = __webpack_require__(2);
+
+/***/ },
+/* 2 */
+/***/ function(module, exports, __webpack_require__) {
+
+ var isFactory = __webpack_require__(5).isFactory;
+ var deepExtend = __webpack_require__(5).deepExtend;
+ var typedFactory = __webpack_require__(6);
+ var emitter = __webpack_require__(3);
+
+ var importFactory = __webpack_require__(10);
+ var configFactory = __webpack_require__(12);
+
+ /**
+ * Math.js core. Creates a new, empty math.js instance
+ * @param {Object} [options] Available options:
+ * {number} epsilon
+ * Minimum relative difference between two
+ * compared values, used by all comparison functions.
+ * {string} matrix
+ * A string 'matrix' (default) or 'array'.
+ * {string} number
+ * A string 'number' (default), 'bignumber', or 'fraction'
+ * {number} precision
+ * The number of significant digits for BigNumbers.
+ * Not applicable for Numbers.
+ * {boolean} predictable
+ * Predictable output type of functions. When true,
+ * output type depends only on the input types. When
+ * false (default), output type can vary depending
+ * on input values. For example `math.sqrt(-2)`
+ * returns `NaN` when predictable is false, and
+ * returns `complex('2i')` when true.
+ * @returns {Object} Returns a bare-bone math.js instance containing
+ * functions:
+ * - `import` to add new functions
+ * - `config` to change configuration
+ * - `on`, `off`, `once`, `emit` for events
+ */
+ exports.create = function create (options) {
// 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.');
+ 'Please load the es5-shim and es5-sham library for compatibility.');
}
- // create namespace
- var math = {};
+ // cached factories and instances
+ var factories = [];
+ var instances = [];
+
+ // create a namespace for the mathjs instance, and attach emitter functions
+ var math = emitter.mixin({});
+ math.type = {};
+ math.expression = {
+ transform: Object.create(math)
+ };
+
+ // create a new typed instance
+ math.typed = typedFactory.create(math.type);
// create configuration options. These are private
var _config = {
+ // minimum relative difference between two compared values,
+ // used by all comparison functions
+ epsilon: 1e-14,
+
// type of default matrix output. Choose 'matrix' (default) or 'array'
matrix: 'matrix',
@@ -127,391 +203,161 @@
// number of significant digits in BigNumbers
precision: 64,
- // minimum relative difference between two compared values,
- // used by all comparison functions
- epsilon: 1e-14
+ // predictable output type of functions. When true, output type depends only
+ // on the input types. When false (default), output type can vary depending
+ // on input values. For example `math.sqrt(-2)` returns `NaN` when
+ // predictable is false, and returns `complex('2i')` when true.
+ predictable: false
};
+ if (options) {
+ // merge options
+ deepExtend(_config, options);
+ }
+
/**
- * 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
+ * Load a function or data type from a factory.
+ * If the function or data type already exists, the existing instance is
+ * returned.
+ * @param {{type: string, name: string, factory: Function}} factory
+ * @returns {*}
*/
- 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__(4)(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.');
- }
+ function load (factory) {
+ if (!isFactory(factory)) {
+ throw new Error('Factory object with properties `type`, `name`, and `factory` expected');
}
- // 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__(5).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 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;
+ var index = factories.indexOf(factory);
+ var instance;
+ if (index === -1) {
+ // doesn't yet exist
+ if (factory.math === true) {
+ // pass with math namespace
+ instance = factory.factory(math.type, _config, load, math.typed, math);
}
else {
- return new BigNumber(number);
+ instance = factory.factory(math.type, _config, load, math.typed);
}
- };
- }
- else {
- throw new Error('Cannot add function convert to BigNumber: function already exists');
- }
-
- // errors
- math.error = __webpack_require__(6);
-
- // types (Matrix, Complex, Unit, ...)
- math.type = {};
- math.type.Complex = __webpack_require__(7);
- math.type.Range = __webpack_require__(8);
- math.type.Index = __webpack_require__(9);
- math.type.Matrix = __webpack_require__(10)(_config);
- math.type.Unit = __webpack_require__(11);
- math.type.Help = __webpack_require__(12);
- math.type.ResultSet = __webpack_require__(13);
- math.type.BigNumber = BigNumber;
-
- math.collection = __webpack_require__(14)(math, _config);
-
- // matrix storage formats
- math.type.CcsMatrix = __webpack_require__(15)(math, _config);
- math.type.CrsMatrix = __webpack_require__(16)(math, _config);
- math.type.DenseMatrix = __webpack_require__(17)(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__(18);
- math.expression.parse = __webpack_require__(19)(math, _config);
- math.expression.Parser = __webpack_require__(20)(math, _config);
- math.expression.docs = __webpack_require__(21);
-
- // serialization utilities
- math.json = {
- reviver: __webpack_require__(22)(math, _config)
- };
-
- // functions - construction (must be defined before the rest of functions)
- __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);
-
- // expression parser
- __webpack_require__(44)(math, _config);
- __webpack_require__(45)(math, _config);
- __webpack_require__(46)(math, _config);
- __webpack_require__(47)(math, _config);
-
- // functions - arithmetic
- __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);
- __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);
- __webpack_require__(68)(math, _config);
- __webpack_require__(69)(math, _config);
- __webpack_require__(70)(math, _config);
- __webpack_require__(71)(math, _config);
- __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);
-
- // functions - bitwise
- __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);
- __webpack_require__(82)(math, _config);
- __webpack_require__(83)(math, _config);
-
- // functions - complex
- __webpack_require__(84)(math, _config);
- __webpack_require__(85)(math, _config);
- __webpack_require__(86)(math, _config);
- __webpack_require__(87)(math, _config);
-
- // functions - logical
- __webpack_require__(88)(math, _config);
- __webpack_require__(89)(math, _config);
- __webpack_require__(90)(math, _config);
- __webpack_require__(91)(math, _config);
-
- // functions - matrix
- __webpack_require__(92)(math, _config);
- __webpack_require__(93)(math, _config);
- __webpack_require__(94)(math, _config);
- __webpack_require__(95)(math, _config);
- __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);
- __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);
-
- // functions - probability
- //require('./function/probability/distribution')(math, _config); // TODO: rethink math.distribution
- __webpack_require__(109)(math, _config);
- __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);
-
- // functions - relational
- __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);
-
- // functions - statistics
- __webpack_require__(124)(math, _config);
- __webpack_require__(125)(math, _config);
- __webpack_require__(126)(math, _config);
- __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);
-
- // functions - trigonometry
- __webpack_require__(132)(math, _config);
- __webpack_require__(133)(math, _config);
- __webpack_require__(134)(math, _config);
- __webpack_require__(135)(math, _config);
- __webpack_require__(136)(math, _config);
- __webpack_require__(137)(math, _config);
- __webpack_require__(138)(math, _config);
- __webpack_require__(139)(math, _config);
- __webpack_require__(140)(math, _config);
- __webpack_require__(141)(math, _config);
- __webpack_require__(142)(math, _config);
- __webpack_require__(143)(math, _config);
- __webpack_require__(144)(math, _config);
- __webpack_require__(145)(math, _config);
- __webpack_require__(146)(math, _config);
- __webpack_require__(147)(math, _config);
- __webpack_require__(148)(math, _config);
- __webpack_require__(149)(math, _config);
- __webpack_require__(150)(math, _config);
- __webpack_require__(151)(math, _config);
- __webpack_require__(152)(math, _config);
- __webpack_require__(153)(math, _config);
- __webpack_require__(154)(math, _config);
- __webpack_require__(155)(math, _config);
- __webpack_require__(156)(math, _config);
-
- // functions - units
- __webpack_require__(157)(math, _config);
-
- // functions - utils
- __webpack_require__(158)(math, _config);
- __webpack_require__(159)(math, _config);
- __webpack_require__(160)(math, _config);
- __webpack_require__(161)(math, _config);
- __webpack_require__(162)(math, _config);
- __webpack_require__(163)(math, _config);
- __webpack_require__(164)(math, _config);
- __webpack_require__(165)(math, _config);
- __webpack_require__(166)(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__(4)(math, _config);
-
- // attach transform functions (for converting one-based indices to zero-based)
- math.expression.transform = {
- concat: __webpack_require__(23)(math, _config),
- filter: __webpack_require__(24)(math, _config),
- forEach:__webpack_require__(25)(math, _config),
- index: __webpack_require__(26)(math, _config),
- map: __webpack_require__(27)(math, _config),
- max: __webpack_require__(28)(math, _config),
- mean: __webpack_require__(29)(math, _config),
- min: __webpack_require__(30)(math, _config),
- range: __webpack_require__(31)(math, _config),
- subset: __webpack_require__(32)(math, _config)
- };
-
- // selector (we initialize after all functions are loaded)
- math.chaining = {};
- math.chaining.Chain = __webpack_require__(33)(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
+
+ // append to the cache
+ factories.push(factory);
+ instances.push(instance);
+ }
+ else {
+ // already existing function, return the cached instance
+ instance = instances[index];
+ }
+
+ return instance;
+ }
+
+ // load the import and config functions
+ math['import'] = load(importFactory);
+ math['config'] = load(configFactory);
+
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 */
+/* 3 */
/***/ function(module, exports, __webpack_require__) {
+ var Emitter = __webpack_require__(4);
+
+ /**
+ * Extend given object with emitter functions `on`, `off`, `once`, `emit`
+ * @param {Object} obj
+ * @return {Object} obj
+ */
+ exports.mixin = function (obj) {
+ // create event emitter
+ var emitter = new Emitter();
+
+ // bind methods to obj (we don't want to expose the emitter.e Array...)
+ obj.on = emitter.on.bind(emitter);
+ obj.off = emitter.off.bind(emitter);
+ obj.once = emitter.once.bind(emitter);
+ obj.emit = emitter.emit.bind(emitter);
+
+ return obj;
+ };
+
+
+/***/ },
+/* 4 */
+/***/ function(module, exports) {
+
+ function E () {
+ // Keep this empty so it's easier to inherit from
+ // (via https://github.com/lipsmack from https://github.com/scottcorgan/tiny-emitter/issues/3)
+ }
+
+ E.prototype = {
+ on: function (name, callback, ctx) {
+ var e = this.e || (this.e = {});
+
+ (e[name] || (e[name] = [])).push({
+ fn: callback,
+ ctx: ctx
+ });
+
+ return this;
+ },
+
+ once: function (name, callback, ctx) {
+ var self = this;
+ var fn = function () {
+ self.off(name, fn);
+ callback.apply(ctx, arguments);
+ };
+
+ return this.on(name, fn, ctx);
+ },
+
+ emit: function (name) {
+ var data = [].slice.call(arguments, 1);
+ var evtArr = ((this.e || (this.e = {}))[name] || []).slice();
+ var i = 0;
+ var len = evtArr.length;
+
+ for (i; i < len; i++) {
+ evtArr[i].fn.apply(evtArr[i].ctx, data);
+ }
+
+ return this;
+ },
+
+ off: function (name, callback) {
+ var e = this.e || (this.e = {});
+ var evts = e[name];
+ var liveEvents = [];
+
+ if (evts && callback) {
+ for (var i = 0, len = evts.length; i < len; i++) {
+ if (evts[i].fn !== callback) liveEvents.push(evts[i]);
+ }
+ }
+
+ // Remove event from queue to prevent memory leak
+ // Suggested by https://github.com/lazd
+ // Ref: https://github.com/scottcorgan/tiny-emitter/commit/c6ebfaa9bc973b33d110a84a307742b7cf94c953#commitcomment-5024910
+
+ (liveEvents.length)
+ ? e[name] = liveEvents
+ : delete e[name];
+
+ return this;
+ }
+ };
+
+ module.exports = E;
+
+
+/***/ },
+/* 5 */
+/***/ function(module, exports) {
+
'use strict';
/**
@@ -546,10 +392,11 @@
});
}
- 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 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
@@ -682,7 +529,7 @@
* 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
+ * @param {Function} fn Function returning the property value. Called
* without arguments.
*/
exports.lazy = function (object, prop, fn) {
@@ -701,7 +548,10 @@
set: function (value) {
_value = value;
_uninitialized = false;
- }
+ },
+
+ configurable: true,
+ enumerable: true
});
}
else {
@@ -710,37 +560,1553 @@
}
};
-
-/***/ },
-/* 3 */
-/***/ function(module, exports, __webpack_require__) {
-
- 'use strict';
-
- var NumberFormatter = __webpack_require__(167);
-
- /**
- * Test whether value is a Number
+ /**
+ * 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;
+ };
+
+ /**
+ * 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__) {
+
+ var typedFunction = __webpack_require__(7);
+ var digits = __webpack_require__(8).digits;
+
+ // returns a new instance of typed-function
+ var createTyped = function () {
+ // initially, return the original instance of typed-function
+ // consecutively, return a new instance from typed.create.
+ createTyped = typedFunction.create;
+ return typedFunction;
+ };
+
+ /**
+ * Factory function for creating a new typed instance
+ * @param {Object} type Object with data types like Complex and BigNumber
+ * @returns {Function}
+ */
+ exports.create = function create(type) {
+ // TODO: typed-function must be able to silently ignore signatures with unknown data types
+
+ // get a new instance of typed-function
+ var typed = createTyped();
+
+ // define all types. The order of the types determines in which order function
+ // arguments are type-checked (so for performance it's important to put the
+ // most used types first).
+ typed.types = [
+ { name: 'number', test: function (x) { return typeof x === 'number'; } },
+ { name: 'Complex', test: function (x) { return x && x.isComplex; } },
+ { name: 'BigNumber', test: function (x) { return x && x.isBigNumber; } },
+ { name: 'Fraction', test: function (x) { return x && x.isFraction; } },
+ { name: 'Unit', test: function (x) { return x && x.isUnit; } },
+ { name: 'string', test: function (x) { return typeof x === 'string'; } },
+ { name: 'Array', test: Array.isArray },
+ { name: 'Matrix', test: function (x) { return x && x.isMatrix; } },
+ { name: 'DenseMatrix', test: function (x) { return x && x.isDenseMatrix; } },
+ { name: 'SparseMatrix', test: function (x) { return x && x.isSparseMatrix; } },
+ { name: 'ImmutableDenseMatrix', test: function (x) { return x && x.isImmutableDenseMatrix; } },
+ { name: 'Range', test: function (x) { return x && x.isRange; } },
+ { name: 'Index', test: function (x) { return x && x.isIndex; } },
+ { name: 'boolean', test: function (x) { return typeof x === 'boolean'; } },
+ { name: 'ResultSet', test: function (x) { return x && x.isResultSet; } },
+ { name: 'Help', test: function (x) { return x && x.isHelp; } },
+ { name: 'function', test: function (x) { return typeof x === 'function';} },
+ { name: 'Date', test: function (x) { return x instanceof Date; } },
+ { name: 'RegExp', test: function (x) { return x instanceof RegExp; } },
+ { name: 'Object', test: function (x) { return typeof x === 'object'; } },
+ { name: 'null', test: function (x) { return x === null; } },
+ { name: 'undefined', test: function (x) { return x === undefined; } }
+ ];
+
+ // TODO: add conversion from BigNumber to number?
+ typed.conversions = [
+ {
+ from: 'number',
+ to: 'BigNumber',
+ convert: function (x) {
+ // note: conversion from number to BigNumber can fail if x has >15 digits
+ if (digits(x) > 15) {
+ throw new TypeError('Cannot implicitly convert a number with >15 significant digits to BigNumber ' +
+ '(value: ' + x + '). ' +
+ 'Use function bignumber(x) to convert to BigNumber.');
+ }
+ return new type.BigNumber(x);
+ }
+ }, {
+ from: 'number',
+ to: 'Complex',
+ convert: function (x) {
+ return new type.Complex(x, 0);
+ }
+ }, {
+ from: 'number',
+ to: 'string',
+ convert: function (x) {
+ return x + '';
+ }
+ }, {
+ from: 'BigNumber',
+ to: 'Complex',
+ convert: function (x) {
+ return new type.Complex(x.toNumber(), 0);
+ }
+ }, {
+ from: 'number',
+ to: 'Fraction',
+ convert: function (x) {
+ if (digits(x) > 15) {
+ throw new TypeError('Cannot implicitly convert a number with >15 significant digits to Fraction ' +
+ '(value: ' + x + '). ' +
+ 'Use function fraction(x) to convert to Fraction.');
+ }
+ return new type.Fraction(x);
+ }
+ }, {
+ from: 'string',
+ to: 'number',
+ convert: function (x) {
+ var n = Number(x);
+ if (isNaN(n)) {
+ throw new Error('Cannot convert "' + x + '" to a number');
+ }
+ return n;
+ }
+ }, {
+ from: 'boolean',
+ to: 'number',
+ convert: function (x) {
+ return +x;
+ }
+ }, {
+ from: 'boolean',
+ to: 'BigNumber',
+ convert: function (x) {
+ return new type.BigNumber(+x);
+ }
+ }, {
+ from: 'boolean',
+ to: 'string',
+ convert: function (x) {
+ return +x;
+ }
+ }, {
+ from: 'null',
+ to: 'number',
+ convert: function () {
+ return 0;
+ }
+ }, {
+ from: 'null',
+ to: 'string',
+ convert: function () {
+ return 'null';
+ }
+ }, {
+ from: 'null',
+ to: 'BigNumber',
+ convert: function () {
+ return new type.BigNumber(0);
+ }
+ }, {
+ from: 'Array',
+ to: 'Matrix',
+ convert: function (array) {
+ // TODO: how to decide on the right type of matrix to create?
+ return new type.DenseMatrix(array);
+ }
+ }, {
+ from: 'Matrix',
+ to: 'Array',
+ convert: function (matrix) {
+ return matrix.valueOf();
+ }
+ }
+ ];
+
+ return typed;
+ };
+
+
+/***/ },
+/* 7 */
+/***/ function(module, exports, __webpack_require__) {
+
+ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/**
+ * typed-function
+ *
+ * Type checking for JavaScript functions
+ *
+ * https://github.com/josdejong/typed-function
+ */
+ 'use strict';
+
+ (function (factory) {
+ if (true) {
+ // AMD. Register as an anonymous module.
+ !(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
+ } else if (typeof exports === 'object') {
+ // OldNode. Does not work with strict CommonJS, but
+ // only CommonJS-like environments that support module.exports,
+ // like OldNode.
+ module.exports = factory();
+ } else {
+ // Browser globals (root is window)
+ window.typed = factory();
+ }
+ }(function () {
+ // factory function to create a new instance of typed-function
+ // TODO: allow passing configuration, types, tests via the factory function
+ function create() {
+ /**
+ * Get a type test function for a specific data type
+ * @param {string} name Name of a data type like 'number' or 'string'
+ * @returns {Function(obj: *) : boolean} Returns a type testing function.
+ * Throws an error for an unknown type.
+ */
+ function getTypeTest(name) {
+ var test;
+ for (var i = 0; i < typed.types.length; i++) {
+ var entry = typed.types[i];
+ if (entry.name === name) {
+ test = entry.test;
+ break;
+ }
+ }
+
+ if (!test) {
+ var hint;
+ for (i = 0; i < typed.types.length; i++) {
+ entry = typed.types[i];
+ if (entry.name.toLowerCase() == name.toLowerCase()) {
+ hint = entry.name;
+ break;
+ }
+ }
+
+ throw new Error('Unknown type "' + name + '"' +
+ (hint ? ('. Did you mean "' + hint + '"?') : ''));
+ }
+ return test;
+ }
+
+ /**
+ * Retrieve the function name from a set of functions, and check
+ * whether the name of all functions match (if given)
+ * @param {Array.<function>} fns
+ */
+ function getName (fns) {
+ var name = '';
+
+ for (var i = 0; i < fns.length; i++) {
+ var fn = fns[i];
+
+ // merge function name
+ if (fn.name != '') {
+ if (name == '') {
+ name = fn.name;
+ }
+ else if (name != fn.name) {
+ var err = new Error('Function names do not match (expected: ' + name + ', actual: ' + fn.name + ')');
+ err.data = {
+ actual: fn.name,
+ expected: name
+ };
+ throw err;
+ }
+ }
+ }
+
+ return name;
+ }
+
+ /**
+ * Create an ArgumentsError. Creates messages like:
+ *
+ * Unexpected type of argument (expected: ..., actual: ..., index: ...)
+ * Too few arguments (expected: ..., index: ...)
+ * Too many arguments (expected: ..., actual: ...)
+ *
+ * @param {String} fn Function name
+ * @param {number} argCount Number of arguments
+ * @param {Number} index Current argument index
+ * @param {*} actual Current argument
+ * @param {string} [expected] An optional, comma separated string with
+ * expected types on given index
+ * @extends Error
+ */
+ function createError(fn, argCount, index, actual, expected) {
+ var actualType = getTypeOf(actual);
+ var _expected = expected ? expected.split(',') : null;
+ var _fn = (fn || 'unnamed');
+ var anyType = _expected && contains(_expected, 'any');
+ var message;
+ var data = {
+ fn: fn,
+ index: index,
+ actual: actual,
+ expected: _expected
+ };
+
+ if (_expected) {
+ if (argCount > index && !anyType) {
+ // unexpected type
+ message = 'Unexpected type of argument in function ' + _fn +
+ ' (expected: ' + _expected.join(' or ') + ', actual: ' + actualType + ', index: ' + index + ')';
+ }
+ else {
+ // too few arguments
+ message = 'Too few arguments in function ' + _fn +
+ ' (expected: ' + _expected.join(' or ') + ', index: ' + index + ')';
+ }
+ }
+ else {
+ // too many arguments
+ message = 'Too many arguments in function ' + _fn +
+ ' (expected: ' + index + ', actual: ' + argCount + ')'
+ }
+
+ var err = new TypeError(message);
+ err.data = data;
+ return err;
+ }
+
+ /**
+ * Collection with function references (local shortcuts to functions)
+ * @constructor
+ * @param {string} [name='refs'] Optional name for the refs, used to generate
+ * JavaScript code
+ */
+ function Refs(name) {
+ this.name = name || 'refs';
+ this.categories = {};
+ }
+
+ /**
+ * Add a function reference.
+ * @param {Function} fn
+ * @param {string} [category='fn'] A function category, like 'fn' or 'signature'
+ * @returns {string} Returns the function name, for example 'fn0' or 'signature2'
+ */
+ Refs.prototype.add = function (fn, category) {
+ var cat = category || 'fn';
+ if (!this.categories[cat]) this.categories[cat] = [];
+
+ var index = this.categories[cat].indexOf(fn);
+ if (index == -1) {
+ index = this.categories[cat].length;
+ this.categories[cat].push(fn);
+ }
+
+ return cat + index;
+ };
+
+ /**
+ * Create code lines for all function references
+ * @returns {string} Returns the code containing all function references
+ */
+ Refs.prototype.toCode = function () {
+ var code = [];
+ var path = this.name + '.categories';
+ var categories = this.categories;
+
+ for (var cat in categories) {
+ if (categories.hasOwnProperty(cat)) {
+ var category = categories[cat];
+
+ for (var i = 0; i < category.length; i++) {
+ code.push('var ' + cat + i + ' = ' + path + '[\'' + cat + '\'][' + i + '];');
+ }
+ }
+ }
+
+ return code.join('\n');
+ };
+
+ /**
+ * A function parameter
+ * @param {string | string[] | Param} types A parameter type like 'string',
+ * 'number | boolean'
+ * @param {boolean} [varArgs=false] Variable arguments if true
+ * @constructor
+ */
+ function Param(types, varArgs) {
+ // parse the types, can be a string with types separated by pipe characters |
+ if (typeof types === 'string') {
+ // parse variable arguments operator (ellipses '...number')
+ var _types = types.trim();
+ var _varArgs = _types.substr(0, 3) === '...';
+ if (_varArgs) {
+ _types = _types.substr(3);
+ }
+ if (_types === '') {
+ this.types = ['any'];
+ }
+ else {
+ this.types = _types.split('|');
+ for (var i = 0; i < this.types.length; i++) {
+ this.types[i] = this.types[i].trim();
+ }
+ }
+ }
+ else if (Array.isArray(types)) {
+ this.types = types;
+ }
+ else if (types instanceof Param) {
+ return types.clone();
+ }
+ else {
+ throw new Error('String or Array expected');
+ }
+
+ // can hold a type to which to convert when handling this parameter
+ this.conversions = [];
+ // TODO: implement better API for conversions, be able to add conversions via constructor (support a new type Object?)
+
+ // variable arguments
+ this.varArgs = _varArgs || varArgs || false;
+
+ // check for any type arguments
+ this.anyType = this.types.indexOf('any') !== -1;
+ }
+
+ /**
+ * Order Params
+ * any type ('any') will be ordered last, and object as second last (as other
+ * types may be an object as well, like Array).
+ *
+ * @param {Param} a
+ * @param {Param} b
+ * @returns {number} Returns 1 if a > b, -1 if a < b, and else 0.
+ */
+ Param.compare = function (a, b) {
+ // TODO: simplify parameter comparison, it's a mess
+ if (a.anyType) return 1;
+ if (b.anyType) return -1;
+
+ if (contains(a.types, 'Object')) return 1;
+ if (contains(b.types, 'Object')) return -1;
+
+ if (a.hasConversions()) {
+ if (b.hasConversions()) {
+ var i, ac, bc;
+
+ for (i = 0; i < a.conversions.length; i++) {
+ if (a.conversions[i] !== undefined) {
+ ac = a.conversions[i];
+ break;
+ }
+ }
+
+ for (i = 0; i < b.conversions.length; i++) {
+ if (b.conversions[i] !== undefined) {
+ bc = b.conversions[i];
+ break;
+ }
+ }
+
+ return typed.conversions.indexOf(ac) - typed.conversions.indexOf(bc);
+ }
+ else {
+ return 1;
+ }
+ }
+ else {
+ if (b.hasConversions()) {
+ return -1;
+ }
+ else {
+ // both params have no conversions
+ var ai, bi;
+
+ for (i = 0; i < typed.types.length; i++) {
+ if (typed.types[i].name === a.types[0]) {
+ ai = i;
+ break;
+ }
+ }
+
+ for (i = 0; i < typed.types.length; i++) {
+ if (typed.types[i].name === b.types[0]) {
+ bi = i;
+ break;
+ }
+ }
+
+ return ai - bi;
+ }
+ }
+ };
+
+ /**
+ * Test whether this parameters types overlap an other parameters types.
+ * @param {Param} other
+ * @return {boolean} Returns true when there are conflicting types
+ */
+ Param.prototype.overlapping = function (other) {
+ for (var i = 0; i < this.types.length; i++) {
+ if (contains(other.types, this.types[i])) {
+ return true;
+ }
+ }
+ return false;
+ };
+
+ /**
+ * Create a clone of this param
+ * @returns {Param} Returns a cloned version of this param
+ */
+ Param.prototype.clone = function () {
+ var param = new Param(this.types.slice(), this.varArgs);
+ param.conversions = this.conversions.slice();
+ return param;
+ };
+
+ /**
+ * Test whether this parameter contains conversions
+ * @returns {boolean} Returns true if the parameter contains one or
+ * multiple conversions.
+ */
+ Param.prototype.hasConversions = function () {
+ return this.conversions.length > 0;
+ };
+
+ /**
+ * Tests whether this parameters contains any of the provided types
+ * @param {Object} types A Map with types, like {'number': true}
+ * @returns {boolean} Returns true when the parameter contains any
+ * of the provided types
+ */
+ Param.prototype.contains = function (types) {
+ for (var i = 0; i < this.types.length; i++) {
+ if (types[this.types[i]]) {
+ return true;
+ }
+ }
+ return false;
+ };
+
+ /**
+ * Return a string representation of this params types, like 'string' or
+ * 'number | boolean' or '...number'
+ * @param {boolean} [toConversion] If true, the returned types string
+ * contains the types where the parameter
+ * will convert to. If false (default)
+ * the "from" types are returned
+ * @returns {string}
+ */
+ Param.prototype.toString = function (toConversion) {
+ var types = [];
+ var keys = {};
+
+ for (var i = 0; i < this.types.length; i++) {
+ var conversion = this.conversions[i];
+ var type = toConversion && conversion ? conversion.to : this.types[i];
+ if (!(type in keys)) {
+ keys[type] = true;
+ types.push(type);
+ }
+ }
+
+ return (this.varArgs ? '...' : '') + types.join('|');
+ };
+
+ /**
+ * A function signature
+ * @param {string | string[] | Param[]} params
+ * Array with the type(s) of each parameter,
+ * or a comma separated string with types
+ * @param {Function} fn The actual function
+ * @constructor
+ */
+ function Signature(params, fn) {
+ var _params;
+ if (typeof params === 'string') {
+ _params = (params !== '') ? params.split(',') : [];
+ }
+ else if (Array.isArray(params)) {
+ _params = params;
+ }
+ else {
+ throw new Error('string or Array expected');
+ }
+
+ this.params = new Array(_params.length);
+ for (var i = 0; i < _params.length; i++) {
+ var param = new Param(_params[i]);
+ this.params[i] = param;
+ if (i === _params.length - 1) {
+ // the last argument
+ this.varArgs = param.varArgs;
+ }
+ else {
+ // non-last argument
+ if (param.varArgs) {
+ throw new SyntaxError('Unexpected variable arguments operator "..."');
+ }
+ }
+ }
+
+ this.fn = fn;
+ }
+
+ /**
+ * Create a clone of this signature
+ * @returns {Signature} Returns a cloned version of this signature
+ */
+ Signature.prototype.clone = function () {
+ return new Signature(this.params.slice(), this.fn);
+ };
+
+ /**
+ * Expand a signature: split params with union types in separate signatures
+ * For example split a Signature "string | number" into two signatures.
+ * @return {Signature[]} Returns an array with signatures (at least one)
+ */
+ Signature.prototype.expand = function () {
+ var signatures = [];
+
+ function recurse(signature, path) {
+ if (path.length < signature.params.length) {
+ var i, newParam, conversion;
+
+ var param = signature.params[path.length];
+ if (param.varArgs) {
+ // a variable argument. do not split the types in the parameter
+ newParam = param.clone();
+
+ // add conversions to the parameter
+ // recurse for all conversions
+ for (i = 0; i < typed.conversions.length; i++) {
+ conversion = typed.conversions[i];
+ if (!contains(param.types, conversion.from) && contains(param.types, conversion.to)) {
+ var j = newParam.types.length;
+ newParam.types[j] = conversion.from;
+ newParam.conversions[j] = conversion;
+ }
+ }
+
+ recurse(signature, path.concat(newParam));
+ }
+ else {
+ // split each type in the parameter
+ for (i = 0; i < param.types.length; i++) {
+ recurse(signature, path.concat(new Param(param.types[i])));
+ }
+
+ // recurse for all conversions
+ for (i = 0; i < typed.conversions.length; i++) {
+ conversion = typed.conversions[i];
+ if (!contains(param.types, conversion.from) && contains(param.types, conversion.to)) {
+ newParam = new Param(conversion.from);
+ newParam.conversions[0] = conversion;
+ recurse(signature, path.concat(newParam));
+ }
+ }
+ }
+ }
+ else {
+ signatures.push(new Signature(path, signature.fn));
+ }
+ }
+
+ recurse(this, []);
+
+ return signatures;
+ };
+
+ /**
+ * Compare two signatures.
+ *
+ * When two params are equal and contain conversions, they will be sorted
+ * by lowest index of the first conversions.
+ *
+ * @param {Signature} a
+ * @param {Signature} b
+ * @returns {number} Returns 1 if a > b, -1 if a < b, and else 0.
+ */
+ Signature.compare = function (a, b) {
+ if (a.params.length > b.params.length) return 1;
+ if (a.params.length < b.params.length) return -1;
+
+ // count the number of conversions
+ var i;
+ var len = a.params.length; // a and b have equal amount of params
+ var ac = 0;
+ var bc = 0;
+ for (i = 0; i < len; i++) {
+ if (a.params[i].hasConversions()) ac++;
+ if (b.params[i].hasConversions()) bc++;
+ }
+
+ if (ac > bc) return 1;
+ if (ac < bc) return -1;
+
+ // compare the order per parameter
+ for (i = 0; i < a.params.length; i++) {
+ var cmp = Param.compare(a.params[i], b.params[i]);
+ if (cmp !== 0) {
+ return cmp;
+ }
+ }
+
+ return 0;
+ };
+
+ /**
+ * Test whether any of the signatures parameters has conversions
+ * @return {boolean} Returns true when any of the parameters contains
+ * conversions.
+ */
+ Signature.prototype.hasConversions = function () {
+ for (var i = 0; i < this.params.length; i++) {
+ if (this.params[i].hasConversions()) {
+ return true;
+ }
+ }
+ return false;
+ };
+
+ /**
+ * Test whether this signature should be ignored.
+ * Checks whether any of the parameters contains a type listed in
+ * typed.ignore
+ * @return {boolean} Returns true when the signature should be ignored
+ */
+ Signature.prototype.ignore = function () {
+ // create a map with ignored types
+ var types = {};
+ for (var i = 0; i < typed.ignore.length; i++) {
+ types[typed.ignore[i]] = true;
+ }
+
+ // test whether any of the parameters contains this type
+ for (i = 0; i < this.params.length; i++) {
+ if (this.params[i].contains(types)) {
+ return true;
+ }
+ }
+
+ return false;
+ };
+
+ /**
+ * Generate the code to invoke this signature
+ * @param {Refs} refs
+ * @param {string} prefix
+ * @returns {string} Returns code
+ */
+ Signature.prototype.toCode = function (refs, prefix) {
+ var code = [];
+
+ var args = new Array(this.params.length);
+ for (var i = 0; i < this.params.length; i++) {
+ var param = this.params[i];
+ var conversion = param.conversions[0];
+ if (param.varArgs) {
+ args[i] = 'varArgs';
+ }
+ else if (conversion) {
+ args[i] = refs.add(conversion.convert, 'convert') + '(arg' + i + ')';
+ }
+ else {
+ args[i] = 'arg' + i;
+ }
+ }
+
+ var ref = this.fn ? refs.add(this.fn, 'signature') : undefined;
+ if (ref) {
+ return prefix + 'return ' + ref + '(' + args.join(', ') + '); // signature: ' + this.params.join(', ');
+ }
+
+ return code.join('\n');
+ };
+
+ /**
+ * Return a string representation of the signature
+ * @returns {string}
+ */
+ Signature.prototype.toString = function () {
+ return this.params.join(', ');
+ };
+
+ /**
+ * A group of signatures with the same parameter on given index
+ * @param {Param[]} path
+ * @param {Signature} [signature]
+ * @param {Node[]} childs
+ * @constructor
+ */
+ function Node(path, signature, childs) {
+ this.path = path || [];
+ this.param = path[path.length - 1] || null;
+ this.signature = signature || null;
+ this.childs = childs || [];
+ }
+
+ /**
+ * Generate code for this group of signatures
+ * @param {Refs} refs
+ * @param {string} prefix
+ * @param {Node | undefined} [anyType] Sibling of this node with any type parameter
+ * @returns {string} Returns the code as string
+ */
+ Node.prototype.toCode = function (refs, prefix, anyType) {
+ // TODO: split this function in multiple functions, it's too large
+ var code = [];
+
+ if (this.param) {
+ var index = this.path.length - 1;
+ var conversion = this.param.conversions[0];
+ var comment = '// type: ' + (conversion ?
+ (conversion.from + ' (convert to ' + conversion.to + ')') :
+ this.param);
+
+ // non-root node (path is non-empty)
+ if (this.param.varArgs) {
+ if (this.param.anyType) {
+ // variable arguments with any type
+ code.push(prefix + 'if (arguments.length > ' + index + ') {');
+ code.push(prefix + ' var varArgs = [];');
+ code.push(prefix + ' for (var i = ' + index + '; i < arguments.length; i++) {');
+ code.push(prefix + ' varArgs.push(arguments[i]);');
+ code.push(prefix + ' }');
+ code.push(this.signature.toCode(refs, prefix + ' '));
+ code.push(prefix + '}');
+ }
+ else {
+ // variable arguments with a fixed type
+ var getTests = function (types, arg) {
+ var tests = [];
+ for (var i = 0; i < types.length; i++) {
+ tests[i] = refs.add(getTypeTest(types[i]), 'test') + '(' + arg + ')';
+ }
+ return tests.join(' || ');
+ }.bind(this);
+
+ var allTypes = this.param.types;
+ var exactTypes = [];
+ for (var i = 0; i < allTypes.length; i++) {
+ if (this.param.conversions[i] === undefined) {
+ exactTypes.push(allTypes[i]);
+ }
+ }
+
+ code.push(prefix + 'if (' + getTests(allTypes, 'arg' + index) + ') { ' + comment);
+ code.push(prefix + ' var varArgs = [arg' + index + '];');
+ code.push(prefix + ' for (var i = ' + (index + 1) + '; i < arguments.length; i++) {');
+ code.push(prefix + ' if (' + getTests(exactTypes, 'arguments[i]') + ') {');
+ code.push(prefix + ' varArgs.push(arguments[i]);');
+
+ for (var i = 0; i < allTypes.length; i++) {
+ var conversion_i = this.param.conversions[i];
+ if (conversion_i) {
+ var test = refs.add(getTypeTest(allTypes[i]), 'test');
+ var convert = refs.add(conversion_i.convert, 'convert');
+ code.push(prefix + ' }');
+ code.push(prefix + ' else if (' + test + '(arguments[i])) {');
+ code.push(prefix + ' varArgs.push(' + convert + '(arguments[i]));');
+ }
+ }
+ code.push(prefix + ' } else {');
+ code.push(prefix + ' throw createError(name, arguments.length, i, arguments[i], \'' + exactTypes.join(',') + '\');');
+ code.push(prefix + ' }');
+ code.push(prefix + ' }');
+ code.push(this.signature.toCode(refs, prefix + ' '));
+ code.push(prefix + '}');
+ }
+ }
+ else {
+ if (this.param.anyType) {
+ // any type
+ code.push(prefix + '// type: any');
+ code.push(this._innerCode(refs, prefix, anyType));
+ }
+ else {
+ // regular type
+ var type = this.param.types[0];
+ var test = type !== 'any' ? refs.add(getTypeTest(type), 'test') : null;
+
+ code.push(prefix + 'if (' + test + '(arg' + index + ')) { ' + comment);
+ code.push(this._innerCode(refs, prefix + ' ', anyType));
+ code.push(prefix + '}');
+ }
+ }
+ }
+ else {
+ // root node (path is empty)
+ code.push(this._innerCode(refs, prefix, anyType));
+ }
+
+ return code.join('\n');
+ };
+
+ /**
+ * Generate inner code for this group of signatures.
+ * This is a helper function of Node.prototype.toCode
+ * @param {Refs} refs
+ * @param {string} prefix
+ * @param {Node | undefined} [anyType] Sibling of this node with any type parameter
+ * @returns {string} Returns the inner code as string
+ * @private
+ */
+ Node.prototype._innerCode = function (refs, prefix, anyType) {
+ var code = [];
+ var i;
+
+ if (this.signature) {
+ code.push(prefix + 'if (arguments.length === ' + this.path.length + ') {');
+ code.push(this.signature.toCode(refs, prefix + ' '));
+ code.push(prefix + '}');
+ }
+
+ var nextAnyType;
+ for (i = 0; i < this.childs.length; i++) {
+ if (this.childs[i].param.anyType) {
+ nextAnyType = this.childs[i];
+ break;
+ }
+ }
+
+ for (i = 0; i < this.childs.length; i++) {
+ code.push(this.childs[i].toCode(refs, prefix, nextAnyType));
+ }
+
+ if (anyType && !this.param.anyType) {
+ code.push(anyType.toCode(refs, prefix, nextAnyType));
+ }
+
+ var exceptions = this._exceptions(refs, prefix);
+ if (exceptions) {
+ code.push(exceptions);
+ }
+
+ return code.join('\n');
+ };
+
+ /**
+ * Generate code to throw exceptions
+ * @param {Refs} refs
+ * @param {string} prefix
+ * @returns {string} Returns the inner code as string
+ * @private
+ */
+ Node.prototype._exceptions = function (refs, prefix) {
+ var index = this.path.length;
+
+ if (this.childs.length === 0) {
+ // TODO: can this condition be simplified? (we have a fall-through here)
+ return [
+ prefix + 'if (arguments.length > ' + index + ') {',
+ prefix + ' throw createError(name, arguments.length, ' + index + ', arguments[' + index + ']);',
+ prefix + '}'
+ ].join('\n');
+ }
+ else {
+ var keys = {};
+ var types = [];
+
+ for (var i = 0; i < this.childs.length; i++) {
+ var node = this.childs[i];
+ if (node.param) {
+ for (var j = 0; j < node.param.types.length; j++) {
+ var type = node.param.types[j];
+ if (!(type in keys) && !node.param.conversions[j]) {
+ keys[type] = true;
+ types.push(type);
+ }
+ }
+ }
+ }
+
+ return prefix + 'throw createError(name, arguments.length, ' + index + ', arguments[' + index + '], \'' + types.join(',') + '\');';
+ }
+ };
+
+ /**
+ * Split all raw signatures into an array with expanded Signatures
+ * @param {Object.<string, Function>} rawSignatures
+ * @return {Signature[]} Returns an array with expanded signatures
+ */
+ function parseSignatures(rawSignatures) {
+ // FIXME: need to have deterministic ordering of signatures, do not create via object
+ var signature;
+ var keys = {};
+ var signatures = [];
+ var i;
+
+ for (var types in rawSignatures) {
+ if (rawSignatures.hasOwnProperty(types)) {
+ var fn = rawSignatures[types];
+ signature = new Signature(types, fn);
+
+ if (signature.ignore()) {
+ continue;
+ }
+
+ var expanded = signature.expand();
+
+ for (i = 0; i < expanded.length; i++) {
+ var signature_i = expanded[i];
+ var key = signature_i.toString();
+ var existing = keys[key];
+ if (!existing) {
+ keys[key] = signature_i;
+ }
+ else {
+ var cmp = Signature.compare(signature_i, existing);
+ if (cmp < 0) {
+ // override if sorted first
+ keys[key] = signature_i;
+ }
+ else if (cmp === 0) {
+ throw new Error('Signature "' + key + '" is defined twice');
+ }
+ // else: just ignore
+ }
+ }
+ }
+ }
+
+ // convert from map to array
+ for (key in keys) {
+ if (keys.hasOwnProperty(key)) {
+ signatures.push(keys[key]);
+ }
+ }
+
+ // order the signatures
+ signatures.sort(function (a, b) {
+ return Signature.compare(a, b);
+ });
+
+ // filter redundant conversions from signatures with varArgs
+ // TODO: simplify this loop or move it to a separate function
+ for (i = 0; i < signatures.length; i++) {
+ signature = signatures[i];
+
+ if (signature.varArgs) {
+ var index = signature.params.length - 1;
+ var param = signature.params[index];
+
+ var t = 0;
+ while (t < param.types.length) {
+ if (param.conversions[t]) {
+ var type = param.types[t];
+
+ for (var j = 0; j < signatures.length; j++) {
+ var other = signatures[j];
+ var p = other.params[index];
+
+ if (other !== signature &&
+ p &&
+ contains(p.types, type) && !p.conversions[index]) {
+ // this (conversion) type already exists, remove it
+ param.types.splice(t, 1);
+ param.conversions.splice(t, 1);
+ t--;
+ break;
+ }
+ }
+ }
+ t++;
+ }
+ }
+ }
+
+ return signatures;
+ }
+
+ /**
+ * create a map with normalized signatures as key and the function as value
+ * @param {Signature[]} signatures An array with split signatures
+ * @return {Object.<string, Function>} Returns a map with normalized
+ * signatures as key, and the function
+ * as value.
+ */
+ function mapSignatures(signatures) {
+ var normalized = {};
+
+ for (var i = 0; i < signatures.length; i++) {
+ var signature = signatures[i];
+ if (signature.fn && !signature.hasConversions()) {
+ var params = signature.params.join(',');
+ normalized[params] = signature.fn;
+ }
+ }
+
+ return normalized;
+ }
+
+ /**
+ * Parse signatures recursively in a node tree.
+ * @param {Signature[]} signatures Array with expanded signatures
+ * @param {Param[]} path Traversed path of parameter types
+ * @return {Node} Returns a node tree
+ */
+ function parseTree(signatures, path) {
+ var i, signature;
+ var index = path.length;
+ var nodeSignature;
+
+ var filtered = [];
+ for (i = 0; i < signatures.length; i++) {
+ signature = signatures[i];
+
+ // filter the first signature with the correct number of params
+ if (signature.params.length === index && !nodeSignature) {
+ nodeSignature = signature;
+ }
+
+ if (signature.params[index] != undefined) {
+ filtered.push(signature);
+ }
+ }
+
+ // sort the filtered signatures by param
+ filtered.sort(function (a, b) {
+ return Param.compare(a.params[index], b.params[index]);
+ });
+
+ // recurse over the signatures
+ var entries = [];
+ for (i = 0; i < filtered.length; i++) {
+ signature = filtered[i];
+ // group signatures with the same param at current index
+ var param = signature.params[index];
+
+ // TODO: replace the next filter loop
+ var existing = entries.filter(function (entry) {
+ return entry.param.overlapping(param);
+ })[0];
+
+ //var existing;
+ //for (var j = 0; j < entries.length; j++) {
+ // if (entries[j].param.overlapping(param)) {
+ // existing = entries[j];
+ // break;
+ // }
+ //}
+
+ if (existing) {
+ if (existing.param.varArgs) {
+ throw new Error('Conflicting types "' + existing.param + '" and "' + param + '"');
+ }
+ existing.signatures.push(signature);
+ }
+ else {
+ entries.push({
+ param: param,
+ signatures: [signature]
+ });
+ }
+ }
+
+ // parse the childs
+ var childs = new Array(entries.length);
+ for (i = 0; i < entries.length; i++) {
+ var entry = entries[i];
+ childs[i] = parseTree(entry.signatures, path.concat(entry.param))
+ }
+
+ return new Node(path, nodeSignature, childs);
+ }
+
+ /**
+ * Generate an array like ['arg0', 'arg1', 'arg2']
+ * @param {number} count Number of arguments to generate
+ * @returns {Array} Returns an array with argument names
+ */
+ function getArgs(count) {
+ // create an array with all argument names
+ var args = [];
+ for (var i = 0; i < count; i++) {
+ args[i] = 'arg' + i;
+ }
+
+ return args;
+ }
+
+ /**
+ * Compose a function from sub-functions each handling a single type signature.
+ * Signatures:
+ * typed(signature: string, fn: function)
+ * typed(name: string, signature: string, fn: function)
+ * typed(signatures: Object.<string, function>)
+ * typed(name: string, signatures: Object.<string, function>)
+ *
+ * @param {string | null} name
+ * @param {Object.<string, Function>} signatures
+ * @return {Function} Returns the typed function
+ * @private
+ */
+ function _typed(name, signatures) {
+ var refs = new Refs();
+
+ // parse signatures, expand them
+ var _signatures = parseSignatures(signatures);
+ if (_signatures.length == 0) {
+ throw new Error('No signatures provided');
+ }
+
+ // parse signatures into a node tree
+ var node = parseTree(_signatures, []);
+
+ //var util = require('util');
+ //console.log('ROOT');
+ //console.log(util.inspect(node, { depth: null }));
+
+ // generate code for the typed function
+ var code = [];
+ var _name = name || '';
+ var _args = getArgs(maxParams(_signatures));
+ code.push('function ' + _name + '(' + _args.join(', ') + ') {');
+ code.push(' "use strict";');
+ code.push(' var name = \'' + _name + '\';');
+ code.push(node.toCode(refs, ' '));
+ code.push('}');
+
+ // generate body for the factory function
+ var body = [
+ refs.toCode(),
+ 'return ' + code.join('\n')
+ ].join('\n');
+
+ // evaluate the JavaScript code and attach function references
+ var factory = (new Function(refs.name, 'createError', body));
+ var fn = factory(refs, createError);
+
+ //console.log('FN\n' + fn.toString()); // TODO: cleanup
+
+ // attach the signatures with sub-functions to the constructed function
+ fn.signatures = mapSignatures(_signatures);
+
+ return fn;
+ }
+
+ /**
+ * Calculate the maximum number of parameters in givens signatures
+ * @param {Signature[]} signatures
+ * @returns {number} The maximum number of parameters
+ */
+ function maxParams(signatures) {
+ var max = 0;
+
+ for (var i = 0; i < signatures.length; i++) {
+ var len = signatures[i].params.length;
+ if (len > max) {
+ max = len;
+ }
+ }
+
+ return max;
+ }
+
+ /**
+ * Get the type of a value
+ * @param {*} x
+ * @returns {string} Returns a string with the type of value
+ */
+ function getTypeOf(x) {
+ var obj;
+
+ for (var i = 0; i < typed.types.length; i++) {
+ var entry = typed.types[i];
+
+ if (entry.name === 'Object') {
+ // Array and Date are also Object, so test for Object afterwards
+ obj = entry;
+ }
+ else {
+ if (entry.test(x)) return entry.name;
+ }
+ }
+
+ // at last, test whether an object
+ if (obj && obj.test(x)) return obj.name;
+
+ return 'unknown';
+ }
+
+ /**
+ * Test whether an array contains some entry
+ * @param {Array} array
+ * @param {*} entry
+ * @return {boolean} Returns true if array contains entry, false if not.
+ */
+ function contains(array, entry) {
+ return array.indexOf(entry) !== -1;
+ }
+
+ // data type tests
+ var types = [
+ { name: 'number', test: function (x) { return typeof x === 'number' } },
+ { name: 'string', test: function (x) { return typeof x === 'string' } },
+ { name: 'boolean', test: function (x) { return typeof x === 'boolean' } },
+ { name: 'Function', test: function (x) { return typeof x === 'function'} },
+ { name: 'Array', test: Array.isArray },
+ { name: 'Date', test: function (x) { return x instanceof Date } },
+ { name: 'RegExp', test: function (x) { return x instanceof RegExp } },
+ { name: 'Object', test: function (x) { return typeof x === 'object' } },
+ { name: 'null', test: function (x) { return x === null } },
+ { name: 'undefined', test: function (x) { return x === undefined } }
+ ];
+
+ // configuration
+ var config = {};
+
+ // type conversions. Order is important
+ var conversions = [];
+
+ // types to be ignored
+ var ignore = [];
+
+ // temporary object for holding types and conversions, for constructing
+ // the `typed` function itself
+ // TODO: find a more elegant solution for this
+ var typed = {
+ config: config,
+ types: types,
+ conversions: conversions,
+ ignore: ignore
+ };
+
+ /**
+ * Construct the typed function itself with various signatures
+ *
+ * Signatures:
+ *
+ * typed(signatures: Object.<string, function>)
+ * typed(name: string, signatures: Object.<string, function>)
+ */
+ typed = _typed('typed', {
+ 'Object': function (signatures) {
+ var fns = [];
+ for (var signature in signatures) {
+ if (signatures.hasOwnProperty(signature)) {
+ fns.push(signatures[signature]);
+ }
+ }
+ var name = getName(fns);
+
+ return _typed(name, signatures);
+ },
+ 'string, Object': _typed,
+ // TODO: add a signature 'Array.<function>'
+ '...Function': function (fns) {
+ var err;
+ var name = getName(fns);
+ var signatures = {};
+
+ for (var i = 0; i < fns.length; i++) {
+ var fn = fns[i];
+
+ // test whether this is a typed-function
+ if (!(typeof fn.signatures === 'object')) {
+ err = new TypeError('Function is no typed-function (index: ' + i + ')');
+ err.data = {index: i};
+ throw err;
+ }
+
+ // merge the signatures
+ for (var signature in fn.signatures) {
+ if (fn.signatures.hasOwnProperty(signature)) {
+ if (signatures.hasOwnProperty(signature)) {
+ if (fn.signatures[signature] !== signatures[signature]) {
+ err = new Error('Signature "' + signature + '" is defined twice');
+ err.data = {signature: signature};
+ throw err;
+ }
+ // else: both signatures point to the same function, that's fine
+ }
+ else {
+ signatures[signature] = fn.signatures[signature];
+ }
+ }
+ }
+ }
+
+ return _typed(name, signatures);
+ }
+ });
+
+ /**
+ * Find a specific signature from a (composed) typed function, for
+ * example:
+ *
+ * typed.find(fn, ['number', 'string'])
+ * typed.find(fn, 'number, string')
+ *
+ * Function find only only works for exact matches.
+ *
+ * @param {Function} fn A typed-function
+ * @param {string | string[]} signature Signature to be found, can be
+ * an array or a comma separated string.
+ * @return {Function} Returns the matching signature, or
+ * throws an errror when no signature
+ * is found.
+ */
+ function find (fn, signature) {
+ if (!fn.signatures) {
+ throw new TypeError('Function is no typed-function');
+ }
+
+ // normalize input
+ var arr;
+ if (typeof signature === 'string') {
+ arr = signature.split(',');
+ for (var i = 0; i < arr.length; i++) {
+ arr[i] = arr[i].trim();
+ }
+ }
+ else if (Array.isArray(signature)) {
+ arr = signature;
+ }
+ else {
+ throw new TypeError('String array or a comma separated string expected');
+ }
+
+ var str = arr.join(',');
+
+ // find an exact match
+ var match = fn.signatures[str];
+ if (match) {
+ return match;
+ }
+
+ // TODO: extend find to match non-exact signatures
+
+ throw new TypeError('Signature not found (signature: ' + (fn.name || 'unnamed') + '(' + arr.join(', ') + '))');
+ }
+
+ /**
+ * Convert a given value to another data type.
+ * @param {*} value
+ * @param {string} type
+ */
+ function convert (value, type) {
+ var from = getTypeOf(value);
+
+ // check conversion is needed
+ if (type === from) {
+ return value;
+ }
+
+ for (var i = 0; i < typed.conversions.length; i++) {
+ var conversion = typed.conversions[i];
+ if (conversion.from === from && conversion.to === type) {
+ return conversion.convert(value);
+ }
+ }
+
+ throw new Error('Cannot convert from ' + from + ' to ' + type);
+ }
+
+ // attach types and conversions to the final `typed` function
+ typed.config = config;
+ typed.types = types;
+ typed.conversions = conversions;
+ typed.ignore = ignore;
+ typed.create = create;
+ typed.find = find;
+ typed.convert = convert;
+
+ // add a type
+ typed.addType = function (type) {
+ if (!type || typeof type.name !== 'string' || typeof type.test !== 'function') {
+ throw new TypeError('Object with properties {name: string, test: function} expected');
+ }
+
+ typed.types.push(type);
+ };
+
+ // add a conversion
+ typed.addConversion = function (conversion) {
+ if (!conversion
+ || typeof conversion.from !== 'string'
+ || typeof conversion.to !== 'string'
+ || typeof conversion.convert !== 'function') {
+ throw new TypeError('Object with properties {from: string, to: string, convert: function} expected');
+ }
+
+ typed.conversions.push(conversion);
+ };
+
+ return typed;
+ }
+
+ return create();
+ }));
+
+
+/***/ },
+/* 8 */
+/***/ function(module, exports, __webpack_require__) {
+
+ 'use strict';
+
+ var NumberFormatter = __webpack_require__(9);
+
+ /**
+ * Test whether value is a number
* @param {*} value
- * @return {Boolean} isNumber
+ * @return {boolean} isNumber
*/
exports.isNumber = function(value) {
- return (value instanceof Number) || (typeof value == 'number');
+ return typeof value === 'number';
};
/**
* Check if a number is integer
- * @param {Number | Boolean} value
- * @return {Boolean} isInteger
+ * @param {number | boolean} value
+ * @return {boolean} isInteger
*/
exports.isInteger = function(value) {
- return (value == Math.round(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
+ * @param {number} x
* @returns {*}
*/
exports.sign = function(x) {
@@ -767,9 +2133,9 @@
*
* Where:
*
- * {Number} value The value to be formatted
+ * {number} value The value to be formatted
* {Object} options An object with formatting options. Available options:
- * {String} notation
+ * {string} notation
* Number notation. Choose from:
* 'fixed' Always use regular number notation.
* For example '123.40' and '14000000'
@@ -782,7 +2148,7 @@
* 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
+ * {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
@@ -793,7 +2159,7 @@
* significant digits after the decimal
* point, and is 0 by default.
* {Object} exponential An object containing two parameters,
- * {Number} lower and {Number} upper,
+ * {number} lower and {number} upper,
* used by notation 'auto' to determine
* when to return exponential notation.
* Default values are `lower=1e-3` and
@@ -815,9 +2181,9 @@
* 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
+ * @param {number} value
+ * @param {Object | Function | number} [options]
+ * @return {string} str The formatted value
*/
exports.format = function(value, options) {
if (typeof options === 'function') {
@@ -882,8 +2248,8 @@
/**
* 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.
+ * @param {number} value
+ * @param {number} [precision] Number of digits in formatted output.
* If not provided, the maximum available digits
* is used.
* @returns {string} str
@@ -894,8 +2260,8 @@
/**
* Format a number with fixed notation.
- * @param {Number} value
- * @param {Number} [precision=0] Optional number of decimals after the
+ * @param {number} value
+ * @param {number} [precision=0] Optional number of decimals after the
* decimal point. Zero by default.
*/
exports.toFixed = function(value, precision) {
@@ -904,8 +2270,8 @@
/**
* Format a number with a certain precision
- * @param {Number} value
- * @param {Number} [precision=undefined] Optional number of digits.
+ * @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)
@@ -923,8 +2289,8 @@
* 0.0034 returns 2
* 120.5e+30 returns 4
*
- * @param {Number} value
- * @return {Number} digits Number of significant digits
+ * @param {number} value
+ * @return {number} digits Number of significant digits
*/
exports.digits = function(value) {
return value
@@ -941,9 +2307,9 @@
/**
* 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
+ * @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
@@ -977,1167 +2343,216 @@
/***/ },
-/* 4 */
-/***/ function(module, exports, __webpack_require__) {
-
- 'use strict';
-
- module.exports = function (math, config) {
- var object = __webpack_require__(2);
- var bignumber = __webpack_require__(168);
- var Complex = __webpack_require__(7);
- var BigNumber = math.type.BigNumber;
-
- math['true'] = true;
- math['false'] = false;
- math['null'] = null;
- math['uninitialized'] = __webpack_require__(169).UNINITIALIZED;
-
- if (config.number === 'bignumber') {
- math['Infinity'] = new BigNumber(Infinity);
- math['NaN'] = new BigNumber(NaN);
-
- object.lazy(math, 'pi', function () {return bignumber.pi(config.precision)});
- object.lazy(math, 'tau', function () {return bignumber.tau(config.precision)});
- object.lazy(math, 'e', function () {return bignumber.e(config.precision)});
- object.lazy(math, 'phi', function () {return bignumber.phi(config.precision)}); // golden ratio, (1+sqrt(5))/2
-
- // uppercase constants (for compatibility with built-in Math)
- object.lazy(math, 'E', function () {return math.e;});
- object.lazy(math, 'LN2', function () {return new BigNumber(2).ln();});
- object.lazy(math, 'LN10', function () {return new BigNumber(10).ln()});
- object.lazy(math, 'LOG2E', function () {return new BigNumber(1).div(new BigNumber(2).ln());});
- object.lazy(math, 'LOG10E', function () {return new BigNumber(1).div(new BigNumber(10).ln())});
- object.lazy(math, 'PI', function () {return math.pi});
- object.lazy(math, 'SQRT1_2', function () {return new BigNumber('0.5').sqrt()});
- object.lazy(math, 'SQRT2', function () {return new BigNumber(2).sqrt()});
- }
- else {
- math['Infinity'] = Infinity;
- math['NaN'] = NaN;
-
- math.pi = Math.PI;
- math.tau = Math.PI * 2;
- math.e = Math.E;
- math.phi = 1.61803398874989484820458683436563811772030917980576286213545; // golden ratio, (1+sqrt(5))/2
-
- // uppercase constants (for compatibility with built-in Math)
- math.E = math.e;
- math.LN2 = Math.LN2;
- math.LN10 = Math.LN10;
- math.LOG2E = Math.LOG2E;
- math.LOG10E = Math.LOG10E;
- math.PI = math.pi;
- math.SQRT1_2 = Math.SQRT1_2;
- math.SQRT2 = Math.SQRT2;
- }
-
- // complex i
- math.i = new Complex(0, 1);
-
- // meta information
- math.version = __webpack_require__(170);
- };
-
-
-/***/ },
-/* 5 */
-/***/ function(module, exports, __webpack_require__) {
-
- var BigNumber = __webpack_require__(340);
-
- // FIXME: replace all require('decimal.js') with require('./BigNumber').
-
- module.exports = BigNumber;
-
-
-/***/ },
-/* 6 */
-/***/ function(module, exports, __webpack_require__) {
-
- 'use strict';
-
- exports.ArgumentsError = __webpack_require__(171);
- exports.DimensionError = __webpack_require__(172);
- exports.IndexError = __webpack_require__(173);
- exports.UnsupportedTypeError = __webpack_require__(174);
-
- // TODO: implement an InvalidValueError?
-
-
-/***/ },
-/* 7 */
-/***/ function(module, exports, __webpack_require__) {
-
- 'use strict';
-
- var util = __webpack_require__(175),
- Unit = __webpack_require__(11),
- 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 = '';
- var im = this.im;
- var re = this.re;
- var strRe = number.format(this.re, options);
- var strIm = number.format(this.im, options);
-
- // round either re or im when smaller than the configured precision
- var precision = isNumber(options) ? options : options ? options.precision : null;
- if (precision !== null) {
- var epsilon = Math.pow(10, -precision);
- if (Math.abs(re / im) < epsilon) {re = 0;}
- if (Math.abs(im / re) < epsilon) {im = 0;}
- }
-
- if (im == 0) {
- // real value
- str = strRe;
- }
- else if (re == 0) {
- // purely complex value
- if (im == 1) {
- str = 'i';
- }
- else if (im == -1) {
- str = '-i';
- }
- else {
- str = strIm + 'i';
- }
- }
- else {
- // complex value
- if (im > 0) {
- if (im == 1) {
- str = strRe + ' + i';
- }
- else {
- str = strRe + ' + ' + strIm + 'i';
- }
- }
- else {
- if (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();
- };
-
- /**
- * Get a JSON representation of the complex number
- * @returns {Object} Returns a JSON object structured as:
- * `{"mathjs": "Complex", "re": 2, "im": 3}`
- */
- Complex.prototype.toJSON = function () {
- return {
- mathjs: 'Complex',
- re: this.re,
- im: this.im
- };
- };
-
- /**
- * Create a Complex number from a JSON object
- * @param {Object} json A JSON Object structured as
- * {"mathjs": "Complex", "re": 2, "im": 3}
- * All properties are optional, default values
- * for `re` and `im` are 0.
- * @return {Complex} Returns a new Complex number
- */
- Complex.fromJSON = function (json) {
- return new Complex(json);
- };
-
- /**
- * Returns a string representation of the complex number.
- * @return {String} str
- */
- Complex.prototype.valueOf = Complex.prototype.toString;
-
- // exports
- module.exports = Complex;
-
-
-/***/ },
-/* 8 */
-/***/ function(module, exports, __webpack_require__) {
-
- 'use strict';
-
- var util = __webpack_require__(175);
-
- 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}
- */
- Range.prototype.toString = function () {
- return this.format();
- };
-
- /**
- * Get a JSON representation of the range
- * @returns {Object} Returns a JSON object structured as:
- * `{"mathjs": "Range", "start": 2, "end": 4, "step": 1}`
- */
- Range.prototype.toJSON = function () {
- return {
- mathjs: 'Range',
- start: this.start,
- end: this.end,
- step: this.step
- };
- };
-
- /**
- * Instantiate a Range from a JSON object
- * @param {Object} json A JSON object structured as:
- * `{"mathjs": "Range", "start": 2, "end": 4, "step": 1}`
- * @return {Range}
- */
- Range.fromJSON = function (json) {
- return new Range(json.start, json.end, json.step);
- };
-
- // exports
- module.exports = Range;
-
-
-/***/ },
/* 9 */
-/***/ function(module, exports, __webpack_require__) {
+/***/ function(module, exports) {
'use strict';
- var util = __webpack_require__(175),
-
- Range = __webpack_require__(8),
-
- number = util.number,
-
- isNumber = number.isNumber,
- isInteger = number.isInteger,
- isArray = Array.isArray;
-
- /**
- * @Constructor Index
- * Create an index. An Index can store ranges having start, step, and end
- * for multiple dimensions.
- * Matrix.get, Matrix.set, and math.subset accept an Index as input.
- *
- * Usage:
- * var index = new Index(range1, range2, ...);
- *
- * Where each range can be any of:
- * An array [start, end]
- * An array [start, end, step]
- * A number
- * An instance of Range
- *
- * The parameters start, end, and step must be integer numbers.
- *
- * @param {...*} ranges
- */
- function Index(ranges) {
- if (!(this instanceof Index)) {
- throw new SyntaxError('Constructor must be called with the new operator');
- }
-
- this._ranges = [];
- this._isScalar = true;
-
- for (var i = 0, ii = arguments.length; i < ii; i++) {
- var arg = arguments[i];
-
- if (arg instanceof Range) {
- this._ranges.push(arg);
- this._isScalar = false;
- }
- else if (isArray(arg)) {
- this._ranges.push(_createRange(arg));
- this._isScalar = false;
- }
- else if (isNumber(arg)) {
- this._ranges.push(_createRange([arg, arg + 1]));
- }
- // TODO: implement support for wildcard '*'
- else {
- var primitive = arg.valueOf(); // for example turn a Matrix into an Array
- if (isArray(primitive)) {
- this._ranges.push(_createRange(primitive));
- this._isScalar = false;
- }
- else {
- throw new TypeError('Ranges must be an Array, Number, or Range');
- }
- }
- }
- }
-
- /**
- * Parse an argument into a range and validate the range
- * @param {Array} arg An array with [start: Number, end: Number] and
- * optional a third element step:Number
- * @return {Range} range
- * @private
- */
- function _createRange(arg) {
- // TODO: make function _createRange simpler/faster
-
- // test whether all arguments are integers
- var num = arg.length;
- for (var i = 0; i < num; i++) {
- if (!isNumber(arg[i]) || !isInteger(arg[i])) {
- throw new TypeError('Index parameters must be integer numbers');
- }
- }
-
- switch (arg.length) {
- case 2:
- return new Range(arg[0], arg[1]); // start, end
- case 3:
- return new Range(arg[0], arg[1], arg[2]); // start, end, step
- default:
- // TODO: improve error message
- throw new SyntaxError('Wrong number of arguments in Index (2 or 3 expected)');
- }
- }
-
- /**
- * Create a clone of the index
- * @return {Index} clone
- */
- Index.prototype.clone = function () {
- var index = new Index();
- index._ranges = util.object.clone(this._ranges);
- index._isScalar = this._isScalar;
- return index;
- };
-
- /**
- * Test whether an object is an Index
- * @param {*} object
- * @return {Boolean} isIndex
- */
- Index.isIndex = function (object) {
- return (object instanceof Index);
- };
-
- /**
- * Create an index from an array with ranges/numbers
- * @param {Array.<Array | Number>} ranges
- * @return {Index} index
- * @private
- */
- Index.create = function (ranges) {
- var index = new Index();
- Index.apply(index, ranges);
- return index;
- };
-
- /**
- * Retrieve the size of the index, the number of elements for each dimension.
- * @returns {Number[]} size
- */
- Index.prototype.size = function () {
- var size = [];
-
- for (var i = 0, ii = this._ranges.length; i < ii; i++) {
- var range = this._ranges[i];
-
- size[i] = range.size()[0];
- }
-
- return size;
- };
-
- /**
- * Get the maximum value for each of the indexes ranges.
- * @returns {Number[]} max
- */
- Index.prototype.max = function () {
- var values = [];
-
- for (var i = 0, ii = this._ranges.length; i < ii; i++) {
- var range = this._ranges[i];
- values[i] = range.max();
- }
-
- return values;
- };
-
- /**
- * Get the minimum value for each of the indexes ranges.
- * @returns {Number[]} min
- */
- Index.prototype.min = function () {
- var values = [];
-
- for (var i = 0, ii = this._ranges.length; i < ii; i++) {
- var range = this._ranges[i];
-
- values[i] = range.min();
- }
-
- return values;
- };
-
- /**
- * Loop over each of the ranges of the index
- * @param {function} callback Called for each range with a Range as first
- * argument, the dimension as second, and the
- * index object as third.
- */
- Index.prototype.forEach = function (callback) {
- for (var i = 0, ii = this._ranges.length; i < ii; i++) {
- callback(this._ranges[i], i, this);
- }
- };
-
- /**
- * Retrieve the range for a given dimension number from the index
- * @param {Number} dim Number of the dimension
- * @returns {Range | null} range
- */
- Index.prototype.range = function(dim) {
- return this._ranges[dim] || null;
- };
-
- /**
- * Test whether this index contains only a single value.
- *
- * This is the case when the index is created with only scalar values as ranges,
- * not for ranges resolving into a single value.
- * @return {boolean} isScalar
- */
- Index.prototype.isScalar = function () {
- return this._isScalar;
- };
-
- /**
- * Expand the Index into an array.
- * For example new Index([0,3], [2,7]) returns [[0,1,2], [2,3,4,5,6]]
- * @returns {Array} array
- */
- Index.prototype.toArray = function () {
- var array = [];
- for (var i = 0, ii = this._ranges.length; i < ii; i++) {
- var range = this._ranges[i],
- row = [],
- x = range.start,
- end = range.end,
- step = range.step;
-
- if (step > 0) {
- while (x < end) {
- row.push(x);
- x += step;
- }
- }
- else if (step < 0) {
- while (x > end) {
- row.push(x);
- x += step;
- }
- }
-
- array.push(row);
- }
-
- return array;
- };
-
- /**
- * Get the primitive value of the Index, a two dimensional array.
- * Equivalent to Index.toArray().
- * @returns {Array} array
- */
- Index.prototype.valueOf = Index.prototype.toArray;
-
- /**
- * Get the string representation of the index, for example '[2:6]' or '[0:2:10, 4:7]'
- * @returns {String} str
- */
- Index.prototype.toString = function () {
- var strings = [];
-
- for (var i = 0, ii = this._ranges.length; i < ii; i++) {
- var range = this._ranges[i];
- var str = number.format(range.start);
- if (range.step != 1) {
- str += ':' + number.format(range.step);
- }
- str += ':' + number.format(range.end);
- strings.push(str);
- }
-
- return '[' + strings.join(', ') + ']';
- };
-
- /**
- * Get a JSON representation of the Index
- * @returns {Object} Returns a JSON object structured as:
- * `{"mathjs": "Index", "ranges": [{"mathjs": "Range", start: 0, end: 10, step:1}, ...]}`
- */
- Index.prototype.toJSON = function () {
- return {
- mathjs: 'Index',
- ranges: this._ranges
- };
- };
-
- /**
- * Instantiate an Index from a JSON object
- * @param {Object} json A JSON object structured as:
- * `{"mathjs": "Index", "ranges": [{"mathjs": "Range", start: 0, end: 10, step:1}, ...]}`
- * @return {Index}
- */
- Index.fromJSON = function (json) {
- return Index.create(json.ranges);
- };
-
- // exports
- module.exports = Index;
+ /**
+ * 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;
/***/ },
@@ -2146,1166 +2561,300 @@
'use strict';
- var string = __webpack_require__(176),
-
- isString = string.isString;
-
- module.exports = function (config) {
-
+ var lazy = __webpack_require__(5).lazy;
+ var isFactory = __webpack_require__(5).isFactory;
+ var traverse = __webpack_require__(5).traverse;
+ var extend = __webpack_require__(5).extend;
+ var ArgumentsError = __webpack_require__(11);
+
+ function factory (type, config, load, typed, math) {
/**
- * @constructor Matrix
- *
- * A Matrix is a wrapper around an Array. A matrix can hold a multi dimensional
- * array. A matrix can be constructed as:
- * var matrix = math.matrix(data)
- *
- * Matrix contains the functions to resize, get and set values, get the size,
- * clone the matrix and to convert the matrix to a vector, array, or scalar.
- * Furthermore, one can iterate over the matrix using map and forEach.
- * The internal Array of the Matrix can be accessed using the function valueOf.
- *
- * Example usage:
- * var matrix = math.matrix([[1, 2], [3, 4]]);
- * matix.size(); // [2, 2]
- * matrix.resize([3, 2], 5);
- * matrix.valueOf(); // [[1, 2], [3, 4], [5, 5]]
- * matrix.subset([1,2]) // 3 (indexes are zero-based)
- *
+ * Import functions from an object or a module
+ *
+ * Syntax:
+ *
+ * math.import(object)
+ * math.import(object, options)
+ *
+ * Where:
+ *
+ * - `object: Object`
+ * An object with functions to be imported.
+ * - `options: Object` An object with import options. Available options:
+ * - `override: boolean`
+ * If true, existing functions will be overwritten. False by default.
+ * - `silent: boolean`
+ * If true, the function will not throw errors on duplicates or invalid
+ * types. False by default.
+ * - `wrap: boolean`
+ * If true, the functions will be wrapped in a wrapper function
+ * which converts data types like Matrix to primitive data types like Array.
+ * The wrapper is needed when extending math.js with libraries which do not
+ * support these data type. False by default.
+ *
+ * Examples:
+ *
+ * // define new functions and variables
+ * math.import({
+ * myvalue: 42,
+ * hello: function (name) {
+ * return 'hello, ' + name + '!';
+ * }
+ * });
+ *
+ * // use the imported function and variable
+ * math.myvalue * 2; // 84
+ * math.hello('user'); // 'hello, user!'
+ *
+ * // import the npm module 'numbers'
+ * // (must be installed first with `npm install numbers`)
+ * math.import(require('numbers'), {wrap: true});
+ *
+ * math.fibonacci(7); // returns 13
+ *
+ * @param {Object | Array} object Object with functions to be imported.
+ * @param {Object} [options] Import options.
*/
- function Matrix() {
- if (!(this instanceof Matrix)) {
- throw new SyntaxError('Constructor must be called with the new operator');
+ function math_import(object, options) {
+ var num = arguments.length;
+ if (num != 1 && num != 2) {
+ throw new ArgumentsError('import', num, 1, 2);
+ }
+
+ if (!options) {
+ options = {};
+ }
+
+ if (isFactory(object)) {
+ _importFactory(object, options);
+ }
+ else if (Array.isArray(object)) {
+ object.forEach(function (entry) {
+ math_import(entry, options);
+ });
+ }
+ else if (typeof object === 'object') {
+ // a map with functions
+ for (var name in object) {
+ if (object.hasOwnProperty(name)) {
+ var value = object[name];
+ if (isSupportedType(value)) {
+ _import(name, value, options);
+ }
+ else if (isFactory(object)) {
+ _importFactory(object, options);
+ }
+ else {
+ math_import(value, options);
+ }
+ }
+ }
+ }
+ else {
+ if (!options.silent) {
+ throw new TypeError('Factory, Object, or Array expected');
+ }
}
}
/**
- * Test whether an object is a Matrix
- * @param {*} object
- * @return {Boolean} isMatrix
- */
- Matrix.isMatrix = function (object) {
- return (object instanceof Matrix);
- };
-
- /**
- * Get the Matrix storage constructor for the given format.
- *
- * @param {string} format The Matrix storage format.
- *
- * @return {Function} The Matrix storage constructor.
- */
- Matrix.storage = function (format) {
- // check storage format is a string
- if (!isString(format)) {
- throw new TypeError('format must be a string value');
- }
-
- // get storage format constructor
- var constructor = Matrix._storage[format];
- if (!constructor) {
- throw new SyntaxError('Unsupported matrix storage format: ' + format);
- }
-
- // return storage constructor
- return constructor;
- };
-
- // a map with all constructors for all storage types
- Matrix._storage = {};
-
- /**
- * Get the storage format used by the matrix.
- *
- * Usage:
- * var format = matrix.storage() // retrieve storage format
- *
- * @return {string} The storage format.
- */
- Matrix.prototype.storage = function () {
- // must be implemented by each of the Matrix implementations
- throw new Error('Cannot invoke storage on a Matrix interface');
- };
-
- /**
- * Get a subset of the matrix, or replace a subset of the matrix.
- *
- * Usage:
- * var subset = matrix.subset(index) // retrieve subset
- * var value = matrix.subset(index, replacement) // replace subset
- *
- * @param {Index} index
- * @param {Array | Matrix | *} [replacement]
- * @param {*} [defaultValue=0] Default value, filled in on new entries when
- * the matrix is resized. If not provided,
- * new matrix elements will be filled with zeros.
- */
- Matrix.prototype.subset = function (index, replacement, defaultValue) {
- // must be implemented by each of the Matrix implementations
- throw new Error('Cannot invoke subset on a Matrix interface');
- };
-
- /**
- * Get a single element from the matrix.
- * @param {Number[]} index Zero-based index
- * @return {*} value
- */
- Matrix.prototype.get = function (index) {
- // must be implemented by each of the Matrix implementations
- throw new Error('Cannot invoke get on a Matrix interface');
- };
-
- /**
- * Replace a single element in the matrix.
- * @param {Number[]} index Zero-based index
+ * Add a property to the math namespace and create a chain proxy for it.
+ * @param {string} name
* @param {*} value
- * @param {*} [defaultValue] Default value, filled in on new entries when
- * the matrix is resized. If not provided,
- * new matrix elements will be left undefined.
- * @return {Matrix} self
- */
- Matrix.prototype.set = function (index, value, defaultValue) {
- // must be implemented by each of the Matrix implementations
- throw new Error('Cannot invoke set on a Matrix interface');
- };
-
- /**
- * Resize the matrix to the given size. Returns a copy of the matrix when
- * `copy=true`, otherwise return the matrix itself (resize in place).
- *
- * @param {Number[]} size The new size the matrix should have.
- * @param {*} [defaultValue=0] Default value, filled in on new entries.
- * If not provided, the matrix elements will
- * be filled with zeros.
- * @param {boolean} [copy] Return a resized copy of the matrix
- *
- * @return {Matrix} The resized matrix
- */
- Matrix.prototype.resize = function (size, defaultValue) {
- // must be implemented by each of the Matrix implementations
- throw new Error('Cannot invoke resize on a Matrix interface');
- };
-
- /**
- * Create a clone of the matrix
- * @return {Matrix} clone
- */
- Matrix.prototype.clone = function () {
- // must be implemented by each of the Matrix implementations
- throw new Error('Cannot invoke clone on a Matrix interface');
- };
-
- /**
- * Retrieve the size of the matrix.
- * @returns {Number[]} size
- */
- Matrix.prototype.size = function() {
- // must be implemented by each of the Matrix implementations
- throw new Error('Cannot invoke size on a Matrix interface');
- };
-
- /**
- * Create a new matrix with the results of the callback function executed on
- * each entry of the matrix.
- * @param {function} callback The callback function is invoked with three
- * parameters: the value of the element, the index
- * of the element, and the Matrix being traversed.
- * @param {boolean} [skipZeros] Invoke callback function for non-zero values only.
- *
- * @return {Matrix} matrix
- */
- Matrix.prototype.map = function (callback, skipZeros) {
- // must be implemented by each of the Matrix implementations
- throw new Error('Cannot invoke map on a Matrix interface');
- };
-
- /**
- * Execute a callback function on each entry of the matrix.
- * @param {function} callback The callback function is invoked with three
- * parameters: the value of the element, the index
- * of the element, and the Matrix being traversed.
- */
- Matrix.prototype.forEach = function (callback) {
- // must be implemented by each of the Matrix implementations
- throw new Error('Cannot invoke forEach on a Matrix interface');
- };
-
- /**
- * Create an Array with a copy of the data of the Matrix
- * @returns {Array} array
- */
- Matrix.prototype.toArray = function () {
- // must be implemented by each of the Matrix implementations
- throw new Error('Cannot invoke toArray on a Matrix interface');
- };
-
- /**
- * Get the primitive value of the Matrix: a multidimensional array
- * @returns {Array} array
- */
- Matrix.prototype.valueOf = function () {
- // must be implemented by each of the Matrix implementations
- throw new Error('Cannot invoke valueOf on a Matrix interface');
- };
-
- /**
- * Get a string representation of the matrix, with optional formatting options.
- * @param {Object | Number | Function} [options] Formatting options. See
- * lib/util/number:format for a
- * description of the available
- * options.
- * @returns {String} str
- */
- Matrix.prototype.format = function (options) {
- // must be implemented by each of the Matrix implementations
- throw new Error('Cannot invoke format on a Matrix interface');
- };
-
- /**
- * Get a string representation of the matrix
- * @returns {String} str
- */
- Matrix.prototype.toString = function () {
- // must be implemented by each of the Matrix implementations
- throw new Error('Cannot invoke toString on a Matrix interface');
- };
-
- /**
- * Calculates the transpose of the matrix
- * @returns {Matrix}
- */
- Matrix.prototype.transpose = function () {
- // must be implemented by each of the Matrix implementations
- throw new Error('Cannot invoke transpose on a Matrix interface');
- };
-
- /**
- * Calculate the trace of a matrix: the sum of the elements on the main
- * diagonal of a square matrix.
- *
- * See also:
- *
- * diagonal
- *
- * @returns {Number} The matrix trace
- */
- Matrix.prototype.trace = function () {
- // must be implemented by each of the Matrix implementations
- throw new Error('Cannot invoke transpose on a Matrix interface');
- };
-
- /**
- * Multiply the matrix values times the argument.
- *
- * @param {Number | BigNumber | Boolean | Complex | Unit | Array | Matrix | null} Value to multiply.
- *
- * @return {Number | BigNumber | Complex | Unit | Matrix}
- */
- Matrix.prototype.multiply = function (value) {
- // must be implemented by each of the Matrix implementations
- throw new Error('Cannot invoke multiply on a Matrix interface');
- };
-
- // exports
- return Matrix;
- };
+ * @param {Object} options See import for a description of the options
+ * @private
+ */
+ function _import(name, value, options) {
+ if (options.wrap && typeof value === 'function') {
+ // create a wrapper around the function
+ value = _wrap(value);
+ }
+
+ if (isTypedFunction(math[name]) && isTypedFunction(value)) {
+ // merge two typed functions
+ if (options.override) {
+ value = typed(extend({}, math[name].signatures, value.signatures));
+ }
+ else {
+ value = typed(math[name], value);
+ }
+
+ math[name] = value;
+ _importTransform(name, value);
+ math.emit('import', name, function resolver() {
+ return value;
+ });
+ return;
+ }
+
+ if (math[name] === undefined || options.override) {
+ math[name] = value;
+ _importTransform(name, value);
+ math.emit('import', name, function resolver() {
+ return value;
+ });
+ return;
+ }
+
+ if (!options.silent) {
+ throw new Error('Cannot import "' + name + '": already exists');
+ }
+ }
+
+ function _importTransform (name, value) {
+ if (value && typeof value.transform === 'function') {
+ math.expression.transform[name] = value.transform;
+ }
+ }
+
+ /**
+ * Create a wrapper a round an function which converts the arguments
+ * to their primitive values (like convert a Matrix to Array)
+ * @param {Function} fn
+ * @return {Function} Returns the wrapped function
+ * @private
+ */
+ function _wrap (fn) {
+ var wrapper = function wrapper () {
+ var args = [];
+ for (var i = 0, len = arguments.length; i < len; i++) {
+ var arg = arguments[i];
+ args[i] = arg && arg.valueOf();
+ }
+ return fn.apply(math, args);
+ };
+
+ if (fn.transform) {
+ wrapper.transform = fn.transform;
+ }
+
+ return wrapper;
+ }
+
+ /**
+ * Import an instance of a factory into math.js
+ * @param {{factory: Function, name: string, path: string, math: boolean}} factory
+ * @param {Object} options See import for a description of the options
+ * @private
+ */
+ function _importFactory(factory, options) {
+ if (typeof factory.name === 'string') {
+ var name = factory.name;
+ var namespace = factory.path ? traverse(math, factory.path) : math;
+ var existing = namespace.hasOwnProperty(name) ? namespace[name] : undefined;
+
+ var resolver = function () {
+ var instance = load(factory);
+
+ if (isTypedFunction(existing) && isTypedFunction(instance)) {
+ // merge two typed functions
+ if (options.override) {
+ instance = typed(extend({}, existing.signatures, instance.signatures));
+ }
+ else {
+ instance = typed(existing, instance);
+ }
+
+ return instance;
+ }
+
+ if (existing === undefined || options.override) {
+ return instance;
+ }
+
+ if (!options.silent) {
+ throw new Error('Cannot import "' + name + '": already exists');
+ }
+ };
+
+ if (factory.lazy !== false) {
+ lazy(namespace, name, resolver);
+ }
+ else {
+ namespace[name] = resolver();
+ }
+
+ math.emit('import', name, resolver, factory.path);
+ }
+ else {
+ // unnamed factory.
+ // no lazy loading
+ load(factory);
+ }
+ }
+
+ /**
+ * Check whether given object is a type which can be imported
+ * @param {Function | number | string | boolean | null | Unit | Complex} object
+ * @return {boolean}
+ * @private
+ */
+ function isSupportedType(object) {
+ return typeof object == 'function'
+ || typeof object === 'number'
+ || typeof object === 'string'
+ || typeof object === 'boolean'
+ || object === null
+ || (object && object.isUnit === true)
+ || (object && object.isComplex === true)
+ }
+
+ /**
+ * Test whether a given thing is a typed-function
+ * @param {*} fn
+ * @return {boolean} Returns true when `fn` is a typed-function
+ */
+ function isTypedFunction (fn) {
+ return typeof fn === 'function' && typeof fn.signatures === 'object';
+ }
+
+ return math_import;
+ }
+
+ exports.math = true; // request access to the math namespace as 5th argument of the factory function
+ exports.name = 'import';
+ exports.factory = factory;
+ exports.lazy = true;
+
/***/ },
/* 11 */
-/***/ function(module, exports, __webpack_require__) {
+/***/ function(module, exports) {
'use strict';
- var util = __webpack_require__(175),
-
- number = util.number,
- string = util.string,
- isNumber = util.number.isNumber,
- isString = util.string.isString;
-
- /**
- * @constructor Unit
- *
- * A unit can be constructed in the following ways:
- * var a = new Unit(value, name);
- * var b = new Unit(null, name);
- * var c = Unit.parse(str);
- *
- * Example usage:
- * var a = new Unit(5, 'cm'); // 50 mm
- * var b = Unit.parse('23 kg'); // 23 kg
- * var c = math.in(a, new Unit(null, 'm'); // 0.05 m
- *
- * @param {Number} [value] A value like 5.2
- * @param {String} [name] A unit name like "cm" or "inch". Can include a prefix
- */
- function Unit(value, name) {
- if (!(this instanceof Unit)) {
- throw new Error('Constructor must be called with the new operator');
- }
-
- if (value != undefined && !isNumber(value)) {
- throw new TypeError('First parameter in Unit constructor must be a number');
- }
- if (name != undefined && (!isString(name) || name == '')) {
- throw new TypeError('Second parameter in Unit constructor must be a string');
- }
-
- if (name != undefined) {
- // find the unit and prefix from the string
- var res = _findUnit(name);
- if (!res) {
- throw new SyntaxError('Unknown unit "' + name + '"');
- }
- this.unit = res.unit;
- this.prefix = res.prefix;
- }
- else {
- this.unit = UNIT_NONE;
- this.prefix = PREFIX_NONE; // link to a list with supported prefixes
- }
-
- this.value = (value != undefined) ? this._normalize(value) : null;
- this.fixPrefix = false; // if true, function format will not search for the
- // best prefix but leave it as initially provided.
- // fixPrefix is set true by the method Unit.to
- }
-
- // private variables and functions for the Unit 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 parseUnit() {
- var unitName = '';
-
- skipWhitespace();
- while (c && c != ' ' && c != '\t') {
- unitName += c;
- next();
- }
-
- return unitName || null;
- }
-
- /**
- * Parse a string into a unit. Returns null if the provided string does not
- * contain a valid unit.
- * @param {String} str A string like "5.2 inch", "4e2 kg"
- * @return {Unit | null} unit
- */
- Unit.parse = function(str) {
- text = str;
- index = -1;
- c = '';
-
- if (!isString(text)) {
- return null;
- }
-
- next();
- skipWhitespace();
- var value = parseNumber();
- var name;
- if (value) {
- name = parseUnit();
-
- next();
- skipWhitespace();
- if (c) {
- // garbage at the end. not good.
- return null;
- }
-
- if (value && name) {
- try {
- // constructor will throw an error when unit is not found
- return new Unit(Number(value), name);
- }
- catch (err) {}
- }
- }
- else {
- name = parseUnit();
-
- next();
- skipWhitespace();
- if (c) {
- // garbage at the end. not good.
- return null;
- }
-
- if (name) {
- try {
- // constructor will throw an error when unit is not found
- return new Unit(null, name);
- }
- catch (err) {}
- }
- }
-
- return null;
- };
-
- /**
- * Test whether value is of type Unit
- * @param {*} value
- * @return {Boolean} isUnit
- */
- Unit.isUnit = function(value) {
- return (value instanceof Unit);
- };
-
- /**
- * create a copy of this unit
- * @return {Unit} clone
- */
- Unit.prototype.clone = function () {
- var clone = new Unit();
-
- for (var p in this) {
- if (this.hasOwnProperty(p)) {
- clone[p] = this[p];
- }
- }
-
- return clone;
- };
-
- /**
- * Normalize a value, based on its currently set unit
- * @param {Number} value
- * @return {Number} normalized value
- * @private
- */
- Unit.prototype._normalize = function(value) {
- return (value + this.unit.offset) * this.unit.value * this.prefix.value;
- };
-
- /**
- * Denormalize a value, based on its currently set unit
- * @param {Number} value
- * @param {Number} [prefixValue] Optional prefix value to be used
- * @return {Number} denormalized value
- * @private
- */
- Unit.prototype._denormalize = function (value, prefixValue) {
- if (prefixValue == undefined) {
- return value / this.unit.value / this.prefix.value - this.unit.offset;
- }
- else {
- return value / this.unit.value / prefixValue - this.unit.offset;
- }
- };
-
- /**
- * Find a unit from a string
- * @param {String} str A string like 'cm' or 'inch'
- * @returns {Object | null} result When found, an object with fields unit and
- * prefix is returned. Else, null is returned.
- * @private
- */
- function _findUnit(str) {
- for (var name in UNITS) {
- if (UNITS.hasOwnProperty(name)) {
- if (string.endsWith(str, name) ) {
- var unit = UNITS[name];
- var prefixLen = (str.length - name.length);
- var prefixName = str.substring(0, prefixLen);
- var prefix = unit.prefixes[prefixName];
- if (prefix !== undefined) {
- // store unit, prefix, and value
- return {
- unit: unit,
- prefix: prefix
- };
- }
- }
- }
- }
-
- return null;
- }
-
- /**
- * Test if the given expression is a unit.
- * The unit can have a prefix but cannot have a value.
- * @param {String} name A string to be tested whether it is a value less unit.
- * The unit can have prefix, like "cm"
- * @return {Boolean} true if the given string is a unit
- */
- Unit.isValuelessUnit = function (name) {
- return (_findUnit(name) != null);
- };
-
- /**
- * check if this unit has given base unit
- * @param {BASE_UNITS | undefined} base
- */
- Unit.prototype.hasBase = function(base) {
- return (this.unit.base === base);
- };
-
- /**
- * Check if this unit has a base equal to another base
- * @param {Unit} other
- * @return {Boolean} true if equal base
- */
- Unit.prototype.equalBase = function(other) {
- return (this.unit.base === other.unit.base);
- };
-
- /**
- * Check if this unit equals another unit
- * @param {Unit} other
- * @return {Boolean} true if both units are equal
- */
- Unit.prototype.equals = function(other) {
- return (this.equalBase(other) && this.value == other.value);
- };
-
- /**
- * Create a clone of this unit with a representation
- * @param {String | Unit} valuelessUnit A unit without value. Can have prefix, like "cm"
- * @returns {Unit} unit having fixed, specified unit
- */
- Unit.prototype.to = function (valuelessUnit) {
- var other;
- var value = this.value == null ? this._normalize(1) : this.value;
- if (isString(valuelessUnit)) {
- other = new Unit(null, valuelessUnit);
-
- if (!this.equalBase(other)) {
- throw new Error('Units do not match');
- }
-
- other.value = value;
- other.fixPrefix = true;
- return other;
- }
- else if (valuelessUnit instanceof Unit) {
- if (!this.equalBase(valuelessUnit)) {
- throw new Error('Units do not match');
- }
- if (valuelessUnit.value !== null) {
- throw new Error('Cannot convert to a unit with a value');
- }
-
- other = valuelessUnit.clone();
- other.value = value;
- other.fixPrefix = true;
- return other;
- }
- else {
- throw new Error('String or Unit expected as parameter');
- }
- };
-
- /**
- * Return the value of the unit when represented with given valueless unit
- * @param {String | Unit} valuelessUnit For example 'cm' or 'inch'
- * @return {Number} value
- */
- Unit.prototype.toNumber = function (valuelessUnit) {
- var other = this.to(valuelessUnit);
- return other._denormalize(other.value, other.prefix.value);
- };
-
-
- /**
- * Get a string representation of the unit.
- * @return {String}
- */
- Unit.prototype.toString = function() {
- return this.format();
- };
-
- /**
- * Get a JSON representation of the unit
- * @returns {Object} Returns a JSON object structured as:
- * `{"mathjs": "Unit", "value": 2, "unit": "cm", "fixPrefix": false}`
- */
- Unit.prototype.toJSON = function () {
- return {
- mathjs: 'Unit',
- value: this._denormalize(this.value),
- unit: this.prefix.name + this.unit.name,
- fixPrefix: this.fixPrefix
- };
- };
-
- /**
- * Instantiate a Unit from a JSON object
- * @param {Object} json A JSON object structured as:
- * `{"mathjs": "Unit", "value": 2, "unit": "cm", "fixPrefix": false}`
- * @return {Unit}
- */
- Unit.fromJSON = function (json) {
- var unit = new Unit(json.value, json.unit);
- unit.fixPrefix = json.fixPrefix || false;
- return unit;
- };
-
- /**
- * Returns the string representation of the unit.
- * @return {String}
- */
- Unit.prototype.valueOf = Unit.prototype.toString;
-
- /**
- * Get a string representation of the Unit, 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}
- */
- Unit.prototype.format = function(options) {
- var value,
- str;
-
- if (this.value !== null && !this.fixPrefix) {
- var bestPrefix = this._bestPrefix();
- value = this._denormalize(this.value, bestPrefix.value);
- str = number.format(value, options) + ' ';
- str += bestPrefix.name + this.unit.name;
- }
- else {
- value = this._denormalize(this.value);
- str = (this.value !== null) ? (number.format(value, options) + ' ') : '';
- str += this.prefix.name + this.unit.name;
- }
-
- return str;
- };
-
- /**
- * Calculate the best prefix using current value.
- * @returns {Object} prefix
- * @private
- */
- Unit.prototype._bestPrefix = function () {
- // find the best prefix value (resulting in the value of which
- // the absolute value of the log10 is closest to zero,
- // though with a little offset of 1.2 for nicer values: you get a
- // sequence 1mm 100mm 500mm 0.6m 1m 10m 100m 500m 0.6km 1km ...
- var absValue = Math.abs(this.value / this.unit.value);
- var bestPrefix = PREFIX_NONE;
- var bestDiff = Math.abs(
- Math.log(absValue / bestPrefix.value) / Math.LN10 - 1.2);
-
- var prefixes = this.unit.prefixes;
- for (var p in prefixes) {
- if (prefixes.hasOwnProperty(p)) {
- var prefix = prefixes[p];
- if (prefix.scientific) {
- var diff = Math.abs(
- Math.log(absValue / prefix.value) / Math.LN10 - 1.2);
-
- if (diff < bestDiff) {
- bestPrefix = prefix;
- bestDiff = diff;
- }
- }
- }
- }
-
- return bestPrefix;
- };
-
- var PREFIXES = {
- NONE: {
- '': {name: '', value: 1, scientific: true}
- },
- SHORT: {
- '': {name: '', value: 1, scientific: true},
-
- 'da': {name: 'da', value: 1e1, scientific: false},
- 'h': {name: 'h', value: 1e2, scientific: false},
- 'k': {name: 'k', value: 1e3, scientific: true},
- 'M': {name: 'M', value: 1e6, scientific: true},
- 'G': {name: 'G', value: 1e9, scientific: true},
- 'T': {name: 'T', value: 1e12, scientific: true},
- 'P': {name: 'P', value: 1e15, scientific: true},
- 'E': {name: 'E', value: 1e18, scientific: true},
- 'Z': {name: 'Z', value: 1e21, scientific: true},
- 'Y': {name: 'Y', value: 1e24, scientific: true},
-
- 'd': {name: 'd', value: 1e-1, scientific: false},
- 'c': {name: 'c', value: 1e-2, scientific: false},
- 'm': {name: 'm', value: 1e-3, scientific: true},
- 'u': {name: 'u', value: 1e-6, scientific: true},
- 'n': {name: 'n', value: 1e-9, scientific: true},
- 'p': {name: 'p', value: 1e-12, scientific: true},
- 'f': {name: 'f', value: 1e-15, scientific: true},
- 'a': {name: 'a', value: 1e-18, scientific: true},
- 'z': {name: 'z', value: 1e-21, scientific: true},
- 'y': {name: 'y', value: 1e-24, scientific: true}
- },
- LONG: {
- '': {name: '', value: 1, scientific: true},
-
- 'deca': {name: 'deca', value: 1e1, scientific: false},
- 'hecto': {name: 'hecto', value: 1e2, scientific: false},
- 'kilo': {name: 'kilo', value: 1e3, scientific: true},
- 'mega': {name: 'mega', value: 1e6, scientific: true},
- 'giga': {name: 'giga', value: 1e9, scientific: true},
- 'tera': {name: 'tera', value: 1e12, scientific: true},
- 'peta': {name: 'peta', value: 1e15, scientific: true},
- 'exa': {name: 'exa', value: 1e18, scientific: true},
- 'zetta': {name: 'zetta', value: 1e21, scientific: true},
- 'yotta': {name: 'yotta', value: 1e24, scientific: true},
-
- 'deci': {name: 'deci', value: 1e-1, scientific: false},
- 'centi': {name: 'centi', value: 1e-2, scientific: false},
- 'milli': {name: 'milli', value: 1e-3, scientific: true},
- 'micro': {name: 'micro', value: 1e-6, scientific: true},
- 'nano': {name: 'nano', value: 1e-9, scientific: true},
- 'pico': {name: 'pico', value: 1e-12, scientific: true},
- 'femto': {name: 'femto', value: 1e-15, scientific: true},
- 'atto': {name: 'atto', value: 1e-18, scientific: true},
- 'zepto': {name: 'zepto', value: 1e-21, scientific: true},
- 'yocto': {name: 'yocto', value: 1e-24, scientific: true}
- },
- SQUARED: {
- '': {name: '', value: 1, scientific: true},
-
- 'da': {name: 'da', value: 1e2, scientific: false},
- 'h': {name: 'h', value: 1e4, scientific: false},
- 'k': {name: 'k', value: 1e6, scientific: true},
- 'M': {name: 'M', value: 1e12, scientific: true},
- 'G': {name: 'G', value: 1e18, scientific: true},
- 'T': {name: 'T', value: 1e24, scientific: true},
- 'P': {name: 'P', value: 1e30, scientific: true},
- 'E': {name: 'E', value: 1e36, scientific: true},
- 'Z': {name: 'Z', value: 1e42, scientific: true},
- 'Y': {name: 'Y', value: 1e48, scientific: true},
-
- 'd': {name: 'd', value: 1e-2, scientific: false},
- 'c': {name: 'c', value: 1e-4, scientific: false},
- 'm': {name: 'm', value: 1e-6, scientific: true},
- 'u': {name: 'u', value: 1e-12, scientific: true},
- 'n': {name: 'n', value: 1e-18, scientific: true},
- 'p': {name: 'p', value: 1e-24, scientific: true},
- 'f': {name: 'f', value: 1e-30, scientific: true},
- 'a': {name: 'a', value: 1e-36, scientific: true},
- 'z': {name: 'z', value: 1e-42, scientific: true},
- 'y': {name: 'y', value: 1e-42, scientific: true}
- },
- CUBIC: {
- '': {name: '', value: 1, scientific: true},
-
- 'da': {name: 'da', value: 1e3, scientific: false},
- 'h': {name: 'h', value: 1e6, scientific: false},
- 'k': {name: 'k', value: 1e9, scientific: true},
- 'M': {name: 'M', value: 1e18, scientific: true},
- 'G': {name: 'G', value: 1e27, scientific: true},
- 'T': {name: 'T', value: 1e36, scientific: true},
- 'P': {name: 'P', value: 1e45, scientific: true},
- 'E': {name: 'E', value: 1e54, scientific: true},
- 'Z': {name: 'Z', value: 1e63, scientific: true},
- 'Y': {name: 'Y', value: 1e72, scientific: true},
-
- 'd': {name: 'd', value: 1e-3, scientific: false},
- 'c': {name: 'c', value: 1e-6, scientific: false},
- 'm': {name: 'm', value: 1e-9, scientific: true},
- 'u': {name: 'u', value: 1e-18, scientific: true},
- 'n': {name: 'n', value: 1e-27, scientific: true},
- 'p': {name: 'p', value: 1e-36, scientific: true},
- 'f': {name: 'f', value: 1e-45, scientific: true},
- 'a': {name: 'a', value: 1e-54, scientific: true},
- 'z': {name: 'z', value: 1e-63, scientific: true},
- 'y': {name: 'y', value: 1e-72, scientific: true}
- },
- BINARY_SHORT: {
- '': {name: '', value: 1, scientific: true},
- 'k': {name: 'k', value: 1e3, scientific: true},
- 'M': {name: 'M', value: 1e6, scientific: true},
- 'G': {name: 'G', value: 1e9, scientific: true},
- 'T': {name: 'T', value: 1e12, scientific: true},
- 'P': {name: 'P', value: 1e15, scientific: true},
- 'E': {name: 'E', value: 1e18, scientific: true},
- 'Z': {name: 'Z', value: 1e21, scientific: true},
- 'Y': {name: 'Y', value: 1e24, scientific: true},
-
- 'Ki': {name: 'Ki', value: 1024, scientific: true},
- 'Mi': {name: 'Mi', value: Math.pow(1024, 2), scientific: true},
- 'Gi': {name: 'Gi', value: Math.pow(1024, 3), scientific: true},
- 'Ti': {name: 'Ti', value: Math.pow(1024, 4), scientific: true},
- 'Pi': {name: 'Pi', value: Math.pow(1024, 5), scientific: true},
- 'Ei': {name: 'Ei', value: Math.pow(1024, 6), scientific: true},
- 'Zi': {name: 'Zi', value: Math.pow(1024, 7), scientific: true},
- 'Yi': {name: 'Yi', value: Math.pow(1024, 8), scientific: true}
- },
- BINARY_LONG: {
- '': {name: '', value: 1, scientific: true},
- 'kilo': {name: 'kilo', value: 1e3, scientific: true},
- 'mega': {name: 'mega', value: 1e6, scientific: true},
- 'giga': {name: 'giga', value: 1e9, scientific: true},
- 'tera': {name: 'tera', value: 1e12, scientific: true},
- 'peta': {name: 'peta', value: 1e15, scientific: true},
- 'exa': {name: 'exa', value: 1e18, scientific: true},
- 'zetta': {name: 'zetta', value: 1e21, scientific: true},
- 'yotta': {name: 'yotta', value: 1e24, scientific: true},
-
- 'kibi': {name: 'kibi', value: 1024, scientific: true},
- 'mebi': {name: 'mebi', value: Math.pow(1024, 2), scientific: true},
- 'gibi': {name: 'gibi', value: Math.pow(1024, 3), scientific: true},
- 'tebi': {name: 'tebi', value: Math.pow(1024, 4), scientific: true},
- 'pebi': {name: 'pebi', value: Math.pow(1024, 5), scientific: true},
- 'exi': {name: 'exi', value: Math.pow(1024, 6), scientific: true},
- 'zebi': {name: 'zebi', value: Math.pow(1024, 7), scientific: true},
- 'yobi': {name: 'yobi', value: Math.pow(1024, 8), scientific: true}
- }
- };
-
- var PREFIX_NONE = {name: '', value: 1, scientific: true};
-
- var BASE_UNITS = {
- NONE: {},
-
- LENGTH: {}, // meter
- MASS: {}, // kilogram
- TIME: {}, // second
- CURRENT: {}, // ampere
- TEMPERATURE: {}, // kelvin
- LUMINOUS_INTENSITY: {}, // candela
- AMOUNT_OF_SUBSTANCE: {}, // mole
-
- FORCE: {}, // Newton
- SURFACE: {}, // m2
- VOLUME: {}, // m3
- ANGLE: {}, // rad
- BIT: {} // bit (digital)
- };
-
- var BASE_UNIT_NONE = {};
-
- var UNIT_NONE = {name: '', base: BASE_UNIT_NONE, value: 1, offset: 0};
-
- var UNITS = {
- // length
- meter: {name: 'meter', base: BASE_UNITS.LENGTH, prefixes: PREFIXES.LONG, value: 1, offset: 0},
- inch: {name: 'inch', base: BASE_UNITS.LENGTH, prefixes: PREFIXES.NONE, value: 0.0254, offset: 0},
- foot: {name: 'foot', base: BASE_UNITS.LENGTH, prefixes: PREFIXES.NONE, value: 0.3048, offset: 0},
- yard: {name: 'yard', base: BASE_UNITS.LENGTH, prefixes: PREFIXES.NONE, value: 0.9144, offset: 0},
- mile: {name: 'mile', base: BASE_UNITS.LENGTH, prefixes: PREFIXES.NONE, value: 1609.344, offset: 0},
- link: {name: 'link', base: BASE_UNITS.LENGTH, prefixes: PREFIXES.NONE, value: 0.201168, offset: 0},
- rod: {name: 'rod', base: BASE_UNITS.LENGTH, prefixes: PREFIXES.NONE, value: 5.029210, offset: 0},
- chain: {name: 'chain', base: BASE_UNITS.LENGTH, prefixes: PREFIXES.NONE, value: 20.1168, offset: 0},
- angstrom: {name: 'angstrom', base: BASE_UNITS.LENGTH, prefixes: PREFIXES.NONE, value: 1e-10, offset: 0},
-
- m: {name: 'm', base: BASE_UNITS.LENGTH, prefixes: PREFIXES.SHORT, value: 1, offset: 0},
- 'in': {name: 'in', base: BASE_UNITS.LENGTH, prefixes: PREFIXES.NONE, value: 0.0254, offset: 0},
- ft: {name: 'ft', base: BASE_UNITS.LENGTH, prefixes: PREFIXES.NONE, value: 0.3048, offset: 0},
- yd: {name: 'yd', base: BASE_UNITS.LENGTH, prefixes: PREFIXES.NONE, value: 0.9144, offset: 0},
- mi: {name: 'mi', base: BASE_UNITS.LENGTH, prefixes: PREFIXES.NONE, value: 1609.344, offset: 0},
- li: {name: 'li', base: BASE_UNITS.LENGTH, prefixes: PREFIXES.NONE, value: 0.201168, offset: 0},
- rd: {name: 'rd', base: BASE_UNITS.LENGTH, prefixes: PREFIXES.NONE, value: 5.029210, offset: 0},
- ch: {name: 'ch', base: BASE_UNITS.LENGTH, prefixes: PREFIXES.NONE, value: 20.1168, offset: 0},
- mil: {name: 'mil', base: BASE_UNITS.LENGTH, prefixes: PREFIXES.NONE, value: 0.0000254, offset: 0}, // 1/1000 inch
-
- // Surface
- m2: {name: 'm2', base: BASE_UNITS.SURFACE, prefixes: PREFIXES.SQUARED, value: 1, offset: 0},
- sqin: {name: 'sqin', base: BASE_UNITS.SURFACE, prefixes: PREFIXES.NONE, value: 0.00064516, offset: 0}, // 645.16 mm2
- sqft: {name: 'sqft', base: BASE_UNITS.SURFACE, prefixes: PREFIXES.NONE, value: 0.09290304, offset: 0}, // 0.09290304 m2
- sqyd: {name: 'sqyd', base: BASE_UNITS.SURFACE, prefixes: PREFIXES.NONE, value: 0.83612736, offset: 0}, // 0.83612736 m2
- sqmi: {name: 'sqmi', base: BASE_UNITS.SURFACE, prefixes: PREFIXES.NONE, value: 2589988.110336, offset: 0}, // 2.589988110336 km2
- sqrd: {name: 'sqrd', base: BASE_UNITS.SURFACE, prefixes: PREFIXES.NONE, value: 25.29295, offset: 0}, // 25.29295 m2
- sqch: {name: 'sqch', base: BASE_UNITS.SURFACE, prefixes: PREFIXES.NONE, value: 404.6873, offset: 0}, // 404.6873 m2
- sqmil: {name: 'sqmil', base: BASE_UNITS.SURFACE, prefixes: PREFIXES.NONE, value: 6.4516e-10, offset: 0}, // 6.4516 * 10^-10 m2
-
- // Volume
- m3: {name: 'm3', base: BASE_UNITS.VOLUME, prefixes: PREFIXES.CUBIC, value: 1, offset: 0},
- L: {name: 'L', base: BASE_UNITS.VOLUME, prefixes: PREFIXES.SHORT, value: 0.001, offset: 0}, // litre
- l: {name: 'l', base: BASE_UNITS.VOLUME, prefixes: PREFIXES.SHORT, value: 0.001, offset: 0}, // litre
- litre: {name: 'litre', base: BASE_UNITS.VOLUME, prefixes: PREFIXES.LONG, value: 0.001, offset: 0},
- cuin: {name: 'cuin', base: BASE_UNITS.VOLUME, prefixes: PREFIXES.NONE, value: 1.6387064e-5, offset: 0}, // 1.6387064e-5 m3
- cuft: {name: 'cuft', base: BASE_UNITS.VOLUME, prefixes: PREFIXES.NONE, value: 0.028316846592, offset: 0}, // 28.316 846 592 L
- cuyd: {name: 'cuyd', base: BASE_UNITS.VOLUME, prefixes: PREFIXES.NONE, value: 0.764554857984, offset: 0}, // 764.554 857 984 L
- teaspoon: {name: 'teaspoon', base: BASE_UNITS.VOLUME, prefixes: PREFIXES.NONE, value: 0.000005, offset: 0}, // 5 mL
- tablespoon: {name: 'tablespoon', base: BASE_UNITS.VOLUME, prefixes: PREFIXES.NONE, value: 0.000015, offset: 0}, // 15 mL
- //{name: 'cup', base: BASE_UNITS.VOLUME, prefixes: PREFIXES.NONE, value: 0.000240, offset: 0}, // 240 mL // not possible, we have already another cup
- drop: {name: 'drop', base: BASE_UNITS.VOLUME, prefixes: PREFIXES.NONE, value: 5e-8, offset: 0}, // 0.05 mL = 5e-8 m3
- gtt: {name: 'gtt', base: BASE_UNITS.VOLUME, prefixes: PREFIXES.NONE, value: 5e-8, offset: 0}, // 0.05 mL = 5e-8 m3
-
- // Liquid volume
- minim: {name: 'minim', base: BASE_UNITS.VOLUME, prefixes: PREFIXES.NONE, value: 0.00000006161152, offset: 0}, // 0.06161152 mL
- fluiddram: {name: 'fluiddram', base: BASE_UNITS.VOLUME, prefixes: PREFIXES.NONE, value: 0.0000036966911, offset: 0}, // 3.696691 mL
- fluidounce: {name: 'fluidounce', base: BASE_UNITS.VOLUME, prefixes: PREFIXES.NONE, value: 0.00002957353, offset: 0}, // 29.57353 mL
- gill: {name: 'gill', base: BASE_UNITS.VOLUME, prefixes: PREFIXES.NONE, value: 0.0001182941, offset: 0}, // 118.2941 mL
- cc: {name: 'cc', base: BASE_UNITS.VOLUME, prefixes: PREFIXES.NONE, value: 1e-6, offset: 0}, // 1e-6 L
- cup: {name: 'cup', base: BASE_UNITS.VOLUME, prefixes: PREFIXES.NONE, value: 0.0002365882, offset: 0}, // 236.5882 mL
- pint: {name: 'pint', base: BASE_UNITS.VOLUME, prefixes: PREFIXES.NONE, value: 0.0004731765, offset: 0}, // 473.1765 mL
- quart: {name: 'quart', base: BASE_UNITS.VOLUME, prefixes: PREFIXES.NONE, value: 0.0009463529, offset: 0}, // 946.3529 mL
- gallon: {name: 'gallon', base: BASE_UNITS.VOLUME, prefixes: PREFIXES.NONE, value: 0.003785412, offset: 0}, // 3.785412 L
- beerbarrel: {name: 'beerbarrel', base: BASE_UNITS.VOLUME, prefixes: PREFIXES.NONE, value: 0.1173478, offset: 0}, // 117.3478 L
- oilbarrel: {name: 'oilbarrel', base: BASE_UNITS.VOLUME, prefixes: PREFIXES.NONE, value: 0.1589873, offset: 0}, // 158.9873 L
- hogshead: {name: 'hogshead', base: BASE_UNITS.VOLUME, prefixes: PREFIXES.NONE, value: 0.2384810, offset: 0}, // 238.4810 L
-
- //{name: 'min', base: BASE_UNITS.VOLUME, prefixes: PREFIXES.NONE, value: 0.00000006161152, offset: 0}, // 0.06161152 mL // min is already in use as minute
- fldr: {name: 'fldr', base: BASE_UNITS.VOLUME, prefixes: PREFIXES.NONE, value: 0.0000036966911, offset: 0}, // 3.696691 mL
- floz: {name: 'floz', base: BASE_UNITS.VOLUME, prefixes: PREFIXES.NONE, value: 0.00002957353, offset: 0}, // 29.57353 mL
- gi: {name: 'gi', base: BASE_UNITS.VOLUME, prefixes: PREFIXES.NONE, value: 0.0001182941, offset: 0}, // 118.2941 mL
- cp: {name: 'cp', base: BASE_UNITS.VOLUME, prefixes: PREFIXES.NONE, value: 0.0002365882, offset: 0}, // 236.5882 mL
- pt: {name: 'pt', base: BASE_UNITS.VOLUME, prefixes: PREFIXES.NONE, value: 0.0004731765, offset: 0}, // 473.1765 mL
- qt: {name: 'qt', base: BASE_UNITS.VOLUME, prefixes: PREFIXES.NONE, value: 0.0009463529, offset: 0}, // 946.3529 mL
- gal: {name: 'gal', base: BASE_UNITS.VOLUME, prefixes: PREFIXES.NONE, value: 0.003785412, offset: 0}, // 3.785412 L
- bbl: {name: 'bbl', base: BASE_UNITS.VOLUME, prefixes: PREFIXES.NONE, value: 0.1173478, offset: 0}, // 117.3478 L
- obl: {name: 'obl', base: BASE_UNITS.VOLUME, prefixes: PREFIXES.NONE, value: 0.1589873, offset: 0}, // 158.9873 L
- //{name: 'hogshead', base: BASE_UNITS.VOLUME, prefixes: PREFIXES.NONE, value: 0.2384810, offset: 0}, // 238.4810 L // TODO: hh?
-
- // Mass
- g: {name: 'g', base: BASE_UNITS.MASS, prefixes: PREFIXES.SHORT, value: 0.001, offset: 0},
- gram: {name: 'gram', base: BASE_UNITS.MASS, prefixes: PREFIXES.LONG, value: 0.001, offset: 0},
-
- ton: {name: 'ton', base: BASE_UNITS.MASS, prefixes: PREFIXES.SHORT, value: 907.18474, offset: 0},
- tonne: {name: 'tonne', base: BASE_UNITS.MASS, prefixes: PREFIXES.SHORT, value: 1000, offset: 0},
-
- grain: {name: 'grain', base: BASE_UNITS.MASS, prefixes: PREFIXES.NONE, value: 64.79891e-6, offset: 0},
- dram: {name: 'dram', base: BASE_UNITS.MASS, prefixes: PREFIXES.NONE, value: 1.7718451953125e-3, offset: 0},
- ounce: {name: 'ounce', base: BASE_UNITS.MASS, prefixes: PREFIXES.NONE, value: 28.349523125e-3, offset: 0},
- poundmass: {name: 'poundmass', base: BASE_UNITS.MASS, prefixes: PREFIXES.NONE, value: 453.59237e-3, offset: 0},
- hundredweight: {name: 'hundredweight', base: BASE_UNITS.MASS, prefixes: PREFIXES.NONE, value: 45.359237, offset: 0},
- stick: {name: 'stick', base: BASE_UNITS.MASS, prefixes: PREFIXES.NONE, value: 115e-3, offset: 0},
- stone: {name: 'stone', base: BASE_UNITS.MASS, prefixes: PREFIXES.NONE, value: 6350, offset: 0},
-
- gr: {name: 'gr', base: BASE_UNITS.MASS, prefixes: PREFIXES.NONE, value: 64.79891e-6, offset: 0},
- dr: {name: 'dr', base: BASE_UNITS.MASS, prefixes: PREFIXES.NONE, value: 1.7718451953125e-3, offset: 0},
- oz: {name: 'oz', base: BASE_UNITS.MASS, prefixes: PREFIXES.NONE, value: 28.349523125e-3, offset: 0},
- lbm: {name: 'lbm', base: BASE_UNITS.MASS, prefixes: PREFIXES.NONE, value: 453.59237e-3, offset: 0},
- cwt: {name: 'cwt', base: BASE_UNITS.MASS, prefixes: PREFIXES.NONE, value: 45.359237, offset: 0},
-
- // Time
- s: {name: 's', base: BASE_UNITS.TIME, prefixes: PREFIXES.SHORT, value: 1, offset: 0},
- min: {name: 'min', base: BASE_UNITS.TIME, prefixes: PREFIXES.NONE, value: 60, offset: 0},
- h: {name: 'h', base: BASE_UNITS.TIME, prefixes: PREFIXES.NONE, value: 3600, offset: 0},
- second: {name: 'second', base: BASE_UNITS.TIME, prefixes: PREFIXES.LONG, value: 1, offset: 0},
- sec: {name: 'sec', base: BASE_UNITS.TIME, prefixes: PREFIXES.LONG, value: 1, offset: 0},
- minute: {name: 'minute', base: BASE_UNITS.TIME, prefixes: PREFIXES.NONE, value: 60, offset: 0},
- hour: {name: 'hour', base: BASE_UNITS.TIME, prefixes: PREFIXES.NONE, value: 3600, offset: 0},
- day: {name: 'day', base: BASE_UNITS.TIME, prefixes: PREFIXES.NONE, value: 86400, offset: 0},
-
- // Angle
- rad: {name: 'rad', base: BASE_UNITS.ANGLE, prefixes: PREFIXES.NONE, value: 1, offset: 0},
- // deg = rad / (2*pi) * 360 = rad / 0.017453292519943295769236907684888
- deg: {name: 'deg', base: BASE_UNITS.ANGLE, prefixes: PREFIXES.NONE, value: 0.017453292519943295769236907684888, offset: 0},
- // grad = rad / (2*pi) * 400 = rad / 0.015707963267948966192313216916399
- grad: {name: 'grad', base: BASE_UNITS.ANGLE, prefixes: PREFIXES.NONE, value: 0.015707963267948966192313216916399, offset: 0},
- // cycle = rad / (2*pi) = rad / 6.2831853071795864769252867665793
- cycle: {name: 'cycle', base: BASE_UNITS.ANGLE, prefixes: PREFIXES.NONE, value: 6.2831853071795864769252867665793, offset: 0},
-
- // Electric current
- A: {name: 'A', base: BASE_UNITS.CURRENT, prefixes: PREFIXES.SHORT, value: 1, offset: 0},
- ampere: {name: 'ampere', base: BASE_UNITS.CURRENT, prefixes: PREFIXES.LONG, value: 1, offset: 0},
-
- // Temperature
- // K(C) = °C + 273.15
- // K(F) = (°F + 459.67) / 1.8
- // K(R) = °R / 1.8
- K: {name: 'K', base: BASE_UNITS.TEMPERATURE, prefixes: PREFIXES.NONE, value: 1, offset: 0},
- degC: {name: 'degC', base: BASE_UNITS.TEMPERATURE, prefixes: PREFIXES.NONE, value: 1, offset: 273.15},
- degF: {name: 'degF', base: BASE_UNITS.TEMPERATURE, prefixes: PREFIXES.NONE, value: 1/1.8, offset: 459.67},
- degR: {name: 'degR', base: BASE_UNITS.TEMPERATURE, prefixes: PREFIXES.NONE, value: 1/1.8, offset: 0},
- kelvin: {name: 'kelvin', base: BASE_UNITS.TEMPERATURE, prefixes: PREFIXES.NONE, value: 1, offset: 0},
- celsius: {name: 'celsius', base: BASE_UNITS.TEMPERATURE, prefixes: PREFIXES.NONE, value: 1, offset: 273.15},
- fahrenheit: {name: 'fahrenheit', base: BASE_UNITS.TEMPERATURE, prefixes: PREFIXES.NONE, value: 1/1.8, offset: 459.67},
- rankine: {name: 'rankine', base: BASE_UNITS.TEMPERATURE, prefixes: PREFIXES.NONE, value: 1/1.8, offset: 0},
-
- // amount of substance
- mol: {name: 'mol', base: BASE_UNITS.AMOUNT_OF_SUBSTANCE, prefixes: PREFIXES.NONE, value: 1, offset: 0},
- mole: {name: 'mole', base: BASE_UNITS.AMOUNT_OF_SUBSTANCE, prefixes: PREFIXES.NONE, value: 1, offset: 0},
-
- // luminous intensity
- cd: {name: 'cd', base: BASE_UNITS.LUMINOUS_INTENSITY, prefixes: PREFIXES.NONE, value: 1, offset: 0},
- candela: {name: 'candela', base: BASE_UNITS.LUMINOUS_INTENSITY, prefixes: PREFIXES.NONE, value: 1, offset: 0},
- // TODO: units STERADIAN
- //{name: 'sr', base: BASE_UNITS.STERADIAN, prefixes: PREFIXES.NONE, value: 1, offset: 0},
- //{name: 'steradian', base: BASE_UNITS.STERADIAN, prefixes: PREFIXES.NONE, value: 1, offset: 0},
-
- // Force
- N: {name: 'N', base: BASE_UNITS.FORCE, prefixes: PREFIXES.SHORT, value: 1, offset: 0},
- newton: {name: 'newton', base: BASE_UNITS.FORCE, prefixes: PREFIXES.LONG, value: 1, offset: 0},
- lbf: {name: 'lbf', base: BASE_UNITS.FORCE, prefixes: PREFIXES.NONE, value: 4.4482216152605, offset: 0},
- poundforce: {name: 'poundforce', base: BASE_UNITS.FORCE, prefixes: PREFIXES.NONE, value: 4.4482216152605, offset: 0},
-
- // Binary
- b: {name: 'b', base: BASE_UNITS.BIT, prefixes: PREFIXES.BINARY_SHORT, value: 1, offset: 0},
- bits: {name: 'bits', base: BASE_UNITS.BIT, prefixes: PREFIXES.BINARY_LONG, value: 1, offset: 0},
- B: {name: 'B', base: BASE_UNITS.BIT, prefixes: PREFIXES.BINARY_SHORT, value: 8, offset: 0},
- bytes: {name: 'bytes', base: BASE_UNITS.BIT, prefixes: PREFIXES.BINARY_LONG, value: 8, offset: 0}
- };
-
- // plurals
- var PLURALS = {
- meters: 'meter',
- inches: 'inch',
- feet: 'foot',
- yards: 'yard',
- miles: 'mile',
- links: 'link',
- rods: 'rod',
- chains: 'chain',
- angstroms: 'angstrom',
-
- litres: 'litre',
- teaspoons: 'teaspoon',
- tablespoons: 'tablespoon',
- minims: 'minim',
- fluiddrams: 'fluiddram',
- fluidounces: 'fluidounce',
- gills: 'gill',
- cups: 'cup',
- pints: 'pint',
- quarts: 'quart',
- gallons: 'gallon',
- beerbarrels: 'beerbarrel',
- oilbarrels: 'oilbarrel',
- hogsheads: 'hogshead',
- gtts: 'gtt',
-
- grams: 'gram',
- tons: 'ton',
- tonnes: 'tonne',
- grains: 'grain',
- drams: 'dram',
- ounces: 'ounce',
- poundmasses: 'poundmass',
- hundredweights: 'hundredweight',
- sticks: 'stick',
-
- seconds: 'second',
- minutes: 'minute',
- hours: 'hour',
- days: 'day',
-
- radians: 'rad',
- degrees: 'deg',
- gradients: 'grad',
- cycles: 'cycle',
-
- amperes: 'ampere',
- moles: 'mole'
- };
-
- for (var name in PLURALS) {
- /* istanbul ignore next (we cannot really test next statement) */
- if (PLURALS.hasOwnProperty(name)) {
- var unit = UNITS[PLURALS[name]];
- var plural = Object.create(unit);
- plural.name = name;
- UNITS[name] = plural;
- }
- }
-
- // aliases
- UNITS.lt = UNITS.l;
- UNITS.liter = UNITS.litre;
- UNITS.liters = UNITS.litres;
- UNITS.lb = UNITS.lbm;
- UNITS.lbs = UNITS.lbm;
-
-
- Unit.PREFIXES = PREFIXES;
- Unit.BASE_UNITS = BASE_UNITS;
- Unit.UNITS = UNITS;
-
- // end of unit aliases
-
-
- // exports
- module.exports = Unit;
+ /**
+ * Create a syntax error with the message:
+ * 'Wrong number of arguments in function <fn> (<count> provided, <min>-<max> expected)'
+ * @param {string} fn Function name
+ * @param {number} count Actual argument count
+ * @param {number} min Minimum required argument count
+ * @param {number} [max] Maximum required argument count
+ * @extends Error
+ */
+ function ArgumentsError(fn, count, min, max) {
+ if (!(this instanceof ArgumentsError)) {
+ throw new SyntaxError('Constructor must be called with the new operator');
+ }
+
+ this.fn = fn;
+ this.count = count;
+ this.min = min;
+ this.max = max;
+
+ this.message = 'Wrong number of arguments in function ' + fn +
+ ' (' + count + ' provided, ' +
+ min + ((max != undefined) ? ('-' + max) : '') + ' expected)';
+
+ this.stack = (new Error()).stack;
+ }
+
+ ArgumentsError.prototype = new Error();
+ ArgumentsError.prototype.constructor = Error;
+ ArgumentsError.prototype.name = 'ArgumentsError';
+ ArgumentsError.prototype.isArgumentsError = true;
+
+ module.exports = ArgumentsError;
/***/ },
@@ -3314,1681 +2863,113 @@
'use strict';
- var util = __webpack_require__(175);
- var object = util.object;
- var string = util.string;
-
- /**
- * Documentation object
- * @param {Object} doc Object containing properties:
- * {String} name
- * {String} category
- * {String} description
- * {String[]} syntax
- * {String[]} examples
- * {String[]} seealso
- * @constructor
- */
- function Help (doc) {
- if (!(this instanceof Help)) {
- throw new SyntaxError('Constructor must be called with the new operator');
- }
-
- if (!doc) throw new Error('Argument "doc" missing');
-
- this.doc = doc;
+ var object = __webpack_require__(5);
+
+ function factory (type, config, load, typed, math) {
+ /**
+ * Set configuration options for math.js, and get current options.
+ * Will emit a 'config' event, with arguments (curr, prev).
+ * @param {Object} [options] Available options:
+ * {number} epsilon
+ * Minimum relative difference between two
+ * compared values, used by all comparison functions.
+ * {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.
+ * {string} parenthesis
+ * How to display parentheses in LaTeX and string
+ * output.
+ * @return {Object} Returns the current configuration
+ */
+ return function _config(options) {
+ if (options) {
+ var prev = object.clone(config);
+
+ // merge options
+ object.deepExtend(config, options);
+
+ var curr = object.clone(config);
+
+ // emit 'config' event
+ math.emit('config', curr, prev);
+
+ return curr;
+ }
+ else {
+ return object.clone(config);
+ }
+ };
}
- /**
- * Test whether a value is an instance of Help
- * @param {*} value
- * @return {Boolean} isHelp
- */
- Help.isHelp = function (value) {
- return (value instanceof Help);
- };
-
- /**
- * Generate readable description from a Help object
- * @param {Object} [math] A math instance, used to evaluate the examples
- * @return {String} readableDoc
- * @private
- */
- Help.prototype.toText = function (math) {
- var doc = this.doc || {};
- var desc = '\n';
-
- if (doc.name) {
- desc += 'Name: ' + doc.name + '\n\n';
- }
- if (doc.category) {
- desc += 'Category: ' + doc.category + '\n\n';
- }
- if (doc.description) {
- desc += 'Description:\n ' + doc.description + '\n\n';
- }
- if (doc.syntax) {
- desc += 'Syntax:\n ' + doc.syntax.join('\n ') + '\n\n';
- }
- if (doc.examples) {
- var parser = math && math.parser();
- desc += 'Examples:\n';
- for (var i = 0; i < doc.examples.length; i++) {
- var expr = doc.examples[i];
- desc += ' ' + expr + '\n';
-
- if (parser) {
- var res;
- try {
- res = parser.eval(expr);
- }
- catch (e) {
- res = e;
- }
- if (res !== undefined && !(res instanceof Help)) {
- desc += ' ' + string.format(res, {precision: 14}) + '\n';
- }
- }
- }
- desc += '\n';
- }
- if (doc.seealso) {
- desc += 'See also: ' + doc.seealso.join(', ') + '\n';
- }
-
- return desc;
- };
-
- /**
- * Generate a string representation of the Help object
- * @return {String} Returns a string
- * @private
- */
- Help.prototype.toString = function () {
- return this.toText();
- };
-
- /**
- * Export the help object to JSON
- */
- Help.prototype.toJSON = function () {
- var obj = object.clone(this.doc);
- obj.mathjs = 'Help';
- return obj;
- };
-
- /**
- * Instantiate a Help object from a JSON object
- * @param {Object} json
- * @returns {Help} Returns a new Help object
- */
- Help.fromJSON = function (json) {
- var doc = {};
- for (var prop in json) {
- if (prop !== 'mathjs') { // ignore mathjs field
- doc[prop] = json[prop];
- }
- }
- return new Help(doc);
- };
-
- /**
- * Returns a string representation of the Help object
- */
- Help.prototype.valueOf = Help.prototype.toString;
-
- // exports
- module.exports = Help;
+ exports.name = 'config';
+ exports.math = true; // request the math namespace as fifth argument
+ exports.factory = factory;
/***/ },
/* 13 */
/***/ function(module, exports, __webpack_require__) {
- 'use strict';
-
- /**
- * A ResultSet contains a list or results
- * @param {Array} entries
- * @constructor
- */
- function ResultSet(entries) {
- if (!(this instanceof ResultSet)) {
- throw new SyntaxError('Constructor must be called with the new operator');
- }
-
- this.entries = entries || [];
- }
-
- /**
- * Returns the array with results hold by this ResultSet
- * @returns {Array} entries
- */
- ResultSet.prototype.valueOf = function () {
- return this.entries;
- };
-
- /**
- * Returns the stringified results of the ResultSet
- * @returns {String} string
- */
- ResultSet.prototype.toString = function () {
- return '[' + this.entries.join(', ') + ']';
- };
-
- /**
- * Get a JSON representation of the ResultSet
- * @returns {Object} Returns a JSON object structured as:
- * `{"mathjs": "ResultSet", "entries": [...]}`
- */
- ResultSet.prototype.toJSON = function () {
- return {
- mathjs: 'ResultSet',
- entries: this.entries
- };
- };
-
- /**
- * Instantiate a ResultSet from a JSON object
- * @param {Object} json A JSON object structured as:
- * `{"mathjs": "ResultSet", "entries": [...]}`
- * @return {ResultSet}
- */
- ResultSet.fromJSON = function (json) {
- return new ResultSet(json.entries);
- };
-
- module.exports = ResultSet;
+ module.exports = [
+ __webpack_require__(243), // data types (Matrix, Complex, Unit, ...)
+ __webpack_require__(280), // constants
+ __webpack_require__(282), // expression parsing
+ __webpack_require__(14), // functions
+ __webpack_require__(487), // serialization utility (math.json.reviver)
+ __webpack_require__(489) // errors
+ ];
/***/ },
/* 14 */
/***/ function(module, exports, __webpack_require__) {
- // utility methods for arrays and matrices
- 'use strict';
-
- var util = __webpack_require__(175),
-
- IndexError = __webpack_require__(173),
- DimensionError = __webpack_require__(172),
-
- array = util.array,
- isArray = util.array.isArray;
-
- module.exports = function (math) {
-
- var Matrix = math.type.Matrix;
-
- var collection = {};
-
- /**
- * Convert function arguments to an array. Arguments can have the following
- * signature:
- * fn()
- * fn(n)
- * fn(m, n, p, ...)
- * fn([m, n, p, ...])
- * @param {...Number | Array | Matrix} args
- * @returns {Array} array
- */
- collection.argsToArray = function(args) {
- if (args.length === 0) {
- // fn()
- return [];
- }
- else if (args.length == 1) {
- // fn(n)
- // fn([m, n, p, ...])
- var array = args[0];
- if (array instanceof Matrix) {
- array = array.valueOf();
- }
- if (!isArray(array)) {
- array = [array];
- }
- return array;
- }
- else {
- // fn(m, n, p, ...)
- return util.array.argsToArray(args);
- }
- };
-
-
- /**
- * Test whether a value is a collection: an Array or Matrix
- * @param {*} x
- * @returns {boolean} isCollection
- */
- collection.isCollection = function(x) {
- return (isArray(x) || (x instanceof Matrix));
- };
-
- /**
- * 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
- */
- collection.deepMap = function deepMap(array, callback, skipZeros) {
- if (array && (typeof array.map === 'function')) {
- return array.map(function (x) {
- return deepMap(x, callback, skipZeros);
- });
- }
- else {
- return callback(array);
- }
- };
-
- /**
- * Execute the callback function element wise for each entry in two given arrays,
- * and for any nested array. Objects can also be scalar objects.
- * Returns an array with the results.
- * @param {Array | Matrix | Object} array1
- * @param {Array | Matrix | Object} array2
- * @param {function} callback The callback is called with two parameters:
- * value1 and value2, which contain the current
- * element of both arrays.
- * @return {Array | Matrix} res
- */
- collection.deepMap2 = function deepMap2(array1, array2, callback) {
- var res, len, i;
-
- if (isArray(array1)) {
- if (isArray(array2)) {
- // callback(array, array)
- if (array1.length != array2.length) {
- throw new DimensionError(array1.length, array2.length);
- }
-
- res = [];
- len = array1.length;
- for (i = 0; i < len; i++) {
- res[i] = deepMap2(array1[i], array2[i], callback);
- }
- }
- else if (array2 instanceof Matrix) {
- // callback(array, matrix)
- res = deepMap2(array1, array2.valueOf(), callback);
- return math.matrix(res);
- }
- else {
- // callback(array, object)
- res = [];
- len = array1.length;
- for (i = 0; i < len; i++) {
- res[i] = deepMap2(array1[i], array2, callback);
- }
- }
- }
- else if (array1 instanceof Matrix) {
- if (array2 instanceof Matrix) {
- // callback(matrix, matrix)
- res = deepMap2(array1.valueOf(), array2.valueOf(), callback);
- return math.matrix(res);
- }
- else {
- // callback(matrix, array)
- // callback(matrix, object)
- res = deepMap2(array1.valueOf(), array2, callback);
- return math.matrix(res);
- }
- }
- else {
- if (isArray(array2)) {
- // callback(object, array)
- res = [];
- len = array2.length;
- for (i = 0; i < len; i++) {
- res[i] = deepMap2(array1, array2[i], callback);
- }
- }
- else if (array2 instanceof Matrix) {
- // callback(object, matrix)
- res = deepMap2(array1, array2.valueOf(), callback);
- return math.matrix(res);
- }
- else {
- // callback(object, object)
- res = callback(array1, array2);
- }
- }
-
- return res;
- };
-
- /**
- * Reduce a given matrix or array to a new matrix or
- * array with one less dimension, applying the given
- * callback in the selected dimension.
- * @param {Array | Matrix} mat
- * @param {Number} dim
- * @param {function} callback
- * @return {Array | Matrix} res
- */
- collection.reduce = function(mat, dim, callback) {
- var size = isArray(mat) ? array.size(mat) : mat.size();
- if (dim < 0) {
- // TODO: would be more clear when throwing a DimensionError here
- throw new IndexError(dim);
- }
- if (dim >= size.length) {
- // TODO: would be more clear when throwing a DimensionError here
- throw new IndexError(dim, size.length);
- }
-
- if (mat instanceof Matrix) {
- return math.matrix(_reduce(mat.valueOf(), dim, callback));
- }else {
- return _reduce(mat, dim, callback);
- }
- };
-
- /**
- * Recursively reduce a matrix
- * @param {Array} mat
- * @param {Number} dim
- * @param {Function} callback
- * @returns {Array} ret
- * @private
- */
- function _reduce(mat, dim, callback){
- var i, ret, val, tran;
-
- if(dim<=0){
- if( !isArray(mat[0]) ){
- val = mat[0];
- for(i=1; i<mat.length; i++){
- val = callback(val, mat[i]);
- }
- return val;
- }else{
- tran = _switch(mat);
- ret = [];
- for(i=0; i<tran.length; i++){
- ret[i] = _reduce(tran[i], dim-1, callback);
- }
- return ret;
- }
- }else{
- ret = [];
- for(i=0; i<mat.length; i++){
- ret[i] = _reduce(mat[i], dim-1, callback);
- }
- return ret;
- }
- }
-
- /**
- * Transpose a matrix
- * @param {Array} mat
- * @returns {Array} ret
- * @private
- */
- function _switch(mat){
- var I = mat.length;
- var J = mat[0].length;
- var i, j;
- var ret = [];
- for( j=0; j<J; j++) {
- var tmp = [];
- for( i=0; i<I; i++) {
- tmp.push(mat[i][j]);
- }
- ret.push(tmp);
- }
- return ret;
- }
-
- /**
- * Recursively loop over all elements in a given multi dimensional array
- * and invoke the callback on each of the elements.
- * @param {Array | Matrix} array
- * @param {function} callback The callback method is invoked with one
- * parameter: the current element in the array
- */
- collection.deepForEach = function deepForEach (array, callback) {
- if (array instanceof Matrix) {
- array = array.valueOf();
- }
-
- for (var i = 0, ii = array.length; i < ii; i++) {
- var value = array[i];
-
- if (isArray(value)) {
- deepForEach(value, callback);
- }
- else {
- callback(value);
- }
- }
- };
-
- return collection;
- };
+ module.exports = [
+ __webpack_require__(61),
+ __webpack_require__(91),
+ __webpack_require__(120),
+ __webpack_require__(136),
+ __webpack_require__(148),
+ __webpack_require__(153),
+ __webpack_require__(155),
+ __webpack_require__(15),
+ __webpack_require__(160),
+ __webpack_require__(172),
+ __webpack_require__(178),
+ __webpack_require__(190),
+ __webpack_require__(231),
+ __webpack_require__(233)
+ ];
+
/***/ },
/* 15 */
/***/ function(module, exports, __webpack_require__) {
- 'use strict';
-
- var util = __webpack_require__(175);
- var DimensionError = __webpack_require__(172);
-
- var array = util.array;
- var object = util.object;
- var string = util.string;
- var number = util.number;
-
- var isArray = Array.isArray;
- var isNumber = util.number.isNumber;
- var isInteger = util.number.isInteger;
-
- var validateIndex = array.validateIndex;
-
- module.exports = function (math) {
-
- var Index = math.type.Index,
- BigNumber = math.type.BigNumber,
- Matrix = math.type.Matrix;
-
- function CcsMatrix(data) {
- if (!(this instanceof CcsMatrix))
- throw new SyntaxError('Constructor must be called with the new operator');
-
- if (data instanceof Matrix) {
- // check data is a CcsMatrix
- if (data.type === 'CcsMatrix') {
- // clone arrays
- this._values = object.clone(data._values);
- this._index = object.clone(data._index);
- this._ptr = object.clone(data._ptr);
- this._size = object.clone(data._size);
- }
- else {
- // build from matrix data
- _createFromArray(this, data.valueOf());
- }
- }
- else if (data && isArray(data.values) && isArray(data.index) && isArray(data.ptr) && isArray(data.size)) {
- // initialize fields
- this._values = data.values;
- this._index = data.index;
- this._ptr = data.ptr;
- this._size = data.size;
- }
- else if (isArray(data)) {
- // create from array
- _createFromArray(this, data);
- }
- else if (data) {
- // unsupported type
- throw new TypeError('Unsupported type of data (' + util.types.type(data) + ')');
- }
- else {
- // nothing provided
- this._values = [];
- this._index = [];
- this._ptr = [0];
- this._size = [0];
- }
- }
-
- var _createFromArray = function (matrix, data) {
- // initialize fields
- matrix._values = [];
- matrix._index = [];
- matrix._ptr = [];
- // discover rows & columns, do not use math.size() to avoid looping array twice
- var rows = data.length;
- var columns = 0;
-
- // check we have rows (empty array)
- if (rows > 0) {
- // column index
- var j = 0;
- do {
- // store pointer to values index
- matrix._ptr.push(matrix._values.length);
- // loop rows
- for (var i = 0; i < rows; i++) {
- // current row
- var row = data[i];
- // check row is an array
- if (isArray(row)) {
- // update columns if needed (only on first column)
- if (j ===0 && columns < row.length)
- columns = row.length;
- // check row has column
- if (j < row.length) {
- // value
- var v = row[j];
- // check value != 0
- if (!math.equal(v, 0)) {
- // store value
- matrix._values.push(v);
- // index
- matrix._index.push(i);
- }
- }
- }
- else {
- // update columns if needed (only on first column)
- if (j === 0 && columns < 1)
- columns = 1;
- // check value != 0 (row is a scalar)
- if (!math.equal(row, 0)) {
- // store value
- matrix._values.push(row);
- // index
- matrix._index.push(i);
- }
- }
- }
- // increment index
- j++;
- }
- while (j < columns);
- }
- // store number of values in ptr
- matrix._ptr.push(matrix._values.length);
- // size
- matrix._size = [rows, columns];
- };
-
- CcsMatrix.prototype = new math.type.Matrix();
-
- CcsMatrix.prototype.type = 'CcsMatrix';
-
- /**
- * Get the storage format used by the matrix.
- *
- * Usage:
- * var format = matrix.storage() // retrieve storage format
- *
- * @return {string} The storage format.
- */
- CcsMatrix.prototype.storage = function () {
- return 'ccs';
- };
-
- /**
- * Get a subset of the matrix, or replace a subset of the matrix.
- *
- * Usage:
- * var subset = matrix.subset(index) // retrieve subset
- * var value = matrix.subset(index, replacement) // replace subset
- *
- * @param {Index} index
- * @param {Array | Maytrix | *} [replacement]
- * @param {*} [defaultValue=0] Default value, filled in on new entries when
- * the matrix is resized. If not provided,
- * new matrix elements will be filled with zeros.
- */
- CcsMatrix.prototype.subset = function (index, replacement, defaultValue) {
- // check arguments
- switch (arguments.length) {
- case 1:
- return _getsubset(this, index);
-
- // intentional fall through
- case 2:
- case 3:
- return _setsubset(this, index, replacement, defaultValue);
-
- default:
- throw new SyntaxError('Wrong number of arguments');
- }
- };
-
- var _getsubset = function (matrix, index) {
- // check index
- if (!(index instanceof Index)) {
- throw new TypeError('Invalid index');
- }
-
- var isScalar = index.isScalar();
- if (isScalar) {
- // return a scalar
- return matrix.get(index.min());
- }
- // validate dimensions
- var size = index.size();
- if (size.length != matrix._size.length) {
- throw new DimensionError(size.length, matrix._size.length);
- }
-
- // validate if any of the ranges in the index is out of range
- var min = index.min();
- var max = index.max();
- for (var i = 0, ii = matrix._size.length; i < ii; i++) {
- validateIndex(min[i], matrix._size[i]);
- validateIndex(max[i], matrix._size[i]);
- }
-
- // map callback
- var callback = function (v) {
- // return value
- return v;
- };
- // get sub-matrix
- return _map(matrix, min[0], max[0], min[1], max[1], callback, false);
- };
-
- var _setsubset = function (matrix, index, submatrix, defaultValue) {
- // check index
- if (!(index instanceof Index)) {
- throw new TypeError('Invalid index');
- }
-
- // get index size and check whether the index contains a single value
- var iSize = index.size(),
- isScalar = index.isScalar();
-
- // calculate the size of the submatrix, and convert it into an Array if needed
- var sSize;
- if (submatrix instanceof Matrix) {
- // submatrix size
- sSize = submatrix.size();
- // use array representation
- submatrix = submatrix.toArray();
- }
- else {
- // get submatrix size (array, scalar)
- sSize = array.size(submatrix);
- }
-
- // check index is a scalar
- if (isScalar) {
- // verify submatrix is a scalar
- if (sSize.length !== 0) {
- throw new TypeError('Scalar expected');
- }
- // set value
- matrix.set(index.min(), submatrix, defaultValue);
- }
- else {
- // validate dimensions, index size must be one or two dimensions
- if (iSize.length !== 1 && iSize.length !== 2) {
- throw new DimensionError(iSize.length, matrix._size.length, '<');
- }
-
- // check submatrix and index have the same dimensions
- if (sSize.length < iSize.length) {
- // calculate number of missing outer dimensions
- var i = 0;
- var outer = 0;
- while (iSize[i] === 1 && sSize[i] === 1) {
- i++;
- }
- while (iSize[i] === 1) {
- outer++;
- i++;
- }
- // unsqueeze both outer and inner dimensions
- submatrix = array.unsqueeze(submatrix, iSize.length, outer, sSize);
- }
-
- // check whether the size of the submatrix matches the index size
- if (!object.deepEqual(iSize, sSize)) {
- throw new DimensionError(iSize, sSize, '>');
- }
-
- // offsets
- var x0 = index.min()[0];
- var y0 = index.min()[1];
-
- // submatrix rows and columns
- var m = sSize[0];
- var n = sSize[1];
-
- // loop submatrix
- for (var x = 0; x < m; x++) {
- // loop columns
- for (var y = 0; y < n; y++) {
- // value at i, j
- var v = submatrix[x][y];
- // invoke set (zero value will remove entry from matrix)
- matrix.set([x + x0, y + y0], v, defaultValue);
- }
- }
- }
- return matrix;
- };
-
- /**
- * Get a single element from the matrix.
- * @param {Number[]} index Zero-based index
- * @return {*} value
- */
- CcsMatrix.prototype.get = function (index) {
- if (!isArray(index))
- throw new TypeError('Array expected');
- if (index.length != this._size.length)
- throw new DimensionError(index.length, this._size.length);
-
- // row and column
- var i = index[0];
- var j = index[1];
-
- // check i, j are valid
- validateIndex(i, this._size[0]);
- validateIndex(j, this._size[1]);
-
- // find value index
- var k = _getValueIndex(i, this._ptr[j], this._ptr[j + 1], this._index);
- // check k is prior to next column k and it is in the correct row
- if (k < this._ptr[j + 1] && this._index[k] === i)
- return object.clone(this._values[k]);
-
- return 0;
- };
-
- /**
- * Replace a single element in the matrix.
- * @param {Number[]} index Zero-based index
- * @param {*} value
- * @param {*} [defaultValue] Default value, filled in on new entries when
- * the matrix is resized. If not provided,
- * new matrix elements will be set to zero.
- * @return {CcsMatrix} self
- */
- CcsMatrix.prototype.set = function (index, v, defaultValue) {
- if (!isArray(index))
- throw new TypeError('Array expected');
- if (index.length != this._size.length)
- throw new DimensionError(index.length, this._size.length);
-
- // row and column
- var i = index[0];
- var j = index[1];
-
- // rows & columns
- var rows = this._size[0];
- var columns = this._size[1];
-
- // check we need to resize matrix
- if (i > rows - 1 || j > columns - 1) {
- // resize matrix
- _resize(this, Math.max(i + 1, rows), Math.max(j + 1, columns), defaultValue);
- // update rows & columns
- rows = this._size[0];
- columns = this._size[1];
- }
-
- // check i, j are valid
- validateIndex(i, rows);
- validateIndex(j, columns);
-
- // find value index
- var k = _getValueIndex(i, this._ptr[j], this._ptr[j + 1], this._index);
- // check k is prior to next column k and it is in the correct row
- if (k < this._ptr[j + 1] && this._index[k] === i) {
- // check value != 0
- if (!math.equal(v, 0)) {
- // update value
- this._values[k] = v;
- }
- else {
- // remove value from matrix
- _remove(k, j, this._values, this._index, this._ptr);
- }
- }
- else {
- // insert value @ (i, j)
- _insert(k, i, j, v, this._values, this._index, this._ptr);
- }
-
- return this;
- };
-
- var _getValueIndex = function(i, top, bottom, index) {
- // check row is on the bottom side
- if (bottom - top === 0 || i > index[bottom - 1])
- return bottom;
- // loop until we find row index
- while (top < bottom) {
- // point in the middle (fast integer division)
- var p = ~~((top + bottom) / 2);
- // row @ p
- var r = index[p];
- // check we have to look on the top side, bottom side or we found the row
- if (i < r)
- bottom = p;
- else if (i > r)
- top = p + 1;
- else
- return p;
- }
- return top;
- };
-
- var _remove = function (k, j, values, index, ptr) {
- // remove value @ k
- values.splice(k, 1);
- index.splice(k, 1);
- // update pointers
- for (var x = j + 1; x < ptr.length; x++)
- ptr[x]--;
- };
-
- var _insert = function (k, i, j, v, values, index, ptr) {
- // insert value
- values.splice(k, 0, v);
- // update row for k
- index.splice(k, 0, i);
- // update column pointers
- for (var x = j + 1; x < ptr.length; x++)
- ptr[x]++;
- };
-
- /**
- * Resize the matrix to the given size. Returns a copy of the matrix when
- * `copy=true`, otherwise return the matrix itself (resize in place).
- *
- * @param {Number[]} size The new size the matrix should have.
- * @param {*} [defaultValue=0] Default value, filled in on new entries.
- * If not provided, the matrix elements will
- * be filled with zeros.
- * @param {boolean} [copy] Return a resized copy of the matrix
- *
- * @return {Matrix} The resized matrix
- */
- CcsMatrix.prototype.resize = function (size, defaultValue, copy) {
- // validate arguments
- if (!isArray(size))
- throw new TypeError('Array expected');
- if (size.length !== 2)
- throw new Error('Only two dimensions matrix are supported');
-
- // check sizes
- 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) + ')');
- }
- });
-
- // matrix to resize
- var m = copy ? this.clone() : this;
- // resize matrix
- return _resize(m, size[0], size[1], defaultValue);
- };
-
- var _resize = function (matrix, rows, columns, defaultValue) {
- // value to insert at the time of growing matrix
- var value = defaultValue || 0;
- // should we insert the value?
- var ins = !math.equal(value, 0);
-
- // old columns and rows
- var r = matrix._size[0];
- var c = matrix._size[1];
-
- var i, j, k;
-
- // check we need to increase columns
- if (columns > c) {
- // loop new columns
- for (j = c; j < columns; j++) {
- // update matrix._ptr for current column
- matrix._ptr[j] = matrix._values.length;
- // check we need to insert matrix._values
- if (ins) {
- // loop rows
- for (i = 0; i < r; i++) {
- // add new matrix._values
- matrix._values.push(value);
- // update matrix._index
- matrix._index.push(i);
- }
- }
- }
- // store number of matrix._values in matrix._ptr
- matrix._ptr[columns] = matrix._values.length;
- }
- else if (columns < c) {
- // truncate matrix._ptr
- matrix._ptr.splice(columns + 1, c - columns);
- // truncate matrix._values and matrix._index
- matrix._values.splice(matrix._ptr[columns], matrix._values.length);
- matrix._index.splice(matrix._ptr[columns], matrix._index.length);
- }
- // update columns
- c = columns;
-
- // check we need to increase rows
- if (rows > r) {
- // check we have to insert values
- if (ins) {
- // inserts
- var n = 0;
- // loop columns
- for (j = 0; j < c; j++) {
- // update matrix._ptr for current column
- matrix._ptr[j] = matrix._ptr[j] + n;
- // where to insert matrix._values
- k = matrix._ptr[j + 1] + n;
- // pointer
- var p = 0;
- // loop new rows, initialize pointer
- for (i = r; i < rows; i++, p++) {
- // add value
- matrix._values.splice(k + p, 0, value);
- // update matrix._index
- matrix._index.splice(k + p, 0, i);
- // increment inserts
- n++;
- }
- }
- // store number of matrix._values in matrix._ptr
- matrix._ptr[c] = matrix._values.length;
- }
- }
- else if (rows < r) {
- // deletes
- var d = 0;
- // loop columns
- for (j = 0; j < c; j++) {
- // update matrix._ptr for current column
- matrix._ptr[j] = matrix._ptr[j] - d;
- // where matrix._values start for next column
- var k0 = matrix._ptr[j];
- var k1 = matrix._ptr[j + 1] - d;
- // loop matrix._index
- for (k = k0; k < k1; k++) {
- // row
- i = matrix._index[k];
- // check we need to delete value and matrix._index
- if (i > rows - 1) {
- // remove value
- matrix._values.splice(k, 1);
- // remove item from matrix._index
- matrix._index.splice(k, 1);
- // increase deletes
- d++;
- }
- }
- }
- // update matrix._ptr for current column
- matrix._ptr[j] = matrix._values.length;
- }
- // update matrix._size
- matrix._size[0] = rows;
- matrix._size[1] = columns;
- // return matrix
- return matrix;
- };
-
- /**
- * Create a clone of the matrix
- * @return {CcsMatrix} clone
- */
- CcsMatrix.prototype.clone = function () {
- var m = new CcsMatrix({
- values: object.clone(this._values),
- index: object.clone(this._index),
- ptr: object.clone(this._ptr),
- size: object.clone(this._size)
- });
- return m;
- };
-
- /**
- * Retrieve the size of the matrix.
- * @returns {Number[]} size
- */
- CcsMatrix.prototype.size = function() {
- return object.clone(this._size);
- };
-
- /**
- * Create a new matrix with the results of the callback function executed on
- * each entry of the matrix.
- * @param {function} callback The callback function is invoked with three
- * parameters: the value of the element, the index
- * of the element, and the Matrix being traversed.
- * @param {boolean} [skipZeros] Invoke callback function for non-zero values only.
- *
- * @return {CcsMatrix} matrix
- */
- CcsMatrix.prototype.map = function (callback, skipZeros) {
- // matrix instance
- var me = this;
- // rows and columns
- var rows = this._size[0];
- var columns = this._size[1];
- // invoke callback
- var invoke = function (v, i, j) {
- // invoke callback
- return callback(v, [i, j], me);
- };
- // invoke _map
- return _map(this, 0, rows - 1, 0, columns - 1, invoke, skipZeros);
- };
-
- /**
- * Create a new matrix with the results of the callback function executed on the interval
- * [minRow..maxRow, minColumn..maxColumn].
- */
- var _map = function (matrix, minRow, maxRow, minColumn, maxColumn, callback, skipZeros) {
- // result arrays
- var values = [];
- var index = [];
- var ptr = [];
- // invoke callback
- var invoke = function (v, x, y) {
- // invoke callback
- v = callback(v, x, y);
- // check value != 0
- if (!math.equal(v, 0)) {
- // store value
- values.push(v);
- // index
- index.push(x);
- }
- };
- // loop columns
- for (var j = minColumn; j <= maxColumn; j++) {
- // store pointer to values index
- ptr.push(values.length);
- // k0 <= k < k1 where k0 = _ptr[j] && k1 = _ptr[j+1]
- var k0 = matrix._ptr[j];
- var k1 = matrix._ptr[j + 1];
- // row pointer
- var p = minRow;
- // loop k within [k0, k1[
- for (var k = k0; k < k1; k++) {
- // row index
- var i = matrix._index[k];
- // check i is in range
- if (i >= minRow && i <= maxRow) {
- // zero values
- if (!skipZeros) {
- for (var x = p; x < i; x++)
- invoke(0, x - minRow, j - minColumn);
- }
- // value @ k
- invoke(matrix._values[k], i - minRow, j - minColumn);
- }
- // update pointer
- p = i + 1;
- }
- // zero values
- if (!skipZeros) {
- for (var y = p; y <= maxRow; y++)
- invoke(0, y - minRow, j - minColumn);
- }
- }
- // store number of values in ptr
- ptr.push(values.length);
- // return ccs
- return new CcsMatrix({
- values: values,
- index: index,
- ptr: ptr,
- size: [maxRow - minRow + 1, maxColumn - minColumn + 1]
- });
- };
-
- /**
- * Execute a callback function on each entry of the matrix.
- * @param {function} callback The callback function is invoked with three
- * parameters: the value of the element, the index
- * of the element, and the Matrix being traversed.
- * @param {boolean} [skipZeros] Invoke callback function for non-zero values only.
- */
- CcsMatrix.prototype.forEach = function (callback, skipZeros) {
- // matrix instance
- var me = this;
- // rows and columns
- var rows = this._size[0];
- var columns = this._size[1];
- // loop columns
- for (var j = 0; j < columns; j++) {
- // k0 <= k < k1 where k0 = _ptr[j] && k1 = _ptr[j+1]
- var k0 = this._ptr[j];
- var k1 = this._ptr[j + 1];
- // column pointer
- var p = 0;
- // loop k within [k0, k1[
- for (var k = k0; k < k1; k++) {
- // row index
- var i = this._index[k];
- // check we need to process zeros
- if (!skipZeros) {
- // zero values
- for (var x = p; x < i; x++)
- callback(0, [x, j], me);
- }
- // value @ k
- callback(this._values[k], [i, j], me);
- // update pointer
- p = i + 1;
- }
- // check we need to process zeros
- if (!skipZeros) {
- // zero values
- for (var y = p; y < rows; y++)
- callback(0, [y, j], me);
- }
- }
- };
-
- /**
- * Create an Array with a copy of the data of the CcsMatrix
- * @returns {Array} array
- */
- CcsMatrix.prototype.toArray = function () {
- return _toArray(this, true);
- };
-
- /**
- * Get the primitive value of the CcsMatrix: a two dimensions array
- * @returns {Array} array
- */
- CcsMatrix.prototype.valueOf = function () {
- return _toArray(this, false);
- };
-
- var _toArray = function (matrix, copy) {
- // result
- var a = [];
- // rows and columns
- var rows = matrix._size[0];
- var columns = matrix._size[1];
- // loop columns
- for (var j = 0; j < columns; j++) {
- // k0 <= k < k1 where k0 = _ptr[j] && k1 = _ptr[j+1]
- var k0 = matrix._ptr[j];
- var k1 = matrix._ptr[j + 1];
- // row pointer
- var p = 0;
- // loop k within [k0, k1[
- for (var k = k0; k < k1; k++) {
- // row index
- var i = matrix._index[k];
- // zeros
- for (var x = p; x < i; x++)
- (a[x] = (a[x] || []))[j] = 0;
- // set value
- (a[i] = (a[i] || []))[j] = copy ? object.clone(matrix._values[k]) : matrix._values[k];
- // update pointer
- p = i + 1;
- }
- // zero values
- for (var y = p; y < rows; y++)
- (a[y] = (a[y] || []))[j] = 0;
- }
- return a;
- };
-
- /**
- * Get a string representation of the matrix, with optional formatting options.
- * @param {Object | Number | Function} [options] Formatting options. See
- * lib/util/number:format for a
- * description of the available
- * options.
- * @returns {String} str
- */
- CcsMatrix.prototype.format = function (options) {
- // rows and columns
- var rows = this._size[0];
- var columns = this._size[1];
- // rows & columns
- var str = 'CCS [' + string.format(rows, options) + ' x ' + string.format(columns, options) + '] density: ' + string.format(this._values.length / (rows * columns), options) + '\n';
- // loop columns
- for (var j = 0; j < columns; j++) {
- // k0 <= k < k1 where k0 = _ptr[j] && k1 = _ptr[j+1]
- var k0 = this._ptr[j];
- var k1 = this._ptr[j + 1];
- // loop k within [k0, k1[
- for (var k = k0; k < k1; k++) {
- // row index
- var i = this._index[k];
- // append value
- str += '\n (' + string.format(i, options) + ', ' + string.format(j, options) + ') ==> ' + string.format(this._values[k], options);
- }
- }
- return str;
- };
-
- /**
- * Get a string representation of the matrix
- * @returns {String} str
- */
- CcsMatrix.prototype.toString = function () {
- return string.format(this.toArray());
- };
-
- /**
- * Get a JSON representation of the matrix
- * @returns {Object}
- */
- CcsMatrix.prototype.toJSON = function () {
- return {
- mathjs: 'CcsMatrix',
- values: this._values,
- index: this._index,
- ptr: this._ptr,
- size: this._size
- };
- };
-
- /**
- * Calculates the transpose of the matrix
- * @returns {Matrix}
- */
- CcsMatrix.prototype.transpose = function () {
- // rows and columns
- var rows = this._size[0];
- var columns = this._size[1];
- // check columns
- if (columns === 0) {
- // throw exception
- throw new RangeError('Cannot transpose a 2D matrix with no columns (size: ' + string.format(this._size) + ')');
- }
- // ccs transpose is a crs matrix with the same structure
- return new math.type.CrsMatrix({
- values: object.clone(this._values),
- index: object.clone(this._index),
- ptr: object.clone(this._ptr),
- size: [columns, rows]
- });
- };
-
- /**
- * Get the kth Matrix diagonal.
- *
- * @param {Number | BigNumber} [k=0] The kth diagonal where the vector will retrieved.
- *
- * @returns {Array} The array vector with the diagonal values.
- */
- CcsMatrix.prototype.diagonal = function(k) {
- // validate k if any
- if (k) {
- // convert BigNumber to a number
- if (k instanceof BigNumber)
- k = k.toNumber();
- // is must be an integer
- if (!isNumber(k) || !isInteger(k)) {
- throw new TypeError ('The parameter k must be an integer number');
- }
- }
- else {
- // default value
- k = 0;
- }
-
- var kSuper = k > 0 ? k : 0;
- var kSub = k < 0 ? -k : 0;
-
- // rows & columns
- var rows = this._size[0];
- var columns = this._size[1];
-
- // number diagonal values
- var n = Math.min(rows - kSub, columns - kSuper);
-
- // diagonal
- var values = [];
- // loop columns
- for (var j = kSuper; j < columns && values.length < n; j++) {
- // k0 <= k < k1 where k0 = _ptr[j] && k1 = _ptr[j+1]
- var k0 = this._ptr[j];
- var k1 = this._ptr[j + 1];
- // column value flag
- var cv = false;
- // loop x within [k0, k1[
- for (var x = k0; x < k1; x++) {
- // row index
- var i = this._index[x];
- // check row
- if (i === j - kSuper + kSub) {
- // set flag
- cv = true;
- // value on this column
- values.push(object.clone(this._values[x]));
- // exit loop
- break;
- }
- else if (i > j - kSuper + kSub) {
- // exit loop, no value on the diagonal for column j
- break;
- }
- }
- // check this column has a value set
- if (!cv && values.length < n) {
- // zero on this column
- values.push(0);
- }
- }
- return values;
- };
-
- /**
- * Generate a matrix from a JSON object
- * @param {Object} json An object structured like
- * `{"mathjs": "CcsMatrix", "values": [], "index": [], "ptr": [], "size": []}`,
- * where mathjs is optional
- * @returns {CcsMatrix}
- */
- CcsMatrix.fromJSON = function (json) {
- return new CcsMatrix(json);
- };
-
- /**
- * Create a diagonal matrix.
- *
- * @param {Array} size The matrix size.
- * @param {Number, Array} value The values for the diagonal.
- * @param {Number | BigNumber} [k=0] The kth diagonal where the vector will be filled in.
- *
- * @returns {CcsMatrix}
- */
- CcsMatrix.diagonal = function (size, value, k) {
- if (!isArray(size))
- throw new TypeError('Array expected, size parameter');
- if (size.length !== 2)
- throw new Error('Only two dimensions matrix are supported');
-
- // map size & validate
- size = size.map(function (s) {
- // check it is a big number
- if (s instanceof BigNumber) {
- // convert it
- s = s.toNumber();
- }
- // validate arguments
- if (!isNumber(s) || !isInteger(s) || s < 1) {
- throw new Error('Size values must be positive integers');
- }
- return s;
- });
-
- // validate k if any
- if (k) {
- // convert BigNumber to a number
- if (k instanceof BigNumber)
- k = k.toNumber();
- // is must be an integer
- if (!isNumber(k) || !isInteger(k)) {
- throw new TypeError ('The parameter k must be an integer number');
- }
- }
- else {
- // default value
- k = 0;
- }
-
- var kSuper = k > 0 ? k : 0;
- var kSub = k < 0 ? -k : 0;
-
- // rows and columns
- var rows = size[0];
- var columns = size[1];
-
- // number of non-zero items
- var n = Math.min(rows - kSub, columns - kSuper);
-
- // value extraction function
- var _value;
-
- // check value
- if (isArray(value)) {
- // validate array
- if (value.length !== n) {
- // number of values in array must be n
- throw new Error('Invalid value array length');
- }
- // define function
- _value = function (i) {
- // return value @ i
- return value[i];
- };
- }
- else {
- // define function
- _value = function () {
- // return value
- return value;
- };
- }
-
- // create arrays
- var values = [];
- var index = [];
- var ptr = [];
-
- // loop items
- for (var j = 0; j < columns; j++) {
- // number of rows with value
- ptr.push(values.length);
- // diagonal index
- var i = j - kSuper;
- // check we need to set diagonal value
- if (i >= 0 && i < n) {
- // get value @ i
- var v = _value(i);
- // check for zero
- if (!math.equal(v, 0)) {
- // column
- index.push(i + kSub);
- // add value
- values.push(v);
- }
- }
- }
- // last value should be number of values
- ptr.push(values.length);
- // create CcsMatrix
- return new CcsMatrix({
- values: values,
- index: index,
- ptr: ptr,
- size: [rows, columns]
- });
- };
-
- /**
- * Calculate the trace of a matrix: the sum of the elements on the main
- * diagonal of a square matrix.
- *
- * See also:
- *
- * diagonal
- *
- * @returns {Number} The matrix trace
- */
- CcsMatrix.prototype.trace = function () {
- // size
- var size = this._size;
- // check dimensions
- var rows = size[0];
- var columns = size[1];
- // matrix must be square
- if (rows === columns) {
- // calulate sum
- var sum = 0;
- // check we have data (avoid looping columns)
- if (this._values.length > 0) {
- // loop columns
- for (var j = 0; j < columns; j++) {
- // k0 <= k < k1 where k0 = _ptr[j] && k1 = _ptr[j+1]
- var k0 = this._ptr[j];
- var k1 = this._ptr[j + 1];
- // loop k within [k0, k1[
- for (var k = k0; k < k1; k++) {
- // row index
- var i = this._index[k];
- // check row
- if (i === j) {
- // accumulate value
- sum = math.add(sum, this._values[k]);
- // exit loop
- break;
- }
- if (i > j) {
- // exit loop, no value on the diagonal for column j
- break;
- }
- }
- }
- }
- // return trace
- return sum;
- }
- throw new RangeError('Matrix must be square (size: ' + string.format(size) + ')');
- };
-
- /**
- * Multiply the matrix values times the argument.
- *
- * @param {Number | BigNumber | Boolean | Complex | Unit | Array | Matrix | null} Value to multiply.
- *
- * @return {Number | BigNumber | Complex | Unit | Matrix}
- */
- CcsMatrix.prototype.multiply = function (value) {
- // check dimensions
- var rows = this._size[0];
- var columns = this._size[1];
-
- // check value is a matrix
- if (value instanceof Matrix) {
- // matrix size
- var z = value.size();
- // check value is a vector
- if (z.length === 1) {
- // mutiply matrix x vector array
- return _multiply(this, z[0], 1, function (i) {
- // value[i]
- return value.get([i]);
- });
- }
- // check two dimensions matrix
- if (z.length === 2) {
- // mutiply matrix x matrix
- return _multiply(this, z[0], z[1], function (i, j) {
- // value[i, j]
- return value.get([i, j]);
- });
- }
- throw new Error('Can only multiply a 1 or 2 dimensional matrix ' +
- '(value has ' + z.length + ' dimensions)');
- }
-
- // check value is an array
- if (isArray(value)) {
- // array size
- var s = array.size(value);
- // check value is a vector
- if (s.length === 1) {
- // mutiply matrix x vector array
- return _multiply(this, s[0], 1, function (i) {
- // value[i]
- return value[i];
- });
- }
- if (s.length === 2) {
- // mutiply matrix x array
- return _multiply(this, s[0], s[1], function (i, j) {
- // value[i, j]
- return value[i][j];
- });
- }
- throw new Error('Can only multiply a 1 or 2 dimensional matrix ' +
- '(value has ' + s.length + ' dimensions)');
- }
-
- var callback = function (v) {
- return math.multiply(v, value);
- };
-
- // map non zero elements
- return _map(this, 0, rows - 1, 0, columns - 1, callback, false);
- };
-
- var _multiply = function (matrix, r, c, get) {
-
- // matrix dimensions
- var rows = matrix._size[0];
- var columns = matrix._size[1];
-
- // check dimensions match
- if (columns !== r) {
- // throw error
- throw new RangeError('Dimension mismatch in multiplication. ' +
- 'Columns of A must match length of B ' +
- '(A is ' + rows + 'x' + columns +
- ', B is ' + r + ', ' +
- columns + ' != ' + r + ')');
- }
-
- // result arrays
- var values = [];
- var index = [];
- var ptr = [];
-
- // create array with rows entries
- var data = [];
- for (var x = 0; x < rows; x++)
- data[x] = 0;
- // loop value columns
- for (var z = 0; z < c; z++) {
- // update ptr
- ptr.push(values.length);
- // do not traverse rows in matrix, it is not efficient in CCS
- for (var j = 0; j < columns; j++) {
- // k0 <= k < k1 where k0 = _ptr[j] && k1 = _ptr[j+1]
- var k0 = matrix._ptr[j];
- var k1 = matrix._ptr[j + 1];
- // loop k within [k0, k1[
- for (var k = k0; k < k1; k++) {
- // row
- var i = matrix._index[k];
- // multiply & aggregate
- data[i] = math.add(data[i], math.multiply(matrix._values[k], get(j, z)));
- }
- }
- // finished processing column z, compress results
- for (var y = 0; y < rows; y++) {
- // check value is different than zero
- if (!math.equal(data[y], 0)) {
- // push value
- values.push(data[y]);
- index.push(y);
- }
- // reset value
- data[y] = 0;
- }
- }
- // update ptr
- ptr.push(values.length);
-
- // check we need to squeeze the result into a scalar
- if (rows === 1 && c === 1)
- return values.length === 1 ? values[0] : 0;
-
- // return CCS matrix
- return new CcsMatrix({
- values: values,
- index: index,
- ptr: ptr,
- size: [rows, c]
- });
- };
-
- return CcsMatrix;
- };
+ module.exports = [
+ __webpack_require__(16),
+ __webpack_require__(24),
+ __webpack_require__(43),
+ __webpack_require__(46),
+ __webpack_require__(47),
+ __webpack_require__(48),
+ __webpack_require__(49),
+ __webpack_require__(50),
+ __webpack_require__(52),
+ __webpack_require__(53),
+ __webpack_require__(54),
+ __webpack_require__(55),
+ __webpack_require__(56),
+ __webpack_require__(57),
+ __webpack_require__(58),
+ __webpack_require__(59),
+ __webpack_require__(60)
+ ];
+
/***/ },
/* 16 */
@@ -4996,2262 +2977,204 @@
'use strict';
- var util = __webpack_require__(175);
- var DimensionError = __webpack_require__(172);
-
- var array = util.array;
- var object = util.object;
- var string = util.string;
- var number = util.number;
-
- var isArray = Array.isArray;
- var isNumber = util.number.isNumber;
- var isInteger = util.number.isInteger;
-
- var validateIndex = array.validateIndex;
-
- module.exports = function (math) {
-
- var Index = math.type.Index,
- BigNumber = math.type.BigNumber,
- Matrix = math.type.Matrix;
-
- function CrsMatrix(data) {
- if (!(this instanceof CrsMatrix))
- throw new SyntaxError('Constructor must be called with the new operator');
-
- if (data instanceof Matrix) {
- // check data is a CrsMatrix
- if (data.type === 'CrsMatrix') {
- // clone arrays
- this._values = object.clone(data._values);
- this._index = object.clone(data._index);
- this._ptr = object.clone(data._ptr);
- this._size = object.clone(data._size);
- }
- else {
- // build from matrix data
- _createFromArray(this, data.valueOf());
- }
- }
- else if (data && isArray(data.values) && isArray(data.index) && isArray(data.ptr) && isArray(data.size)) {
- // initialize fields
- this._values = data.values;
- this._index = data.index;
- this._ptr = data.ptr;
- this._size = data.size;
- }
- else if (isArray(data)) {
- // create from array
- _createFromArray(this, data);
- }
- else if (data) {
- // unsupported type
- throw new TypeError('Unsupported type of data (' + util.types.type(data) + ')');
- }
- else {
- // nothing provided
- this._values = [];
- this._index = [];
- this._ptr = [0];
- this._size = [0];
- }
- }
-
- var _createFromArray = function (matrix, data) {
- // initialize fields
- matrix._values = [];
- matrix._index = [];
- matrix._ptr = [];
- // discover rows & columns, do not use math.size() to avoid looping array twice
- var rows = data.length;
- var columns = 0;
-
- // loop rows
- for (var i = 0; i < rows; i++) {
- // store value index in ptr
- matrix._ptr.push(matrix._values.length);
- // current row
- var row = data[i];
- // check row is an array
- if (isArray(row)) {
- // update columns if needed
- if (row.length > columns)
- columns = row.length;
- // loop columns
- for (var j = 0; j < row.length; j++) {
- // value at data[i][j]
- var v = row[j];
- // check value != 0
- if (!math.equal(v, 0)) {
- // store value
- matrix._values.push(v);
- // add column index
- matrix._index.push(j);
- }
- }
- }
- else {
- // update columns if needed (only on first row)
- if (i === 0 && columns < 1)
- columns = 1;
- // check value != 0 (row is a scalar)
- if (!math.equal(row, 0)) {
- // store value
- matrix._values.push(row);
- // index
- matrix._index.push(0);
- }
- }
- }
- // store number of values in ptr
- matrix._ptr.push(matrix._values.length);
- // size
- matrix._size = [rows, columns];
- };
-
- CrsMatrix.prototype = new math.type.Matrix();
-
- CrsMatrix.prototype.type = 'CrsMatrix';
-
- /**
- * Get the storage format used by the matrix.
- *
- * Usage:
- * var format = matrix.storage() // retrieve storage format
- *
- * @return {string} The storage format.
- */
- CrsMatrix.prototype.storage = function () {
- return 'crs';
- };
-
- /**
- * Get a subset of the matrix, or replace a subset of the matrix.
- *
- * Usage:
- * var subset = matrix.subset(index) // retrieve subset
- * var value = matrix.subset(index, replacement) // replace subset
- *
- * @param {Index} index
- * @param {Array | Maytrix | *} [replacement]
- * @param {*} [defaultValue=0] Default value, filled in on new entries when
- * the matrix is resized. If not provided,
- * new matrix elements will be filled with zeros.
- */
- CrsMatrix.prototype.subset = function (index, replacement, defaultValue) {
- // check arguments
- switch (arguments.length) {
- case 1:
- return _getsubset(this, index);
-
- // intentional fall through
- case 2:
- case 3:
- return _setsubset(this, index, replacement, defaultValue);
-
- default:
- throw new SyntaxError('Wrong number of arguments');
- }
- };
-
- var _getsubset = function (matrix, index) {
- // check index
- if (!(index instanceof Index)) {
- throw new TypeError('Invalid index');
- }
-
- var isScalar = index.isScalar();
- if (isScalar) {
- // return a scalar
- return matrix.get(index.min());
- }
- // validate dimensions
- var size = index.size();
- if (size.length != matrix._size.length) {
- throw new DimensionError(size.length, matrix._size.length);
- }
-
- // validate if any of the ranges in the index is out of range
- var min = index.min();
- var max = index.max();
- for (var i = 0, ii = matrix._size.length; i < ii; i++) {
- validateIndex(min[i], matrix._size[i]);
- validateIndex(max[i], matrix._size[i]);
- }
-
- // map callback
- var callback = function (v) {
- // return value
- return v;
- };
- // get sub-matrix
- return _map(matrix, min[0], max[0], min[1], max[1], callback, false);
- };
-
- var _setsubset = function (matrix, index, submatrix, defaultValue) {
- // check index
- if (!(index instanceof Index)) {
- throw new TypeError('Invalid index');
- }
-
- // get index size and check whether the index contains a single value
- var iSize = index.size(),
- isScalar = index.isScalar();
-
- // calculate the size of the submatrix, and convert it into an Array if needed
- var sSize;
- if (submatrix instanceof Matrix) {
- // submatrix size
- sSize = submatrix.size();
- // use array representation
- submatrix = submatrix.toArray();
- }
- else {
- // get submatrix size (array, scalar)
- sSize = array.size(submatrix);
- }
-
- // check index is a scalar
- if (isScalar) {
- // verify submatrix is a scalar
- if (sSize.length !== 0) {
- throw new TypeError('Scalar expected');
- }
- // set value
- matrix.set(index.min(), submatrix, defaultValue);
- }
- else {
- // validate dimensions, index size must be one or two dimensions
- if (iSize.length !== 1 && iSize.length !== 2) {
- throw new DimensionError(iSize.length, matrix._size.length, '<');
- }
-
- // check submatrix and index have the same dimensions
- if (sSize.length < iSize.length) {
- // calculate number of missing outer dimensions
- var i = 0;
- var outer = 0;
- while (iSize[i] === 1 && sSize[i] === 1) {
- i++;
- }
- while (iSize[i] === 1) {
- outer++;
- i++;
- }
- // unsqueeze both outer and inner dimensions
- submatrix = array.unsqueeze(submatrix, iSize.length, outer, sSize);
- }
-
- // check whether the size of the submatrix matches the index size
- if (!object.deepEqual(iSize, sSize)) {
- throw new DimensionError(iSize, sSize, '>');
- }
-
- // offsets
- var x0 = index.min()[0];
- var y0 = index.min()[1];
-
- // submatrix rows and columns
- var m = sSize[0];
- var n = sSize[1];
-
- // loop submatrix
- for (var x = 0; x < m; x++) {
- // loop columns
- for (var y = 0; y < n; y++) {
- // value at i, j
- var v = submatrix[x][y];
- // invoke set (zero value will remove entry from matrix)
- matrix.set([x + x0, y + y0], v, defaultValue);
- }
- }
- }
- return matrix;
- };
-
- /**
- * Get a single element from the matrix.
- * @param {Number[]} index Zero-based index
- * @return {*} value
- */
- CrsMatrix.prototype.get = function (index) {
- if (!isArray(index))
- throw new TypeError('Array expected');
- if (index.length != this._size.length)
- throw new DimensionError(index.length, this._size.length);
-
- // row and column
- var i = index[0];
- var j = index[1];
-
- // check i, j are valid
- validateIndex(i, this._size[0]);
- validateIndex(j, this._size[1]);
-
- // find value index
- var k = _getValueIndex(j, this._ptr[i], this._ptr[i + 1], this._index);
- // check k is prior to next row k and it is in the correct row
- if (k < this._ptr[i + 1] && this._index[k] === j)
- return object.clone(this._values[k]);
-
- return 0;
- };
-
- /**
- * Replace a single element in the matrix.
- * @param {Number[]} index Zero-based index
- * @param {*} value
- * @param {*} [defaultValue] Default value, filled in on new entries when
- * the matrix is resized. If not provided,
- * new matrix elements will be set to zero.
- * @return {CrsMatrix} self
- */
- CrsMatrix.prototype.set = function (index, v, defaultValue) {
- if (!isArray(index))
- throw new TypeError('Array expected');
- if (index.length != this._size.length)
- throw new DimensionError(index.length, this._size.length);
-
- // row and column
- var i = index[0];
- var j = index[1];
-
- // rows & columns
- var rows = this._size[0];
- var columns = this._size[1];
-
- // check we need to resize matrix
- if (i > rows - 1 || j > columns - 1) {
- // resize matrix
- _resize(this, Math.max(i + 1, rows), Math.max(j + 1, columns), defaultValue);
- // update rows & columns
- rows = this._size[0];
- columns = this._size[1];
- }
-
- // check i, j are valid
- validateIndex(i, rows);
- validateIndex(j, columns);
-
- // find value index
- var k = _getValueIndex(j, this._ptr[i], this._ptr[i + 1], this._index);
- // check k is prior to next row k and it is in the correct column
- if (k < this._ptr[i + 1] && this._index[k] === j) {
- // check value != 0
- if (!math.equal(v, 0)) {
- // update value
- this._values[k] = v;
- }
- else {
- // remove value from matrix
- _remove(k, i, this._values, this._index, this._ptr);
- }
- }
- else {
- // insert value @ (i, j)
- _insert(k, i, j, v, this._values, this._index, this._ptr);
- }
-
- return this;
- };
-
- var _getValueIndex = function(j, left, right, index) {
- // check column is on the right side
- if (right - left === 0 || j > index[right - 1])
- return right;
- // loop until we find row index
- while (left < right) {
- // point in the middle (fast integer division)
- var p = ~~((left + right) / 2);
- // column @ p
- var c = index[p];
- // check we have to look on the left side, right side or we found the column
- if (j < c)
- right = p;
- else if (j > c)
- left = p + 1;
- else
- return p;
- }
- return left;
- };
-
- var _remove = function (k, i, values, index, ptr) {
- // remove value @ k
- values.splice(k, 1);
- index.splice(k, 1);
- // update pointers
- for (var x = i + 1; x < ptr.length; x++)
- ptr[x]--;
- };
-
- var _insert = function (k, i, j, v, values, index, ptr) {
- // insert value
- values.splice(k, 0, v);
- // update column for k
- index.splice(k, 0, j);
- // update row pointers
- for (var x = i + 1; x < ptr.length; x++)
- ptr[x]++;
- };
-
- /**
- * Resize the matrix to the given size. Returns a copy of the matrix when
- * `copy=true`, otherwise return the matrix itself (resize in place).
- *
- * @param {Number[]} size The new size the matrix should have.
- * @param {*} [defaultValue=0] Default value, filled in on new entries.
- * If not provided, the matrix elements will
- * be filled with zeros.
- * @param {boolean} [copy] Return a resized copy of the matrix
- *
- * @return {Matrix} The resized matrix
- */
- CrsMatrix.prototype.resize = function (size, defaultValue, copy) {
- // validate arguments
- if (!isArray(size))
- throw new TypeError('Array expected');
- if (size.length !== 2)
- throw new Error('Only two dimensions matrix are supported');
-
- // check sizes
- 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) + ')');
- }
- });
-
- // matrix to resize
- var m = copy ? this.clone() : this;
- // resize matrix
- return _resize(m, size[0], size[1], defaultValue);
- };
-
- var _resize = function (matrix, rows, columns, defaultValue) {
- // value to insert at the time of growing matrix
- var value = defaultValue || 0;
- // should we insert the value?
- var ins = !math.equal(value, 0);
-
- // old columns and rows
- var r = matrix._size[0];
- var c = matrix._size[1];
-
- var i, j, k;
-
- // check we need to increase rows
- if (rows > r) {
- // loop new rows
- for (i = r; i < rows; i++) {
- // update matrix._ptr for current column
- matrix._ptr[i] = matrix._values.length;
- // check we need to insert matrix._values
- if (ins) {
- // loop columns
- for (j = 0; j < c; j++) {
- // add new matrix._values
- matrix._values.push(value);
- // update matrix._index
- matrix._index.push(j);
- }
- }
- }
- // store number of matrix._values in matrix._ptr
- matrix._ptr[rows] = matrix._values.length;
- }
- else if (rows < r) {
- // truncate matrix._ptr
- matrix._ptr.splice(rows + 1, r - rows);
- // truncate matrix._values and matrix._index
- matrix._values.splice(matrix._ptr[rows], matrix._values.length);
- matrix._index.splice(matrix._ptr[rows], matrix._index.length);
- }
- // update rows
- r = rows;
-
- // check we need to increase columns
- if (columns > c) {
- // check we have to insert values
- if (ins) {
- // inserts
- var n = 0;
- // loop rows
- for (i = 0; i < r; i++) {
- // update matrix._ptr for current row
- matrix._ptr[i] = matrix._ptr[i] + n;
- // where to insert matrix._values
- k = matrix._ptr[i + 1] + n;
- // pointer
- var p = 0;
- // loop new columns, initialize pointer
- for (j = c; j < columns; j++, p++) {
- // add value
- matrix._values.splice(k + p, 0, value);
- // update matrix._index
- matrix._index.splice(k + p, 0, j);
- // increment inserts
- n++;
- }
- }
- // store number of matrix._values in matrix._ptr
- matrix._ptr[r] = matrix._values.length;
- }
- }
- else if (columns < c) {
- // deletes
- var d = 0;
- // loop rows
- for (i = 0; i < r; i++) {
- // update matrix._ptr for current row
- matrix._ptr[i] = matrix._ptr[i] - d;
- // where matrix._values start for next column
- var k0 = matrix._ptr[i];
- var k1 = matrix._ptr[i + 1] - d;
- // loop matrix._index
- for (k = k0; k < k1; k++) {
- // column
- j = matrix._index[k];
- // check we need to delete value and matrix._index
- if (j > columns - 1) {
- // remove value
- matrix._values.splice(k, 1);
- // remove item from matrix._index
- matrix._index.splice(k, 1);
- // increase deletes
- d++;
- }
- }
- }
- // update matrix._ptr for current column
- matrix._ptr[i] = matrix._values.length;
- }
- // update matrix._size
- matrix._size[0] = rows;
- matrix._size[1] = columns;
- // return matrix
- return matrix;
- };
-
- /**
- * Create a clone of the matrix
- * @return {CrsMatrix} clone
- */
- CrsMatrix.prototype.clone = function () {
- var m = new CrsMatrix({
- values: object.clone(this._values),
- index: object.clone(this._index),
- ptr: object.clone(this._ptr),
- size: object.clone(this._size)
- });
- return m;
- };
-
- /**
- * Retrieve the size of the matrix.
- * @returns {Number[]} size
- */
- CrsMatrix.prototype.size = function() {
- return object.clone(this._size);
- };
-
- /**
- * Create a new matrix with the results of the callback function executed on
- * each entry of the matrix.
- * @param {function} callback The callback function is invoked with three
- * parameters: the value of the element, the index
- * of the element, and the Matrix being traversed.
- * @param {boolean} [skipZeros] Invoke callback function for non-zero values only.
- *
- * @return {Matrix} matrix
- */
- CrsMatrix.prototype.map = function (callback, skipZeros) {
- // matrix instance
- var me = this;
- // rows and columns
- var rows = this._size[0];
- var columns = this._size[1];
- // invoke callback
- var invoke = function (v, i, j) {
- // invoke callback
- return callback(v, [i, j], me);
- };
- // invoke _map
- return _map(this, 0, rows - 1, 0, columns - 1, invoke, skipZeros);
- };
-
- /**
- * Create a new matrix with the results of the callback function executed on the interval
- * [minRow..maxRow, minColumn..maxColumn].
- */
- var _map = function (matrix, minRow, maxRow, minColumn, maxColumn, callback, skipZeros) {
- // result arrays
- var values = [];
- var index = [];
- var ptr = [];
- // invoke callback
- var invoke = function (v, x, y) {
- // invoke callback
- v = callback(v, x, y);
- // check value != 0
- if (!math.equal(v, 0)) {
- // store value
- values.push(v);
- // index
- index.push(y);
- }
- };
- // loop rows
- for (var i = minRow; i <= maxRow; i++) {
- // store pointer to values index
- ptr.push(values.length);
- // k0 <= k < k1 where k0 = _ptr[j] && k1 = _ptr[j+1]
- var k0 = matrix._ptr[i];
- var k1 = matrix._ptr[i + 1];
- // column pointer
- var p = minColumn;
- // loop k within [k0, k1[
- for (var k = k0; k < k1; k++) {
- // column index
- var j = matrix._index[k];
- // check j is in range
- if (j >= minColumn && j <= maxColumn) {
- // zero values
- if (!skipZeros) {
- // write zeros from column p to j
- for (var x = p; x < j; x++)
- invoke(0, i - minRow, x - minColumn);
- }
- // value @ k
- invoke(matrix._values[k], i - minRow, j - minColumn);
- }
- // update pointer
- p = j + 1;
- }
- // zero values
- if (!skipZeros) {
- // write zeros from column p to maxColumn
- for (var y = p; y <= maxColumn; y++)
- invoke(0, i - minRow, y - minColumn);
- }
- }
- // store number of values in ptr
- ptr.push(values.length);
- // return ccs
- return new CrsMatrix({
- values: values,
- index: index,
- ptr: ptr,
- size: [maxRow - minRow + 1, maxColumn - minColumn + 1]
- });
- };
-
- /**
- * Execute a callback function on each entry of the matrix.
- * @param {function} callback The callback function is invoked with three
- * parameters: the value of the element, the index
- * of the element, and the Matrix being traversed.
- * @param {boolean} [skipZeros] Invoke callback function for non-zero values only.
- */
- CrsMatrix.prototype.forEach = function (callback, skipZeros) {
- // matrix instance
- var me = this;
- // rows and columns
- var rows = this._size[0];
- var columns = this._size[1];
- // loop rows
- for (var i = 0; i < rows; i++) {
- // k0 <= k < k1 where k0 = _ptr[i] && k1 = _ptr[i+1]
- var k0 = this._ptr[i];
- var k1 = this._ptr[i + 1];
- // column pointer
- var p = 0;
- // loop k within [k0, k1[
- for (var k = k0; k < k1; k++) {
- // column index
- var j = this._index[k];
- // check we need to process zeros
- if (!skipZeros) {
- // zero values
- for (var x = p; x < j; x++)
- callback(0, [i, x], me);
- }
- // value @ k
- callback(this._values[k], [i, j], me);
- // update pointer
- p = j + 1;
- }
- // check we need to process zeros
- if (!skipZeros) {
- // zero values
- for (var y = p; y < columns; y++)
- callback(0, [i, y], me);
- }
- }
- };
-
- /**
- * Create an Array with a copy of the data of the CrsMatrix
- * @returns {Array} array
- */
- CrsMatrix.prototype.toArray = function () {
- return _toArray(this, true);
- };
-
- /**
- * Get the primitive value of the CrsMatrix: a two dimensions array
- * @returns {Array} array
- */
- CrsMatrix.prototype.valueOf = function () {
- return _toArray(this, false);
- };
-
- var _toArray = function (matrix, copy) {
- // result
- var a = [];
- // rows and columns
- var rows = matrix._size[0];
- var columns = matrix._size[1];
- // loop rows
- for (var i = 0; i < rows; i++) {
- // push row
- var r = a[i] = [];
- // k0 <= k < k1 where k0 = _ptr[i] && k1 = _ptr[i+1]
- var k0 = matrix._ptr[i];
- var k1 = matrix._ptr[i + 1];
- // column pointer
- var p = 0;
- // loop k is within [k0, k1[
- for (var k = k0; k < k1; k++) {
- // column index
- var j = matrix._index[k];
- // zero values
- for (var x = p; x < j; x++)
- r[x] = 0;
- // set value
- r[j] = copy ? object.clone(matrix._values[k]) : matrix._values[k];
- // update pointer
- p = j + 1;
- }
- // zero values
- for (var y = p; y < columns; y++)
- r[y] = 0;
- }
- return a;
- };
-
- /**
- * Get a string representation of the matrix, with optional formatting options.
- * @param {Object | Number | Function} [options] Formatting options. See
- * lib/util/number:format for a
- * description of the available
- * options.
- * @returns {String} str
- */
- CrsMatrix.prototype.format = function (options) {
- // rows and columns
- var rows = this._size[0];
- var columns = this._size[1];
- // rows & columns
- var str = 'CRS [' + string.format(rows, options) + ' x ' + string.format(columns, options) + '] density: ' + string.format(this._values.length / (rows * columns), options) + '\n';
- // loop rows
- for (var i = 0; i < rows; i++) {
- // k0 <= k < k1 where k0 = _ptr[i] && k1 = _ptr[i+1]
- var k0 = this._ptr[i];
- var k1 = this._ptr[i + 1];
- // loop k within [k0, k1[
- for (var k = k0; k < k1; k++) {
- // column index
- var j = this._index[k];
- // append value
- str += '\n (' + string.format(i, options) + ', ' + string.format(j, options) + ') ==> ' + string.format(this._values[k], options);
- }
- }
- return str;
- };
-
- /**
- * Get a string representation of the matrix
- * @returns {String} str
- */
- CrsMatrix.prototype.toString = function () {
- return string.format(this.toArray());
- };
-
- /**
- * Get a JSON representation of the matrix
- * @returns {Object}
- */
- CrsMatrix.prototype.toJSON = function () {
- return {
- mathjs: 'CrsMatrix',
- values: this._values,
- index: this._index,
- ptr: this._ptr,
- size: this._size
- };
- };
-
- /**
- * Calculates the transpose of the matrix
- * @returns {Matrix}
- */
- CrsMatrix.prototype.transpose = function () {
- // rows and columns
- var rows = this._size[0];
- var columns = this._size[1];
- // check columns
- if (columns === 0) {
- // throw exception
- throw new RangeError('Cannot transpose a 2D matrix with no columns (size: ' + string.format(this._size) + ')');
- }
- // crs transpose is a ccs matrix with the same structure
- return new math.type.CcsMatrix({
- values: object.clone(this._values),
- index: object.clone(this._index),
- ptr: object.clone(this._ptr),
- size: [columns, rows]
- });
- };
-
- /**
- * Get the kth Matrix diagonal.
- *
- * @param {Number | BigNumber} [k=0] The kth diagonal where the vector will retrieved.
- *
- * @returns {Array} The array vector with the diagonal values.
- */
- CrsMatrix.prototype.diagonal = function(k) {
- // validate k if any
- if (k) {
- // convert BigNumber to a number
- if (k instanceof BigNumber)
- k = k.toNumber();
- // is must be an integer
- if (!isNumber(k) || !isInteger(k)) {
- throw new TypeError ('The parameter k must be an integer number');
- }
- }
- else {
- // default value
- k = 0;
- }
-
- var kSuper = k > 0 ? k : 0;
- var kSub = k < 0 ? -k : 0;
-
- // rows & columns
- var rows = this._size[0];
- var columns = this._size[1];
-
- // number diagonal values
- var n = Math.min(rows - kSub, columns - kSuper);
-
- // diagonal
- var values = [];
- // loop rows
- for (var i = kSub; i < rows && values.length < n; i++) {
- // k0 <= k < k1 where k0 = _ptr[i] && k1 = _ptr[i+1]
- var k0 = this._ptr[i];
- var k1 = this._ptr[i + 1];
- // row value flag
- var rv = false;
- // loop x within [k0, k1[
- for (var x = k0; x < k1; x++) {
- // column index
- var j = this._index[x];
- // check column
- if (j === i + kSuper - kSub) {
- // set flag
- rv = true;
- // value on this column
- values.push(object.clone(this._values[x]));
- // exit loop
- break;
- }
- else if (j > i + kSuper - kSub) {
- // exit loop, no value on the diagonal for row i
- break;
- }
- }
- // check this row has a value set
- if (!rv && values.length < n) {
- // zero on this column
- values.push(0);
- }
- }
- return values;
- };
-
- /**
- * Generate a matrix from a JSON object
- * @param {Object} json An object structured like
- * `{"mathjs": "CrsMatrix", "values": [], "index": [], "ptr": [], "size": []}`,
- * where mathjs is optional
- * @returns {CrsMatrix}
- */
- CrsMatrix.fromJSON = function (json) {
- return new CrsMatrix(json);
- };
-
- /**
- * Create a diagonal matrix.
- *
- * @param {Array} size The matrix size.
- * @param {Number, Array} value The values for the diagonal.
- * @param {Number | BigNumber} [k=0] The kth diagonal where the vector will be filled in.
- *
- * @returns {CrsMatrix}
- */
- CrsMatrix.diagonal = function (size, value, k) {
- if (!isArray(size))
- throw new TypeError('Array expected, size parameter');
- if (size.length !== 2)
- throw new Error('Only two dimensions matrix are supported');
-
- // map size & validate
- size = size.map(function (s) {
- // check it is a big number
- if (s instanceof BigNumber) {
- // convert it
- s = s.toNumber();
- }
- // validate arguments
- if (!isNumber(s) || !isInteger(s) || s < 1) {
- throw new Error('Size values must be positive integers');
- }
- return s;
- });
-
- // validate k if any
- if (k) {
- // convert BigNumber to a number
- if (k instanceof BigNumber)
- k = k.toNumber();
- // is must be an integer
- if (!isNumber(k) || !isInteger(k)) {
- throw new TypeError ('The parameter k must be an integer number');
- }
- }
- else {
- // default value
- k = 0;
- }
-
- var kSuper = k > 0 ? k : 0;
- var kSub = k < 0 ? -k : 0;
-
- // rows and columns
- var rows = size[0];
- var columns = size[1];
-
- // number of non-zero items
- var n = Math.min(rows - kSub, columns - kSuper);
-
- // value extraction function
- var _value;
-
- // check value
- if (isArray(value)) {
- // validate array
- if (value.length !== n) {
- // number of values in array must be n
- throw new Error('Invalid value array length');
- }
- // define function
- _value = function (i) {
- // return value @ i
- return value[i];
- };
- }
- else {
- // define function
- _value = function () {
- // return value
- return value;
- };
- }
-
- // create arrays
- var values = [];
- var index = [];
- var ptr = [];
-
- // loop items
- for (var i = 0; i < rows; i++) {
- // number of rows with value
- ptr.push(values.length);
- // diagonal index
- var j = i - kSub;
- // check we need to set diagonal value
- if (j >= 0 && j < n) {
- // get value @ j
- var v = _value(j);
- // check for zero
- if (!math.equal(v, 0)) {
- // column
- index.push(j + kSuper);
- // add value
- values.push(v);
- }
- }
- }
- // last value should be number of values
- ptr.push(values.length);
- // create CrsMatrix
- return new CrsMatrix({
- values: values,
- index: index,
- ptr: ptr,
- size: [rows, columns]
- });
- };
-
- /**
- * Calculate the trace of a matrix: the sum of the elements on the main
- * diagonal of a square matrix.
+ var clone = __webpack_require__(5).clone;
+ var isInteger = __webpack_require__(8).isInteger;
+ var array = __webpack_require__(18);
+ var IndexError = __webpack_require__(17);
+ var DimensionError = __webpack_require__(22);
+
+ function factory (type, config, load, typed) {
+ var matrix = load(__webpack_require__(23));
+
+ /**
+ * Concatenate two or more matrices.
+ *
+ * Syntax:
+ *
+ * math.concat(A, B, C, ...)
+ * math.concat(A, B, C, ..., dim)
+ *
+ * Where:
+ *
+ * - `dim: number` is a zero-based dimension over which to concatenate the matrices.
+ * By default the last dimension of the matrices.
+ *
+ * Examples:
+ *
+ * var A = [[1, 2], [5, 6]];
+ * var B = [[3, 4], [7, 8]];
+ *
+ * math.concat(A, B); // returns [[1, 2, 3, 4], [5, 6, 7, 8]]
+ * math.concat(A, B, 0); // returns [[1, 2], [5, 6], [3, 4], [7, 8]]
+ * math.concat('hello', ' ', 'world'); // returns 'hello world'
*
* See also:
*
- * diagonal
- *
- * @returns {Number} The matrix trace
- */
- CrsMatrix.prototype.trace = function () {
- // size
- var size = this._size;
- // check dimensions
- var rows = size[0];
- var columns = size[1];
- // matrix must be square
- if (rows === columns) {
- // calulate sum
- var sum = 0;
- // check we have data (avoid looping rows)
- if (this._values.length > 0) {
- // loop rows
- for (var i = 0; i < rows; i++) {
- // k0 <= k < k1 where k0 = _ptr[i] && k1 = _ptr[i+1]
- var k0 = this._ptr[i];
- var k1 = this._ptr[i + 1];
- // loop k within [k0, k1[
- for (var k = k0; k < k1; k++) {
- // column index
- var j = this._index[k];
- // check row
- if (i === j) {
- // accumulate value
- sum = math.add(sum, this._values[k]);
- // exit loop
- break;
- }
- if (j > i) {
- // exit loop, no value on the diagonal for column j
- break;
- }
- }
- }
- }
- // return trace
- return sum;
- }
- throw new RangeError('Matrix must be square (size: ' + string.format(size) + ')');
- };
-
- /**
- * Multiply the matrix values times the argument.
- *
- * @param {Number | BigNumber | Boolean | Complex | Unit | Array | Matrix | null} Value to multiply.
- *
- * @return {Number | BigNumber | Complex | Unit | Matrix}
- */
- CrsMatrix.prototype.multiply = function (value) {
- // check dimensions
- var rows = this._size[0];
- var columns = this._size[1];
-
- // check value is a matrix
- if (value instanceof Matrix) {
- // matrix size
- var z = value.size();
- // check value is a vector
- if (z.length === 1) {
- // mutiply matrix x vector array
- return _multiply(this, z[0], 1, function (i) {
- // value[i]
- return value.get([i]);
- });
- }
- // check two dimensions matrix
- if (z.length === 2) {
- // mutiply matrix x matrix
- return _multiply(this, z[0], z[1], function (i, j) {
- // value[i, j]
- return value.get([i, j]);
- });
- }
- throw new Error('Can only multiply a 1 or 2 dimensional matrix ' +
- '(value has ' + z.length + ' dimensions)');
- }
-
- // check value is an array
- if (isArray(value)) {
- // array size
- var s = array.size(value);
- // check value is a vector
- if (s.length === 1) {
- // mutiply matrix x vector array
- return _multiply(this, s[0], 1, function (i) {
- // value[i]
- return value[i];
- });
- }
- if (s.length === 2) {
- // mutiply matrix x array
- return _multiply(this, s[0], s[1], function (i, j) {
- // value[i, j]
- return value[i][j];
- });
- }
- throw new Error('Can only multiply a 1 or 2 dimensional matrix ' +
- '(value has ' + s.length + ' dimensions)');
- }
-
- var callback = function (v) {
- return math.multiply(v, value);
- };
-
- // map non zero elements
- return _map(this, 0, rows - 1, 0, columns - 1, callback, false);
- };
-
- var _multiply = function (matrix, r, c, get) {
-
- // matrix dimensions
- var rows = matrix._size[0];
- var columns = matrix._size[1];
-
- // check dimensions match
- if (columns !== r) {
- // throw error
- throw new RangeError('Dimension mismatch in multiplication. ' +
- 'Columns of A must match length of B ' +
- '(A is ' + rows + 'x' + columns +
- ', B is ' + r + ', ' +
- columns + ' != ' + r + ')');
- }
-
- // result arrays
- var values = [];
- var index = [];
- var ptr = [];
-
- // loop rows
- for (var i = 0; i < rows; i++) {
- // update ptr
- ptr.push(values.length);
- // k0 <= k < k1 where k0 = _ptr[i] && k1 = _ptr[i+1]
- var k0 = matrix._ptr[i];
- var k1 = matrix._ptr[i + 1];
- // loop value columns
- for (var z = 0; z < c; z++) {
- // value @ (i, x)
- var value = 0;
- // loop k within [k0, k1[
- for (var k = k0; k < k1; k++) {
- // column
- var j = matrix._index[k];
- // multiply & aggregate
- value = math.add(value, math.multiply(matrix._values[k], get(j, z)));
- }
- // check value is different than zero
- if (!math.equal(value, 0)) {
- // push value & column
- values.push(value);
- index.push(z);
- }
- }
- }
- // update ptr
- ptr.push(values.length);
-
- // check we need to squeeze the result into a scalar
- if (rows === 1 && c === 1)
- return values.length === 1 ? values[0] : 0;
-
- // return CRS matrix
- return new CrsMatrix({
- values: values,
- index: index,
- ptr: ptr,
- size: [rows, c]
- });
- };
-
- return CrsMatrix;
- };
+ * size, squeeze, subset, transpose
+ *
+ * @param {... Array | Matrix} args Two or more matrices
+ * @return {Array | Matrix} Concatenated matrix
+ */
+ var concat = typed('concat', {
+ // TODO: change signature to '...Array | Matrix, dim?' when supported
+ '...Array | Matrix | number | BigNumber': function (args) {
+ var i;
+ var len = args.length;
+ var dim = -1; // zero-based dimension
+ var prevDim;
+ var asMatrix = false;
+ var matrices = []; // contains multi dimensional arrays
+
+ for (i = 0; i < len; i++) {
+ var arg = args[i];
+
+ // test whether we need to return a Matrix (if not we return an Array)
+ if (arg && arg.isMatrix === true) {
+ asMatrix = true;
+ }
+
+ if (typeof arg === 'number' || (arg && arg.isBigNumber === true)) {
+ if (i !== len - 1) {
+ throw new Error('Dimension must be specified as last argument');
+ }
+
+ // last argument contains the dimension on which to concatenate
+ prevDim = dim;
+ dim = arg.valueOf(); // change BigNumber to number
+
+ if (!isInteger(dim)) {
+ throw new TypeError('Integer number expected for dimension');
+ }
+
+ if (dim < 0) {
+ // TODO: would be more clear when throwing a DimensionError here
+ throw new IndexError(dim);
+ }
+ if (i > 0 && dim > prevDim) {
+ // TODO: would be more clear when throwing a DimensionError here
+ throw new IndexError(dim, prevDim + 1);
+ }
+ }
+ else {
+ // this is a matrix or array
+ var m = clone(arg).valueOf();
+ var size = array.size(m);
+ matrices[i] = m;
+ prevDim = dim;
+ dim = size.length - 1;
+
+ // verify whether each of the matrices has the same number of dimensions
+ if (i > 0 && dim != prevDim) {
+ throw new DimensionError(prevDim + 1, dim + 1);
+ }
+ }
+ }
+
+ if (matrices.length == 0) {
+ throw new SyntaxError('At least one matrix expected');
+ }
+
+ var res = matrices.shift();
+ while (matrices.length) {
+ res = _concat(res, matrices.shift(), dim, 0);
+ }
+
+ return asMatrix ? matrix(res) : res;
+ },
+
+ '...string': function (args) {
+ return args.join('');
+ }
+ });
+
+ concat.toTex = '\\mathrm{${name}}\\left(${args}\\right)';
+
+ return concat;
+ }
+
+ /**
+ * Recursively concatenate two matrices.
+ * The contents of the matrices is not cloned.
+ * @param {Array} a Multi dimensional array
+ * @param {Array} b Multi dimensional array
+ * @param {number} concatDim The dimension on which to concatenate (zero-based)
+ * @param {number} dim The current dim (zero-based)
+ * @return {Array} c The concatenated matrix
+ * @private
+ */
+ function _concat(a, b, concatDim, dim) {
+ if (dim < concatDim) {
+ // recurse into next dimension
+ if (a.length != b.length) {
+ throw new DimensionError(a.length, b.length);
+ }
+
+ var c = [];
+ for (var i = 0; i < a.length; i++) {
+ c[i] = _concat(a[i], b[i], concatDim, dim + 1);
+ }
+ return c;
+ }
+ else {
+ // concatenate this dimension
+ return a.concat(b);
+ }
+ }
+
+ exports.name = 'concat';
+ exports.factory = factory;
+
/***/ },
/* 17 */
-/***/ function(module, exports, __webpack_require__) {
+/***/ function(module, exports) {
'use strict';
- var util = __webpack_require__(175);
- var DimensionError = __webpack_require__(172);
-
- var string = util.string;
- var array = util.array;
- var object = util.object;
-
- var isArray = Array.isArray;
- var isNumber = util.number.isNumber;
- var isInteger = util.number.isInteger;
-
- var validateIndex = array.validateIndex;
-
- module.exports = function (math) {
-
- var Index = math.type.Index,
- BigNumber = math.type.BigNumber,
- Matrix = math.type.Matrix;
-
- function DenseMatrix(data) {
- if (!(this instanceof DenseMatrix))
- throw new SyntaxError('Constructor must be called with the new operator');
-
- if (data instanceof Matrix) {
- // check data is a DenseMatrix
- if (data.type === 'DenseMatrix') {
- // clone data & size
- this._data = object.clone(data._data);
- this._size = object.clone(data._size);
- }
- else {
- // build data from existing matrix
- this._data = data.toArray();
- this._size = data.size();
- }
- }
- else if (data && isArray(data.data) && isArray(data.size)) {
- // initialize fields from JSON representation
- this._data = data.data;
- this._size = data.size;
- }
- else if (isArray(data)) {
- // replace nested Matrices with Arrays
- this._data = preprocess(data);
- // verify the size of the array, TODO: compute size while processing array
- this._size = array.size(this._data);
- }
- else if (data) {
- // unsupported type
- throw new TypeError('Unsupported type of data (' + util.types.type(data) + ')');
- }
- else {
- // nothing provided
- this._data = [];
- this._size = [0];
- }
- }
-
- DenseMatrix.prototype = new math.type.Matrix();
-
- DenseMatrix.prototype.type = 'DenseMatrix';
-
- /**
- * Get the storage format used by the matrix.
- *
- * Usage:
- * var format = matrix.storage() // retrieve storage format
- *
- * @return {string} The storage format.
- */
- DenseMatrix.prototype.storage = function () {
- return 'dense';
- };
-
- /**
- * Get a subset of the matrix, or replace a subset of the matrix.
- *
- * Usage:
- * var subset = matrix.subset(index) // retrieve subset
- * var value = matrix.subset(index, replacement) // replace subset
- *
- * @param {Index} index
- * @param {Array | DenseMatrix | *} [replacement]
- * @param {*} [defaultValue=0] Default value, filled in on new entries when
- * the matrix is resized. If not provided,
- * new matrix elements will be filled with zeros.
- */
- DenseMatrix.prototype.subset = function (index, replacement, defaultValue) {
- switch (arguments.length) {
- case 1:
- return _get(this, index);
-
- // intentional fall through
- case 2:
- case 3:
- return _set(this, index, replacement, defaultValue);
-
- default:
- throw new SyntaxError('Wrong number of arguments');
- }
- };
-
- /**
- * Get a single element from the matrix.
- * @param {Number[]} index Zero-based index
- * @return {*} value
- */
- DenseMatrix.prototype.get = function (index) {
- if (!isArray(index))
- throw new TypeError('Array expected');
- if (index.length != this._size.length)
- throw new DimensionError(index.length, this._size.length);
-
- // check index
- for (var x = 0; x < index.length; x++)
- validateIndex(index[x], this._size[x]);
-
- var data = this._data;
- for (var i = 0, ii = index.length; i < ii; i++) {
- var index_i = index[i];
- validateIndex(index_i, data.length);
- data = data[index_i];
- }
-
- return object.clone(data);
- };
-
- /**
- * Replace a single element in the matrix.
- * @param {Number[]} index Zero-based index
- * @param {*} value
- * @param {*} [defaultValue] Default value, filled in on new entries when
- * the matrix is resized. If not provided,
- * new matrix elements will be left undefined.
- * @return {DenseMatrix} self
- */
- DenseMatrix.prototype.set = function (index, value, defaultValue) {
- if (!isArray(index))
- throw new TypeError('Array expected');
- if (index.length < this._size.length)
- throw new DimensionError(index.length, this._size.length, '<');
-
- var i, ii, index_i;
-
- // enlarge matrix when needed
- var size = index.map(function (i) {
- return i + 1;
- });
- _fit(this, size, defaultValue);
-
- // traverse over the dimensions
- var data = this._data;
- for (i = 0, ii = index.length - 1; i < ii; i++) {
- index_i = index[i];
- validateIndex(index_i, data.length);
- data = data[index_i];
- }
-
- // set new value
- index_i = index[index.length - 1];
- validateIndex(index_i, data.length);
- data[index_i] = value;
-
- return this;
- };
-
- /**
- * Get a submatrix of this matrix
- * @param {DenseMatrix} matrix
- * @param {Index} index Zero-based index
- * @private
- */
- function _get (matrix, index) {
- if (!(index instanceof Index)) {
- throw new TypeError('Invalid index');
- }
-
- var isScalar = index.isScalar();
- if (isScalar) {
- // return a scalar
- return matrix.get(index.min());
- }
- else {
- // validate dimensions
- var size = index.size();
- if (size.length != matrix._size.length) {
- throw new DimensionError(size.length, matrix._size.length);
- }
-
- // validate if any of the ranges in the index is out of range
- var min = index.min();
- var max = index.max();
- for (var i = 0, ii = matrix._size.length; i < ii; i++) {
- validateIndex(min[i], matrix._size[i]);
- validateIndex(max[i], matrix._size[i]);
- }
-
- // retrieve submatrix
- // TODO: more efficient when creating an empty matrix and setting _data and _size manually
- return new DenseMatrix(_getSubmatrix(matrix._data, index, size.length, 0));
- }
- }
-
- /**
- * Recursively get a submatrix of a multi dimensional matrix.
- * Index is not checked for correct number or length of dimensions.
- * @param {Array} data
- * @param {Index} index
- * @param {number} dims Total number of dimensions
- * @param {number} dim Current dimension
- * @return {Array} submatrix
- * @private
- */
- function _getSubmatrix (data, index, dims, dim) {
- var last = (dim == dims - 1);
- var range = index.range(dim);
-
- if (last) {
- return range.map(function (i) {
- return data[i];
- });
- }
- else {
- return range.map(function (i) {
- var child = data[i];
- return _getSubmatrix(child, index, dims, dim + 1);
- });
- }
- }
-
- /**
- * Replace a submatrix in this matrix
- * Indexes are zero-based.
- * @param {DenseMatrix} matrix
- * @param {Index} index
- * @param {DenseMatrix | Array | *} submatrix
- * @param {*} defaultValue Default value, filled in on new entries when
- * the matrix is resized.
- * @return {DenseMatrix} matrix
- * @private
- */
- function _set (matrix, index, submatrix, defaultValue) {
- if (!(index instanceof Index)) {
- throw new TypeError('Invalid index');
- }
-
- // get index size and check whether the index contains a single value
- var iSize = index.size(),
- isScalar = index.isScalar();
-
- // calculate the size of the submatrix, and convert it into an Array if needed
- var sSize;
- if (submatrix instanceof math.type.Matrix) {
- sSize = submatrix.size();
- submatrix = submatrix.valueOf();
- }
- else {
- sSize = array.size(submatrix);
- }
-
- if (isScalar) {
- // set a scalar
-
- // check whether submatrix is a scalar
- if (sSize.length !== 0) {
- throw new TypeError('Scalar expected');
- }
-
- matrix.set(index.min(), submatrix, defaultValue);
- }
- else {
- // set a submatrix
-
- // validate dimensions
- if (iSize.length < matrix._size.length) {
- throw new DimensionError(iSize.length, matrix._size.length, '<');
- }
-
- if (sSize.length < iSize.length) {
- // calculate number of missing outer dimensions
- var i = 0;
- var outer = 0;
- while (iSize[i] === 1 && sSize[i] === 1) {
- i++;
- }
- while (iSize[i] === 1) {
- outer++;
- i++;
- }
-
- // unsqueeze both outer and inner dimensions
- submatrix = array.unsqueeze(submatrix, iSize.length, outer, sSize);
- }
-
- // check whether the size of the submatrix matches the index size
- if (!object.deepEqual(iSize, sSize)) {
- throw new DimensionError(iSize, sSize, '>');
- }
-
- // enlarge matrix when needed
- var size = index.max().map(function (i) {
- return i + 1;
- });
- _fit(matrix, size, defaultValue);
-
- // insert the sub matrix
- var dims = iSize.length,
- dim = 0;
- _setSubmatrix (matrix._data, index, submatrix, dims, dim);
- }
-
- return matrix;
- }
-
- /**
- * Replace a submatrix of a multi dimensional matrix.
- * @param {Array} data
- * @param {Index} index
- * @param {Array} submatrix
- * @param {number} dims Total number of dimensions
- * @param {number} dim
- * @private
- */
- function _setSubmatrix (data, index, submatrix, dims, dim) {
- var last = (dim == dims - 1),
- range = index.range(dim);
-
- if (last) {
- range.forEach(function (dataIndex, subIndex) {
- validateIndex(dataIndex);
- data[dataIndex] = submatrix[subIndex];
- });
- }
- else {
- range.forEach(function (dataIndex, subIndex) {
- validateIndex(dataIndex);
- _setSubmatrix(data[dataIndex], index, submatrix[subIndex], dims, dim + 1);
- });
- }
- }
-
- /**
- * Resize the matrix to the given size. Returns a copy of the matrix when
- * `copy=true`, otherwise return the matrix itself (resize in place).
- *
- * @param {Number[]} size The new size the matrix should have.
- * @param {*} [defaultValue=0] Default value, filled in on new entries.
- * If not provided, the matrix elements will
- * be filled with zeros.
- * @param {boolean} [copy] Return a resized copy of the matrix
- *
- * @return {Matrix} The resized matrix
- */
- DenseMatrix.prototype.resize = function (size, defaultValue, copy) {
- // validate arguments
- if (!isArray(size))
- throw new TypeError('Array expected');
-
- // matrix to resize
- var m = copy ? this.clone() : this;
- // resize matrix
- return _resize(m, size, defaultValue);
- };
-
- var _resize = function (matrix, size, defaultValue) {
- // check size
- if (size.length === 0) {
- // first value in matrix
- var v = matrix._data;
- // go deep
- while (isArray(v)) {
- v = v[0];
- }
- return object.clone(v);
- }
- // resize matrix
- matrix._size = object.clone(size);
- matrix._data = array.resize(matrix._data, matrix._size, defaultValue);
- // return matrix
- return matrix;
- };
-
- /**
- * Enlarge the matrix when it is smaller than given size.
- * If the matrix is larger or equal sized, nothing is done.
- * @param {DenseMatrix} matrix The matrix to be resized
- * @param {Number[]} size
- * @param {*} defaultValue Default value, filled in on new entries.
- * @private
- */
- function _fit(matrix, size, defaultValue) {
- var newSize = object.clone(matrix._size),
- changed = false;
-
- // add dimensions when needed
- while (newSize.length < size.length) {
- newSize.push(0);
- changed = true;
- }
-
- // enlarge size when needed
- for (var i = 0, ii = size.length; i < ii; i++) {
- if (size[i] > newSize[i]) {
- newSize[i] = size[i];
- changed = true;
- }
- }
-
- if (changed) {
- // resize only when size is changed
- _resize(matrix, newSize, defaultValue);
- }
- }
-
- /**
- * Create a clone of the matrix
- * @return {DenseMatrix} clone
- */
- DenseMatrix.prototype.clone = function () {
- var m = new DenseMatrix({
- data: object.clone(this._data),
- size: object.clone(this._size)
- });
- return m;
- };
-
- /**
- * Retrieve the size of the matrix.
- * @returns {Number[]} size
- */
- DenseMatrix.prototype.size = function() {
- return this._size;
- };
-
- /**
- * Create a new matrix with the results of the callback function executed on
- * each entry of the matrix.
- * @param {function} callback The callback function is invoked with three
- * parameters: the value of the element, the index
- * of the element, and the Matrix being traversed.
- *
- * @return {DenseMatrix} matrix
- */
- DenseMatrix.prototype.map = function (callback) {
- // matrix instance
- var me = this;
- var recurse = function (value, index) {
- if (isArray(value)) {
- return value.map(function (child, i) {
- return recurse(child, index.concat(i));
- });
- }
- else {
- return callback(value, index, me);
- }
- };
- // return dense format
- return new DenseMatrix({
- data: recurse(this._data, []),
- size: object.clone(this._size)
- });
- };
-
- /**
- * Execute a callback function on each entry of the matrix.
- * @param {function} callback The callback function is invoked with three
- * parameters: the value of the element, the index
- * of the element, and the Matrix being traversed.
- */
- DenseMatrix.prototype.forEach = function (callback) {
- // matrix instance
- var me = this;
- var recurse = function (value, index) {
- if (isArray(value)) {
- value.forEach(function (child, i) {
- recurse(child, index.concat(i));
- });
- }
- else {
- callback(value, index, me);
- }
- };
- recurse(this._data, []);
- };
-
- /**
- * Create an Array with a copy of the data of the DenseMatrix
- * @returns {Array} array
- */
- DenseMatrix.prototype.toArray = function () {
- return object.clone(this._data);
- };
-
- /**
- * Get the primitive value of the DenseMatrix: a multidimensional array
- * @returns {Array} array
- */
- DenseMatrix.prototype.valueOf = function () {
- return this._data;
- };
-
- /**
- * Get a string representation of the matrix, with optional formatting options.
- * @param {Object | Number | Function} [options] Formatting options. See
- * lib/util/number:format for a
- * description of the available
- * options.
- * @returns {String} str
- */
- DenseMatrix.prototype.format = function (options) {
- return string.format(this._data, options);
- };
-
- /**
- * Get a string representation of the matrix
- * @returns {String} str
- */
- DenseMatrix.prototype.toString = function () {
- return string.format(this._data);
- };
-
- /**
- * Get a JSON representation of the matrix
- * @returns {Object}
- */
- DenseMatrix.prototype.toJSON = function () {
- return {
- mathjs: 'DenseMatrix',
- data: this._data,
- size: this._size
- };
- };
-
- /**
- * Calculates the transpose of the matrix
- * @returns {Matrix}
- */
- DenseMatrix.prototype.transpose = function () {
- // check dimensions
- switch (this._size.length) {
- case 1:
- // vector
- return this.clone();
- case 2:
- // rows and columns
- var rows = this._size[0];
- var columns = this._size[1];
- // check columns
- if (columns === 0) {
- // throw exception
- throw new RangeError('Cannot transpose a 2D matrix with no columns (size: ' + string.format(this._size) + ')');
- }
- // transposed matrix data
- var transposed = [];
- var transposedRow;
- // loop columns
- for (var j = 0; j < columns; j++) {
- // initialize row
- transposedRow = transposed[j] = [];
- // loop rows
- for (var i = 0; i < rows; i++) {
- // set data
- transposedRow[i] = object.clone(this._data[i][j]);
- }
- }
- // return matrix
- return new DenseMatrix({
- data: transposed,
- size: [columns, rows]
- });
- default:
- // multi dimensional
- throw new RangeError('Matrix must be two dimensional (size: ' + string.format(this._size) + ')');
- }
- };
-
- /**
- * Get the kth Matrix diagonal.
- *
- * @param {Number | BigNumber} [k=0] The kth diagonal where the vector will retrieved.
- *
- * @returns {Array} The array vector with the diagonal values.
- */
- DenseMatrix.prototype.diagonal = function(k) {
- // validate k if any
- if (k) {
- // convert BigNumber to a number
- if (k instanceof BigNumber)
- k = k.toNumber();
- // is must be an integer
- if (!isNumber(k) || !isInteger(k)) {
- throw new TypeError ('The parameter k must be an integer number');
- }
- }
- else {
- // default value
- k = 0;
- }
-
- var kSuper = k > 0 ? k : 0;
- var kSub = k < 0 ? -k : 0;
-
- // rows & columns
- var rows = this._size[0];
- var columns = this._size[1];
-
- // number diagonal values
- var n = Math.min(rows - kSub, columns - kSuper);
-
- // x is a matrix get diagonal from matrix
- var vector = [];
-
- // loop rows
- for (var i = 0; i < n; i++) {
- vector[i] = object.clone(this._data[i + kSub][i + kSuper]);
- }
- return vector;
- };
-
- /**
- * Create a diagonal matrix.
- *
- * @param {Array} size The matrix size.
- * @param {Number, Array} value The values for the diagonal.
- * @param {Number | BigNumber} [k=0] The kth diagonal where the vector will be filled in.
- * @param {Number} [defaultValue] The default value for non-diagonal
- *
- * @returns {DenseMatrix}
- */
- DenseMatrix.diagonal = function (size, value, k, defaultValue) {
- if (!isArray(size))
- throw new TypeError('Array expected, size parameter');
- if (size.length !== 2)
- throw new Error('Only two dimensions matrix are supported');
-
- // map size & validate
- size = size.map(function (s) {
- // check it is a big number
- if (s instanceof BigNumber) {
- // convert it
- s = s.toNumber();
- }
- // validate arguments
- if (!isNumber(s) || !isInteger(s) || s < 1) {
- throw new Error('Size values must be positive integers');
- }
- return s;
- });
-
- // validate k if any
- if (k) {
- // convert BigNumber to a number
- if (k instanceof BigNumber)
- k = k.toNumber();
- // is must be an integer
- if (!isNumber(k) || !isInteger(k)) {
- throw new TypeError ('The parameter k must be an integer number');
- }
- }
- else {
- // default value
- k = 0;
- }
-
- var kSuper = k > 0 ? k : 0;
- var kSub = k < 0 ? -k : 0;
-
- // rows and columns
- var rows = size[0];
- var columns = size[1];
-
- // number of non-zero items
- var n = Math.min(rows - kSub, columns - kSuper);
-
- // value extraction function
- var _value;
-
- // check value
- if (isArray(value)) {
- // validate array
- if (value.length !== n) {
- // number of values in array must be n
- throw new Error('Invalid value array length');
- }
- // define function
- _value = function (i) {
- // return value @ i
- return value[i];
- };
- }
- else {
- // define function
- _value = function () {
- // return value
- return value;
- };
- }
-
- // empty array
- var data = [];
-
- // check we need to resize array
- if (size.length > 0) {
- // resize array
- data = array.resize(data, size, defaultValue);
- // fill diagonal
- for (var d = 0; d < n; d++) {
- data[d + kSub][d + kSuper] = _value(d);
- }
- }
-
- // create DenseMatrix
- return new DenseMatrix({
- data: data,
- size: [rows, columns]
- });
- };
-
- /**
- * Calculate the trace of a matrix: the sum of the elements on the main
- * diagonal of a square matrix.
- *
- * See also:
- *
- * diagonal
- *
- * @returns {Number} The matrix trace
- */
- DenseMatrix.prototype.trace = function () {
- // size & data
- var size = this._size;
- var data = this._data;
- // check dimensions
- switch (size.length) {
- case 1:
- // vector
- if (size[0] == 1) {
- // return data[0]
- return object.clone(data[0]);
- }
- throw new RangeError('Matrix must be square (size: ' + string.format(size) + ')');
- case 2:
- // two dimensional array
- var rows = size[0];
- var cols = size[1];
- if (rows === cols) {
- // calulate sum
- var sum = 0;
- // loop diagonal
- for (var i = 0; i < rows; i++)
- sum = math.add(sum, data[i][i]);
- // return trace
- return sum;
- }
- throw new RangeError('Matrix must be square (size: ' + string.format(size) + ')');
- default:
- // multi dimensional array
- throw new RangeError('Matrix must be two dimensional (size: ' + string.format(size) + ')');
- }
- };
-
- /**
- * Generate a matrix from a JSON object
- * @param {Object} json An object structured like
- * `{"mathjs": "DenseMatrix", data: [], size: []}`,
- * where mathjs is optional
- * @returns {DenseMatrix}
- */
- DenseMatrix.fromJSON = function (json) {
- return new DenseMatrix(json);
- };
-
- /**
- * Multiply the matrix values times the argument.
- *
- * @param {Number | BigNumber | Boolean | Complex | Unit | Array | Matrix | null} Value to multiply.
- *
- * @return {Number | BigNumber | Complex | Unit | Matrix}
- */
- DenseMatrix.prototype.multiply = function (value) {
- // process matrix size
- switch(this._size.length) {
- case 1:
- // multiply vector
- return _multiplyVector(this, this._size[0], value);
- case 2:
- // multiply matrix
- return _multiplyMatrix(this, this._size[0], this._size[1], value);
- default:
- throw new Error('Can only multiply a 1 or 2 dimensional matrix ' +
- '(matrix has ' + this._size.length + ' dimensions)');
- }
- };
-
- var _multiplyVector = function (matrix, m, value) {
- // check value is a matrix
- if (value instanceof Matrix) {
- // matrix size
- var z = value.size();
- // check value is a vector
- if (z.length === 1) {
- // vectors must have same length
- if (z[0] !== m)
- throw new RangeError('Dimension mismatch in multiplication. Vectors must have the same length.');
- // multiply vector x vector
- return _multiplyVectorVector(matrix, m, function (i) {
- // value[i]
- return value.get([i]);
- });
- }
- // check two dimensions matrix
- if (z.length === 2) {
- // vector length must be equal rows in matrix
- if (z[0] !== m)
- throw new RangeError('Dimension mismatch in multiplication. Matrix rows and Vector length must be equal.');
- // mutiply vector x matrix
- return _multiplyVectorMatrix(matrix, m, z[1], function (i, j) {
- // value[i]
- return value.get([i, j]);
- });
- }
- throw new Error('Can only multiply a 1 or 2 dimensional matrix ' +
- '(value has ' + z.length + ' dimensions)');
- }
-
- // check value is an array
- if (isArray(value)) {
- // array size
- var s = array.size(value);
- // check value is a vector
- if (s.length === 1) {
- // vectors must have same length
- if (s[0] !== m)
- throw new RangeError('Dimension mismatch in multiplication. Vectors must have the same length.');
- // multiply vector x vector
- return _multiplyVectorVector(matrix, m, function (i) {
- // value[i]
- return value[i];
- });
- }
- if (s.length === 2) {
- // vector length must be equal rows in matrix
- if (s[0] !== m)
- throw new RangeError('Dimension mismatch in multiplication. Matrix rows and Vector length must be equal.');
- // mutiply vector x matrix
- return _multiplyVectorMatrix(matrix, m, s[1], function (i, j) {
- // value[i]
- return value[i][j];
- });
- }
- throw new Error('Can only multiply a 1 or 2 dimensional matrix ' +
- '(value has ' + s.length + ' dimensions)');
- }
-
- // value is a scalar
- return matrix.map(function (v) {
- return math.multiply(value, v);
- });
- };
-
- var _multiplyVectorVector = function (matrix, m, get) {
- // check empty vector
- if (m === 0)
- throw new Error('Cannot multiply two empty vectors');
- // result
- var result = 0;
- // loop data
- for (var i = 0; i < m; i++) {
- // multiply and accumulate
- result = math.add(result, math.multiply(matrix._data[i], get(i)));
- }
- return result;
- };
-
- var _multiplyVectorMatrix = function (matrix, m, n, get) {
- // result
- var result = [];
- // loop columns in matrix
- for (var j = 0; j < n; j++) {
- // sum
- var sum = 0;
- // loop vector
- for (var i = 0; i < m; i++) {
- // multiply and accumulate
- sum = math.add(sum, math.multiply(matrix._data[i], get(i, j)));
- }
- result[j] = sum;
- }
- // check we need to squeeze the result into a scalar
- if (n === 1)
- return result[0];
- // return matrix
- return new DenseMatrix({
- data: result,
- size: [n]
- });
- };
-
- var _multiplyMatrix = function (matrix, m, n, value) {
- // check value is a matrix
- if (value instanceof Matrix) {
- // matrix size
- var z = value.size();
- // check value is a vector
- if (z.length === 1) {
- // vectors must have same length
- if (z[0] !== n)
- throw new RangeError('Dimension mismatch in multiplication. Matrix columns must match vector length.');
- // multiply matrix vector
- return _multiplyMatrixVector(matrix, m, n, function (i) {
- // value[i]
- return value.get([i]);
- });
- }
- // check two dimensions matrix
- if (z.length === 2) {
- // vector length must be equal rows in matrix
- if (z[0] !== n) {
- throw new RangeError('Dimension mismatch in multiplication. ' +
- 'Columns of A must match length of B ' +
- '(A is ' + m + 'x' + n +
- ', B is ' + z[0] + ', ' +
- n + ' != ' + z[0] + ')');
- }
- // mutiply vector x matrix
- return _multiplyMatrixMatrix(matrix, m, n, z[1], function (i, j) {
- // value[i, j]
- return value.get([i, j]);
- });
- }
- throw new Error('Can only multiply a 1 or 2 dimensional matrix ' +
- '(value has ' + z.length + ' dimensions)');
- }
-
- // check value is an array
- if (isArray(value)) {
- // array size
- var s = array.size(value);
- // check value is a vector
- if (s.length === 1) {
- // vectors must have same length
- if (s[0] !== n)
- throw new RangeError('Dimension mismatch in multiplication. Matrix columns must match vector length.');
- // multiply matrix vector
- return _multiplyMatrixVector(matrix, m, n, function (i) {
- // value[i]
- return value[i];
- });
- }
- if (s.length === 2) {
- // vector length must be equal rows in matrix
- if (s[0] !== n) {
- throw new RangeError('Dimension mismatch in multiplication. ' +
- 'Columns of A must match length of B ' +
- '(A is ' + m + 'x' + n +
- ', B is ' + s[0] + ', ' +
- n + ' != ' + s[0] + ')');
- }
- // mutiply vector x matrix
- return _multiplyMatrixMatrix(matrix, m, n, s[1], function (i, j) {
- // value[i, j]
- return value[i][j];
- });
- }
- throw new Error('Can only multiply a 1 or 2 dimensional matrix ' +
- '(value has ' + s.length + ' dimensions)');
- }
-
- // value is a scalar
- return matrix.map(function (v) {
- return math.multiply(value, v);
- });
- };
-
- var _multiplyMatrixVector = function (matrix, m, n, get) {
- // result
- var result = [];
- // loop matrix rows
- for (var i = 0; i < m; i++) {
- // current row
- var row = matrix._data[i];
- // sum
- var sum = 0;
- // loop matrix columns
- for (var j = 0; j < n; j++) {
- // multiply & accumulate
- sum = math.add(sum, math.multiply(row[j], get(j)));
- }
- result[i] = sum;
- }
- // check we need to squeeze the result into a scalar
- if (m === 1)
- return result[0];
- // return matrix
- return new DenseMatrix({
- data: result,
- size: [m]
- });
- };
-
- var _multiplyMatrixMatrix = function (matrix, m, n, c, get) {
- // result
- var result = [];
- // loop matrix rows
- for (var i = 0; i < m; i++) {
- // current row
- var row = matrix._data[i];
- // initialize row array
- result[i] = [];
- // loop other matrix columns
- for (var j = 0; j < c; j++) {
- // sum
- var sum = 0;
- // loop matrix columns
- for (var x = 0; x < n; x++) {
- // multiply & accumulate
- sum = math.add(sum, math.multiply(row[x], get(x, j)));
- }
- result[i][j] = sum;
- }
- }
- // check we need to squeeze the result into a scalar
- if (m === 1 && c === 1)
- return result[0][0];
- // return matrix
- return new DenseMatrix({
- data: result,
- size: [m, c]
- });
- };
-
- /**
- * Preprocess data, which can be an Array or DenseMatrix with nested Arrays and
- * Matrices. Replaces all nested Matrices with Arrays
- * @param {Array} data
- * @return {Array} data
- */
- function preprocess(data) {
- for (var i = 0, ii = data.length; i < ii; i++) {
- var elem = data[i];
- if (isArray(elem)) {
- data[i] = preprocess(elem);
- }
- else if (elem instanceof math.type.Matrix) {
- data[i] = preprocess(elem.valueOf());
- }
- }
-
- return data;
- }
-
- // exports
- return DenseMatrix;
- };
+ /**
+ * Create a range error with the message:
+ * 'Index out of range (index < min)'
+ * 'Index out of range (index < max)'
+ *
+ * @param {number} index The actual index
+ * @param {number} [min=0] Minimum index (included)
+ * @param {number} [max] Maximum index (excluded)
+ * @extends RangeError
+ */
+ function IndexError(index, min, max) {
+ if (!(this instanceof IndexError)) {
+ throw new SyntaxError('Constructor must be called with the new operator');
+ }
+
+ this.index = index;
+ if (arguments.length < 3) {
+ this.min = 0;
+ this.max = min;
+ }
+ else {
+ this.min = min;
+ this.max = max;
+ }
+
+ if (this.min !== undefined && this.index < this.min) {
+ this.message = 'Index out of range (' + this.index + ' < ' + this.min + ')';
+ }
+ else if (this.max !== undefined && this.index >= this.max) {
+ this.message = 'Index out of range (' + this.index + ' > ' + (this.max - 1) + ')';
+ }
+ else {
+ this.message = 'Index out of range (' + this.index + ')';
+ }
+
+ this.stack = (new Error()).stack;
+ }
+
+ IndexError.prototype = new RangeError();
+ IndexError.prototype.constructor = RangeError;
+ IndexError.prototype.name = 'IndexError';
+ IndexError.prototype.isIndexError = true;
+
+ module.exports = IndexError;
/***/ },
@@ -7260,2752 +3183,778 @@
'use strict';
- exports.ArrayNode = __webpack_require__(177);
- exports.AssignmentNode = __webpack_require__(178);
- exports.BlockNode = __webpack_require__(179);
- exports.ConditionalNode = __webpack_require__(180);
- exports.ConstantNode = __webpack_require__(181);
- exports.IndexNode = __webpack_require__(182);
- exports.FunctionAssignmentNode = __webpack_require__(183);
- exports.FunctionNode = __webpack_require__(184);
- exports.Node = __webpack_require__(185);
- exports.OperatorNode = __webpack_require__(186);
- exports.RangeNode = __webpack_require__(187);
- exports.SymbolNode = __webpack_require__(188);
- exports.UpdateNode = __webpack_require__(189);
+ var number = __webpack_require__(8);
+ var string = __webpack_require__(20);
+ var object = __webpack_require__(5);
+ var types = __webpack_require__(19);
+
+ var DimensionError = __webpack_require__(22);
+ var IndexError = __webpack_require__(17);
+
+ /**
+ * Calculate the size of a multi dimensional array.
+ * This function checks the size of the first entry, it does not validate
+ * whether all dimensions match. (use function `validate` for that)
+ * @param {Array} x
+ * @Return {Number[]} size
+ */
+ exports.size = function (x) {
+ var s = [];
+
+ while (Array.isArray(x)) {
+ s.push(x.length);
+ x = x[0];
+ }
+
+ return s;
+ };
+
+ /**
+ * Recursively validate whether each element in a multi dimensional array
+ * has a size corresponding to the provided size array.
+ * @param {Array} array Array to be validated
+ * @param {number[]} size Array with the size of each dimension
+ * @param {number} dim Current dimension
+ * @throws DimensionError
+ * @private
+ */
+ function _validate(array, size, dim) {
+ var i;
+ var len = array.length;
+
+ if (len != size[dim]) {
+ throw new DimensionError(len, size[dim]);
+ }
+
+ if (dim < size.length - 1) {
+ // recursively validate each child array
+ var dimNext = dim + 1;
+ for (i = 0; i < len; i++) {
+ var child = array[i];
+ if (!Array.isArray(child)) {
+ throw new DimensionError(size.length - 1, size.length, '<');
+ }
+ _validate(array[i], size, dimNext);
+ }
+ }
+ else {
+ // last dimension. none of the childs may be an array
+ for (i = 0; i < len; i++) {
+ if (Array.isArray(array[i])) {
+ throw new DimensionError(size.length + 1, size.length, '>');
+ }
+ }
+ }
+ }
+
+ /**
+ * Validate whether each element in a multi dimensional array has
+ * a size corresponding to the provided size array.
+ * @param {Array} array Array to be validated
+ * @param {number[]} size Array with the size of each dimension
+ * @throws DimensionError
+ */
+ exports.validate = function(array, size) {
+ var isScalar = (size.length == 0);
+ if (isScalar) {
+ // scalar
+ if (Array.isArray(array)) {
+ throw new DimensionError(array.length, 0);
+ }
+ }
+ else {
+ // array
+ _validate(array, size, 0);
+ }
+ };
+
+ /**
+ * Test whether index is an integer number with index >= 0 and index < length
+ * @param {number} index Zero-based index
+ * @param {number} [length] Length of the array
+ */
+ exports.validateIndex = function(index, length) {
+ if (!number.isNumber(index) || !number.isInteger(index)) {
+ throw new TypeError('Index must be an integer (value: ' + index + ')');
+ }
+ if (index < 0) {
+ throw new IndexError(index);
+ }
+ if (length !== undefined && index >= length) {
+ throw new IndexError(index, length);
+ }
+ };
+
+ // a constant used to specify an undefined defaultValue
+ exports.UNINITIALIZED = {};
+
+ /**
+ * Resize a multi dimensional array. The resized array is returned.
+ * @param {Array} array Array to be resized
+ * @param {Array.<number>} size Array with the size of each dimension
+ * @param {*} [defaultValue=0] Value to be filled in in new entries,
+ * zero by default. To leave new entries undefined,
+ * specify array.UNINITIALIZED as defaultValue
+ * @return {Array} array The resized array
+ */
+ exports.resize = function(array, size, defaultValue) {
+ // TODO: add support for scalars, having size=[] ?
+
+ // check the type of the arguments
+ if (!Array.isArray(array) || !Array.isArray(size)) {
+ throw new TypeError('Array expected');
+ }
+ if (size.length === 0) {
+ throw new Error('Resizing to scalar is not supported');
+ }
+
+ // check whether size contains positive integers
+ size.forEach(function (value) {
+ if (!number.isNumber(value) || !number.isInteger(value) || value < 0) {
+ throw new TypeError('Invalid size, must contain positive integers ' +
+ '(size: ' + string.format(size) + ')');
+ }
+ });
+
+ // recursively resize the array
+ var _defaultValue = (defaultValue !== undefined) ? defaultValue : 0;
+ _resize(array, size, 0, _defaultValue);
+
+ return array;
+ };
+
+ /**
+ * Recursively resize a multi dimensional array
+ * @param {Array} array Array to be resized
+ * @param {number[]} size Array with the size of each dimension
+ * @param {number} dim Current dimension
+ * @param {*} [defaultValue] Value to be filled in in new entries,
+ * undefined by default.
+ * @private
+ */
+ function _resize (array, size, dim, defaultValue) {
+ var i;
+ var elem;
+ var oldLen = array.length;
+ var newLen = size[dim];
+ var minLen = Math.min(oldLen, newLen);
+
+ // apply new length
+ array.length = newLen;
+
+ if (dim < size.length - 1) {
+ // non-last dimension
+ var dimNext = dim + 1;
+
+ // resize existing child arrays
+ for (i = 0; i < minLen; i++) {
+ // resize child array
+ elem = array[i];
+ if (!Array.isArray(elem)) {
+ elem = [elem]; // add a dimension
+ array[i] = elem;
+ }
+ _resize(elem, size, dimNext, defaultValue);
+ }
+
+ // create new child arrays
+ for (i = minLen; i < newLen; i++) {
+ // get child array
+ elem = [];
+ array[i] = elem;
+
+ // resize new child array
+ _resize(elem, size, dimNext, defaultValue);
+ }
+ }
+ else {
+ // last dimension
+
+ // remove dimensions of existing values
+ for (i = 0; i < minLen; i++) {
+ while (Array.isArray(array[i])) {
+ array[i] = array[i][0];
+ }
+ }
+
+ if(defaultValue !== exports.UNINITIALIZED) {
+ // fill new elements with the default value
+ for (i = minLen; i < newLen; i++) {
+ array[i] = object.clone(defaultValue);
+ }
+ }
+ }
+ }
+
+ /**
+ * Squeeze a multi dimensional array
+ * @param {Array} array
+ * @param {Array} [size]
+ * @returns {Array} returns the array itself
+ */
+ exports.squeeze = function(array, size) {
+ var s = size || exports.size(array);
+
+ // squeeze outer dimensions
+ while (Array.isArray(array) && array.length === 1) {
+ array = array[0];
+ s.shift();
+ }
+
+ // find the first dimension to be squeezed
+ var dims = s.length;
+ while (s[dims - 1] === 1) {
+ dims--;
+ }
+
+ // squeeze inner dimensions
+ if (dims < s.length) {
+ array = _squeeze(array, dims, 0);
+ s.length = dims;
+ }
+
+ return array;
+ };
+
+ /**
+ * Recursively squeeze a multi dimensional array
+ * @param {Array} array
+ * @param {number} dims Required number of dimensions
+ * @param {number} dim Current dimension
+ * @returns {Array | *} Returns the squeezed array
+ * @private
+ */
+ function _squeeze (array, dims, dim) {
+ var i, ii;
+
+ if (dim < dims) {
+ var next = dim + 1;
+ for (i = 0, ii = array.length; i < ii; i++) {
+ array[i] = _squeeze(array[i], dims, next);
+ }
+ }
+ else {
+ while (Array.isArray(array)) {
+ array = array[0];
+ }
+ }
+
+ return array;
+ }
+
+ /**
+ * Unsqueeze a multi dimensional array: add dimensions when missing
+ * @param {Array} array
+ * @param {number} dims Desired number of dimensions of the array
+ * @param {number} [outer] Number of outer dimensions to be added
+ * @param {Array} [size] Current size of array
+ * @returns {Array} returns the array itself
+ * @private
+ */
+ exports.unsqueeze = function(array, dims, outer, size) {
+ var s = size || exports.size(array);
+
+ // unsqueeze outer dimensions
+ if (outer) {
+ for (var i = 0; i < outer; i++) {
+ array = [array];
+ s.unshift(1);
+ }
+ }
+
+ // unsqueeze inner dimensions
+ array = _unsqueeze(array, dims, 0);
+ while (s.length < dims) {
+ s.push(1);
+ }
+
+ return array;
+ };
+
+ /**
+ * Recursively unsqueeze a multi dimensional array
+ * @param {Array} array
+ * @param {number} dims Required number of dimensions
+ * @param {number} dim Current dimension
+ * @returns {Array | *} Returns the squeezed array
+ * @private
+ */
+ function _unsqueeze (array, dims, dim) {
+ var i, ii;
+
+ if (Array.isArray(array)) {
+ var next = dim + 1;
+ for (i = 0, ii = array.length; i < ii; i++) {
+ array[i] = _unsqueeze(array[i], dims, next);
+ }
+ }
+ else {
+ for (var d = dim; d < dims; d++) {
+ array = [array];
+ }
+ }
+
+ return array;
+ }
+ /**
+ * Flatten a multi dimensional array, put all elements in a one dimensional
+ * array
+ * @param {Array} array A multi dimensional array
+ * @return {Array} The flattened array (1 dimensional)
+ */
+ exports.flatten = function(array) {
+ if (!Array.isArray(array)) {
+ //if not an array, return as is
+ return array;
+ }
+ var flat = [];
+
+ array.forEach(function callback(value) {
+ if (Array.isArray(value)) {
+ value.forEach(callback); //traverse through sub-arrays recursively
+ }
+ else {
+ flat.push(value);
+ }
+ });
+
+ return flat;
+ };
+
+ /**
+ * Test whether an object is an array
+ * @param {*} value
+ * @return {boolean} isArray
+ */
+ exports.isArray = Array.isArray;
/***/ },
/* 19 */
-/***/ function(module, exports, __webpack_require__) {
+/***/ function(module, exports) {
'use strict';
- var util = __webpack_require__(175),
-
- ArgumentsError = __webpack_require__(171),
-
- isString = util.string.isString,
- isArray = Array.isArray,
-
- // scope and nodes
- ArrayNode = __webpack_require__(177),
- AssignmentNode = __webpack_require__(178),
- BlockNode = __webpack_require__(179),
- ConditionalNode = __webpack_require__(180),
- ConstantNode = __webpack_require__(181),
- FunctionAssignmentNode = __webpack_require__(183),
- IndexNode = __webpack_require__(182),
- OperatorNode = __webpack_require__(186),
- FunctionNode = __webpack_require__(184),
- RangeNode = __webpack_require__(187),
- SymbolNode = __webpack_require__(188),
- UpdateNode = __webpack_require__(189);
-
- module.exports = function (math) {
-
- // types
- var Matrix = math.type.Matrix,
- collection = math.collection;
-
- /**
- * Parse an expression. Returns a node tree, which can be evaluated by
- * invoking node.eval();
- *
- * Syntax:
- *
- * parse(expr)
- * parse(expr, options)
- * parse([expr1, expr2, expr3, ...])
- * parse([expr1, expr2, expr3, ...], options)
- *
- * Example:
- *
- * var node = parse('sqrt(3^2 + 4^2)');
- * node.compile(math).eval(); // 5
- *
- * var scope = {a:3, b:4}
- * var node = parse('a * b'); // 12
- * var code = node.compile(math);
- * code.eval(scope); // 12
- * scope.a = 5;
- * code.eval(scope); // 20
- *
- * var nodes = math.parse(['a = 3', 'b = 4', 'a * b']);
- * nodes[2].compile(math).eval(); // 12
- *
- * @param {String | String[] | Matrix} expr
- * @param {{nodes: Object<String, Node>}} [options] Available options:
- * - `nodes` a set of custom nodes
- * @return {Node | Node[]} node
- * @throws {Error}
- */
- function parse (expr, options) {
- if (arguments.length != 1 && arguments.length != 2) {
- throw new ArgumentsError('parse', arguments.length, 1, 2);
- }
-
- // pass extra nodes
- extra_nodes = (options && options.nodes) ? options.nodes : {};
-
- if (isString(expr)) {
- // parse a single expression
- expression = expr;
- return parseStart();
- }
- else if (isArray(expr) || expr instanceof Matrix) {
- // parse an array or matrix with expressions
- return collection.deepMap(expr, function (elem) {
- if (!isString(elem)) throw new TypeError('String expected');
-
- expression = elem;
- return parseStart();
- });
- }
- else {
- // oops
- throw new TypeError('String or matrix expected');
- }
- }
-
- // token types enumeration
- var TOKENTYPE = {
- NULL : 0,
- DELIMITER : 1,
- NUMBER : 2,
- SYMBOL : 3,
- UNKNOWN : 4
- };
-
- // map with all delimiters
- var DELIMITERS = {
- ',': true,
- '(': true,
- ')': true,
- '[': true,
- ']': true,
- '\"': true,
- ';': true,
-
- '+': true,
- '-': true,
- '*': true,
- '.*': true,
- '/': true,
- './': true,
- '%': true,
- '^': true,
- '.^': true,
- '~': true,
- '!': true,
- '&': true,
- '|': true,
- '^|': true,
- '\'': true,
- '=': true,
- ':': true,
- '?': true,
-
- '==': true,
- '!=': true,
- '<': true,
- '>': true,
- '<=': true,
- '>=': true,
-
- '<<': true,
- '>>': true,
- '>>>': true
- };
-
- // map with all named delimiters
- var NAMED_DELIMITERS = {
- 'mod': true,
- 'to': true,
- 'in': true,
- 'and': true,
- 'xor': true,
- 'or': true,
- 'not': true
- };
-
- var extra_nodes = {}; // current extra nodes
- var expression = ''; // current expression
- var index = 0; // current index in expr
- var c = ''; // current token character in expr
- var token = ''; // current token
- var token_type = TOKENTYPE.NULL; // type of the token
- var nesting_level = 0; // level of nesting inside parameters, used to ignore newline characters
- var conditional_level = null; // when a conditional is being parsed, the level of the conditional is stored here
-
- /**
- * Get the first character from the expression.
- * The character is stored into the char c. If the end of the expression is
- * reached, the function puts an empty string in c.
- * @private
- */
- function first() {
- index = 0;
- c = expression.charAt(0);
- nesting_level = 0;
- conditional_level = null;
- }
-
- /**
- * Get the next character from the expression.
- * The character is stored into the char c. If the end of the expression is
- * reached, the function puts an empty string in c.
- * @private
- */
- function next() {
- index++;
- c = expression.charAt(index);
- }
-
- /**
- * Preview the next character from the expression.
- * @return {String} cNext
- * @private
- */
- function nextPreview() {
- return expression.charAt(index + 1);
- }
-
- /**
- * Preview the second next character from the expression.
- * @return {String} cNext
- * @private
- */
- function nextNextPreview() {
- return expression.charAt(index + 2);
- }
-
- /**
- * Get next token in the current string expr.
- * The token and token type are available as token and token_type
- * @private
- */
- function getToken() {
- token_type = TOKENTYPE.NULL;
- token = '';
-
- // skip over whitespaces
- // space, tab, and newline when inside parameters
- while (c == ' ' || c == '\t' || (c == '\n' && nesting_level)) {
- // TODO: also take '\r' carriage return as newline? Or does that give problems on mac?
- next();
- }
-
- // skip comment
- if (c == '#') {
- while (c != '\n' && c != '') {
- next();
- }
- }
-
- // check for end of expression
- if (c == '') {
- // token is still empty
- token_type = TOKENTYPE.DELIMITER;
- return;
- }
-
- // check for new line character
- if (c == '\n' && !nesting_level) {
- token_type = TOKENTYPE.DELIMITER;
- token = c;
- next();
- return;
- }
-
- // check for delimiters consisting of 3 characters
- var c2 = c + nextPreview();
- var c3 = c2 + nextNextPreview();
- if (c3.length == 3 && DELIMITERS[c3]) {
- token_type = TOKENTYPE.DELIMITER;
- token = c3;
- next();
- next();
- next();
- return;
- }
-
- // check for delimiters consisting of 2 characters
- if (c2.length == 2 && DELIMITERS[c2]) {
- token_type = TOKENTYPE.DELIMITER;
- token = c2;
- next();
- next();
- return;
- }
-
- // check for delimiters consisting of 1 character
- if (DELIMITERS[c]) {
- token_type = TOKENTYPE.DELIMITER;
- token = c;
- next();
- return;
- }
-
- // check for a number
- if (isDigitDot(c)) {
- token_type = TOKENTYPE.NUMBER;
-
- // get number, can have a single dot
- if (c == '.') {
- token += c;
- next();
-
- if (!isDigit(c)) {
- // this is no legal number, it is just a dot
- token_type = TOKENTYPE.UNKNOWN;
- }
- }
- else {
- while (isDigit(c)) {
- token += c;
- next();
- }
- if (c == '.') {
- token += c;
- next();
- }
- }
- while (isDigit(c)) {
- token += c;
- next();
- }
-
- // check for exponential notation like "2.3e-4", "1.23e50" or "2e+4"
- c2 = nextPreview();
- if ((c == 'E' || c == 'e') && (isDigit(c2) || c2 == '-' || c2 == '+')) {
- token += c;
- next();
-
- if (c == '+' || c == '-') {
- token += c;
- next();
- }
-
- // Scientific notation MUST be followed by an exponent
- if (!isDigit(c)) {
- // this is no legal number, exponent is missing.
- token_type = TOKENTYPE.UNKNOWN;
- }
-
- while (isDigit(c)) {
- token += c;
- next();
- }
- }
-
- return;
- }
-
- // check for variables, functions, named operators
- if (isAlpha(c)) {
- while (isAlpha(c) || isDigit(c)) {
- token += c;
- next();
- }
-
- if (NAMED_DELIMITERS[token]) {
- token_type = TOKENTYPE.DELIMITER;
- }
- else {
- token_type = TOKENTYPE.SYMBOL;
- }
-
- return;
- }
-
- // something unknown is found, wrong characters -> a syntax error
- token_type = TOKENTYPE.UNKNOWN;
- while (c != '') {
- token += c;
- next();
- }
- throw createSyntaxError('Syntax error in part "' + token + '"');
- }
-
- /**
- * Get next token and skip newline tokens
- */
- function getTokenSkipNewline () {
- do {
- getToken();
- }
- while (token == '\n');
- }
-
- /**
- * Open parameters.
- * New line characters will be ignored until closeParams() is called
- */
- function openParams() {
- nesting_level++;
- }
-
- /**
- * Close parameters.
- * New line characters will no longer be ignored
- */
- function closeParams() {
- nesting_level--;
- }
-
- /**
- * checks if the given char c is a letter (upper or lower case)
- * or underscore
- * @param {String} c a string with one character
- * @return {Boolean}
- * @private
- */
- function isAlpha (c) {
- return ((c >= 'a' && c <= 'z') ||
- (c >= 'A' && c <= 'Z') ||
- c == '_');
- }
-
- /**
- * checks if the given char c is a digit or dot
- * @param {String} c a string with one character
- * @return {Boolean}
- * @private
- */
- function isDigitDot (c) {
- return ((c >= '0' && c <= '9') ||
- c == '.');
- }
-
- /**
- * checks if the given char c is a digit
- * @param {String} c a string with one character
- * @return {Boolean}
- * @private
- */
- function isDigit (c) {
- return ((c >= '0' && c <= '9'));
- }
-
- /**
- * Start of the parse levels below, in order of precedence
- * @return {Node} node
- * @private
- */
- function parseStart () {
- // get the first character in expression
- first();
-
- getToken();
-
- var node = parseBlock();
-
- // check for garbage at the end of the expression
- // an expression ends with a empty character '' and token_type DELIMITER
- if (token != '') {
- if (token_type == TOKENTYPE.DELIMITER) {
- // user entered a not existing operator like "//"
-
- // TODO: give hints for aliases, for example with "<>" give as hint " did you mean != ?"
- throw createError('Unexpected operator ' + token);
- }
- else {
- throw createSyntaxError('Unexpected part "' + token + '"');
- }
- }
-
- return node;
- }
-
- /**
- * Parse a block with expressions. Expressions can be separated by a newline
- * character '\n', or by a semicolon ';'. In case of a semicolon, no output
- * of the preceding line is returned.
- * @return {Node} node
- * @private
- */
- function parseBlock () {
- var node;
- var blocks = [];
- var visible;
-
- if (token == '') {
- // empty expression
- return new ConstantNode('undefined', 'undefined');
- }
-
- if (token != '\n' && token != ';') {
- node = parseFunctionAssignment();
- }
-
- // TODO: simplify this loop
- while (token == '\n' || token == ';') {
- if (blocks.length == 0 && node) {
- visible = (token != ';');
- blocks.push({
- node: node,
- visible: visible
- });
- }
-
- getToken();
- if (token != '\n' && token != ';' && token != '') {
- node = parseFunctionAssignment();
-
- visible = (token != ';');
- blocks.push({
- node: node,
- visible: visible
- });
- }
- }
-
- if (blocks.length > 0) {
- return new BlockNode(blocks);
- }
- else {
- return node;
- }
- }
-
- /**
- * Parse a function assignment like "function f(a,b) = a*b"
- * @return {Node} node
- * @private
- */
- function parseFunctionAssignment () {
- // TODO: function assignment using keyword 'function' is deprecated since version 0.18.0, cleanup some day
- if (token_type == TOKENTYPE.SYMBOL && token == 'function') {
- throw createSyntaxError('Deprecated keyword "function". ' +
- 'Functions can now be assigned without it, like "f(x) = x^2".');
- }
-
- return parseAssignment();
- }
-
- /**
- * Assignment of a variable, can be a variable like "a=2.3" or a updating an
- * existing variable like "matrix(2,3:5)=[6,7,8]"
- * @return {Node} node
- * @private
- */
- function parseAssignment () {
- var name, args, expr, valid;
-
- var node = parseConditional();
-
- if (token == '=') {
- if (node instanceof SymbolNode) {
- // parse a variable assignment like 'a = 2/3'
- name = node.name;
- getTokenSkipNewline();
- expr = parseAssignment();
- return new AssignmentNode(name, expr);
- }
- else if (node instanceof IndexNode) {
- // parse a matrix subset assignment like 'A[1,2] = 4'
- getTokenSkipNewline();
- expr = parseAssignment();
- return new UpdateNode(node, expr);
- }
- else if (node instanceof FunctionNode) {
- // parse function assignment like 'f(x) = x^2'
- valid = true;
- args = [];
-
- name = node.name;
- node.args.forEach(function (arg, index) {
- if (arg instanceof SymbolNode) {
- args[index] = arg.name;
- }
- else {
- valid = false;
- }
- });
-
- if (valid) {
- getTokenSkipNewline();
- expr = parseAssignment();
- return new FunctionAssignmentNode(name, args, expr);
- }
- }
-
- throw createSyntaxError('Invalid left hand side of assignment operator =');
- }
-
- return node;
- }
-
- /**
- * conditional operation
- *
- * condition ? truePart : falsePart
- *
- * Note: conditional operator is right-associative
- *
- * @return {Node} node
- * @private
- */
- function parseConditional () {
- var node = parseLogicalOr();
-
- while (token == '?') {
- // set a conditional level, the range operator will be ignored as long
- // as conditional_level == nesting_level.
- var prev = conditional_level;
- conditional_level = nesting_level;
- getTokenSkipNewline();
-
- var condition = node;
- var trueExpr = parseLogicalOr();
-
- if (token != ':') throw createSyntaxError('False part of conditional expression expected');
-
- conditional_level = null;
- getTokenSkipNewline();
-
- var falseExpr = parseConditional(); // Note: check for conditional operator again, right associativity
-
- node = new ConditionalNode(condition, trueExpr, falseExpr);
-
- // restore the previous conditional level
- conditional_level = prev;
- }
-
- return node;
- }
-
- /**
- * logical or, 'x or y'
- * @return {Node} node
- * @private
- */
- function parseLogicalOr() {
- var node = parseLogicalXor();
-
- while (token == 'or') {
- getTokenSkipNewline();
- node = new OperatorNode('or', 'or', [node, parseLogicalXor()]);
- }
-
- return node;
- }
-
- /**
- * logical exclusive or, 'x xor y'
- * @return {Node} node
- * @private
- */
- function parseLogicalXor() {
- var node = parseLogicalAnd();
-
- while (token == 'xor') {
- getTokenSkipNewline();
- node = new OperatorNode('xor', 'xor', [node, parseLogicalAnd()]);
- }
-
- return node;
- }
-
- /**
- * logical and, 'x and y'
- * @return {Node} node
- * @private
- */
- function parseLogicalAnd() {
- var node = parseBitwiseOr();
-
- while (token == 'and') {
- getTokenSkipNewline();
- node = new OperatorNode('and', 'and', [node, parseBitwiseOr()]);
- }
-
- return node;
- }
-
- /**
- * bitwise or, 'x | y'
- * @return {Node} node
- * @private
- */
- function parseBitwiseOr() {
- var node = parseBitwiseXor();
-
- while (token == '|') {
- getTokenSkipNewline();
- node = new OperatorNode('|', 'bitOr', [node, parseBitwiseXor()]);
- }
-
- return node;
- }
-
- /**
- * bitwise exclusive or (xor), 'x ^| y'
- * @return {Node} node
- * @private
- */
- function parseBitwiseXor() {
- var node = parseBitwiseAnd();
-
- while (token == '^|') {
- getTokenSkipNewline();
- node = new OperatorNode('^|', 'bitXor', [node, parseBitwiseAnd()]);
- }
-
- return node;
- }
-
- /**
- * bitwise and, 'x & y'
- * @return {Node} node
- * @private
- */
- function parseBitwiseAnd () {
- var node = parseRelational();
-
- while (token == '&') {
- getTokenSkipNewline();
- node = new OperatorNode('&', 'bitAnd', [node, parseRelational()]);
- }
-
- return node;
- }
-
- /**
- * relational operators
- * @return {Node} node
- * @private
- */
- function parseRelational () {
- var node, operators, name, fn, params;
-
- node = parseShift();
-
- operators = {
- '==': 'equal',
- '!=': 'unequal',
- '<': 'smaller',
- '>': 'larger',
- '<=': 'smallerEq',
- '>=': 'largerEq'
- };
- while (token in operators) {
- name = token;
- fn = operators[name];
-
- getTokenSkipNewline();
- params = [node, parseShift()];
- node = new OperatorNode(name, fn, params);
- }
-
- return node;
- }
-
- /**
- * Bitwise left shift, bitwise right arithmetic shift, bitwise right logical shift
- * @return {Node} node
- * @private
- */
- function parseShift () {
- var node, operators, name, fn, params;
-
- node = parseConversion();
-
- operators = {
- '<<' : 'leftShift',
- '>>' : 'rightArithShift',
- '>>>' : 'rightLogShift'
- };
-
- while (token in operators) {
- name = token;
- fn = operators[name];
-
- getTokenSkipNewline();
- params = [node, parseConversion()];
- node = new OperatorNode(name, fn, params);
- }
-
- return node;
- }
-
- /**
- * conversion operators 'to' and 'in'
- * @return {Node} node
- * @private
- */
- function parseConversion () {
- var node, operators, name, fn, params;
-
- node = parseRange();
-
- operators = {
- 'to' : 'to',
- 'in' : 'to' // alias of 'to'
- };
-
- while (token in operators) {
- name = token;
- fn = operators[name];
-
- getTokenSkipNewline();
- params = [node, parseRange()];
- node = new OperatorNode(name, fn, params);
- }
-
- return node;
- }
-
- /**
- * parse range, "start:end", "start:step:end", ":", "start:", ":end", etc
- * @return {Node} node
- * @private
- */
- function parseRange () {
- var node, params = [];
-
- if (token == ':') {
- // implicit start=1 (one-based)
- node = new ConstantNode('1', 'number');
- }
- else {
- // explicit start
- node = parseAddSubtract();
- }
-
- if (token == ':' && (conditional_level !== nesting_level)) {
- // we ignore the range operator when a conditional operator is being processed on the same level
- params.push(node);
-
- // parse step and end
- while (token == ':' && params.length < 3) {
- getTokenSkipNewline();
-
- if (token == ')' || token == ']' || token == ',' || token == '') {
- // implicit end
- params.push(new SymbolNode('end'));
- }
- else {
- // explicit end
- params.push(parseAddSubtract());
- }
- }
-
- if (params.length == 3) {
- // params = [start, step, end]
- node = new RangeNode(params[0], params[2], params[1]); // start, end, step
- }
- else { // length == 2
- // params = [start, end]
- node = new RangeNode(params[0], params[1]); // start, end
- }
- }
-
- return node;
- }
-
- /**
- * add or subtract
- * @return {Node} node
- * @private
- */
- function parseAddSubtract () {
- var node, operators, name, fn, params;
-
- node = parseMultiplyDivide();
-
- operators = {
- '+': 'add',
- '-': 'subtract'
- };
- while (token in operators) {
- name = token;
- fn = operators[name];
-
- getTokenSkipNewline();
- params = [node, parseMultiplyDivide()];
- node = new OperatorNode(name, fn, params);
- }
-
- return node;
- }
-
- /**
- * multiply, divide, modulus
- * @return {Node} node
- * @private
- */
- function parseMultiplyDivide () {
- var node, operators, name, fn, params;
-
- node = parseUnary();
-
- operators = {
- '*': 'multiply',
- '.*': 'dotMultiply',
- '/': 'divide',
- './': 'dotDivide',
- '%': 'mod',
- 'mod': 'mod'
- };
-
- if (token in operators) {
- while (token in operators) {
- name = token;
- fn = operators[name];
-
- getTokenSkipNewline();
- params = [node, parseUnary()];
- node = new OperatorNode(name, fn, params);
- }
- }
-
- // parse implicit multiplication
- if ((token_type == TOKENTYPE.SYMBOL) ||
- (token == 'in' && (node instanceof ConstantNode)) ||
- (token_type == TOKENTYPE.NUMBER && !(node instanceof ConstantNode)) ||
- (token == '(' || token == '[')) {
- // symbol: implicit multiplication like '2a', '(2+3)a', 'a b'
- // number: implicit multiplication like '(2+3)2'
- // Note: we don't allow implicit multiplication between numbers,
- // like '2 3'. I'm not sure whether that is a good idea.
- // parenthesis: implicit multiplication like '2(3+4)', '(3+4)(1+2)', '2[1,2,3]'
- node = new OperatorNode('*', 'multiply', [node, parseMultiplyDivide()]);
- }
-
- return node;
- }
-
- /**
- * Unary plus and minus, and logical and bitwise not
- * @return {Node} node
- * @private
- */
- function parseUnary () {
- var name, params;
- var fn = {
- '-': 'unaryMinus',
- '+': 'unaryPlus',
- '~': 'bitNot',
- 'not': 'not'
- }[token];
-
- if (fn) {
- name = token;
-
- getTokenSkipNewline();
- params = [parseUnary()];
-
- return new OperatorNode(name, fn, params);
- }
-
- return parsePow();
- }
-
- /**
- * power
- * Note: power operator is right associative
- * @return {Node} node
- * @private
- */
- function parsePow () {
- var node, name, fn, params;
-
- node = parseLeftHandOperators();
-
- if (token == '^' || token == '.^') {
- name = token;
- fn = (name == '^') ? 'pow' : 'dotPow';
-
- getTokenSkipNewline();
- params = [node, parseUnary()]; // Go back to unary, we can have '2^-3'
- node = new OperatorNode(name, fn, params);
- }
-
- return node;
- }
-
- /**
- * Left hand operators: factorial x!, transpose x'
- * @return {Node} node
- * @private
- */
- function parseLeftHandOperators () {
- var node, operators, name, fn, params;
-
- node = parseCustomNodes();
-
- operators = {
- '!': 'factorial',
- '\'': 'transpose'
- };
-
- while (token in operators) {
- name = token;
- fn = operators[name];
-
- getToken();
- params = [node];
-
- node = new OperatorNode(name, fn, params);
- }
-
- return node;
- }
-
- /**
- * Parse a custom node handler. A node handler can be used to process
- * nodes in a custom way, for example for handling a plot.
- *
- * A handler must be passed as second argument of the parse function.
- * - must extend math.expression.node.Node
- * - must contain a function _compile(defs: Object) : String
- * - must contain a function find(filter: Object) : Node[]
- * - must contain a function toString() : String
- * - the constructor is called with a single argument containing all parameters
- *
- * For example:
- *
- * nodes = {
- * 'plot': PlotHandler
- * };
- *
- * The constructor of the handler is called as:
- *
- * node = new PlotHandler(params);
- *
- * The handler will be invoked when evaluating an expression like:
- *
- * node = math.parse('plot(sin(x), x)', nodes);
- *
- * @return {Node} node
- * @private
- */
- function parseCustomNodes () {
- var params = [], handler;
-
- if (token_type == TOKENTYPE.SYMBOL && extra_nodes[token]) {
- handler = extra_nodes[token];
-
- getToken();
-
- // parse parameters
- if (token == '(') {
- params = [];
-
- openParams();
- getToken();
-
- if (token != ')') {
- params.push(parseConditional());
-
- // parse a list with parameters
- while (token == ',') {
- getToken();
- params.push(parseConditional());
- }
- }
-
- if (token != ')') {
- throw createSyntaxError('Parenthesis ) expected');
- }
- closeParams();
- getToken();
- }
-
- // create a new node handler
- //noinspection JSValidateTypes
- return new handler(params);
- }
-
- return parseSymbol();
- }
-
- /**
- * parse symbols: functions, variables, constants, units
- * @return {Node} node
- * @private
- */
- function parseSymbol () {
- var node, name;
-
- if (token_type == TOKENTYPE.SYMBOL ||
- (token_type == TOKENTYPE.DELIMITER && token in NAMED_DELIMITERS)) {
- name = token;
-
- getToken();
-
- // parse function parameters and matrix index
- node = parseFunctions(name);
- node = parseIndex(node);
- return node;
- }
-
- return parseString();
- }
-
- /**
- * parse a function call like fn(a, b, c)
- * @param {string} name Function name
- * @return {FunctionNode | SymbolNode} node
- * @private
- */
- function parseFunctions (name) {
- var params;
-
- if (token == '(') {
- params = [];
-
- openParams();
- getToken();
-
- if (token != ')') {
- params.push(parseConditional());
-
- // parse a list with parameters
- while (token == ',') {
- getToken();
- params.push(parseConditional());
- }
- }
-
- if (token != ')') {
- throw createSyntaxError('Parenthesis ) expected');
- }
- closeParams();
- getToken();
-
- return new FunctionNode(name, params);
- }
-
- return new SymbolNode(name);
- }
-
- /**
- * parse index parameters, enclosed in square brackets [...], for example A[2,3]
- * @param {Node} node Node on which to apply the parameters. If there
- * are no parameters in the expression, the node
- * itself is returned
- * @return {Node} node
- * @private
- */
- function parseIndex (node) {
- var params;
-
- while (token == '[') {
- params = [];
-
- openParams();
- getToken();
-
- if (token != ']') {
- params.push(parseConditional());
-
- // parse a list with parameters
- while (token == ',') {
- getToken();
- params.push(parseConditional());
- }
- }
-
- if (token != ']') {
- throw createSyntaxError('Parenthesis ] expected');
- }
- closeParams();
- getToken();
-
- node = new IndexNode(node, params);
- }
-
- return node;
- }
-
- /**
- * parse a string.
- * A string is enclosed by double quotes
- * @return {Node} node
- * @private
- */
- function parseString () {
- var node, str, tPrev;
-
- if (token == '"') {
- // string "..."
- str = '';
- tPrev = '';
- while (c != '' && (c != '\"' || tPrev == '\\')) { // also handle escape character
- str += c;
- tPrev = c;
- next();
- }
-
- getToken();
- if (token != '"') {
- throw createSyntaxError('End of string " expected');
- }
- getToken();
-
- // create constant
- node = new ConstantNode(str, 'string');
-
- // parse index parameters
- node = parseIndex(node);
-
- return node;
- }
-
- return parseMatrix();
- }
-
- /**
- * parse the matrix
- * @return {Node} node
- * @private
- */
- function parseMatrix () {
- var array, params, rows, cols;
-
- if (token == '[') {
- // matrix [...]
- openParams();
- getToken();
-
- if (token != ']') {
- // this is a non-empty matrix
- var row = parseRow();
-
- if (token == ';') {
- // 2 dimensional array
- rows = 1;
- params = [row];
-
- // the rows of the matrix are separated by dot-comma's
- while (token == ';') {
- getToken();
-
- params[rows] = parseRow();
- rows++;
- }
-
- if (token != ']') {
- throw createSyntaxError('End of matrix ] expected');
- }
- closeParams();
- getToken();
-
- // check if the number of columns matches in all rows
- cols = params[0].nodes.length;
- for (var r = 1; r < rows; r++) {
- if (params[r].nodes.length != cols) {
- throw createError('Column dimensions mismatch ' +
- '(' + params[r].nodes.length + ' != ' + cols + ')');
- }
- }
-
- array = new ArrayNode(params);
- }
- else {
- // 1 dimensional vector
- if (token != ']') {
- throw createSyntaxError('End of matrix ] expected');
- }
- closeParams();
- getToken();
-
- array = row;
- }
- }
- else {
- // this is an empty matrix "[ ]"
- closeParams();
- getToken();
- array = new ArrayNode([]);
- }
-
- return array;
- }
-
- return parseNumber();
- }
-
- /**
- * Parse a single comma-separated row from a matrix, like 'a, b, c'
- * @return {ArrayNode} node
- */
- function parseRow () {
- var params = [parseAssignment()];
- var len = 1;
-
- while (token == ',') {
- getToken();
-
- // parse expression
- params[len] = parseAssignment();
- len++;
- }
-
- return new ArrayNode(params);
- }
-
- /**
- * parse a number
- * @return {Node} node
- * @private
- */
- function parseNumber () {
- var number;
-
- if (token_type == TOKENTYPE.NUMBER) {
- // this is a number
- number = token;
- getToken();
-
- return new ConstantNode(number, 'number');
- }
-
- return parseParentheses();
- }
-
- /**
- * parentheses
- * @return {Node} node
- * @private
- */
- function parseParentheses () {
- var node;
-
- // check if it is a parenthesized expression
- if (token == '(') {
- // parentheses (...)
- openParams();
- getToken();
-
- node = parseAssignment(); // start again
-
- if (token != ')') {
- throw createSyntaxError('Parenthesis ) expected');
- }
- closeParams();
- getToken();
-
- return node;
- }
-
- return parseEnd();
- }
-
- /**
- * Evaluated when the expression is not yet ended but expected to end
- * @return {Node} res
- * @private
- */
- function parseEnd () {
- if (token == '') {
- // syntax error or unexpected end of expression
- throw createSyntaxError('Unexpected end of expression');
- } else {
- throw createSyntaxError('Value expected');
- }
- }
-
- /**
- * Shortcut for getting the current row value (one based)
- * Returns the line of the currently handled expression
- * @private
- */
- /* TODO: implement keeping track on the row number
- function row () {
- return null;
- }
- */
-
- /**
- * Shortcut for getting the current col value (one based)
- * Returns the column (position) where the last token starts
- * @private
- */
- function col () {
- return index - token.length + 1;
- }
-
- /**
- * Create an error
- * @param {String} message
- * @return {SyntaxError} instantiated error
- * @private
- */
- function createSyntaxError (message) {
- var c = col();
- var error = new SyntaxError(message + ' (char ' + c + ')');
- error['char'] = c;
-
- return error;
- }
-
- /**
- * Create an error
- * @param {String} message
- * @return {Error} instantiated error
- * @private
- */
- function createError (message) {
- var c = col();
- var error = new Error(message + ' (char ' + c + ')');
- error['char'] = c;
-
- return error;
- }
-
- return parse;
+ /**
+ * Determine the type of a variable
+ *
+ * type(x)
+ *
+ * The following types are recognized:
+ *
+ * 'undefined'
+ * 'null'
+ * 'boolean'
+ * 'number'
+ * 'string'
+ * 'Array'
+ * 'Function'
+ * 'Date'
+ * 'RegExp'
+ * 'Object'
+ *
+ * @param {*} x
+ * @return {string} Returns the name of the type. Primitive types are lower case,
+ * non-primitive types are upper-camel-case.
+ * For example 'number', 'string', 'Array', 'Date'.
+ */
+ exports.type = function(x) {
+ var type = typeof x;
+
+ if (type === 'object') {
+ if (x === null) return 'null';
+ if (x instanceof Boolean) return 'boolean';
+ if (x instanceof Number) return 'number';
+ if (x instanceof String) return 'string';
+ if (Array.isArray(x)) return 'Array';
+ if (x instanceof Date) return 'Date';
+ if (x instanceof RegExp) return 'RegExp';
+
+ return 'Object';
+ }
+
+ if (type === 'function') return 'Function';
+
+ return type;
};
+
/***/ },
/* 20 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
- module.exports = function (math) {
-
- var _parse = math.expression.parse;
-
- /**
- * @constructor Parser
- * Parser contains methods to evaluate or parse expressions, and has a number
- * of convenience methods to get, set, and remove variables from memory. Parser
- * keeps a scope containing variables in memory, which is used for all
- * evaluations.
- *
- * Methods:
- * var result = parser.eval(expr); // evaluate an expression
- * var value = parser.get(name); // retrieve a variable from the parser
- * parser.set(name, value); // set a variable in the parser
- * parser.remove(name); // clear a variable from the
- * // parsers scope
- * parser.clear(); // clear the parsers scope
- *
- * Example usage:
- * var parser = new Parser();
- * // Note: there is a convenience method which can be used instead:
- * // var parser = new math.parser();
- *
- * // evaluate expressions
- * parser.eval('sqrt(3^2 + 4^2)'); // 5
- * parser.eval('sqrt(-4)'); // 2i
- * parser.eval('2 inch in cm'); // 5.08 cm
- * parser.eval('cos(45 deg)'); // 0.7071067811865476
- *
- * // define variables and functions
- * parser.eval('x = 7 / 2'); // 3.5
- * parser.eval('x + 3'); // 6.5
- * parser.eval('function f(x, y) = x^y'); // f(x, y)
- * parser.eval('f(2, 3)'); // 8
- *
- * // get and set variables and functions
- * var x = parser.get('x'); // 7
- * var f = parser.get('f'); // function
- * var g = f(3, 2); // 9
- * parser.set('h', 500);
- * var i = parser.eval('h / 2'); // 250
- * parser.set('hello', function (name) {
- * return 'hello, ' + name + '!';
- * });
- * parser.eval('hello("user")'); // "hello, user!"
- *
- * // clear defined functions and variables
- * parser.clear();
- *
- */
- function Parser() {
- if (!(this instanceof Parser)) {
- throw new SyntaxError(
- 'Constructor must be called with the new operator');
- }
- this.scope = {};
- }
-
- /**
- * Parse an expression and return the parsed function node.
- * The node tree can be compiled via `code = node.compile(math)`,
- * and the compiled code can be executed as `code.eval([scope])`
- * @param {String} expr
- * @return {Node} node
- * @throws {Error}
- */
- Parser.prototype.parse = function (expr) {
- throw new Error('Parser.parse is deprecated. Use math.parse instead.');
- };
-
- /**
- * Parse and compile an expression, return the compiled javascript code.
- * The node can be evaluated via code.eval([scope])
- * @param {String} expr
- * @return {{eval: function}} code
- * @throws {Error}
- */
- Parser.prototype.compile = function (expr) {
- throw new Error('Parser.compile is deprecated. Use math.compile instead.');
- };
-
- /**
- * Parse and evaluate the given expression
- * @param {String} expr A string containing an expression, for example "2+3"
- * @return {*} result The result, or undefined when the expression was empty
- * @throws {Error}
- */
- Parser.prototype.eval = function (expr) {
- // TODO: validate arguments
- return _parse(expr)
- .compile(math)
- .eval(this.scope);
- };
-
- /**
- * Get a variable (a function or variable) by name from the parsers scope.
- * Returns undefined when not found
- * @param {String} name
- * @return {* | undefined} value
- */
- Parser.prototype.get = function (name) {
- // TODO: validate arguments
- return this.scope[name];
- };
-
- /**
- * Set a symbol (a function or variable) by name from the parsers scope.
- * @param {String} name
- * @param {* | undefined} value
- */
- Parser.prototype.set = function (name, value) {
- // TODO: validate arguments
- return this.scope[name] = value;
- };
-
- /**
- * Remove a variable from the parsers scope
- * @param {String} name
- */
- Parser.prototype.remove = function (name) {
- // TODO: validate arguments
- delete this.scope[name];
- };
-
- /**
- * Clear the scope with variables and functions
- */
- Parser.prototype.clear = function () {
- for (var name in this.scope) {
- if (this.scope.hasOwnProperty(name)) {
- delete this.scope[name];
+ var formatNumber = __webpack_require__(8).format;
+ var formatBigNumber = __webpack_require__(21).format;
+
+ /**
+ * Test whether value is a string
+ * @param {*} value
+ * @return {boolean} isString
+ */
+ exports.isString = function(value) {
+ return typeof value === 'string';
+ };
+
+ /**
+ * Check if a text ends with a certain string.
+ * @param {string} text
+ * @param {string} search
+ */
+ exports.endsWith = function(text, search) {
+ var start = text.length - search.length;
+ var end = text.length;
+ return (text.substring(start, end) === search);
+ };
+
+ /**
+ * Format a value of any type into a string.
+ *
+ * Usage:
+ * math.format(value)
+ * math.format(value, precision)
+ *
+ * If value is a function, the returned string is 'function' unless the function
+ * has a property `description`, in that case this properties value is returned.
+ *
+ * Example usage:
+ * math.format(2/7); // '0.2857142857142857'
+ * math.format(math.pi, 3); // '3.14'
+ * math.format(new Complex(2, 3)); // '2 + 3i'
+ * math.format('hello'); // '"hello"'
+ *
+ * @param {*} value Value to be stringified
+ * @param {Object | number | Function} [options] Formatting options. See
+ * lib/utils/number:format for a
+ * description of the available
+ * options.
+ * @return {string} str
+ */
+ exports.format = function(value, options) {
+ if (typeof value === 'number') {
+ return formatNumber(value, options);
+ }
+
+ if (value && value.isBigNumber === true) {
+ return formatBigNumber(value, options);
+ }
+
+ if (value && value.isFraction === true) {
+ if (!options || options.fraction !== 'decimal') {
+ // output as ratio, like '1/3'
+ return (value.s * value.n) + '/' + value.d;
+ }
+ else {
+ // output as decimal, like '0.(3)'
+ return value.toString();
+ }
+ }
+
+ if (Array.isArray(value)) {
+ return formatArray(value, options);
+ }
+
+ if (exports.isString(value)) {
+ return '"' + value + '"';
+ }
+
+ if (typeof value === 'function') {
+ return value.syntax ? value.syntax + '' : 'function';
+ }
+
+ if (typeof value === 'object') {
+ if (typeof value.format === 'function') {
+ return value.format(options);
+ }
+ else {
+ return value.toString();
+ }
+ }
+
+ return String(value);
+ };
+
+ /**
+ * Recursively format an n-dimensional matrix
+ * Example output: "[[1, 2], [3, 4]]"
+ * @param {Array} array
+ * @param {Object | number | Function} [options] Formatting options. See
+ * lib/utils/number:format for a
+ * description of the available
+ * options.
+ * @returns {string} str
+ */
+ function formatArray (array, options) {
+ if (Array.isArray(array)) {
+ var str = '[';
+ var len = array.length;
+ for (var i = 0; i < len; i++) {
+ if (i != 0) {
+ str += ', ';
}
+ str += formatArray(array[i], options);
}
- };
+ str += ']';
+ return str;
+ }
+ else {
+ return exports.format(array, options);
+ }
+ }
- return Parser;
- };
/***/ },
/* 21 */
-/***/ function(module, exports, __webpack_require__) {
-
- // constants
- exports.e = __webpack_require__(190);
- exports.E = __webpack_require__(190);
- exports['false'] = __webpack_require__(191);
- exports.i = __webpack_require__(192);
- exports['Infinity'] = __webpack_require__(193);
- exports.LN2 = __webpack_require__(194);
- exports.LN10 = __webpack_require__(195);
- exports.LOG2E = __webpack_require__(196);
- exports.LOG10E = __webpack_require__(197);
- exports.NaN = __webpack_require__(198);
- exports['null'] = __webpack_require__(199);
- exports.pi = __webpack_require__(200);
- exports.PI = __webpack_require__(200);
- exports.phi = __webpack_require__(201);
- exports.SQRT1_2 = __webpack_require__(202);
- exports.SQRT2 = __webpack_require__(203);
- exports.tau = __webpack_require__(204);
- exports['true'] = __webpack_require__(205);
- exports.version = __webpack_require__(206);
-
- // functions - arithmetic
- exports.abs = __webpack_require__(210);
- exports.add = __webpack_require__(211);
- exports.ceil = __webpack_require__(212);
- exports.cube = __webpack_require__(213);
- exports.divide = __webpack_require__(214);
- exports.dotDivide = __webpack_require__(215);
- exports.dotMultiply = __webpack_require__(216);
- exports.dotPow = __webpack_require__(217);
- exports.exp = __webpack_require__(218);
- exports.fix = __webpack_require__(219);
- exports.floor = __webpack_require__(220);
- exports.gcd = __webpack_require__(221);
- exports.lcm = __webpack_require__(222);
- exports.log = __webpack_require__(223);
- exports.log10 = __webpack_require__(224);
- exports.mod = __webpack_require__(225);
- exports.multiply = __webpack_require__(226);
- exports.norm = __webpack_require__(227);
- exports.nthRoot = __webpack_require__(228);
- exports.pow = __webpack_require__(229);
- exports.round = __webpack_require__(230);
- exports.sign = __webpack_require__(231);
- exports.sqrt = __webpack_require__(232);
- exports.square = __webpack_require__(233);
- exports.subtract = __webpack_require__(234);
- exports.unaryMinus = __webpack_require__(235);
- exports.unaryPlus = __webpack_require__(236);
- exports.xgcd = __webpack_require__(237);
-
- // functions - bitwise
- exports.bitAnd = __webpack_require__(238);
- exports.bitNot = __webpack_require__(239);
- exports.bitOr = __webpack_require__(240);
- exports.bitXor = __webpack_require__(241);
- exports.leftShift = __webpack_require__(242);
- exports.rightArithShift = __webpack_require__(243);
- exports.rightLogShift = __webpack_require__(244);
-
- // functions - complex
- exports.arg = __webpack_require__(245);
- exports.conj = __webpack_require__(246);
- exports.re = __webpack_require__(247);
- exports.im = __webpack_require__(248);
-
- // functions - construction
- exports.bignumber = __webpack_require__(249);
- exports['boolean'] = __webpack_require__(250);
- exports.complex = __webpack_require__(251);
- exports.index = __webpack_require__(252);
- exports.matrix = __webpack_require__(253);
- exports.number = __webpack_require__(254);
- exports.string = __webpack_require__(255);
- exports.unit = __webpack_require__(256);
-
- // functions - expression
- exports['eval'] = __webpack_require__(257);
- exports.help = __webpack_require__(258);
-
- // functions - logical
- exports['and'] = __webpack_require__(259);
- exports['not'] = __webpack_require__(260);
- exports['or'] = __webpack_require__(261);
- exports['xor'] = __webpack_require__(262);
-
- // functions - matrix
- exports['concat'] = __webpack_require__(263);
- exports.cross = __webpack_require__(264);
- exports.det = __webpack_require__(265);
- exports.diag = __webpack_require__(266);
- exports.dot = __webpack_require__(267);
- exports.eye = __webpack_require__(268);
- exports.flatten = __webpack_require__(269);
- exports.inv = __webpack_require__(270);
- exports.ones = __webpack_require__(271);
- exports.range = __webpack_require__(272);
- exports.resize = __webpack_require__(273);
- exports.size = __webpack_require__(274);
- exports.squeeze = __webpack_require__(275);
- exports.subset = __webpack_require__(276);
- exports.trace = __webpack_require__(277);
- exports.transpose = __webpack_require__(278);
- exports.zeros = __webpack_require__(279);
-
- // functions - probability
- exports.combinations = __webpack_require__(280);
- //exports.distribution = require('./function/probability/distribution');
- exports.factorial = __webpack_require__(281);
- exports.gamma = __webpack_require__(282);
- exports.permutations = __webpack_require__(283);
- exports.pickRandom = __webpack_require__(284);
- exports.random = __webpack_require__(285);
- exports.randomInt = __webpack_require__(286);
-
- // functions - relational
- exports.compare = __webpack_require__(287);
- exports.deepEqual = __webpack_require__(288);
- exports['equal'] = __webpack_require__(289);
- exports.larger = __webpack_require__(290);
- exports.largerEq = __webpack_require__(291);
- exports.smaller = __webpack_require__(292);
- exports.smallerEq = __webpack_require__(293);
- exports.unequal = __webpack_require__(294);
-
- // functions - statistics
- exports.max = __webpack_require__(295);
- exports.mean = __webpack_require__(296);
- exports.median = __webpack_require__(297);
- exports.min = __webpack_require__(298);
- exports.prod = __webpack_require__(299);
- exports.std = __webpack_require__(300);
- exports.sum = __webpack_require__(301);
- exports['var'] = __webpack_require__(302);
-
- // functions - trigonometry
- exports.acos = __webpack_require__(303);
- exports.acosh = __webpack_require__(304);
- exports.acot = __webpack_require__(305);
- exports.acoth = __webpack_require__(306);
- exports.acsc = __webpack_require__(307);
- exports.acsch = __webpack_require__(308);
- exports.asec = __webpack_require__(309);
- exports.asech = __webpack_require__(310);
- exports.asin = __webpack_require__(311);
- exports.asinh = __webpack_require__(312);
- exports.atan = __webpack_require__(313);
- exports.atanh = __webpack_require__(314);
- exports.atan2 = __webpack_require__(315);
- exports.cos = __webpack_require__(316);
- exports.cosh = __webpack_require__(317);
- exports.cot = __webpack_require__(318);
- exports.coth = __webpack_require__(319);
- exports.csc = __webpack_require__(320);
- exports.csch = __webpack_require__(321);
- exports.sec = __webpack_require__(322);
- exports.sech = __webpack_require__(323);
- exports.sin = __webpack_require__(324);
- exports.sinh = __webpack_require__(325);
- exports.tan = __webpack_require__(326);
- exports.tanh = __webpack_require__(327);
-
- // functions - units
- exports.to = __webpack_require__(328);
-
- // functions - utils
- exports.clone = __webpack_require__(329);
- exports.map = __webpack_require__(330);
- exports.filter = __webpack_require__(331);
- exports.forEach = __webpack_require__(332);
- exports.format = __webpack_require__(333);
- // exports.print = require('./function/utils/print'); // TODO: add documentation for print as soon as the parser supports objects.
- exports['import'] = __webpack_require__(334);
- exports.sort = __webpack_require__(335);
- exports['typeof'] = __webpack_require__(336);
+/***/ function(module, exports) {
+
+ /**
+ * Convert a BigNumber to a formatted string representation.
+ *
+ * Syntax:
+ *
+ * format(value)
+ * format(value, options)
+ * format(value, precision)
+ * format(value, fn)
+ *
+ * Where:
+ *
+ * {number} value The value to be formatted
+ * {Object} options An object with formatting options. Available options:
+ * {string} notation
+ * Number notation. Choose from:
+ * 'fixed' Always use regular number notation.
+ * For example '123.40' and '14000000'
+ * 'exponential' Always use exponential notation.
+ * For example '1.234e+2' and '1.4e+7'
+ * 'auto' (default) Regular number notation for numbers
+ * having an absolute value between
+ * `lower` and `upper` bounds, and uses
+ * exponential notation elsewhere.
+ * Lower bound is included, upper bound
+ * is excluded.
+ * For example '123.4' and '1.4e7'.
+ * {number} precision A number between 0 and 16 to round
+ * the digits of the number.
+ * In case of notations 'exponential' and
+ * 'auto', `precision` defines the total
+ * number of significant digits returned
+ * and is undefined by default.
+ * In case of notation 'fixed',
+ * `precision` defines the number of
+ * significant digits after the decimal
+ * point, and is 0 by default.
+ * {Object} exponential An object containing two parameters,
+ * {number} lower and {number} upper,
+ * used by notation 'auto' to determine
+ * when to return exponential notation.
+ * Default values are `lower=1e-3` and
+ * `upper=1e5`.
+ * Only applicable for notation `auto`.
+ * {Function} fn A custom formatting function. Can be used to override the
+ * built-in notations. Function `fn` is called with `value` as
+ * parameter and must return a string. Is useful for example to
+ * format all values inside a matrix in a particular way.
+ *
+ * Examples:
+ *
+ * format(6.4); // '6.4'
+ * format(1240000); // '1.24e6'
+ * format(1/3); // '0.3333333333333333'
+ * format(1/3, 3); // '0.333'
+ * format(21385, 2); // '21000'
+ * format(12.071, {notation: 'fixed'}); // '12'
+ * format(2.3, {notation: 'fixed', precision: 2}); // '2.30'
+ * format(52.8, {notation: 'exponential'}); // '5.28e+1'
+ *
+ * @param {BigNumber} value
+ * @param {Object | Function | number} [options]
+ * @return {string} str The formatted value
+ */
+ exports.format = function (value, options) {
+ if (typeof options === 'function') {
+ // handle format(value, fn)
+ return options(value);
+ }
+
+ // handle special cases
+ if (!value.isFinite()) {
+ return value.isNaN() ? 'NaN' : (value.gt(0) ? 'Infinity' : '-Infinity');
+ }
+
+ // default values for options
+ var notation = 'auto';
+ var precision = undefined;
+
+ if (options !== undefined) {
+ // determine notation from options
+ if (options.notation) {
+ notation = options.notation;
+ }
+
+ // determine precision from options
+ if (typeof options === 'number') {
+ precision = options;
+ }
+ else if (options.precision) {
+ precision = options.precision;
+ }
+ }
+
+ // handle the various notations
+ switch (notation) {
+ case 'fixed':
+ return exports.toFixed(value, precision);
+
+ case 'exponential':
+ return exports.toExponential(value, precision);
+
+ case 'auto':
+ // determine lower and upper bound for exponential notation.
+ // TODO: implement support for upper and lower to be BigNumbers themselves
+ var lower = 1e-3;
+ var upper = 1e5;
+ if (options && options.exponential) {
+ if (options.exponential.lower !== undefined) {
+ lower = options.exponential.lower;
+ }
+ if (options.exponential.upper !== undefined) {
+ upper = options.exponential.upper;
+ }
+ }
+
+ // adjust the configuration of the BigNumber constructor (yeah, this is quite tricky...)
+ var oldConfig = {
+ toExpNeg: value.constructor.toExpNeg,
+ toExpPos: value.constructor.toExpPos
+ };
+
+ value.constructor.config({
+ toExpNeg: Math.round(Math.log(lower) / Math.LN10),
+ toExpPos: Math.round(Math.log(upper) / Math.LN10)
+ });
+
+ // handle special case zero
+ if (value.isZero()) return '0';
+
+ // determine whether or not to output exponential notation
+ var str;
+ var abs = value.abs();
+ if (abs.gte(lower) && abs.lt(upper)) {
+ // normal number notation
+ str = value.toSignificantDigits(precision).toFixed();
+ }
+ else {
+ // exponential notation
+ str = exports.toExponential(value, precision);
+ }
+
+ // remove trailing zeros after the decimal point
+ return str.replace(/((\.\d*?)(0+))($|e)/, function () {
+ var digits = arguments[2];
+ var e = arguments[4];
+ return (digits !== '.') ? digits + e : e;
+ });
+
+ default:
+ throw new Error('Unknown notation "' + notation + '". ' +
+ 'Choose "auto", "exponential", or "fixed".');
+ }
+ };
+
+ /**
+ * Format a number in exponential notation. Like '1.23e+5', '2.3e+0', '3.500e-3'
+ * @param {BigNumber} value
+ * @param {number} [precision] Number of digits in formatted output.
+ * If not provided, the maximum available digits
+ * is used.
+ * @returns {string} str
+ */
+ exports.toExponential = function (value, precision) {
+ if (precision !== undefined) {
+ return value.toExponential(precision - 1); // Note the offset of one
+ }
+ else {
+ return value.toExponential();
+ }
+ };
+
+ /**
+ * Format a number with fixed notation.
+ * @param {BigNumber} value
+ * @param {number} [precision=0] Optional number of decimals after the
+ * decimal point. Zero by default.
+ */
+ exports.toFixed = function (value, precision) {
+ return value.toFixed(precision || 0);
+ // Note: the (precision || 0) is needed as the toFixed of BigNumber has an
+ // undefined default precision instead of 0.
+ }
/***/ },
/* 22 */
-/***/ function(module, exports, __webpack_require__) {
+/***/ function(module, exports) {
'use strict';
- module.exports = function (math) {
- /**
- * Instantiate mathjs data types from their JSON representation
- * @param {string} key
- * @param {*} value
- * @returns {*} Returns the revived object
- */
- function reviver(key, value) {
- var name = value && value.mathjs;
-
- var constructor = math.type[name];
- if (constructor && constructor.fromJSON) {
- return constructor.fromJSON(value);
- }
-
- return value;
+ /**
+ * Create a range error with the message:
+ * 'Dimension mismatch (<actual size> != <expected size>)'
+ * @param {number | number[]} actual The actual size
+ * @param {number | number[]} expected The expected size
+ * @param {string} [relation='!='] Optional relation between actual
+ * and expected size: '!=', '<', etc.
+ * @extends RangeError
+ */
+ function DimensionError(actual, expected, relation) {
+ if (!(this instanceof DimensionError)) {
+ throw new SyntaxError('Constructor must be called with the new operator');
}
- return reviver;
- };
+ this.actual = actual;
+ this.expected = expected;
+ this.relation = relation;
+
+ this.message = 'Dimension mismatch (' +
+ (Array.isArray(actual) ? ('[' + actual.join(', ') + ']') : actual) +
+ ' ' + (this.relation || '!=') + ' ' +
+ (Array.isArray(expected) ? ('[' + expected.join(', ') + ']') : expected) +
+ ')';
+
+ this.stack = (new Error()).stack;
+ }
+
+ DimensionError.prototype = new RangeError();
+ DimensionError.prototype.constructor = RangeError;
+ DimensionError.prototype.name = 'DimensionError';
+ DimensionError.prototype.isDimensionError = true;
+
+ module.exports = DimensionError;
+
/***/ },
/* 23 */
-/***/ function(module, exports, __webpack_require__) {
-
- 'use strict';
-
- var BigNumber = __webpack_require__(5);
- var errorTransform = __webpack_require__(208).transform;
- var isNumber = __webpack_require__(3).isNumber;
- var argsToArray = __webpack_require__(169).argsToArray;
-
- /**
- * Attach a transform function to math.range
- * Adds a property transform containing the transform function.
- *
- * This transform changed the last `dim` parameter of function concat
- * from one-based to zero based
- * @param {Object} math
- */
- module.exports = function (math) {
- var transform = function () {
- // copy arguments into an array
- var args = argsToArray(arguments);
-
- // change last argument from one-based to zero-based
- var lastIndex = args.length - 1;
- var last = args[lastIndex];
- if (isNumber(last)) {
- args[lastIndex] = last - 1;
- }
- else if (last instanceof BigNumber) {
- args[lastIndex] = last.minus(1);
- }
-
- try {
- return math.concat.apply(math, args);
- }
- catch (err) {
- throw errorTransform(err);
- }
- };
-
- math.concat.transform = transform;
-
- return transform;
- };
-
-
-/***/ },
-/* 24 */
-/***/ function(module, exports, __webpack_require__) {
-
- 'use strict';
-
- var SymbolNode = __webpack_require__(188);
- var isBoolean = __webpack_require__(209).isBoolean;
- var argsToArray = __webpack_require__(169).argsToArray;
- var ArgumentsError = __webpack_require__(171);
-
- /**
- * Attach a transform function to math.filter
- * Adds a property transform containing the transform function.
- *
- * This transform adds support for equations as test function for math.filter,
- * so you can do something like 'filter([3, -2, 5], x > 0)'.
- * @param {Object} math
- */
- module.exports = function (math) {
- var _filter = math.filter;
-
- var transform = function (args, math, scope) {
- if (args.length !== 2) {
- throw new ArgumentsError('filter', arguments.length, 2);
- }
-
- var x = args[0].compile(math).eval(scope);
- var test;
- if (args[1] instanceof SymbolNode) {
- // a function pointer, like filter([3, -2, 5], myTestFunction);
- test = args[1].compile(math).eval(scope);
- }
- else {
- // an equation like filter([3, -2, 5], x > 0)
-
- // find an undefined symbol
- var _scope = scope || {};
- var symbol = args[1]
- .filter(function (node) {
- return (node instanceof SymbolNode) &&
- !(node.name in math) &&
- !(node.name in _scope);
- })[0];
-
- // create a test function for this equation
- var sub = Object.create(_scope);
- var eq = args[1].compile(math);
- if (symbol) {
- var name = symbol.name;
- test = function (x) {
- sub[name] = x;
- return eq.eval(sub);
- }
- }
- else {
- throw new Error('No undefined variable found in filter equation');
- }
- }
-
- return _filter(x, test);
- };
-
- transform.rawArgs = true;
- math.filter.transform = transform;
-
- return transform;
- };
-
-
-/***/ },
-/* 25 */
-/***/ function(module, exports, __webpack_require__) {
-
- 'use strict';
-
- /**
- * Attach a transform function to math.forEach
- * Adds a property transform containing the transform function.
- *
- * This transform creates a one-based index instead of a zero-based index
- * @param {Object} math
- */
- module.exports = function (math) {
-
- var Matrix = math.type.Matrix;
-
- var transform = function (x, callback) {
- if (arguments.length != 2) {
- throw new math.error.ArgumentsError('forEach', arguments.length, 2);
- }
-
- if (Array.isArray(x)) {
- _forEachArray(x, callback, x);
- } else if (x instanceof Matrix) {
- _forEachArray(x.valueOf(), callback, x);
- } else {
- throw new math.error.UnsupportedTypeError('forEach', math['typeof'](x));
- }
- };
-
- function _forEachArray (array, callback, arrayOrig) {
- var recurse = function (value, index) {
- if (Array.isArray(value)) {
- value.forEach(function (child, i) {
- // we create a copy of the index array and append the new index value
- recurse(child, index.concat(i + 1)); // one based index, hence i+1
- });
- }
- else {
- callback(value, index, arrayOrig);
- }
- };
- recurse(array, []);
- }
-
- math.forEach.transform = transform;
-
- return transform;
- };
-
-
-/***/ },
-/* 26 */
-/***/ function(module, exports, __webpack_require__) {
-
- 'use strict';
-
- var BigNumber = __webpack_require__(5);
- var Range = __webpack_require__(8);
- var Index = __webpack_require__(9);
- var isNumber = __webpack_require__(3).isNumber;
-
- /**
- * Attach a transform function to math.index
- * Adds a property transform containing the transform function.
- *
- * This transform creates a one-based index instead of a zero-based index
- * @param {Object} math
- */
- module.exports = function (math) {
- var transform = function () {
- var args = [];
- for (var i = 0, ii = arguments.length; i < ii; i++) {
- var arg = arguments[i];
-
- // change from one-based to zero based, and convert BigNumber to number
- if (arg instanceof Range) {
- arg.start--;
- arg.end -= (arg.step > 0 ? 0 : 2);
- }
- else if (isNumber(arg)) {
- arg--;
- }
- else if (arg instanceof BigNumber) {
- arg = arg.toNumber() - 1;
- }
- else {
- throw new TypeError('Ranges must be a Number or Range');
- }
-
- args[i] = arg;
- }
-
- var res = new Index();
- Index.apply(res, args);
- return res;
- };
-
- math.index.transform = transform;
-
- return transform;
- };
-
-
-/***/ },
-/* 27 */
-/***/ function(module, exports, __webpack_require__) {
-
- 'use strict';
-
- /**
- * Attach a transform function to math.map
- * Adds a property transform containing the transform function.
- *
- * This transform creates a one-based index instead of a zero-based index
- * @param {Object} math
- */
- module.exports = function (math) {
-
- var Matrix = math.type.Matrix;
-
- var transform = function (x, callback) {
- if (arguments.length != 2) {
- throw new math.error.ArgumentsError('map', arguments.length, 2);
- }
-
- if (Array.isArray(x)) {
- return _mapArray(x, callback, x);
- } else if (x instanceof Matrix) {
- return math.matrix(_mapArray(x.valueOf(), callback, x));
- } else {
- throw new math.error.UnsupportedTypeError('map', math['typeof'](x));
- }
- };
-
- function _mapArray (arrayIn, callback, arrayOrig) {
- var recurse = function (value, index) {
- if (Array.isArray(value)) {
- return value.map(function (child, i) {
- // we create a copy of the index array and append the new index value
- return recurse(child, index.concat(i + 1)); // one based index, hence i + 1
- });
- }
- else {
- return callback(value, index, arrayOrig);
- }
- };
-
- return recurse(arrayIn, []);
- }
-
- math.map.transform = transform;
-
- return transform;
- };
-
-
-/***/ },
-/* 28 */
-/***/ function(module, exports, __webpack_require__) {
-
- 'use strict';
-
- var BigNumber = __webpack_require__(5);
- var errorTransform = __webpack_require__(208).transform;
- var isNumber = __webpack_require__(3).isNumber;
- var argsToArray = __webpack_require__(169).argsToArray;
-
- /**
- * Attach a transform function to math.max
- * Adds a property transform containing the transform function.
- *
- * This transform changed the last `dim` parameter of function max
- * from one-based to zero based
- * @param {Object} math
- */
- module.exports = function (math) {
-
- var isCollection = math.collection.isCollection;
-
- var transform = function () {
- var args = argsToArray(arguments);
-
- // change last argument dim from one-based to zero-based
- if (args.length == 2 && isCollection(args[0])) {
- var dim = args[1];
- if (isNumber(dim)) {
- args[1] = dim - 1;
- }
- else if (dim instanceof BigNumber) {
- args[1] = dim.minus(1);
- }
- }
-
- try {
- return math.max.apply(math, args);
- }
- catch (err) {
- throw errorTransform(err);
- }
- };
-
- math.max.transform = transform;
-
- return transform;
- };
-
-
-/***/ },
-/* 29 */
-/***/ function(module, exports, __webpack_require__) {
-
- 'use strict';
-
- var BigNumber = __webpack_require__(5);
- var errorTransform = __webpack_require__(208).transform;
- var isNumber = __webpack_require__(3).isNumber;
- var argsToArray = __webpack_require__(169).argsToArray;
-
- /**
- * Attach a transform function to math.mean
- * Adds a property transform containing the transform function.
- *
- * This transform changed the last `dim` parameter of function mean
- * from one-based to zero based
- * @param {Object} math
- */
- module.exports = function (math) {
-
- var isCollection = math.collection.isCollection;
-
- var transform = function () {
- var args = argsToArray(arguments);
-
- // change last argument dim from one-based to zero-based
- if (args.length == 2 && isCollection(args[0])) {
- var dim = args[1];
- if (isNumber(dim)) {
- args[1] = dim - 1;
- }
- else if (dim instanceof BigNumber) {
- args[1] = dim.minus(1);
- }
- }
-
- try {
- return math.mean.apply(math, args);
- }
- catch (err) {
- throw errorTransform(err);
- }
- };
-
- math.mean.transform = transform;
-
- return transform;
- };
-
-
-/***/ },
-/* 30 */
-/***/ function(module, exports, __webpack_require__) {
-
- 'use strict';
-
- var BigNumber = __webpack_require__(5);
- var errorTransform = __webpack_require__(208).transform;
- var isNumber = __webpack_require__(3).isNumber;
- var argsToArray = __webpack_require__(169).argsToArray;
-
- /**
- * Attach a transform function to math.min
- * Adds a property transform containing the transform function.
- *
- * This transform changed the last `dim` parameter of function min
- * from one-based to zero based
- * @param {Object} math
- */
- module.exports = function (math) {
-
- var isCollection = math.collection.isCollection;
-
- var transform = function () {
- var args = argsToArray(arguments);
-
- // change last argument dim from one-based to zero-based
- if (args.length == 2 && isCollection(args[0])) {
- var dim = args[1];
- if (isNumber(dim)) {
- args[1] = dim - 1;
- }
- else if (dim instanceof BigNumber) {
- args[1] = dim.minus(1);
- }
- }
-
- try {
- return math.min.apply(math, args);
- }
- catch (err) {
- throw errorTransform(err);
- }
- };
-
- math.min.transform = transform;
-
- return transform;
- };
-
-
-/***/ },
-/* 31 */
-/***/ function(module, exports, __webpack_require__) {
-
- 'use strict';
-
- var isBoolean = __webpack_require__(209).isBoolean;
- var argsToArray = __webpack_require__(169).argsToArray;
-
- /**
- * Attach a transform function to math.range
- * Adds a property transform containing the transform function.
- *
- * This transform creates a range which includes the end value
- * @param {Object} math
- */
- module.exports = function (math) {
- var transform = function () {
- var args = argsToArray(arguments);
-
- var lastIndex = args.length - 1;
- var last = args[lastIndex];
- if (!isBoolean(last)) {
- args.push(true); // append a parameter includeEnd=true
- }
-
- return math.range.apply(math, args);
- };
-
- math.range.transform = transform;
-
- return transform;
- };
-
-
-/***/ },
-/* 32 */
-/***/ function(module, exports, __webpack_require__) {
-
- 'use strict';
-
- var errorTransform = __webpack_require__(208).transform;
- var isBoolean = __webpack_require__(209).isBoolean;
- var argsToArray = __webpack_require__(169).argsToArray;
-
- /**
- * Attach a transform function to math.subset
- * Adds a property transform containing the transform function.
- *
- * This transform creates a range which includes the end value
- * @param {Object} math
- */
- module.exports = function (math) {
- var transform = function () {
- try {
- return math.subset.apply(math, argsToArray(arguments));
- }
- catch (err) {
- throw errorTransform(err);
- }
- };
-
- math.subset.transform = transform;
-
- return transform;
- };
-
-
-/***/ },
-/* 33 */
-/***/ function(module, exports, __webpack_require__) {
-
- 'use strict';
-
- module.exports = function (math) {
- var string = __webpack_require__(176);
-
- /**
- * @constructor Chain
- * Wrap any value in a chain, allowing to perform chained operations on
- * the value.
- *
- * All methods available in the math.js library can be called upon the chain,
- * and then will be evaluated with the value itself as first argument.
- * The chain can be closed by executing chain.done(), which will return
- * the final value.
- *
- * The Chain has a number of special functions:
- * - done() Finalize the chained operation and return the
- * chain's value.
- * - valueOf() The same as done()
- * - toString() Returns a string representation of the chain's value.
- *
- * @param {*} [value]
- */
- function Chain (value) {
- if (!(this instanceof Chain)) {
- throw new SyntaxError('Constructor must be called with the new operator');
- }
-
- if (value instanceof Chain) {
- this.value = value.value;
- }
- else {
- this.value = value;
- }
- }
-
- /**
- * Close the chain. Returns the final value.
- * Does the same as method valueOf()
- * @returns {*} value
- */
- Chain.prototype.done = function () {
- return this.value;
- };
-
- /**
- * Close the chain. Returns the final value.
- * Does the same as method done()
- * @returns {*} value
- */
- Chain.prototype.valueOf = function () {
- return this.value;
- };
-
- /**
- * Get a string representation of the value in the chain
- * @returns {String}
- */
- Chain.prototype.toString = function () {
- return string.format(this.value);
- };
-
- /**
- * Create a proxy method for the chain
- * @param {String} name
- * @param {*} value The value or function to be proxied
- */
- function createProxy(name, value) {
- var slice = Array.prototype.slice;
- if (typeof value === 'function') {
- // a function
- Chain.prototype[name] = function () {
- var args = [this.value].concat(slice.call(arguments, 0));
- return new Chain(value.apply(this, args));
- }
- }
- else {
- // a constant
- Chain.prototype[name] = new Chain(value);
- }
- }
-
- Chain.createProxy = createProxy;
-
- /**
- * initialise the Chain prototype with all functions and constants in math
- */
- for (var prop in math) {
- if (math.hasOwnProperty(prop)) {
- createProxy(prop, math[prop]);
- }
- }
-
- return Chain;
- };
-
-
-/***/ },
-/* 34 */
-/***/ function(module, exports, __webpack_require__) {
-
- 'use strict';
-
- module.exports = function (math) {
- var util = __webpack_require__(175),
-
- // take the BigNumber instance the provided math.js instance
- BigNumber = math.type.BigNumber,
- collection = math.collection,
-
- isCollection = collection.isCollection,
- isNumber = util.number.isNumber,
- isString = util.string.isString,
- isBoolean = util['boolean'].isBoolean;
-
- /**
- * Create a BigNumber, which can store numbers with arbitrary precision.
- * When a matrix is provided, all elements will be converted to BigNumber.
- *
- * Syntax:
- *
- * math.bignumber(x)
- *
- * Examples:
- *
- * 0.1 + 0.2; // returns Number 0.30000000000000004
- * math.bignumber(0.1) + math.bignumber(0.2); // returns BigNumber 0.3
- *
- *
- * 7.2e500; // returns Number Infinity
- * math.bignumber('7.2e500'); // returns BigNumber 7.2e500
- *
- * See also:
- *
- * boolean, complex, index, matrix, string, unit
- *
- * @param {Number | String | Array | Matrix | Boolean | null} [value] Value for the big number,
- * 0 by default.
- * @returns {BigNumber} The created bignumber
- */
- math.bignumber = function bignumber(value) {
- if (arguments.length > 1) {
- throw new math.error.ArgumentsError('bignumber', arguments.length, 0, 1);
- }
-
- if ((value instanceof BigNumber) || isNumber(value) || isString(value)) {
- return new BigNumber(value);
- }
-
- if (isBoolean(value) || value === null) {
- return new BigNumber(+value);
- }
-
- if (isCollection(value)) {
- return collection.deepMap(value, bignumber);
- }
-
- if (arguments.length == 0) {
- return new BigNumber(0);
- }
-
- throw new math.error.UnsupportedTypeError('bignumber', math['typeof'](value));
- };
- };
-
-
-/***/ },
-/* 35 */
-/***/ function(module, exports, __webpack_require__) {
-
- 'use strict';
-
- module.exports = function (math) {
- var util = __webpack_require__(175),
-
- BigNumber = math.type.BigNumber,
- collection = math.collection,
-
- isCollection = collection.isCollection,
- isNumber = util.number.isNumber,
- isString = util.string.isString;
-
- /**
- * Create a boolean or convert a string or number to a boolean.
- * In case of a number, `true` is returned for non-zero numbers, and `false` in
- * case of zero.
- * Strings can be `'true'` or `'false'`, or can contain a number.
- * When value is a matrix, all elements will be converted to boolean.
- *
- * Syntax:
- *
- * math.boolean(x)
- *
- * Examples:
- *
- * math.boolean(0); // returns false
- * math.boolean(1); // returns true
- * math.boolean(-3); // returns true
- * math.boolean('true'); // returns true
- * math.boolean('false'); // returns false
- * math.boolean([1, 0, 1, 1]); // returns [true, false, true, true]
- *
- * See also:
- *
- * bignumber, complex, index, matrix, string, unit
- *
- * @param {String | Number | Boolean | Array | Matrix | null} value A value of any type
- * @return {Boolean | Array | Matrix} The boolean value
- */
- math['boolean'] = function bool (value) {
- if (arguments.length != 1) {
- throw new math.error.ArgumentsError('boolean', arguments.length, 0, 1);
- }
-
- if (value === 'true' || value === true) {
- return true;
- }
-
- if (value === 'false' || value === false || value === null) {
- return false;
- }
-
- if (value instanceof Boolean) {
- return value == true;
- }
-
- if (isNumber(value)) {
- return (value !== 0);
- }
-
- if (value instanceof BigNumber) {
- return !value.isZero();
- }
-
- if (isString(value)) {
- // try case insensitive
- var lcase = value.toLowerCase();
- if (lcase === 'true') {
- return true;
- }
- else if (lcase === 'false') {
- return false;
- }
-
- // test whether value is a valid number
- var num = Number(value);
- if (value != '' && !isNaN(num)) {
- return (num !== 0);
- }
- }
-
- if (isCollection(value)) {
- return collection.deepMap(value, bool);
- }
-
- throw new SyntaxError(value.toString() + ' is no valid boolean');
- };
- };
-
-
-/***/ },
-/* 36 */
-/***/ function(module, exports, __webpack_require__) {
-
- 'use strict';
-
- module.exports = function (math) {
- var util = __webpack_require__(175),
-
- BigNumber = math.type.BigNumber,
- Complex = __webpack_require__(7),
- collection = math.collection,
-
- isCollection = collection.isCollection,
- isNumber = util.number.isNumber,
- isString = util.string.isString,
- isComplex = Complex.isComplex;
-
- /**
- * Create a complex value or convert a value to a complex value.
- *
- * Syntax:
- *
- * math.complex() // creates a complex value with zero
- * // as real and imaginary part.
- * math.complex(re : number, im : string) // creates a complex value with provided
- * // values for real and imaginary part.
- * math.complex(re : number) // creates a complex value with provided
- * // real value and zero imaginary part.
- * math.complex(complex : Complex) // clones the provided complex value.
- * math.complex(arg : string) // parses a string into a complex value.
- * math.complex(array : Array) // converts the elements of the array
- * // or matrix element wise into a
- * // complex value.
- * math.complex({re: number, im: number}) // creates a complex value with provided
- * // values for real an imaginary part.
- * math.complex({r: number, phi: number}) // creates a complex value with provided
- * // polar coordinates
- *
- * Examples:
- *
- * var a = math.complex(3, -4); // a = Complex 3 - 4i
- * a.re = 5; // a = Complex 5 - 4i
- * var i = a.im; // Number -4;
- * var b = math.complex('2 + 6i'); // Complex 2 + 6i
- * var c = math.complex(); // Complex 0 + 0i
- * var d = math.add(a, b); // Complex 5 + 2i
- *
- * See also:
- *
- * bignumber, boolean, index, matrix, number, string, unit
- *
- * @param {* | Array | Matrix} [args]
- * Arguments specifying the real and imaginary part of the complex number
- * @return {Complex | Array | Matrix} Returns a complex value
- */
- math.complex = function complex(args) {
- switch (arguments.length) {
- case 0:
- // no parameters. Set re and im zero
- return new Complex(0, 0);
-
- case 1:
- // parse string into a complex number
- var arg = arguments[0];
-
- if (isNumber(arg)) {
- return new Complex(arg, 0);
- }
-
- if (arg instanceof BigNumber) {
- // convert to Number
- return new Complex(arg.toNumber(), 0);
- }
-
- if (isComplex(arg)) {
- // create a clone
- return arg.clone();
- }
-
- if (isString(arg)) {
- var c = Complex.parse(arg);
- if (c) {
- return c;
- }
- else {
- throw new SyntaxError('String "' + arg + '" is no valid complex number');
- }
- }
-
- if (isCollection(arg)) {
- return collection.deepMap(arg, complex);
- }
-
- if (typeof arg === 'object') {
- if('re' in arg && 'im' in arg) {
- return new Complex(arg.re, arg.im);
- } else if ('r' in arg && 'phi' in arg) {
- return Complex.fromPolar(arg.r, arg.phi);
- }
- }
-
- throw new TypeError('Two numbers, single string or an fitting object expected in function complex');
-
- case 2:
- // re and im provided
- var re = arguments[0],
- im = arguments[1];
-
- // convert re to number
- if (re instanceof BigNumber) {
- re = re.toNumber();
- }
-
- // convert im to number
- if (im instanceof BigNumber) {
- im = im.toNumber();
- }
-
- if (isNumber(re) && isNumber(im)) {
- return new Complex(re, im);
- }
- else {
- throw new TypeError('Two numbers or a single string expected in function complex');
- }
-
- default:
- throw new math.error.ArgumentsError('complex', arguments.length, 0, 2);
- }
- };
- };
-
-
-/***/ },
-/* 37 */
-/***/ function(module, exports, __webpack_require__) {
-
- 'use strict';
-
- module.exports = function (math) {
- var util = __webpack_require__(175),
-
- BigNumber = math.type.BigNumber,
- Index = __webpack_require__(9);
-
- /**
- * Create an index. An Index can store ranges having start, step, and end
- * for multiple dimensions.
- * Matrix.get, Matrix.set, and math.subset accept an Index as input.
- *
- * Syntax:
- *
- * math.index(range1, range2, ...)
- *
- * Where:
- *
- * Each range can be any of:
- *
- * - An array [start, end]
- * - An array [start, end, step]
- * - A number
- * - An instance of `Range`
- *
- * The parameters start, end, and step must be integer numbers. Start and end
- * are zero based. The start of a range is included, the end is excluded.
- *
- * Examples:
- *
- * var math = math.js
- *
- * var b = [1, 2, 3, 4, 5];
- * math.subset(b, math.index([1, 3])); // returns [2, 3]
- *
- * var a = math.matrix([[1, 2], [3, 4]]);
- * a.subset(math.index(0, 1)); // returns 2
- * a.subset(math.index(1, null)); // returns [3, 4]
- *
- * See also:
- *
- * bignumber, boolean, complex, matrix, number, string, unit
- *
- * @param {...*} ranges Zero or more ranges or numbers.
- * @return {Index} Returns the created index
- */
- math.index = function(ranges) {
- // downgrade BigNumber to Number
- var args = Array.prototype.slice.apply(arguments).map(function (arg) {
- if (arg instanceof BigNumber) {
- return arg.toNumber();
- }
- else if (Array.isArray(arg)) {
- return arg.map(function (elem) {
- return (elem instanceof BigNumber) ? elem.toNumber() : elem;
- });
- }
- else {
- return arg;
- }
- });
-
- var res = new Index();
- Index.apply(res, args);
- return res;
- };
- };
-
-
-/***/ },
-/* 38 */
-/***/ function(module, exports, __webpack_require__) {
-
- 'use strict';
-
- var string = __webpack_require__(176);
-
- var isArray = Array.isArray;
- var isString = string.isString;
-
- module.exports = function (math) {
- var Matrix = math.type.Matrix;
-
+/***/ function(module, exports) {
+
+ 'use strict';
+
+ function factory (type, config, load, typed) {
/**
* Create a Matrix. The function creates a new `math.type.Matrix` object from
* an `Array`. A Matrix has utility functions to manipulate the data in the
* matrix, like getting the size and getting or setting values in the matrix.
+ * Supported storage formats are 'dense' and 'sparse'.
*
* Syntax:
*
- * math.matrix() // creates an empty matrix using default storage format (dense).
- * math.matrix(data) // creates a matrix with initial data using default storage format (dense).
- * math.matrix('dense') // creates an empty matrix using the given storage format.
- * math.matrix(data, 'dense') // creates a matrix with initial data using the given storage format.
+ * math.matrix() // 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:
*
@@ -10017,3567 +3966,179 @@
*
* See also:
*
- * bignumber, boolean, complex, index, number, string, unit
+ * 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
*/
- math.matrix = function matrix(data, format) {
- // check arguments
- switch (arguments.length) {
- case 0:
- // set data and format
- data = [];
- format = 'default';
- break;
- case 1:
- // check data was provided
- if (isArray(data)) {
- // use default format
- format = 'default';
- }
- else if (data instanceof Matrix) {
- // same format as matrix
- format = data.storage();
- }
- else if (isString(data)) {
- // set format
- format = data;
- // empty array
- data = [];
- }
- break;
- case 2:
- // check data is an array
- if (!isArray(data) && !(data instanceof Matrix)) {
- // throw
- throw new TypeError('data must be an array value or Matrix instance');
- }
- break;
- default:
- throw new math.error.ArgumentsError('matrix', arguments.length, 0, 2);
- }
-
+ 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 constructor = Matrix.storage(format);
+ var M = type.Matrix.storage(format || 'default');
// create instance
- return new constructor(data);
- };
- };
-
-
-/***/ },
-/* 39 */
-/***/ function(module, exports, __webpack_require__) {
-
- 'use strict';
-
- module.exports = function (math) {
- var util = __webpack_require__(175);
-
- var BigNumber = math.type.BigNumber;
- var Unit = math.type.Unit;
- var collection = math.collection;
-
- var isCollection = collection.isCollection;
- var isNumber = util.number.isNumber;
- var isBoolean = util['boolean'].isBoolean;
- var isString = util.string.isString;
-
- /**
- * Create a number or convert a string, boolean, or unit to a number.
- * When value is a matrix, all elements will be converted to number.
- *
- * Syntax:
- *
- * math.number(value)
- * math.number(unit, valuelessUnit)
- *
- * Examples:
- *
- * math.number(2); // returns number 2
- * math.number('7.2'); // returns number 7.2
- * math.number(true); // returns number 1
- * math.number([true, false, true, true]); // returns [1, 0, 1, 1]
- * math.number(math.unit('52cm'), 'm'); // returns 0.52
- *
- * See also:
- *
- * bignumber, boolean, complex, index, matrix, string, unit
- *
- * @param {String | Number | Boolean | Array | Matrix | Unit | null} [value] Value to be converted
- * @param {Unit | string} [valuelessUnit] A valueless unit, used to convert a unit to a number
- * @return {Number | Array | Matrix} The created number
- */
- math.number = function number (value, valuelessUnit) {
- switch (arguments.length) {
- case 0:
- return 0;
-
- case 1:
- if (isCollection(value)) {
- return collection.deepMap(value, number);
- }
-
- if (value instanceof BigNumber) {
- return value.toNumber();
- }
-
- if (isString(value)) {
- var num = Number(value);
- if (isNaN(num)) {
- num = Number(value.valueOf());
- }
- if (isNaN(num)) {
- throw new SyntaxError(value.toString() + ' is no valid number');
- }
- return num;
- }
-
- if (isBoolean(value) || value === null) {
- return +value;
- }
-
- if (isNumber(value)) {
- return value;
- }
-
- if (value instanceof Unit) {
- throw new Error('Second argument with valueless unit expected');
- }
-
- throw new math.error.UnsupportedTypeError('number', math['typeof'](value));
-
- case 2:
- if (value instanceof Unit && isString(valuelessUnit) || valuelessUnit instanceof Unit) {
- return value.toNumber(valuelessUnit);
- }
-
- throw new math.error.UnsupportedTypeError('number', math['typeof'](value), math['typeof'](valuelessUnit));
-
-
- default:
- throw new math.error.ArgumentsError('number', arguments.length, 0, 1);
- }
- };
- };
-
-
-/***/ },
-/* 40 */
-/***/ function(module, exports, __webpack_require__) {
-
- 'use strict';
-
- module.exports = function (math) {
- var Parser = math.expression.Parser;
-
- /**
- * Create a parser. The function creates a new `math.expression.Parser` object.
- *
- * Syntax:
- *
- * math.parser()
- *
- * Examples:
- *
- * var parser = new math.parser();
- *
- * // evaluate expressions
- * var a = parser.eval('sqrt(3^2 + 4^2)'); // 5
- * var b = parser.eval('sqrt(-4)'); // 2i
- * var c = parser.eval('2 inch in cm'); // 5.08 cm
- * var d = parser.eval('cos(45 deg)'); // 0.7071067811865476
- *
- * // define variables and functions
- * parser.eval('x = 7 / 2'); // 3.5
- * parser.eval('x + 3'); // 6.5
- * parser.eval('function f(x, y) = x^y'); // f(x, y)
- * parser.eval('f(2, 3)'); // 8
- *
- * // get and set variables and functions
- * var x = parser.get('x'); // 7
- * var f = parser.get('f'); // function
- * var g = f(3, 2); // 9
- * parser.set('h', 500);
- * var i = parser.eval('h / 2'); // 250
- * parser.set('hello', function (name) {
- * return 'hello, ' + name + '!';
- * });
- * parser.eval('hello("user")'); // "hello, user!"
- *
- * // clear defined functions and variables
- * parser.clear();
- *
- * See also:
- *
- * eval, compile, parse
- *
- * @return {Parser} Parser
- */
- math.parser = function parser() {
- return new Parser();
- };
- };
-
-
-/***/ },
-/* 41 */
-/***/ function(module, exports, __webpack_require__) {
-
- 'use strict';
-
- module.exports = function (math) {
- /**
- * Wrap any value in a chain, allowing to perform chained operations on
- * the value.
- *
- * All methods available in the math.js library can be called upon the chain,
- * and then will be evaluated with the value itself as first argument.
- * The chain can be closed by executing `chain.done()`, which returns
- * the final value.
- *
- * The chain has a number of special functions:
- *
- * - `done()` Finalize the chain and return the chain's value.
- * - `valueOf()` The same as `done()`
- * - `toString()` Executes `math.format()` onto the chain's value, returning
- * a string representation of the value.
- *
- * Syntax:
- *
- * math.chain(value)
- *
- * Examples:
- *
- * math.chain(3)
- * .add(4)
- * .subtract(2)
- * .done(); // 5
- *
- * math.chain( [[1, 2], [3, 4]] )
- * .subset(math.index(0, 0), 8)
- * .multiply(3)
- * .done(); // [[24, 6], [9, 12]]
- *
- * @param {*} [value] A value of any type on which to start a chained operation.
- * @return {math.chaining.Chain} The created chain
- */
- math.chain = function(value) {
- // TODO: check number of arguments
- return new math.chaining.Chain(value);
- };
-
- // TODO: deprecate math.select in v2.0
- math.select = function(value) {
- // give a warning once.
- if (console && typeof console.log === 'function') {
- console.log('WARNING: Function "select" is renamed to "chain". It will be deprecated in v2.0.')
- }
-
- // replace warning function with chain function
- math.select = math.chain;
- math.chaining.Chain.prototype['select'] = math.select;
-
- return math.chain(value);
- }
- };
-
-
-/***/ },
-/* 42 */
-/***/ function(module, exports, __webpack_require__) {
-
- 'use strict';
-
- module.exports = function (math) {
- var util = __webpack_require__(175),
-
- collection = math.collection,
-
- number = util.number,
- isNumber = util.number.isNumber,
- isCollection = collection.isCollection;
-
- /**
- * Create a string or convert any object into a string.
- * Elements of Arrays and Matrices are processed element wise.
- *
- * Syntax:
- *
- * math.string(value)
- *
- * Examples:
- *
- * math.string(4.2); // returns string '4.2'
- * math.string(math.complex(3, 2); // returns string '3 + 2i'
- *
- * var u = math.unit(5, 'km');
- * math.string(u.to('m')); // returns string '5000 m'
- *
- * math.string([true, false]); // returns ['true', 'false']
- *
- * See also:
- *
- * bignumber, boolean, complex, index, matrix, number, unit
- *
- * @param {* | Array | Matrix | null} [value] A value to convert to a string
- * @return {String | Array | Matrix} The created string
- */
- math.string = function string (value) {
- switch (arguments.length) {
- case 0:
- return '';
-
- case 1:
- if (isNumber(value)) {
- return number.format(value);
- }
-
- if (isCollection(value)) {
- return collection.deepMap(value, string);
- }
-
- if (value === null) {
- return 'null';
- }
-
- return value.toString();
-
- default:
- throw new math.error.ArgumentsError('string', arguments.length, 0, 1);
- }
- };
- };
-
-
-/***/ },
-/* 43 */
-/***/ function(module, exports, __webpack_require__) {
-
- 'use strict';
-
- module.exports = function (math) {
- var util = __webpack_require__(175),
-
- BigNumber = math.type.BigNumber,
- Unit = __webpack_require__(11),
- collection = math.collection,
-
- isCollection = collection.isCollection,
- isString = util.string.isString;
-
- /**
- * Create a unit. Depending on the passed arguments, the function
- * will create and return a new math.type.Unit object.
- * When a matrix is provided, all elements will be converted to units.
- *
- * Syntax:
- *
- * math.unit(unit : string)
- * math.unit(value : number, unit : string)
- *
- * Examples:
- *
- * var a = math.unit(5, 'cm'); // returns Unit 50 mm
- * var b = math.unit('23 kg'); // returns Unit 23 kg
- * a.to('m'); // returns Unit 0.05 m
- *
- * See also:
- *
- * bignumber, boolean, complex, index, matrix, number, string
- *
- * @param {* | Array | Matrix} args A number and unit.
- * @return {Unit | Array | Matrix} The created unit
- */
- math.unit = function unit(args) {
- switch(arguments.length) {
- case 1:
- // parse a string
- var arg = arguments[0];
-
- if (arg instanceof Unit) {
- // create a clone of the unit
- return arg.clone();
- }
-
- if (isString(arg)) {
- if (Unit.isValuelessUnit(arg)) {
- return new Unit(null, arg); // a pure unit
- }
-
- var u = Unit.parse(arg); // a unit with value, like '5cm'
- if (u) {
- return u;
- }
-
- throw new SyntaxError('String "' + arg + '" is no valid unit');
- }
-
- if (isCollection(args)) {
- return collection.deepMap(args, unit);
- }
-
- throw new TypeError('A string or a number and string expected in function unit');
-
- case 2:
- // a number and a unit
-
- if (arguments[0] instanceof BigNumber) {
- // convert value to number
- return new Unit(arguments[0].toNumber(), arguments[1]);
- }
- else {
- return new Unit(arguments[0], arguments[1]);
- }
-
- default:
- throw new math.error.ArgumentsError('unit', arguments.length, 1, 2);
- }
- };
- };
-
-
-/***/ },
-/* 44 */
-/***/ function(module, exports, __webpack_require__) {
-
- 'use strict';
-
- module.exports = function (math, config) {
- var util = __webpack_require__(175),
- _parse = math.expression.parse,
-
- collection = math.collection,
-
- isString = util.string.isString,
- isCollection = collection.isCollection;
-
- /**
- * Parse and compile an expression.
- * Returns a an object with a function `eval([scope])` to evaluate the
- * compiled expression.
- *
- * Syntax:
- *
- * math.compile(expr) // returns one node
- * math.compile([expr1, expr2, expr3, ...]) // returns an array with nodes
- *
- * Examples:
- *
- * var code = math.compile('sqrt(3^2 + 4^2)');
- * code.eval(); // 5
- *
- * var scope = {a: 3, b: 4}
- * var code = math.compile('a * b'); // 12
- * code.eval(scope); // 12
- * scope.a = 5;
- * code.eval(scope); // 20
- *
- * var nodes = math.compile(['a = 3', 'b = 4', 'a * b']);
- * nodes[2].eval(); // 12
- *
- * See also:
- *
- * parse, eval
- *
- * @param {String | String[] | Matrix} expr
- * The expression to be compiled
- * @return {{eval: Function} | Array.<{eval: Function}>} code
- * An object with the compiled expression
- * @throws {Error}
- */
- math.compile = function compile (expr) {
- if (arguments.length != 1) {
- throw new math.error.ArgumentsError('compile', arguments.length, 1);
- }
-
- if (isString(expr)) {
- // evaluate a single expression
- return _parse(expr).compile(math);
- }
- else if (isCollection(expr)) {
- // evaluate an array or matrix with expressions
- return collection.deepMap(expr, function (elem) {
- return _parse(elem).compile(math);
- });
- }
- else {
- // oops
- throw new TypeError('String, array, or matrix expected');
- }
- }
- };
-
-
-/***/ },
-/* 45 */
-/***/ function(module, exports, __webpack_require__) {
-
- 'use strict';
-
- module.exports = function (math) {
- var util = __webpack_require__(175),
- _parse = math.expression.parse,
-
- collection = math.collection,
-
- isString = util.string.isString,
- isCollection = collection.isCollection;
-
- /**
- * Evaluate an expression.
- *
- * Syntax:
- *
- * math.eval(expr)
- * math.eval(expr, scope)
- * math.eval([expr1, expr2, expr3, ...])
- * math.eval([expr1, expr2, expr3, ...], scope)
- *
- * Example:
- *
- * math.eval('(2+3)/4'); // 1.25
- * math.eval('sqrt(3^2 + 4^2)'); // 5
- * math.eval('sqrt(-4)'); // 2i
- * math.eval(['a=3', 'b=4', 'a*b']);, // [3, 4, 12]
- *
- * var scope = {a:3, b:4};
- * math.eval('a * b', scope); // 12
- *
- * See also:
- *
- * parse, compile
- *
- * @param {String | String[] | Matrix} expr The expression to be evaluated
- * @param {Object} [scope] Scope to read/write variables
- * @return {*} The result of the expression
- * @throws {Error}
- */
- math.eval = function _eval (expr, scope) {
- if (arguments.length != 1 && arguments.length != 2) {
- throw new math.error.ArgumentsError('eval', arguments.length, 1, 2);
- }
-
- // instantiate a scope
- scope = scope || {};
-
- if (isString(expr)) {
- // evaluate a single expression
- return _parse(expr)
- .compile(math)
- .eval(scope);
- }
- else if (isCollection(expr)) {
- // evaluate an array or matrix with expressions
- return collection.deepMap(expr, function (elem) {
- return _parse(elem)
- .compile(math).eval(scope);
- });
- }
- else {
- // oops
- throw new TypeError('String, array, or matrix expected');
- }
- };
- };
-
-
-/***/ },
-/* 46 */
-/***/ function(module, exports, __webpack_require__) {
-
- 'use strict';
-
- module.exports = function (math) {
- var Help = __webpack_require__(12);
-
- /**
- * Retrieve help on a function or data type.
- * Help files are retrieved from the documentation in math.expression.docs.
- *
- * Syntax:
- *
- * math.help(search)
- *
- * Examples:
- *
- * console.log(math.help('sin').toString());
- * console.log(math.help(math.add).toString());
- * console.log(math.help(math.add).toJSON());
- *
- * @param {function | string | Object} search A function or function name
- * for which to get help
- * @return {Help} A help object
- */
- math.help = function help(search) {
- if (arguments.length != 1) {
- throw new SyntaxError('Wrong number of arguments in function help ' +
- '(' + arguments.length + ' provided, 1 expected)');
- }
-
- var text = null;
- if ((search instanceof String) || (typeof(search) === 'string')) {
- text = search;
- }
- else {
- var prop;
- for (prop in math) {
- // search in functions and constants
- if (math.hasOwnProperty(prop) && (search === math[prop])) {
- text = prop;
- break;
- }
- }
-
- /* TODO: implement help for data types
- if (!text) {
- // search data type
- for (prop in math.type) {
- if (math.type.hasOwnProperty(prop)) {
- if (search === math.type[prop]) {
- text = prop;
- break;
- }
- }
- }
- }
- */
- }
-
- var doc = math.expression.docs[text];
- if (!text) {
- throw new Error('Cannot find "' + search + '" in math.js');
- } else if (!doc) {
- throw new Error('No documentation found on "' + text + '"');
- }
- return new Help(doc);
- };
- };
-
-
-/***/ },
-/* 47 */
-/***/ function(module, exports, __webpack_require__) {
-
- 'use strict';
-
- module.exports = function (math, config) {
- var _parse = math.expression.parse;
-
- /**
- * Parse an expression. Returns a node tree, which can be evaluated by
- * invoking node.eval();
- *
- * Syntax:
- *
- * parse(expr)
- * parse(expr, options)
- * parse([expr1, expr2, expr3, ...])
- * parse([expr1, expr2, expr3, ...], options)
- *
- * Example:
- *
- * var node = parse('sqrt(3^2 + 4^2)');
- * node.compile(math).eval(); // 5
- *
- * var scope = {a:3, b:4}
- * var node = parse('a * b'); // 12
- * var code = node.compile(math);
- * code.eval(scope); // 12
- * scope.a = 5;
- * code.eval(scope); // 20
- *
- * var nodes = math.parse(['a = 3', 'b = 4', 'a * b']);
- * nodes[2].compile(math).eval(); // 12
- *
- * @param {String | String[] | Matrix} expr Expression to be parsed
- * @param {{nodes: Object<String, Node>}} [options] Available options:
- * - `nodes` a set of custom nodes
- * @return {Node | Node[]} node
- * @throws {Error}
- */
- math.parse = function parse (expr, options) {
- return _parse.apply(_parse, arguments);
- }
-
- };
-
-
-/***/ },
-/* 48 */
-/***/ function(module, exports, __webpack_require__) {
-
- 'use strict';
-
- module.exports = function (math) {
- var util = __webpack_require__(175),
-
- BigNumber = math.type.BigNumber,
- Complex = __webpack_require__(7),
- collection = math.collection,
-
- isNumber = util.number.isNumber,
- isBoolean = util.boolean.isBoolean,
- isComplex = Complex.isComplex,
- isCollection = collection.isCollection;
-
- /**
- * Calculate the absolute value of a number. For matrices, the function is
- * evaluated element wise.
- *
- * Syntax:
- *
- * math.abs(x)
- *
- * Examples:
- *
- * math.abs(3.5); // returns Number 3.5
- * math.abs(-4.2); // returns Number 4.2
- *
- * math.abs([3, -5, -1, 0, 2]); // returns Array [3, 5, 1, 0, 2]
- *
- * See also:
- *
- * sign
- *
- * @param {Number | BigNumber | Boolean | Complex | Array | Matrix | null} x
- * A number or matrix for which to get the absolute value
- * @return {Number | BigNumber | Complex | Array | Matrix}
- * Absolute value of `x`
- */
- math.abs = function abs(x) {
- if (arguments.length != 1) {
- throw new math.error.ArgumentsError('abs', arguments.length, 1);
- }
-
- if (isNumber(x)) {
- return Math.abs(x);
- }
-
- if (isComplex(x)) {
- // do not compute sqrt(re * re + im * im) since it will overflow with big numbers!
- var re = Math.abs(x.re);
- var im = Math.abs(x.im);
- if (re >= im) {
- var i = im / re;
- return re * Math.sqrt(1 + i * i);
- }
- var j = re / im;
- return im * Math.sqrt(1 + j * j);
- }
-
- if (x instanceof BigNumber) {
- return x.abs();
- }
-
- if (isCollection(x)) {
- // deep map collection, skip zeros since abs(0) = 0
- return collection.deepMap(x, abs, true);
- }
-
- if (isBoolean(x) || x === null) {
- return Math.abs(x);
- }
-
- throw new math.error.UnsupportedTypeError('abs', math['typeof'](x));
- };
- };
-
-
-/***/ },
-/* 49 */
-/***/ function(module, exports, __webpack_require__) {
-
- 'use strict';
-
- module.exports = function (math) {
- var util = __webpack_require__(175),
-
- BigNumber = math.type.BigNumber,
- Complex = __webpack_require__(7),
- Unit = __webpack_require__(11),
- collection = math.collection,
-
- isBoolean = util['boolean'].isBoolean,
- isNumber = util.number.isNumber,
- isString = util.string.isString,
- isComplex = Complex.isComplex,
- isUnit = Unit.isUnit,
- isCollection = collection.isCollection;
-
- /**
- * Add two values, `x + y`.
- * For matrices, the function is evaluated element wise.
- *
- * Syntax:
- *
- * math.add(x, y)
- *
- * Examples:
- *
- * math.add(2, 3); // returns Number 5
- *
- * var a = math.complex(2, 3);
- * var b = math.complex(-4, 1);
- * math.add(a, b); // returns Complex -2 + 4i
- *
- * math.add([1, 2, 3], 4); // returns Array [5, 6, 7]
- *
- * var c = math.unit('5 cm');
- * var d = math.unit('2.1 mm');
- * math.add(c, d); // returns Unit 52.1 mm
- *
- * See also:
- *
- * subtract
- *
- * @param {Number | BigNumber | Boolean | Complex | Unit | String | Array | Matrix | null} x First value to add
- * @param {Number | BigNumber | Boolean | Complex | Unit | String | Array | Matrix | null} y Second value to add
- * @return {Number | BigNumber | Complex | Unit | String | Array | Matrix} Sum of `x` and `y`
- */
- math.add = function add(x, y) {
- if (arguments.length != 2) {
- throw new math.error.ArgumentsError('add', arguments.length, 2);
- }
-
- if (isNumber(x)) {
- if (isNumber(y)) {
- // number + number
- return x + y;
- }
- else if (isComplex(y)) {
- // number + complex
- return new Complex(
- x + y.re,
- y.im
- );
- }
- }
-
- if (isComplex(x)) {
- if (isComplex(y)) {
- // complex + complex
- return new Complex(
- x.re + y.re,
- x.im + y.im
- );
- }
- else if (isNumber(y)) {
- // complex + number
- return new Complex(
- x.re + y,
- x.im
- );
- }
- }
-
- if (isUnit(x)) {
- if (isUnit(y)) {
- if (x.value == null) {
- throw new Error('Parameter x contains a unit with undefined value');
- }
-
- if (y.value == null) {
- throw new Error('Parameter y contains a unit with undefined value');
- }
-
- if (!x.equalBase(y)) {
- throw new Error('Units do not match');
- }
-
- var res = x.clone();
- res.value += y.value;
- res.fixPrefix = false;
- return res;
- }
- }
-
- if (x instanceof BigNumber) {
- // try to convert to big number
- if (isNumber(y)) {
- y = BigNumber.convert(y);
- }
- else if (isBoolean(y) || y === null) {
- y = new BigNumber(y ? 1 : 0);
- }
-
- if (y instanceof BigNumber) {
- return x.plus(y);
- }
-
- // downgrade to Number
- return add(x.toNumber(), y);
- }
- if (y instanceof BigNumber) {
- // try to convert to big number
- if (isNumber(x)) {
- x = BigNumber.convert(x);
- }
- else if (isBoolean(x) || x === null) {
- x = new BigNumber(x ? 1 : 0);
- }
-
- if (x instanceof BigNumber) {
- return x.plus(y);
- }
-
- // downgrade to Number
- return add(x, y.toNumber());
- }
-
- if (isCollection(x) || isCollection(y)) {
- return collection.deepMap2(x, y, add);
- }
-
- if (isString(x) || isString(y)) {
- return x + y;
- }
-
- if (isBoolean(x) || x === null) {
- return add(+x, y);
- }
- if (isBoolean(y) || y === null) {
- return add(x, +y);
- }
-
- throw new math.error.UnsupportedTypeError('add', math['typeof'](x), math['typeof'](y));
- };
- };
-
-
-/***/ },
-/* 50 */
-/***/ function(module, exports, __webpack_require__) {
-
- 'use strict';
-
- module.exports = function (math) {
- var util = __webpack_require__(175),
-
- BigNumber = math.type.BigNumber,
- Complex = __webpack_require__(7),
- collection = math.collection,
-
- isNumber = util.number.isNumber,
- isBoolean = util['boolean'].isBoolean,
- isCollection =collection.isCollection,
- isComplex = Complex.isComplex;
-
- /**
- * Round a value towards plus infinity
- * If `x` is complex, both real and imaginary part are rounded towards plus infinity.
- * For matrices, the function is evaluated element wise.
- *
- * Syntax:
- *
- * math.ceil(x)
- *
- * Examples:
- *
- * math.ceil(3.2); // returns Number 4
- * math.ceil(3.8); // returns Number 4
- * math.ceil(-4.2); // returns Number -4
- * math.ceil(-4.7); // returns Number -4
- *
- * var c = math.complex(3.2, -2.7);
- * math.ceil(c); // returns Complex 4 - 2i
- *
- * math.ceil([3.2, 3.8, -4.7]); // returns Array [4, 4, -4]
- *
- * See also:
- *
- * floor, fix, round
- *
- * @param {Number | BigNumber | Boolean | Complex | Array | Matrix | null} x Number to be rounded
- * @return {Number | BigNumber | Complex | Array | Matrix} Rounded value
- */
- math.ceil = function ceil(x) {
- if (arguments.length != 1) {
- throw new math.error.ArgumentsError('ceil', arguments.length, 1);
- }
-
- if (isNumber(x)) {
- return Math.ceil(x);
- }
-
- if (isComplex(x)) {
- return new Complex (
- Math.ceil(x.re),
- Math.ceil(x.im)
- );
- }
-
- if (x instanceof BigNumber) {
- return x.ceil();
- }
-
- if (isCollection(x)) {
- // deep map collection, skip zeros since ceil(0) = 0
- return collection.deepMap(x, ceil, true);
- }
-
- if (isBoolean(x) || x === null) {
- return Math.ceil(x);
- }
-
- throw new math.error.UnsupportedTypeError('ceil', math['typeof'](x));
- };
- };
-
-
-/***/ },
-/* 51 */
-/***/ function(module, exports, __webpack_require__) {
-
- 'use strict';
-
- module.exports = function (math) {
- var util = __webpack_require__(175),
-
- BigNumber = math.type.BigNumber,
- Complex = __webpack_require__(7),
- collection = math.collection,
-
- isNumber = util.number.isNumber,
- isBoolean = util['boolean'].isBoolean,
- isComplex = Complex.isComplex,
- isCollection = collection.isCollection;
-
- /**
- * Compute the cube of a value, `x * x * x`.
- * For matrices, the function is evaluated element wise.
- *
- * Syntax:
- *
- * math.cube(x)
- *
- * Examples:
- *
- * math.cube(2); // returns Number 8
- * math.pow(2, 3); // returns Number 8
- * math.cube(4); // returns Number 64
- * 4 * 4 * 4; // returns Number 64
- *
- * math.cube([1, 2, 3, 4]); // returns Array [1, 8, 27, 64]
- *
- * See also:
- *
- * multiply, square, pow
- *
- * @param {Number | BigNumber | Boolean | Complex | Array | Matrix | null} x Number for which to calculate the cube
- * @return {Number | BigNumber | Complex | Array | Matrix} Cube of x
- */
- math.cube = function cube(x) {
- if (arguments.length != 1) {
- throw new math.error.ArgumentsError('cube', arguments.length, 1);
- }
-
- if (isNumber(x)) {
- return x * x * x;
- }
-
- if (isComplex(x)) {
- return math.multiply(math.multiply(x, x), x);
- }
-
- if (x instanceof BigNumber) {
- return x.times(x).times(x);
- }
-
- if (isCollection(x)) {
- return collection.deepMap(x, cube);
- }
-
- if (isBoolean(x) || x === null) {
- return cube(+x);
- }
-
- throw new math.error.UnsupportedTypeError('cube', math['typeof'](x));
- };
- };
-
-
-/***/ },
-/* 52 */
-/***/ function(module, exports, __webpack_require__) {
-
- 'use strict';
-
- module.exports = function(math) {
- var util = __webpack_require__(175);
-
- var BigNumber = math.type.BigNumber;
- var Complex = __webpack_require__(7);
- var Matrix = math.type.Matrix;
- var Unit = __webpack_require__(11);
-
- var isNumber = util.number.isNumber;
- var isBoolean = util['boolean'].isBoolean;
- var isComplex = Complex.isComplex;
- var isUnit = Unit.isUnit;
-
- /**
- * Divide two scalar values, `x / y`.
- * This function is meant for internal use: it is used by the public functions
- * `divide` and `inv`.
- *
- * This function does not support collections (Array or Matrix), and does
- * not validate the number of of inputs.
- *
- * @param {Number | BigNumber | Boolean | Complex | Unit | null} x Numerator
- * @param {Number | BigNumber | Boolean | Complex | null} y Denominator
- * @return {Number | BigNumber | Complex | Unit} Quotient, `x / y`
- * @private
- */
- math._divide = function _divide(x, y) {
- // TODO: this is a temporary function, to be removed as soon as the library is modularized (i.e. no dependencies on math from the individual functions)
- if (isNumber(x)) {
- if (isNumber(y)) {
- // number / number
- return x / y;
- }
- else if (isComplex(y)) {
- // number / complex
- return _divideComplex(new Complex(x, 0), y);
- }
- }
-
- if (isComplex(x)) {
- if (isComplex(y)) {
- // complex / complex
- return _divideComplex(x, y);
- }
- else if (isNumber(y)) {
- // complex / number
- return _divideComplex(x, new Complex(y, 0));
- }
- }
-
- if (x instanceof BigNumber) {
- // try to convert to big number
- if (isNumber(y)) {
- y = BigNumber.convert(y);
- }
- else if (isBoolean(y) || y === null) {
- y = new BigNumber(y ? 1 : 0);
- }
-
- if (y instanceof BigNumber) {
- return x.div(y);
- }
-
- // downgrade to Number
- return _divide(x.toNumber(), y);
- }
- if (y instanceof BigNumber) {
- // try to convert to big number
- if (isNumber(x)) {
- x = BigNumber.convert(x);
- }
- else if (isBoolean(x) || x === null) {
- x = new BigNumber(x ? 1 : 0);
- }
-
- if (x instanceof BigNumber) {
- return x.div(y)
- }
-
- // downgrade to Number
- return _divide(x, y.toNumber());
- }
-
- if (isUnit(x)) {
- if (isNumber(y)) {
- var res = x.clone();
- res.value = ((res.value === null) ? res._normalize(1) : res.value) / y;
- return res;
- }
- }
-
- if (isBoolean(x) || x === null) {
- return _divide(+x, y);
- }
- if (isBoolean(y) || y === null) {
- return _divide(x, +y);
- }
-
- throw new math.error.UnsupportedTypeError('divide', math['typeof'](x), math['typeof'](y));
- };
-
- /**
- * Divide two complex numbers. x / y or divide(x, y)
- * @param {Complex} x
- * @param {Complex} y
- * @return {Complex} res
- * @private
- */
- function _divideComplex (x, y) {
- var den = y.re * y.re + y.im * y.im;
- if (den != 0) {
- return new Complex(
- (x.re * y.re + x.im * y.im) / den,
- (x.im * y.re - x.re * y.im) / den
- );
- }
- else {
- // both y.re and y.im are zero
- return new Complex(
- (x.re != 0) ? (x.re / 0) : 0,
- (x.im != 0) ? (x.im / 0) : 0
- );
- }
- }
- };
-
-
-/***/ },
-/* 53 */
-/***/ function(module, exports, __webpack_require__) {
-
- 'use strict';
-
- module.exports = function(math) {
- var collection = math.collection;
- var isCollection = collection.isCollection;
-
- /**
- * Divide two values, `x / y`.
- * To divide matrices, `x` is multiplied with the inverse of `y`: `x * inv(y)`.
- *
- * Syntax:
- *
- * math.divide(x, y)
- *
- * Examples:
- *
- * math.divide(2, 3); // returns Number 0.6666666666666666
- *
- * var a = math.complex(5, 14);
- * var b = math.complex(4, 1);
- * math.divide(a, b); // returns Complex 2 + 3i
- *
- * var c = [[7, -6], [13, -4]];
- * var d = [[1, 2], [4, 3]];
- * math.divide(c, d); // returns Array [[-9, 4], [-11, 6]]
- *
- * var e = math.unit('18 km');
- * math.divide(e, 4.5); // returns Unit 4 km
- *
- * See also:
- *
- * multiply
- *
- * @param {Number | BigNumber | Boolean | Complex | Unit | Array | Matrix | null} x Numerator
- * @param {Number | BigNumber | Boolean | Complex | Array | Matrix | null} y Denominator
- * @return {Number | BigNumber | Complex | Unit | Array | Matrix} Quotient, `x / y`
- */
- math.divide = function(x, y) {
- if (arguments.length != 2) {
- throw new math.error.ArgumentsError('divide', arguments.length, 2);
- }
-
- if (isCollection(x)) {
- if (isCollection(y)) {
- // TODO: implement matrix right division using pseudo inverse
- // http://www.mathworks.nl/help/matlab/ref/mrdivide.html
- // http://www.gnu.org/software/octave/doc/interpreter/Arithmetic-Ops.html
- // http://stackoverflow.com/questions/12263932/how-does-gnu-octave-matrix-division-work-getting-unexpected-behaviour
- return math.multiply(x, math.inv(y));
- }
- else {
- // matrix / scalar
- return collection.deepMap2(x, y, math._divide);
- }
- }
-
- if (isCollection(y)) {
- // TODO: implement matrix right division using pseudo inverse
- return math.multiply(x, math.inv(y));
- }
-
- // divide two scalars
- return math._divide(x, y);
- };
- };
-
-
-/***/ },
-/* 54 */
-/***/ function(module, exports, __webpack_require__) {
-
- 'use strict';
-
- module.exports = function (math) {
- var collection = math.collection;
-
- /**
- * Divide two matrices element wise. The function accepts both matrices and
- * scalar values.
- *
- * Syntax:
- *
- * math.dotDivide(x, y)
- *
- * Examples:
- *
- * math.dotDivide(2, 4); // returns 0.5
- *
- * a = [[9, 5], [6, 1]];
- * b = [[3, 2], [5, 2]];
- *
- * math.dotDivide(a, b); // returns [[3, 2.5], [1.2, 0.5]]
- * math.divide(a, b); // returns [[1.75, 0.75], [-1.75, 2.25]]
- *
- * See also:
- *
- * divide, multiply, dotMultiply
- *
- * @param {Number | BigNumber | Boolean | Complex | Unit | Array | Matrix | null} x Numerator
- * @param {Number | BigNumber | Boolean | Complex | Unit | Array | Matrix | null} y Denominator
- * @return {Number | BigNumber | Complex | Unit | Array | Matrix} Quotient, `x ./ y`
- */
- math.dotDivide = function dotDivide(x, y) {
- if (arguments.length != 2) {
- throw new math.error.ArgumentsError('dotDivide', arguments.length, 2);
- }
-
- return collection.deepMap2(x, y, math.divide);
- };
-
- // TODO: deprecated since version 0.23.0, clean up some day
- math.edivide = function () {
- throw new Error('Function edivide is renamed to dotDivide');
- }
- };
-
-
-/***/ },
-/* 55 */
-/***/ function(module, exports, __webpack_require__) {
-
- 'use strict';
-
- module.exports = function (math) {
- var util = __webpack_require__(175),
- collection = math.collection;
-
- /**
- * Multiply two matrices element wise. The function accepts both matrices and
- * scalar values.
- *
- * Syntax:
- *
- * math.dotMultiply(x, y)
- *
- * Examples:
- *
- * math.dotMultiply(2, 4); // returns 8
- *
- * a = [[9, 5], [6, 1]];
- * b = [[3, 2], [5, 2]];
- *
- * math.dotMultiply(a, b); // returns [[27, 10], [30, 2]]
- * math.multiply(a, b); // returns [[52, 28], [23, 14]]
- *
- * See also:
- *
- * multiply, divide, dotDivide
- *
- * @param {Number | BigNumber | Boolean | Complex | Unit | Array | Matrix | null} x Left hand value
- * @param {Number | BigNumber | Boolean | Complex | Unit | Array | Matrix | null} y Right hand value
- * @return {Number | BigNumber | Complex | Unit | Array | Matrix} Multiplication of `x` and `y`
- */
- math.dotMultiply = function dotMultiply(x, y) {
- if (arguments.length != 2) {
- throw new math.error.ArgumentsError('dotMultiply', arguments.length, 2);
- }
-
- return collection.deepMap2(x, y, math.multiply);
- };
-
- // TODO: deprecated since version 0.23.0, clean up some day
- math.emultiply = function () {
- throw new Error('Function emultiply is renamed to dotMultiply');
- }
- };
-
-
-/***/ },
-/* 56 */
-/***/ function(module, exports, __webpack_require__) {
-
- 'use strict';
-
- module.exports = function (math) {
- var util = __webpack_require__(175),
- collection = math.collection;
-
- /**
- * Calculates the power of x to y element wise.
- *
- * Syntax:
- *
- * math.dotPow(x, y)
- *
- * Examples:
- *
- * math.dotPow(2, 3); // returns Number 8
- *
- * var a = [[1, 2], [4, 3]];
- * math.dotPow(a, 2); // returns Array [[1, 4], [16, 9]]
- * math.pow(a, 2); // returns Array [[9, 8], [16, 17]]
- *
- * See also:
- *
- * pow, sqrt, multiply
- *
- * @param {Number | BigNumber | Boolean | Complex | Unit | Array | Matrix | null} x The base
- * @param {Number | BigNumber | Boolean | Complex | Unit | Array | Matrix | null} y The exponent
- * @return {Number | BigNumber | Complex | Unit | Array | Matrix} The value of `x` to the power `y`
- */
- math.dotPow = function dotPow(x, y) {
- if (arguments.length != 2) {
- throw new math.error.ArgumentsError('dotPow', arguments.length, 2);
- }
-
- return collection.deepMap2(x, y, math.pow);
- };
-
- // TODO: deprecated since version 0.23.0, clean up some day
- math.epow = function () {
- throw new Error('Function epow is renamed to dotPow');
- }
- };
-
-
-/***/ },
-/* 57 */
-/***/ function(module, exports, __webpack_require__) {
-
- 'use strict';
-
- module.exports = function (math) {
- var util = __webpack_require__(175),
-
- BigNumber = math.type.BigNumber,
- Complex = __webpack_require__(7),
- Matrix = math.type.Matrix,
- collection = math.collection,
-
- isNumber = util.number.isNumber,
- isBoolean = util['boolean'].isBoolean,
- isComplex = Complex.isComplex,
- isCollection = collection.isCollection;
-
- /**
- * Calculate the exponent of a value.
- * For matrices, the function is evaluated element wise.
- *
- * Syntax:
- *
- * math.exp(x)
- *
- * Examples:
- *
- * math.exp(2); // returns Number 7.3890560989306495
- * math.pow(math.e, 2); // returns Number 7.3890560989306495
- * math.log(math.exp(2)); // returns Number 2
- *
- * math.exp([1, 2, 3]);
- * // returns Array [
- * // 2.718281828459045,
- * // 7.3890560989306495,
- * // 20.085536923187668
- * // ]
- *
- * See also:
- *
- * log, pow
- *
- * @param {Number | BigNumber | Boolean | Complex | Array | Matrix | null} x A number or matrix to exponentiate
- * @return {Number | BigNumber | Complex | Array | Matrix} Exponent of `x`
- */
- math.exp = function exp (x) {
- if (arguments.length != 1) {
- throw new math.error.ArgumentsError('exp', arguments.length, 1);
- }
-
- if (isNumber(x)) {
- return Math.exp(x);
- }
-
- if (isComplex(x)) {
- var r = Math.exp(x.re);
- return new Complex(
- r * Math.cos(x.im),
- r * Math.sin(x.im)
- );
- }
-
- if (x instanceof BigNumber) {
- return x.exp();
- }
-
- if (isCollection(x)) {
- return collection.deepMap(x, exp);
- }
-
- if (isBoolean(x) || x === null) {
- return Math.exp(x);
- }
-
- throw new math.error.UnsupportedTypeError('exp', math['typeof'](x));
- };
- };
-
-
-/***/ },
-/* 58 */
-/***/ function(module, exports, __webpack_require__) {
-
- 'use strict';
-
- module.exports = function (math) {
- var util = __webpack_require__(175),
-
- BigNumber = math.type.BigNumber,
- Complex = __webpack_require__(7),
- collection = math.collection,
-
- isNumber = util.number.isNumber,
- isBoolean = util['boolean'].isBoolean,
- isComplex = Complex.isComplex,
- isCollection = collection.isCollection;
-
- /**
- * Round a value towards zero.
- * For matrices, the function is evaluated element wise.
- *
- * Syntax:
- *
- * math.fix(x)
- *
- * Examples:
- *
- * math.fix(3.2); // returns Number 3
- * math.fix(3.8); // returns Number 3
- * math.fix(-4.2); // returns Number -4
- * math.fix(-4.7); // returns Number -4
- *
- * var c = math.complex(3.2, -2.7);
- * math.fix(c); // returns Complex 3 - 2i
- *
- * math.fix([3.2, 3.8, -4.7]); // returns Array [3, 3, -4]
- *
- * See also:
- *
- * ceil, floor, round
- *
- * @param {Number | BigNumber | Boolean | Complex | Array | Matrix | null} x Number to be rounded
- * @return {Number | BigNumber | Complex | Array | Matrix} Rounded value
- */
- math.fix = function fix(x) {
- if (arguments.length != 1) {
- throw new math.error.ArgumentsError('fix', arguments.length, 1);
- }
-
- if (isNumber(x)) {
- return (x > 0) ? Math.floor(x) : Math.ceil(x);
- }
-
- if (isComplex(x)) {
- return new Complex(
- (x.re > 0) ? Math.floor(x.re) : Math.ceil(x.re),
- (x.im > 0) ? Math.floor(x.im) : Math.ceil(x.im)
- );
- }
-
- if (x instanceof BigNumber) {
- return x.isNegative() ? x.ceil() : x.floor();
- }
-
- if (isCollection(x)) {
- // deep map collection, skip zeros since fix(0) = 0
- return collection.deepMap(x, fix, true);
- }
-
- if (isBoolean(x) || x === null) {
- return fix(+x);
- }
-
- throw new math.error.UnsupportedTypeError('fix', math['typeof'](x));
- };
- };
-
-
-/***/ },
-/* 59 */
-/***/ function(module, exports, __webpack_require__) {
-
- 'use strict';
-
- module.exports = function (math) {
- var util = __webpack_require__(175),
-
- BigNumber = math.type.BigNumber,
- Complex = __webpack_require__(7),
- collection = math.collection,
-
- isNumber = util.number.isNumber,
- isBoolean = util['boolean'].isBoolean,
- isComplex = Complex.isComplex,
- isCollection = collection.isCollection;
-
- /**
- * Round a value towards minus infinity.
- * For matrices, the function is evaluated element wise.
- *
- * Syntax:
- *
- * math.floor(x)
- *
- * Examples:
- *
- * math.floor(3.2); // returns Number 3
- * math.floor(3.8); // returns Number 3
- * math.floor(-4.2); // returns Number -5
- * math.floor(-4.7); // returns Number -5
- *
- * var c = math.complex(3.2, -2.7);
- * math.floor(c); // returns Complex 3 - 3i
- *
- * math.floor([3.2, 3.8, -4.7]); // returns Array [3, 3, -5]
- *
- * See also:
- *
- * ceil, fix, round
- *
- * @param {Number | BigNumber | Boolean | Complex | Array | Matrix | null} x Number to be rounded
- * @return {Number | BigNumber | Complex | Array | Matrix} Rounded value
- */
- math.floor = function floor(x) {
- if (arguments.length != 1) {
- throw new math.error.ArgumentsError('floor', arguments.length, 1);
- }
-
- if (isNumber(x)) {
- return Math.floor(x);
- }
-
- if (isComplex(x)) {
- return new Complex (
- Math.floor(x.re),
- Math.floor(x.im)
- );
- }
-
- if (x instanceof BigNumber) {
- return x.floor();
- }
-
- if (isCollection(x)) {
- // deep map collection, skip zeros since floor(0) = 0
- return collection.deepMap(x, floor, true);
- }
-
- if (isBoolean(x) || x === null) {
- return floor(+x);
- }
-
- throw new math.error.UnsupportedTypeError('floor', math['typeof'](x));
- };
- };
-
-
-/***/ },
-/* 60 */
-/***/ function(module, exports, __webpack_require__) {
-
- 'use strict';
-
- module.exports = function (math) {
- var util = __webpack_require__(175),
-
- BigNumber = math.type.BigNumber,
- collection = math.collection,
-
- isNumber = util.number.isNumber,
- isBoolean = util['boolean'].isBoolean,
- isInteger = util.number.isInteger,
- isCollection = collection.isCollection;
-
- /**
- * Calculate the greatest common divisor for two or more values or arrays.
- *
- * For matrices, the function is evaluated element wise.
- *
- * Syntax:
- *
- * math.gcd(a, b)
- * math.gcd(a, b, c, ...)
- *
- * Examples:
- *
- * math.gcd(8, 12); // returns 4
- * math.gcd(-4, 6); // returns 2
- * math.gcd(25, 15, -10); // returns 5
- *
- * math.gcd([8, -4], [12, 6]); // returns [4, 2]
- *
- * See also:
- *
- * lcm, xgcd
- *
- * @param {... Number | BigNumber | Boolean | Array | Matrix | null} args Two or more integer numbers
- * @return {Number | BigNumber | Array | Matrix} The greatest common divisor
- */
- math.gcd = function gcd(args) {
- var a = arguments[0],
- b = arguments[1],
- r; // remainder
-
- if (arguments.length == 2) {
- // two arguments
- if (isNumber(a) && isNumber(b)) {
- if (!isInteger(a) || !isInteger(b)) {
- throw new Error('Parameters in function gcd must be integer numbers');
- }
-
- // http://en.wikipedia.org/wiki/Euclidean_algorithm
- while (b != 0) {
- r = a % b;
- a = b;
- b = r;
- }
- return (a < 0) ? -a : a;
- }
-
- // evaluate gcd element wise
- if (isCollection(a) || isCollection(b)) {
- return collection.deepMap2(a, b, gcd);
- }
-
- if (a instanceof BigNumber) {
- // try to convert to big number
- if (isNumber(b)) {
- b = BigNumber.convert(b);
- }
- else if (isBoolean(b) || b === null) {
- b = new BigNumber(b ? 1 : 0);
- }
-
- if (b instanceof BigNumber) {
- return _bigGcd(a, b);
- }
-
- // downgrade to Number
- return gcd(a.toNumber(), b);
- }
- if (b instanceof BigNumber) {
- // try to convert to big number
- if (isNumber(a)) {
- a = BigNumber.convert(a);
- }
- else if (isBoolean(a) || a === null) {
- a = new BigNumber(a ? 1 : 0);
- }
-
- if (a instanceof BigNumber) {
- return _bigGcd(a, b);
- }
-
- // downgrade to Number
- return gcd(a.toNumber(), b);
- }
-
- if (isBoolean(a) || a === null) {
- return gcd(+a, b);
- }
- if (isBoolean(b) || b === null) {
- return gcd(a, +b);
- }
-
- throw new math.error.UnsupportedTypeError('gcd', math['typeof'](a), math['typeof'](b));
- }
-
- if (arguments.length > 2) {
- // multiple arguments. Evaluate them iteratively
- for (var i = 1; i < arguments.length; i++) {
- a = gcd(a, arguments[i]);
- }
- return a;
- }
-
- // zero or one argument
- throw new SyntaxError('Function gcd expects two or more arguments');
- };
-
- /**
- * Calculate gcd for BigNumbers
- * @param {BigNumber} a
- * @param {BigNumber} b
- * @returns {BigNumber} greatest common denominator of a and b
- * @private
- */
- function _bigGcd(a, b) {
- if (!a.isInt() || !b.isInt()) {
- throw new Error('Parameters in function gcd must be integer numbers');
- }
-
- // http://en.wikipedia.org/wiki/Euclidean_algorithm
- var zero = new BigNumber(0);
- while (!b.isZero()) {
- var r = a.mod(b);
- a = b;
- b = r;
- }
- return a.lt(zero) ? a.neg() : a;
- }
- };
-
-
-/***/ },
-/* 61 */
-/***/ function(module, exports, __webpack_require__) {
-
- 'use strict';
-
- module.exports = function (math) {
- var util = __webpack_require__(175),
-
- BigNumber = math.type.BigNumber,
- collection = math.collection,
-
- isNumber = util.number.isNumber,
- isBoolean = util['boolean'].isBoolean,
- isInteger = util.number.isInteger,
- isCollection = collection.isCollection;
-
- /**
- * Calculate the least common multiple for two or more values or arrays.
- *
- * lcm is defined as:
- *
- * lcm(a, b) = abs(a * b) / gcd(a, b)
- *
- * For matrices, the function is evaluated element wise.
- *
- * Syntax:
- *
- * math.lcm(a, b)
- * math.lcm(a, b, c, ...)
- *
- * Examples:
- *
- * math.lcm(4, 6); // returns 12
- * math.lcm(6, 21); // returns 42
- * math.lcm(6, 21, 5); // returns 210
- *
- * math.lcm([4, 6], [6, 21]); // returns [12, 42]
- *
- * See also:
- *
- * gcd, xgcd
- *
- * @param {... Number | BigNumber | Boolean | Array | Matrix | null} args Two or more integer numbers
- * @return {Number | BigNumber | Array | Matrix} The least common multiple
- */
- math.lcm = function lcm(args) {
- var a = arguments[0],
- b = arguments[1],
- t;
-
- if (arguments.length == 2) {
- // two arguments
- if (isNumber(a) && isNumber(b)) {
- if (!isInteger(a) || !isInteger(b)) {
- throw new Error('Parameters in function lcm must be integer numbers');
- }
-
- if (a == 0 || b == 0) {
- return 0;
- }
-
- // http://en.wikipedia.org/wiki/Euclidean_algorithm
- // evaluate lcm here inline to reduce overhead
- var prod = a * b;
- while (b != 0) {
- t = b;
- b = a % t;
- a = t;
- }
- return Math.abs(prod / a);
- }
-
- // evaluate lcm element wise
- if (isCollection(a) || isCollection(b)) {
- return collection.deepMap2(a, b, lcm);
- }
-
- if (a instanceof BigNumber) {
- // try to convert to big number
- if (isNumber(b)) {
- b = BigNumber.convert(b);
- }
- else if (isBoolean(b) || b === null) {
- b = new BigNumber(b ? 1 : 0);
- }
-
- if (b instanceof BigNumber) {
- return _bigLcm(a, b);
- }
-
- // downgrade to Number
- return lcm(a.toNumber(), b);
- }
- if (b instanceof BigNumber) {
- // try to convert to big number
- if (isNumber(a)) {
- a = BigNumber.convert(a);
- }
- else if (isBoolean(a) || a === null) {
- a = new BigNumber(a ? 1 : 0);
- }
-
- if (a instanceof BigNumber) {
- return _bigLcm(a, b);
- }
-
- // downgrade to Number
- return lcm(a.toNumber(), b);
- }
-
- if (isBoolean(a) || a === null) {
- return lcm(+a, b);
- }
- if (isBoolean(b) || b === null) {
- return lcm(a, +b);
- }
-
- throw new math.error.UnsupportedTypeError('lcm', math['typeof'](a), math['typeof'](b));
- }
-
- if (arguments.length > 2) {
- // multiple arguments. Evaluate them iteratively
- for (var i = 1; i < arguments.length; i++) {
- a = lcm(a, arguments[i]);
- }
- return a;
- }
-
- // zero or one argument
- throw new SyntaxError('Function lcm expects two or more arguments');
- };
-
- /**
- * Calculate lcm for BigNumbers
- * @param {BigNumber} a
- * @param {BigNumber} b
- * @returns {BigNumber} the least common multiple of a and b
- * @private
- */
- function _bigLcm(a, b) {
- if (!a.isInt() || !b.isInt()) {
- throw new Error('Parameters in function lcm must be integer numbers');
- }
-
- if (a.isZero() || b.isZero()) {
- return new BigNumber(0);
- }
-
- // http://en.wikipedia.org/wiki/Euclidean_algorithm
- // evaluate lcm here inline to reduce overhead
- var prod = a.times(b);
- while (!b.isZero()) {
- var t = b;
- b = a.mod(t);
- a = t;
- }
- return prod.div(a).abs();
- }
- };
-
-
-/***/ },
-/* 62 */
-/***/ function(module, exports, __webpack_require__) {
-
- 'use strict';
-
- module.exports = function (math) {
- var util = __webpack_require__(175),
-
- BigNumber = math.type.BigNumber,
- Complex = __webpack_require__(7),
- collection = math.collection,
-
- isNumber = util.number.isNumber,
- isBoolean = util['boolean'].isBoolean,
- isComplex = Complex.isComplex,
- isCollection = collection.isCollection;
-
- /**
- * Calculate the logarithm of a value.
- *
- * For matrices, the function is evaluated element wise.
- *
- * Syntax:
- *
- * math.log(x)
- * math.log(x, base)
- *
- * Examples:
- *
- * math.log(3.5); // returns 1.252762968495368
- * math.exp(math.log(2.4)); // returns 2.4
- *
- * math.pow(10, 4); // returns 10000
- * math.log(10000, 10); // returns 4
- * math.log(10000) / math.log(10); // returns 4
- *
- * math.log(1024, 2); // returns 10
- * math.pow(2, 10); // returns 1024
- *
- * See also:
- *
- * exp, log10
- *
- * @param {Number | BigNumber | Boolean | Complex | Array | Matrix | null} x
- * Value for which to calculate the logarithm.
- * @param {Number | BigNumber | Boolean | Complex | null} [base=e]
- * Optional base for the logarithm. If not provided, the natural
- * logarithm of `x` is calculated.
- * @return {Number | BigNumber | Complex | Array | Matrix}
- * Returns the logarithm of `x`
- */
- math.log = function log(x, base) {
- if (arguments.length == 1) {
- // calculate natural logarithm, log(x)
- if (isNumber(x)) {
- if (x >= 0) {
- return Math.log(x);
- }
- else {
- // negative value -> complex value computation
- return log(new Complex(x, 0));
- }
- }
-
- if (isComplex(x)) {
- return new Complex (
- Math.log(Math.sqrt(x.re * x.re + x.im * x.im)),
- Math.atan2(x.im, x.re)
- );
- }
-
- if (x instanceof BigNumber) {
- if (x.isNegative()) {
- // negative value -> downgrade to number to do complex value computation
- return log(x.toNumber());
- }
- else {
- return x.ln();
- }
- }
-
- if (isCollection(x)) {
- return collection.deepMap(x, log);
- }
-
- if (isBoolean(x) || x === null) {
- return log(+x);
- }
-
- throw new math.error.UnsupportedTypeError('log', math['typeof'](x));
- }
- else if (arguments.length == 2) {
- // calculate logarithm for a specified base, log(x, base)
- return math.divide(log(x), log(base));
- }
- else {
- throw new math.error.ArgumentsError('log', arguments.length, 1, 2);
- }
- };
- };
-
-
-/***/ },
-/* 63 */
-/***/ function(module, exports, __webpack_require__) {
-
- 'use strict';
-
- module.exports = function (math) {
- var util = __webpack_require__(175),
-
- BigNumber = math.type.BigNumber,
- Complex = __webpack_require__(7),
- collection = math.collection,
-
- isNumber = util.number.isNumber,
- isBoolean = util['boolean'].isBoolean,
- isComplex = Complex.isComplex,
- isCollection = collection.isCollection;
-
- /**
- * Calculate the 10-base of a value. This is the same as calculating `log(x, 10)`.
- *
- * For matrices, the function is evaluated element wise.
- *
- * Syntax:
- *
- * math.log10(x)
- *
- * Examples:
- *
- * math.log10(0.00001); // returns -5
- * math.log10(10000); // returns 4
- * math.log(10000) / math.log(10); // returns 4
- * math.pow(10, 4); // returns 10000
- *
- * See also:
- *
- * exp, log
- *
- * @param {Number | BigNumber | Boolean | Complex | Array | Matrix | null} x
- * Value for which to calculate the logarithm.
- * @return {Number | BigNumber | Complex | Array | Matrix}
- * Returns the 10-base logarithm of `x`
- */
- math.log10 = function log10(x) {
- if (arguments.length != 1) {
- throw new math.error.ArgumentsError('log10', arguments.length, 1);
- }
-
- if (isNumber(x)) {
- if (x >= 0) {
- return Math.log(x) / Math.LN10;
- }
- else {
- // negative value -> complex value computation
- return log10(new Complex(x, 0));
- }
- }
-
- if (x instanceof BigNumber) {
- if (x.isNegative()) {
- // negative value -> downgrade to number to do complex value computation
- return log10(x.toNumber());
- }
- else {
- return x.log();
- }
- }
-
- if (isComplex(x)) {
- return new Complex (
- Math.log(Math.sqrt(x.re * x.re + x.im * x.im)) / Math.LN10,
- Math.atan2(x.im, x.re) / Math.LN10
- );
- }
-
- if (isCollection(x)) {
- return collection.deepMap(x, log10);
- }
-
- if (isBoolean(x) || x === null) {
- return log10(+x);
- }
-
- throw new math.error.UnsupportedTypeError('log10', math['typeof'](x));
- };
- };
-
-
-/***/ },
-/* 64 */
-/***/ function(module, exports, __webpack_require__) {
-
- 'use strict';
-
- module.exports = function (math) {
- var util = __webpack_require__(175),
-
- BigNumber = math.type.BigNumber,
- collection = math.collection,
-
- isNumber = util.number.isNumber,
- isBoolean = util['boolean'].isBoolean,
- isCollection = collection.isCollection;
-
- /**
- * Calculates the modulus, the remainder of an integer division.
- *
- * For matrices, the function is evaluated element wise.
- *
- * The modulus is defined as:
- *
- * x - y * floor(x / y)
- *
- * See http://en.wikipedia.org/wiki/Modulo_operation.
- *
- * Syntax:
- *
- * math.mod(x, y)
- *
- * Examples:
- *
- * math.mod(8, 3); // returns 2
- * math.mod(11, 2); // returns 1
- *
- * function isOdd(x) {
- * return math.mod(x, 2) != 0;
- * }
- *
- * isOdd(2); // returns false
- * isOdd(3); // returns true
- *
- * See also:
- *
- * divide
- *
- * @param {Number | BigNumber | Boolean | Array | Matrix | null} x Dividend
- * @param {Number | BigNumber | Boolean | Array | Matrix | null} y Divisor
- * @return {Number | BigNumber | Array | Matrix} Returns the remainder of `x` divided by `y`.
- */
- math.mod = function mod(x, y) {
- if (arguments.length != 2) {
- throw new math.error.ArgumentsError('mod', arguments.length, 2);
- }
-
- // see http://functions.wolfram.com/IntegerFunctions/Mod/
-
- if (isNumber(x)) {
- if (isNumber(y)) {
- // number % number
- return _mod(x, y);
- }
- }
-
- if (x instanceof BigNumber) {
- // try to convert to big number
- if (isNumber(y)) {
- y = BigNumber.convert(y);
- }
- else if (isBoolean(y) || y === null) {
- y = new BigNumber(y ? 1 : 0);
- }
-
- if (y instanceof BigNumber) {
- return y.isZero() ? x : x.mod(y);
- }
-
- // downgrade x to Number
- return mod(x.toNumber(), y);
- }
- if (y instanceof BigNumber) {
- // try to convert to big number
- if (isNumber(x)) {
- x = BigNumber.convert(x);
- }
- else if (isBoolean(x) || x === null) {
- x = new BigNumber(x ? 1 : 0);
- }
-
- if (x instanceof BigNumber) {
- return y.isZero() ? x : x.mod(y);
- }
-
- // downgrade y to Number
- return mod(x, y.toNumber());
- }
-
- // TODO: implement mod for complex values
-
- if (isCollection(x) || isCollection(y)) {
- return collection.deepMap2(x, y, mod);
- }
-
- if (isBoolean(x) || x === null) {
- return mod(+x, y);
- }
- if (isBoolean(y) || y === null) {
- return mod(x, +y);
- }
-
- throw new math.error.UnsupportedTypeError('mod', math['typeof'](x), math['typeof'](y));
- };
-
- /**
- * Calculate the modulus of two numbers
- * @param {Number} x
- * @param {Number} y
- * @returns {number} res
- * @private
- */
- function _mod(x, y) {
- if (y > 0) {
- // We don't use JavaScript's % operator here as this doesn't work
- // correctly for x < 0 and x == 0
- // see http://en.wikipedia.org/wiki/Modulo_operation
- return x - y * Math.floor(x / y);
- }
- else if (y == 0) {
- return x;
- }
- else { // y < 0
- // TODO: implement mod for a negative divisor
- throw new Error('Cannot calculate mod for a negative divisor');
- }
- }
- };
-
-
-/***/ },
-/* 65 */
-/***/ function(module, exports, __webpack_require__) {
-
- 'use strict';
-
- module.exports = function(math) {
- var util = __webpack_require__(175),
-
- BigNumber = math.type.BigNumber,
- Complex = __webpack_require__(7),
- Matrix = math.type.Matrix,
- Unit = __webpack_require__(11),
- collection = math.collection,
-
- isNumber = util.number.isNumber,
- isBoolean = util['boolean'].isBoolean,
- isComplex = Complex.isComplex,
- isArray = Array.isArray,
- isUnit = Unit.isUnit;
-
- /**
- * Multiply two values, `x * y`. The result is squeezed.
- * For matrices, the matrix product is calculated.
- *
- * Syntax:
- *
- * math.multiply(x, y)
- *
- * Examples:
- *
- * math.multiply(4, 5.2); // returns Number 20.8
- *
- * var a = math.complex(2, 3);
- * var b = math.complex(4, 1);
- * math.multiply(a, b); // returns Complex 5 + 14i
- *
- * var c = [[1, 2], [4, 3]];
- * var d = [[1, 2, 3], [3, -4, 7]];
- * math.multiply(c, d); // returns Array [[7, -6, 17], [13, -4, 33]]
- *
- * var e = math.unit('2.1 km');
- * math.multiply(3, e); // returns Unit 6.3 km
- *
- * See also:
- *
- * divide
- *
- * @param {Number | BigNumber | Boolean | Complex | Unit | Array | Matrix | null} x First value to multiply
- * @param {Number | BigNumber | Boolean | Complex | Unit | Array | Matrix | null} y Second value to multiply
- * @return {Number | BigNumber | Complex | Unit | Array | Matrix} Multiplication of `x` and `y`
- */
- math.multiply = function multiply(x, y) {
- var res;
-
- if (arguments.length != 2) {
- throw new math.error.ArgumentsError('multiply', arguments.length, 2);
- }
-
- if (isNumber(x)) {
- if (isNumber(y)) {
- // number * number
- return x * y;
- }
- else if (isComplex(y)) {
- // number * complex
- return _multiplyComplex(new Complex(x, 0), y);
- }
- else if (isUnit(y)) {
- res = y.clone();
- res.value = (res.value === null) ? res._normalize(x) : (res.value * x);
- return res;
- }
- }
-
- if (isComplex(x)) {
- if (isNumber(y)) {
- // complex * number
- return _multiplyComplex(x, new Complex(y, 0));
- }
- else if (isComplex(y)) {
- // complex * complex
- return _multiplyComplex(x, y);
- }
- }
-
- if (x instanceof BigNumber) {
- // try to convert to big number
- if (isNumber(y)) {
- y = BigNumber.convert(y);
- }
- else if (isBoolean(y) || y === null) {
- y = new BigNumber(y ? 1 : 0);
- }
-
- if (y instanceof BigNumber) {
- return x.times(y);
- }
-
- // downgrade to Number
- return multiply(x.toNumber(), y);
- }
- if (y instanceof BigNumber) {
- // try to convert to big number
- if (isNumber(x)) {
- x = BigNumber.convert(x);
- }
- else if (isBoolean(x) || x === null) {
- x = new BigNumber(x ? 1 : 0);
- }
-
- if (x instanceof BigNumber) {
- return x.times(y);
- }
-
- // downgrade to Number
- return multiply(x, y.toNumber());
- }
-
- if (isUnit(x)) {
- if (isNumber(y)) {
- res = x.clone();
- res.value = (res.value === null) ? res._normalize(y) : (res.value * y);
- return res;
- }
- }
-
- if (isArray(x)) {
- // create dense matrix from array
- var m = math.matrix(x);
- // use optimized operations in matrix
- var r = m.multiply(y);
- // check result
- if (r instanceof Matrix) {
- // check we need to return a matrix
- if (y instanceof Matrix)
- return r;
- // output should be an array
- return r.valueOf();
- }
- // scalar
- return r;
- }
-
- if (x instanceof Matrix) {
- // use optimized matrix implementation
- return x.multiply(y);
- }
-
- if (isArray(y)) {
- // scalar * array
- return collection.deepMap2(x, y, multiply);
- }
- else if (y instanceof Matrix) {
- // adapter function
- var mf = function (v) {
- return multiply(x, v);
- };
- // scalar * matrix
- return collection.deepMap(y, mf, true);
- }
-
- if (isBoolean(x) || x === null) {
- return multiply(+x, y);
- }
- if (isBoolean(y) || y === null) {
- return multiply(x, +y);
- }
-
- throw new math.error.UnsupportedTypeError('multiply', math['typeof'](x), math['typeof'](y));
- };
-
- /**
- * Multiply two complex numbers. x * y or multiply(x, y)
- * @param {Complex} x
- * @param {Complex} y
- * @return {Complex | Number} res
- * @private
- */
- function _multiplyComplex (x, y) {
- // Note: we test whether x or y are pure real or pure complex,
- // to prevent unnecessary NaN values. For example, Infinity*i should
- // result in Infinity*i, and not in NaN+Infinity*i
-
- if (x.im == 0) {
- // x is pure real
- if (y.im == 0) {
- // y is pure real
- return new Complex(x.re * y.re, 0);
- }
- else if (y.re == 0) {
- // y is pure complex
- return new Complex(
- 0,
- x.re * y.im
- );
- }
- else {
- // y has a real and complex part
- return new Complex(
- x.re * y.re,
- x.re * y.im
- );
- }
- }
- else if (x.re == 0) {
- // x is pure complex
- if (y.im == 0) {
- // y is pure real
- return new Complex(
- 0,
- x.im * y.re
- );
- }
- else if (y.re == 0) {
- // y is pure complex
- return new Complex(-x.im * y.im, 0);
- }
- else {
- // y has a real and complex part
- return new Complex(
- -x.im * y.im,
- x.im * y.re
- );
- }
- }
- else {
- // x has a real and complex part
- if (y.im == 0) {
- // y is pure real
- return new Complex(
- x.re * y.re,
- x.im * y.re
- );
- }
- else if (y.re == 0) {
- // y is pure complex
- return new Complex(
- -x.im * y.im,
- x.re * y.im
- );
- }
- else {
- // y has a real and complex part
- return new Complex(
- x.re * y.re - x.im * y.im,
- x.re * y.im + x.im * y.re
- );
- }
- }
- }
- };
-
-
-/***/ },
-/* 66 */
-/***/ function(module, exports, __webpack_require__) {
-
- 'use strict';
-
- module.exports = function (math) {
- var util = __webpack_require__(175),
-
- BigNumber = math.type.BigNumber,
- Complex = __webpack_require__(7),
- Matrix = math.type.Matrix,
-
- isNumber = util.number.isNumber,
- isBoolean = util['boolean'].isBoolean,
- isComplex = Complex.isComplex,
- isArray = Array.isArray;
-
- /**
- * Calculate the norm of a number, vector or matrix.
- *
- * The second parameter p is optional. If not provided, it defaults to 2.
- *
- * Syntax:
- *
- * math.norm(x)
- * math.norm(x, p)
- *
- * Examples:
- *
- * math.abs(-3.5); // returns 3.5
- * math.norm(-3.5); // returns 3.5
- *
- * math.norm(math.complex(3, -4)); // returns 5
- *
- * math.norm([1, 2, -3], Infinity); // returns 3
- * math.norm([1, 2, -3], -Infinity); // returns 1
- *
- * math.norm([3, 4], 2); // returns 5
- *
- * math.norm([[1, 2], [3, 4]], 1) // returns 6
- * math.norm([[1, 2], [3, 4]], 'inf'); // returns 7
- * math.norm([[1, 2], [3, 4]], 'fro'); // returns 5.477225575051661
- *
- * See also:
- *
- * abs
- *
- * @param {Number | BigNumber | Complex | Boolean | Array | Matrix | null} x
- * Value for which to calculate the norm
- * @param {Number | String} [p=2]
- * Vector space.
- * Supported numbers include Infinity and -Infinity.
- * Supported strings are: 'inf', '-inf', and 'fro' (The Frobenius norm)
- * @return {Number} the p-norm
- */
- math.norm = function norm(x, p) {
- if (arguments.length < 1 || arguments.length > 2) {
- throw new math.error.ArgumentsError('abs', arguments.length, 1, 2);
- }
-
- if (isNumber(x)) {
- // norm(x) = abs(x)
- return Math.abs(x);
- }
-
- if (isComplex(x)) {
- // do not compute sqrt(re * re + im * im) since it will overflow with big numbers!
- var re = Math.abs(x.re);
- var im = Math.abs(x.im);
- if (re >= im) {
- var i = im / re;
- return re * Math.sqrt(1 + i * i);
- }
- var j = re / im;
- return im * Math.sqrt(1 + j * j);
- }
-
- if (x instanceof BigNumber) {
- // norm(x) = abs(x)
- return x.abs();
- }
-
- if (isBoolean(x) || x === null) {
- // norm(x) = abs(x)
- return Math.abs(x);
- }
-
- if (isArray(x)) {
- // use matrix optimized operations
- return norm(math.matrix(x), p);
- }
-
- if (x instanceof Matrix) {
- // size
- var sizeX = x.size();
- // missing p
- if (p == null)
- p = 2;
- // check it is a Vector
- if (sizeX.length == 1) {
- // check p
- if (p === Number.POSITIVE_INFINITY || p === 'inf') {
- // norm(x, Infinity) = max(abs(x))
- var n;
- x.forEach(
- function (value) {
- var v = math.abs(value);
- if (!n || math.larger(v, n))
- n = v;
- },
- true);
- return n;
- }
- if (p === Number.NEGATIVE_INFINITY || p === '-inf') {
- // norm(x, -Infinity) = min(abs(x))
- var n;
- x.forEach(
- function (value) {
- var v = math.abs(value);
- if (!n || math.smaller(v, n))
- n = v;
- },
- true);
- return n;
- }
- if (p === 'fro')
- return norm(x);
- if (isNumber(p) && !isNaN(p)) {
- // check p != 0
- if (!math.equal(p, 0)) {
- // norm(x, p) = sum(abs(xi) ^ p) ^ 1/p
- var n = 0;
- x.forEach(
- function (value) {
- n = math.add(math.pow(math.abs(value), p), n);
- },
- true);
- return math.pow(n, 1 / p);
- }
- return Number.POSITIVE_INFINITY;
- }
- // invalid parameter value
- throw new Error('Unsupported parameter value');
- }
- else if (sizeX.length == 2) {
- // check p
- if (p == 1) {
- // norm(x) = the largest column sum
- var c = [];
- x.forEach(
- function (value, index) {
- var j = index[1];
- c[j] = math.add(c[j] || 0, math.abs(value));
- },
- true);
- return math.max(c);
- }
- if (p == Number.POSITIVE_INFINITY || p === 'inf') {
- // norm(x) = the largest row sum
- var r = [];
- x.forEach(
- function (value, index) {
- var i = index[0];
- r[i] = math.add(r[i] || 0, math.abs(value));
- },
- true);
- return math.max(r);
- }
- if (p === 'fro') {
- // norm(x) = sqrt(sum(diag(x'x)))
- return math.sqrt(x.transpose().multiply(x).trace());
- }
- if (p == 2) {
- // not implemented
- throw new Error('Unsupported parameter value, missing implementation of matrix singular value decomposition');
- }
- // invalid parameter value
- throw new Error('Unsupported parameter value');
- }
- }
-
- throw new math.error.UnsupportedTypeError('norm', x);
- };
- };
-
-
-/***/ },
-/* 67 */
-/***/ function(module, exports, __webpack_require__) {
-
- 'use strict';
-
- module.exports = function (math) {
- var util = __webpack_require__(175);
-
- var BigNumber = math.type.BigNumber;
- var collection = math.collection;
-
- var isNumber = util.number.isNumber;
- var isBoolean = util['boolean'].isBoolean;
- var isCollection = collection.isCollection;
-
- /**
- * Calculate the nth root of a value.
- * The principal nth root of a positive real number A, is the positive real
- * solution of the equation
- *
- * x^root = A
- *
- * For matrices, the function is evaluated element wise.
- *
- * Syntax:
- *
- * math.nthRoot(a, root)
- *
- * Examples:
- *
- * math.nthRoot(9, 2); // returns 3, as 3^2 == 9
- * math.sqrt(9); // returns 3, as 3^2 == 9
- * math.nthRoot(64, 3); // returns 4, as 4^3 == 64
- *
- * See also:
- *
- * sqrt, pow
- *
- * @param {Number | BigNumber | Boolean | Array | Matrix | null} a
- * Value for which to calculate the nth root
- * @param {Number | BigNumber | Boolean | null} [root=2] The root.
- * @return {Number | Complex | Array | Matrix} Returns the nth root of `a`
- */
- math.nthRoot = function nthRoot (a, root) {
- if (arguments.length != 1 && arguments.length != 2) {
- throw new math.error.ArgumentsError('nthRoot', arguments.length, 1, 2);
- }
-
- switch(arguments.length) {
- case 1:
- if (isNumber(a)) {
- return _nthRoot(a);
- }
- else if (a instanceof BigNumber) {
- return _nthRootBig(a);
- }
- else if (isCollection(a)) {
- return collection.deepMap(x, nthRoot);
- }
-
- if (isBoolean(a) || a === null) {
- return nthRoot(+a);
- }
-
- break;
-
- case 2:
- if (isNumber(a)) {
- if (isNumber(root)) {
- return _nthRoot(a, root);
- }
- else if (root instanceof BigNumber) {
- // try to convert to bignumber
- a = BigNumber.convert(a);
-
- if (a instanceof BigNumber) {
- return _nthRootBig(a, root);
- }
- else {
- // downgrade to number
- return _nthRoot(a, root.toNumber());
- }
- }
- }
- else if (a instanceof BigNumber) {
- // try to convert to bignumber
- if (isNumber(root)) {
- root = BigNumber.convert(root);
- }
-
- if (root instanceof BigNumber) {
- return _nthRootBig(a, root);
- }
- else {
- // downgrade to number
- return _nthRoot(a.toNumber(), root);
- }
- }
- else if (isCollection(a) && !isCollection(root)) {
- return collection.deepMap2(a, root, nthRoot);
- }
-
- if (isBoolean(a) || a === null) {
- return nthRoot(+a, root);
- }
- if (isBoolean(root) || root === null) {
- return nthRoot(a, +root);
- }
-
- break;
-
- default:
- throw new math.error.ArgumentsError('nthRoot', arguments.length, 1, 2);
- }
-
- if (isBoolean(x) || x === null) {
- return arguments.length == 2 ? nthRoot(+x, n) : nthRoot(+x);
- }
-
-
- throw new math.error.UnsupportedTypeError('nthRoot', math['typeof'](a), math['typeof'](root));
- };
-
- /**
- * Calculate the nth root of a, solve x^root == a
- * http://rosettacode.org/wiki/Nth_root#JavaScript
- * @param {number} a
- * @param {number} [root=2]
- * @private
- */
- function _nthRoot(a, root) {
- var _root = (root != undefined) ? root : 2;
- var inv = _root < 0;
- if (inv) _root = -_root;
-
- if (_root == 0) throw new Error('Root must be non-zero');
- if (a < 0 && (Math.abs(_root) % 2 != 1)) throw new Error('Root must be odd when a is negative.');
-
- // edge cases zero and infinity
- if (a == 0) return 0;
- if (!Number.isFinite(a)) {
- return inv ? 0 : a;
- }
-
- var epsilon = 1e-16;
- var x = 1; // Initial guess
- var i = 0;
- var iMax = 100;
- do {
- var delta = (a / Math.pow(x, _root - 1) - x) / _root;
- x = x + delta;
- i++;
- }
- while (Math.abs(delta) > epsilon && i < iMax);
-
- return inv ? 1 / x : x;
- }
-
- /**
- * Calculate the nth root of a for BigNumbers, solve x^root == a
- * http://rosettacode.org/wiki/Nth_root#JavaScript
- * @param {BigNumber} a
- * @param {BigNumber} [root=2]
- * @private
- */
- function _nthRootBig(a, root) {
- var _root = (root != undefined) ? root : new BigNumber(2);
- var zero = new BigNumber(0);
- var one = new BigNumber(1);
- var inv = _root.isNegative();
- if (inv) _root = _root.negated();
-
- if (_root.isZero()) throw new Error('Root must be non-zero');
- if (a.isNegative() && !_root.abs().mod(2).equals(1)) throw new Error('Root must be odd when a is negative.');
-
- // edge cases zero and infinity
- if (a.isZero()) return zero;
- if (!a.isFinite())
- {
- return inv ? zero : a;
- }
-
- var x = one; // Initial guess
- var i = 0;
- var iMax = 100;
- do {
- var xPrev = x;
- var delta = a.div(x.pow(_root.minus(1))).minus(x).div(_root);
- x = x.plus(delta);
- i++;
- }
- while (!x.equals(xPrev) && i < iMax);
-
- return inv ? one.div(x) : x;
- }
- };
-
-
-/***/ },
-/* 68 */
-/***/ function(module, exports, __webpack_require__) {
-
- 'use strict';
-
- module.exports = function (math) {
- var util = __webpack_require__(175),
-
- BigNumber = math.type.BigNumber,
- Complex = __webpack_require__(7),
- Matrix = math.type.Matrix,
-
- array = util.array,
- isNumber = util.number.isNumber,
- isBoolean = util.boolean.isBoolean,
- isArray = Array.isArray,
- isInteger = util.number.isInteger,
- isComplex = Complex.isComplex;
-
- /**
- * Calculates the power of x to y, `x ^ y`.
- * Matrix exponentiation is supported for square matrices `x`, and positive
- * integer exponents `y`.
- *
- * Syntax:
- *
- * math.pow(x, y)
- *
- * Examples:
- *
- * math.pow(2, 3); // returns Number 8
- *
- * var a = math.complex(2, 3);
- * math.pow(a, 2) // returns Complex -5 + 12i
- *
- * var b = [[1, 2], [4, 3]];
- * math.pow(b, 2); // returns Array [[9, 8], [16, 17]]
- *
- * See also:
- *
- * multiply, sqrt
- *
- * @param {Number | BigNumber | Boolean | Complex | Array | Matrix | null} x The base
- * @param {Number | BigNumber | Boolean | Complex | null} y The exponent
- * @return {Number | BigNumber | Complex | Array | Matrix} The value of `x` to the power `y`
- */
- math.pow = function pow(x, y) {
- if (arguments.length != 2) {
- throw new math.error.ArgumentsError('pow', arguments.length, 2);
- }
-
- if (isNumber(x)) {
- if (isNumber(y)) {
- if (isInteger(y) || x >= 0) {
- // real value computation
- return Math.pow(x, y);
- }
- else {
- return powComplex(new Complex(x, 0), new Complex(y, 0));
- }
- }
- else if (isComplex(y)) {
- return powComplex(new Complex(x, 0), y);
- }
- }
-
- if (isComplex(x)) {
- if (isNumber(y)) {
- return powComplex(x, new Complex(y, 0));
- }
- else if (isComplex(y)) {
- return powComplex(x, y);
- }
- }
-
- if (x instanceof BigNumber) {
- // try to upgrade y to to bignumber
- if (isNumber(y)) {
- y = BigNumber.convert(y);
- }
- else if (isBoolean(y) || y === null) {
- y = new BigNumber(y ? 1 : 0);
- }
-
- if (y instanceof BigNumber) {
- if (y.isInteger() || !x.isNegative()) {
- return x.pow(y);
- }
- else {
- // downgrade to number to do complex valued computation
- return pow(x.toNumber(), y.toNumber());
- }
- }
- else {
- // failed to upgrade y to bignumber, lets downgrade x to number
- return pow(x.toNumber(), y);
- }
- }
-
- if (y instanceof BigNumber) {
- // try to convert x to bignumber
- if (isNumber(x)) {
- x = BigNumber.convert(x);
- }
- else if (isBoolean(x) || x === null) {
- x = new BigNumber(x ? 1 : 0);
- }
-
- if (x instanceof BigNumber) {
- if (y.isInteger() && !x.isNegative()) {
- return x.pow(y);
- }
- else {
- // downgrade to number to do complex valued computation
- return pow(x.toNumber(), y.toNumber());
- }
- }
- else {
- // failed to upgrade x to bignumber, lets downgrade y to number
- return pow(x, y.toNumber());
- }
- }
-
- if (isArray(x)) {
- if (!isNumber(y) || !isInteger(y) || y < 0) {
- throw new TypeError('For A^b, b must be a positive integer ' +
- '(value is ' + y + ')');
- }
- // verify that A is a 2 dimensional square matrix
- var s = array.size(x);
- if (s.length != 2) {
- throw new Error('For A^b, A must be 2 dimensional ' +
- '(A has ' + s.length + ' dimensions)');
- }
- if (s[0] != s[1]) {
- throw new Error('For A^b, A must be square ' +
- '(size is ' + s[0] + 'x' + s[1] + ')');
- }
-
- // compute power of matrix
- var res = math.eye(s[0]).valueOf();
- var px = x;
- while (y >= 1) {
- if ((y & 1) == 1) {
- res = math.multiply(px, res);
- }
- y >>= 1;
- px = math.multiply(px, px);
- }
- return res;
- }
- else if (x instanceof Matrix) {
- return math.matrix(pow(x.valueOf(), y));
- }
-
- if (isBoolean(x) || x === null) {
- return pow(+x, y);
- }
- if (isBoolean(y) || y === null) {
- return pow(x, +y);
- }
-
- throw new math.error.UnsupportedTypeError('pow', math['typeof'](x), math['typeof'](y));
- };
-
- /**
- * Calculates the power of x to y, x^y, for two complex numbers.
- * @param {Complex} x
- * @param {Complex} y
- * @return {Complex} res
- * @private
- */
- function powComplex (x, y) {
- // complex computation
- // x^y = exp(log(x)*y) = exp((abs(x)+i*arg(x))*y)
- var temp1 = math.log(x);
- var temp2 = math.multiply(temp1, y);
- return math.exp(temp2);
- }
- };
-
-
-/***/ },
-/* 69 */
-/***/ function(module, exports, __webpack_require__) {
-
- 'use strict';
-
- module.exports = function (math) {
- var util = __webpack_require__(175),
-
- BigNumber = math.type.BigNumber,
- Complex = __webpack_require__(7),
- collection = math.collection,
-
- isNumber = util.number.isNumber,
- isInteger = util.number.isInteger,
- isBoolean = util['boolean'].isBoolean,
- isComplex = Complex.isComplex,
- isCollection = collection.isCollection,
- toFixed = util.number.toFixed;
-
- /**
- * Round a value towards the nearest integer.
- * For matrices, the function is evaluated element wise.
- *
- * Syntax:
- *
- * math.round(x)
- * math.round(x, n)
- *
- * Examples:
- *
- * math.round(3.2); // returns Number 3
- * math.round(3.8); // returns Number 4
- * math.round(-4.2); // returns Number -4
- * math.round(-4.7); // returns Number -5
- * math.round(math.pi, 3); // returns Number 3.142
- * math.round(123.45678, 2); // returns Number 123.46
- *
- * var c = math.complex(3.2, -2.7);
- * math.round(c); // returns Complex 3 - 3i
- *
- * math.round([3.2, 3.8, -4.7]); // returns Array [3, 4, -5]
- *
- * See also:
- *
- * ceil, fix, floor
- *
- * @param {Number | BigNumber | Boolean | Complex | Array | Matrix | null} x Number to be rounded
- * @param {Number | BigNumber | Boolean | Array | null} [n=0] Number of decimals
- * @return {Number | BigNumber | Complex | Array | Matrix} Rounded value
- */
- math.round = function round(x, n) {
- if (arguments.length != 1 && arguments.length != 2) {
- throw new math.error.ArgumentsError('round', arguments.length, 1, 2);
- }
-
- if (n == undefined) {
- // round (x)
- if (isNumber(x)) {
- return Math.round(x);
- }
-
- if (isComplex(x)) {
- return new Complex (
- Math.round(x.re),
- Math.round(x.im)
- );
- }
-
- if (x instanceof BigNumber) {
- return x.toDecimalPlaces(0);
- }
-
- if (isCollection(x)) {
- return collection.deepMap(x, round);
- }
-
- if (isBoolean(x) || x === null) {
- return Math.round(x);
- }
-
- throw new math.error.UnsupportedTypeError('round', math['typeof'](x));
- }
- else {
- // round (x, n)
- if (!isNumber(n) || !isInteger(n)) {
- if (n instanceof BigNumber) {
- n = parseFloat(n.valueOf());
- }
- else if (isBoolean(n) || x === null) {
- return round(x, +n);
- }
- else {
- throw new TypeError('Number of decimals in function round must be an integer');
- }
- }
- if (n < 0 || n > 15) {
- throw new Error ('Number of decimals in function round must be in te range of 0-15');
- }
-
- if (isNumber(x)) {
- return roundNumber(x, n);
- }
-
- if (isComplex(x)) {
- return new Complex (
- roundNumber(x.re, n),
- roundNumber(x.im, n)
- );
- }
-
- if (x instanceof BigNumber) {
- return x.toDecimalPlaces(n);
- }
-
- if (isCollection(x) || isCollection(n)) {
- return collection.deepMap2(x, n, round);
- }
-
- if (isBoolean(x) || x === null) {
- return round(+x, n);
- }
-
- throw new math.error.UnsupportedTypeError('round', math['typeof'](x), math['typeof'](n));
- }
- };
-
- /**
- * round a number to the given number of decimals, or to zero if decimals is
- * not provided
- * @param {Number} value
- * @param {Number} decimals number of decimals, between 0 and 15 (0 by default)
- * @return {Number} roundedValue
- */
- function roundNumber (value, decimals) {
- return parseFloat(toFixed(value, decimals));
- }
- };
-
-
-/***/ },
-/* 70 */
-/***/ function(module, exports, __webpack_require__) {
-
- 'use strict';
-
- module.exports = function (math) {
- var util = __webpack_require__(175),
-
- BigNumber = math.type.BigNumber,
- Complex = __webpack_require__(7),
- collection = math.collection,
-
- number = util.number,
- isNumber = util.number.isNumber,
- isBoolean = util['boolean'].isBoolean,
- isComplex = Complex.isComplex,
- isCollection = collection.isCollection;
-
- /**
- * Compute the sign of a value. The sign of a value x is:
- *
- * - 1 when x > 1
- * - -1 when x < 0
- * - 0 when x == 0
- *
- * For matrices, the function is evaluated element wise.
- *
- * Syntax:
- *
- * math.sign(x)
- *
- * Examples:
- *
- * math.sign(3.5); // returns 1
- * math.sign(-4.2); // returns -1
- * math.sign(0); // returns 0
- *
- * math.sign([3, 5, -2, 0, 2]); // returns [1, 1, -1, 0, 1]
- *
- * See also:
- *
- * abs
- *
- * @param {Number | BigNumber | Boolean | Complex | Array | Matrix | null} x
- * The number for which to determine the sign
- * @return {Number | BigNumber | Complex | Array | Matrix}e
- * The sign of `x`
- */
- math.sign = function sign(x) {
- if (arguments.length != 1) {
- throw new math.error.ArgumentsError('sign', arguments.length, 1);
- }
-
- if (isNumber(x)) {
- return number.sign(x);
- }
-
- if (isComplex(x)) {
- var abs = Math.sqrt(x.re * x.re + x.im * x.im);
- return new Complex(x.re / abs, x.im / abs);
- }
-
- if (x instanceof BigNumber) {
- return new BigNumber(x.cmp(0));
- }
-
- if (isCollection(x)) {
- // deep map collection, skip zeros since sign(0) = 0
- return collection.deepMap(x, sign, true);
- }
-
- if (isBoolean(x) || x === null) {
- return number.sign(x);
- }
-
- throw new math.error.UnsupportedTypeError('sign', math['typeof'](x));
- };
- };
-
-
-/***/ },
-/* 71 */
-/***/ function(module, exports, __webpack_require__) {
-
- 'use strict';
-
- module.exports = function (math) {
- var util = __webpack_require__(175),
-
- BigNumber = math.type.BigNumber,
- Complex = __webpack_require__(7),
- collection = math.collection,
-
- isNumber = util.number.isNumber,
- isBoolean = util['boolean'].isBoolean,
- isComplex = Complex.isComplex,
- isCollection = collection.isCollection;
-
- /**
- * Calculate the square root of a value.
- *
- * For matrices, the function is evaluated element wise.
- *
- * Syntax:
- *
- * math.sqrt(x)
- *
- * Examples:
- *
- * math.sqrt(25); // returns 5
- * math.square(5); // returns 25
- * math.sqrt(-4); // returns Complex -2i
- *
- * See also:
- *
- * square, multiply
- *
- * @param {Number | BigNumber | Boolean | Complex | Array | Matrix | null} x
- * Value for which to calculate the square root.
- * @return {Number | BigNumber | Complex | Array | Matrix}
- * Returns the square root of `x`
- */
- math.sqrt = function sqrt (x) {
- if (arguments.length != 1) {
- throw new math.error.ArgumentsError('sqrt', arguments.length, 1);
- }
-
- if (isNumber(x)) {
- if (x >= 0) {
- return Math.sqrt(x);
- }
- else {
- return sqrt(new Complex(x, 0));
- }
- }
-
- if (isComplex(x)) {
- var r = Math.sqrt(x.re * x.re + x.im * x.im);
-
- var re, im;
-
- if (x.re >= 0) {
- re = 0.5 * Math.sqrt(2.0 * (r + x.re));
- }
- else {
- re = Math.abs(x.im) / Math.sqrt(2 * (r - x.re));
- }
-
- if (x.re <= 0) {
- im = 0.5 * Math.sqrt(2.0 * (r - x.re));
- }
- else {
- im = Math.abs(x.im) / Math.sqrt(2 * (r + x.re));
- }
-
- if (x.im >= 0) {
- return new Complex(re, im);
- }
- else {
- return new Complex(re, -im);
- }
- }
-
- if (x instanceof BigNumber) {
- if (x.isNegative()) {
- // negative value -> downgrade to number to do complex value computation
- return sqrt(x.toNumber());
- }
- else {
- return x.sqrt();
- }
- }
-
- if (isCollection(x)) {
- // deep map collection, skip zeros since sqrt(0) = 0
- return collection.deepMap(x, sqrt, true);
- }
-
- if (isBoolean(x) || x === null) {
- return sqrt(+x);
- }
-
- throw new math.error.UnsupportedTypeError('sqrt', math['typeof'](x));
- };
- };
-
-
-/***/ },
-/* 72 */
-/***/ function(module, exports, __webpack_require__) {
-
- 'use strict';
-
- module.exports = function (math) {
- var util = __webpack_require__(175),
-
- BigNumber = math.type.BigNumber,
- Complex = __webpack_require__(7),
- collection = math.collection,
-
- isNumber = util.number.isNumber,
- isBoolean = util['boolean'].isBoolean,
- isComplex = Complex.isComplex,
- isCollection = collection.isCollection;
-
- /**
- * Compute the square of a value, `x * x`.
- * For matrices, the function is evaluated element wise.
- *
- * Syntax:
- *
- * math.square(x)
- *
- * Examples:
- *
- * math.square(2); // returns Number 4
- * math.square(3); // returns Number 9
- * math.pow(3, 2); // returns Number 9
- * math.multiply(3, 3); // returns Number 9
- *
- * math.square([1, 2, 3, 4]); // returns Array [1, 4, 9, 16]
- *
- * See also:
- *
- * multiply, cube, sqrt, pow
- *
- * @param {Number | BigNumber | Boolean | Complex | Array | Matrix | null} x
- * Number for which to calculate the square
- * @return {Number | BigNumber | Complex | Array | Matrix}
- * Squared value
- */
- math.square = function square(x) {
- if (arguments.length != 1) {
- throw new math.error.ArgumentsError('square', arguments.length, 1);
- }
-
- if (isNumber(x)) {
- return x * x;
- }
-
- if (isComplex(x)) {
- return math.multiply(x, x);
- }
-
- if (x instanceof BigNumber) {
- return x.times(x);
- }
-
- if (isCollection(x)) {
- // deep map collection, skip zeros since square(0) = 0
- return collection.deepMap(x, square, true);
- }
-
- if (isBoolean(x) || x === null) {
- return x * x;
- }
-
- throw new math.error.UnsupportedTypeError('square', math['typeof'](x));
- };
- };
-
-
-/***/ },
-/* 73 */
-/***/ function(module, exports, __webpack_require__) {
-
- 'use strict';
-
- module.exports = function (math) {
- var util = __webpack_require__(175),
-
- BigNumber = math.type.BigNumber,
- Complex = __webpack_require__(7),
- Matrix = math.type.Matrix,
- Unit = __webpack_require__(11),
- collection = math.collection,
-
- isBoolean = util['boolean'].isBoolean,
- isNumber = util.number.isNumber,
- isComplex = Complex.isComplex,
- isUnit = Unit.isUnit,
- isCollection = collection.isCollection;
+ return new M(data, datatype);
+ }
+ }
+
+ exports.name = 'matrix';
+ exports.factory = factory;
+
+
+/***/ },
+/* 24 */
+/***/ function(module, exports, __webpack_require__) {
+
+ 'use strict';
+
+ var size = __webpack_require__(18).size;
+
+ function factory (type, config, load, typed) {
+ var matrix = load(__webpack_require__(23));
+ var subtract = load(__webpack_require__(25));
+ var multiply = load(__webpack_require__(40));
+
+ /**
+ * Calculate the cross product for two vectors in three dimensional space.
+ * The cross product of `A = [a1, a2, a3]` and `B =[b1, b2, b3]` is defined
+ * as:
+ *
+ * cross(A, B) = [
+ * a2 * b3 - a3 * b2,
+ * a3 * b1 - a1 * b3,
+ * a1 * b2 - a2 * b1
+ * ]
+ *
+ * Syntax:
+ *
+ * math.cross(x, y)
+ *
+ * Examples:
+ *
+ * math.cross([1, 1, 0], [0, 1, 1]); // Returns [1, -1, 1]
+ * math.cross([3, -3, 1], [4, 9, 2]); // Returns [-15, -2, 39]
+ * math.cross([2, 3, 4], [5, 6, 7]); // Returns [-3, 6, -3]
+ *
+ * See also:
+ *
+ * dot, multiply
+ *
+ * @param {Array | Matrix} x First vector
+ * @param {Array | Matrix} y Second vector
+ * @return {Array | Matrix} Returns the cross product of `x` and `y`
+ */
+ var cross = typed('cross', {
+ 'Matrix, Matrix': function (x, y) {
+ return matrix(_cross(x.toArray(), y.toArray()));
+ },
+
+ 'Matrix, Array': function (x, y) {
+ return matrix(_cross(x.toArray(), y));
+ },
+
+ 'Array, Matrix': function (x, y) {
+ return matrix(_cross(x, y.toArray()));
+ },
+
+ 'Array, Array': _cross
+ });
+
+ cross.toTex = '\\left(${args[0]}\\right)\\times\\left(${args[1]}\\right)';
+
+ return cross;
+
+ /**
+ * Calculate the cross product for two arrays
+ * @param {Array} x First vector
+ * @param {Array} y Second vector
+ * @returns {Array} Returns the cross product of x and y
+ * @private
+ */
+ function _cross(x, y) {
+ var xSize= size(x);
+ var ySize = size(y);
+
+ if (xSize.length != 1 || ySize.length != 1 || xSize[0] != 3 || ySize[0] != 3) {
+ throw new RangeError('Vectors with length 3 expected ' +
+ '(Size A = [' + xSize.join(', ') + '], B = [' + ySize.join(', ') + '])');
+ }
+
+ return [
+ subtract(multiply(x[1], y[2]), multiply(x[2], y[1])),
+ subtract(multiply(x[2], y[0]), multiply(x[0], y[2])),
+ subtract(multiply(x[0], y[1]), multiply(x[1], y[0]))
+ ];
+ }
+ }
+
+ exports.name = 'cross';
+ exports.factory = factory;
+
+
+/***/ },
+/* 25 */
+/***/ function(module, exports, __webpack_require__) {
+
+ 'use strict';
+
+ var DimensionError = __webpack_require__(22);
+
+ function factory (type, config, load, typed) {
+ var latex = __webpack_require__(26);
+
+ var matrix = load(__webpack_require__(23));
+ var addScalar = load(__webpack_require__(27));
+ var unaryMinus = load(__webpack_require__(28));
+
+ var algorithm01 = load(__webpack_require__(30));
+ var algorithm03 = load(__webpack_require__(31));
+ var algorithm05 = load(__webpack_require__(32));
+ var algorithm10 = load(__webpack_require__(34));
+ var algorithm13 = load(__webpack_require__(35));
+ var algorithm14 = load(__webpack_require__(39));
/**
* Subtract two values, `x - y`.
@@ -13589,7 +4150,7 @@
*
* Examples:
*
- * math.subtract(5.3, 2); // returns Number 3.3
+ * math.subtract(5.3, 2); // returns number 3.3
*
* var a = math.complex(2, 3);
* var b = math.complex(4, 1);
@@ -13605,139 +4166,340 @@
*
* add
*
- * @param {Number | BigNumber | Boolean | Complex | Unit | Array | Matrix | null} x
+ * @param {number | BigNumber | Fraction | Complex | Unit | Array | Matrix} x
* Initial value
- * @param {Number | BigNumber | Boolean | Complex | Unit | Array | Matrix | null} y
+ * @param {number | BigNumber | Fraction | Complex | Unit | Array | Matrix} y
* Value to subtract from `x`
- * @return {Number | BigNumber | Complex | Unit | Array | Matrix}
+ * @return {number | BigNumber | Fraction | Complex | Unit | Array | Matrix}
* Subtraction of `x` and `y`
*/
- math.subtract = function subtract(x, y) {
- if (arguments.length != 2) {
- throw new math.error.ArgumentsError('subtract', arguments.length, 2);
- }
-
- if (isNumber(x)) {
- if (isNumber(y)) {
- // number - number
- return x - y;
- }
- else if (isComplex(y)) {
- // number - complex
- return new Complex (
- x - y.re,
- - y.im
- );
- }
- }
- else if (isComplex(x)) {
- if (isNumber(y)) {
- // complex - number
- return new Complex (
- x.re - y,
- x.im
- )
- }
- else if (isComplex(y)) {
- // complex - complex
- return new Complex (
- x.re - y.re,
- x.im - y.im
- )
- }
- }
-
- if (x instanceof BigNumber) {
- // try to convert to big number
- if (isNumber(y)) {
- y = BigNumber.convert(y);
- }
- else if (isBoolean(y) || y === null) {
- y = new BigNumber(y ? 1 : 0);
- }
-
- if (y instanceof BigNumber) {
- return x.minus(y);
- }
-
- // downgrade to Number
- return subtract(x.toNumber(), y);
- }
- if (y instanceof BigNumber) {
- // try to convert to big number
- if (isNumber(x)) {
- x = BigNumber.convert(x);
- }
- else if (isBoolean(x) || x === null) {
- x = new BigNumber(x ? 1 : 0);
- }
-
- if (x instanceof BigNumber) {
- return x.minus(y)
- }
-
- // downgrade to Number
- return subtract(x, y.toNumber());
- }
-
- if (isUnit(x)) {
- if (isUnit(y)) {
- if (x.value == null) {
- throw new Error('Parameter x contains a unit with undefined value');
- }
-
- if (y.value == null) {
- throw new Error('Parameter y contains a unit with undefined value');
- }
-
- if (!x.equalBase(y)) {
- throw new Error('Units do not match');
- }
-
- var res = x.clone();
- res.value -= y.value;
- res.fixPrefix = false;
-
- return res;
- }
- }
-
- if (isCollection(x) || isCollection(y)) {
- return collection.deepMap2(x, y, subtract);
- }
-
- if (isBoolean(x) || x === null) {
- return subtract(+x, y);
- }
- if (isBoolean(y) || y === null) {
- return subtract(x, +y);
- }
-
- throw new math.error.UnsupportedTypeError('subtract', math['typeof'](x), math['typeof'](y));
- };
- };
-
-
-/***/ },
-/* 74 */
+ var subtract = typed('subtract', {
+
+ 'number, number': function (x, y) {
+ return x - y;
+ },
+
+ 'Complex, Complex': function (x, y) {
+ return new type.Complex (
+ x.re - y.re,
+ x.im - y.im
+ );
+ },
+
+ 'BigNumber, BigNumber': function (x, y) {
+ return x.minus(y);
+ },
+
+ 'Fraction, Fraction': function (x, y) {
+ return x.sub(y);
+ },
+
+ 'Unit, Unit': function (x, y) {
+ if (x.value == null) {
+ throw new Error('Parameter x contains a unit with undefined value');
+ }
+
+ if (y.value == null) {
+ throw new Error('Parameter y contains a unit with undefined value');
+ }
+
+ if (!x.equalBase(y)) {
+ throw new Error('Units do not match');
+ }
+
+ var res = x.clone();
+ res.value -= y.value;
+ res.fixPrefix = false;
+
+ return res;
+ },
+
+ 'Matrix, Matrix': function (x, y) {
+ // matrix sizes
+ var xsize = x.size();
+ var ysize = y.size();
+
+ // check dimensions
+ if (xsize.length !== ysize.length)
+ throw new DimensionError(xsize.length, ysize.length);
+
+ // result
+ var c;
+
+ // process matrix storage
+ switch (x.storage()) {
+ case 'sparse':
+ switch (y.storage()) {
+ case 'sparse':
+ // sparse - sparse
+ c = algorithm05(x, y, subtract);
+ break;
+ default:
+ // sparse - dense
+ c = algorithm03(y, x, subtract, true);
+ break;
+ }
+ break;
+ default:
+ switch (y.storage()) {
+ case 'sparse':
+ // dense - sparse
+ c = algorithm01(x, y, subtract, false);
+ break;
+ default:
+ // dense - dense
+ c = algorithm13(x, y, subtract);
+ break;
+ }
+ break;
+ }
+ return c;
+ },
+
+ 'Array, Array': function (x, y) {
+ // use matrix implementation
+ return subtract(matrix(x), matrix(y)).valueOf();
+ },
+
+ 'Array, Matrix': function (x, y) {
+ // use matrix implementation
+ return subtract(matrix(x), y);
+ },
+
+ 'Matrix, Array': function (x, y) {
+ // use matrix implementation
+ return subtract(x, matrix(y));
+ },
+
+ 'Matrix, any': function (x, y) {
+ // result
+ var c;
+ // check storage format
+ switch (x.storage()) {
+ case 'sparse':
+ // algorithm 7 is faster than 9 since it calls f() for nonzero items only!
+ c = algorithm10(x, unaryMinus(y), addScalar);
+ break;
+ default:
+ c = algorithm14(x, y, subtract);
+ break;
+ }
+ return c;
+ },
+
+ 'any, Matrix': function (x, y) {
+ // result
+ var c;
+ // check storage format
+ switch (y.storage()) {
+ case 'sparse':
+ c = algorithm10(y, x, subtract, true);
+ break;
+ default:
+ c = algorithm14(y, x, subtract, true);
+ break;
+ }
+ return c;
+ },
+
+ 'Array, any': function (x, y) {
+ // use matrix implementation
+ return algorithm14(matrix(x), y, subtract, false).valueOf();
+ },
+
+ 'any, Array': function (x, y) {
+ // use matrix implementation
+ return algorithm14(matrix(y), x, subtract, true).valueOf();
+ }
+ });
+
+ subtract.toTex = '\\left(${args[0]}' + latex.operators['subtract'] + '${args[1]}\\right)';
+
+ return subtract;
+ }
+
+ exports.name = 'subtract';
+ exports.factory = factory;
+
+
+/***/ },
+/* 26 */
+/***/ function(module, exports) {
+
+ 'use strict';
+
+ exports.symbols = {
+ // GREEK LETTERS
+ Alpha: 'A', alpha: '\\alpha',
+ Beta: 'B', beta: '\\beta',
+ Gamma: '\\Gamma', gamma: '\\gamma',
+ Delta: '\\Delta', delta: '\\delta',
+ Epsilon: 'E', epsilon: '\\epsilon', varepsilon: '\\varepsilon',
+ Zeta: 'Z', zeta: '\\zeta',
+ Eta: 'H', eta: '\\eta',
+ Theta: '\\Theta', theta: '\\theta', vartheta: '\\vartheta',
+ Iota: 'I', iota: '\\iota',
+ Kappa: 'K', kappa: '\\kappa', varkappa: '\\varkappa',
+ Lambda: '\\Lambda', lambda: '\\lambda',
+ Mu: 'M', mu: '\\mu',
+ Nu: 'N', nu: '\\nu',
+ Xi: '\\Xi', xi: '\\xi',
+ Omicron: 'O', omicron: 'o',
+ Pi: '\\Pi', pi: '\\pi', varpi: '\\varpi',
+ Rho: 'P', rho: '\\rho', varrho: '\\varrho',
+ Sigma: '\\Sigma', sigma: '\\sigma', varsigma: '\\varsigma',
+ Tau: 'T', tau: '\\tau',
+ Upsilon: '\\Upsilon', upsilon: '\\upsilon',
+ Phi: '\\Phi', phi: '\\phi', varphi: '\\varphi',
+ Chi: 'X', chi: '\\chi',
+ Psi: '\\Psi', psi: '\\psi',
+ Omega: '\\Omega', omega: '\\omega',
+ //logic
+ 'true': '\\mathrm{True}',
+ 'false': '\\mathrm{False}',
+ //other
+ i: 'i', //TODO use \i ??
+ inf: '\\infty',
+ Inf: '\\infty',
+ infinity: '\\infty',
+ Infinity: '\\infty',
+ oo: '\\infty',
+ lim: '\\lim',
+ 'undefined': '\\mathbf{?}'
+ };
+
+ exports.operators = {
+ 'transpose': '^\\top',
+ 'factorial': '!',
+ 'pow': '^',
+ 'dotPow': '.^\\wedge', //TODO find ideal solution
+ 'unaryPlus': '+',
+ 'unaryMinus': '-',
+ 'bitNot': '~', //TODO find ideal solution
+ 'not': '\\neg',
+ 'multiply': '\\cdot',
+ 'divide': '\\frac', //TODO how to handle that properly?
+ 'dotMultiply': '.\\cdot', //TODO find ideal solution
+ 'dotDivide': '.:', //TODO find ideal solution
+ 'mod': '\\mod',
+ 'add': '+',
+ 'subtract': '-',
+ 'to': '\\rightarrow',
+ 'leftShift': '<<',
+ 'rightArithShift': '>>',
+ 'rightLogShift': '>>>',
+ 'equal': '=',
+ 'unequal': '\\neq',
+ 'smaller': '<',
+ 'larger': '>',
+ 'smallerEq': '\\leq',
+ 'largerEq': '\\geq',
+ 'bitAnd': '\\&',
+ 'bitXor': '\\underline{|}',
+ 'bitOr': '|',
+ 'and': '\\wedge',
+ 'xor': '\\veebar',
+ 'or': '\\vee'
+ };
+
+ exports.defaultTemplate = '\\mathrm{${name}}\\left(${args}\\right)';
+
+ var units = {
+ deg: '^\\circ'
+ };
+
+ //@param {string} name
+ //@param {boolean} isUnit
+ exports.toSymbol = function (name, isUnit) {
+ isUnit = typeof isUnit === 'undefined' ? false : isUnit;
+ if (isUnit) {
+ if (units.hasOwnProperty(name)) {
+ return units[name];
+ }
+ return '\\mathrm{' + name + '}';
+ }
+
+ if (exports.symbols.hasOwnProperty(name)) {
+ return exports.symbols[name];
+ }
+ else if (name.indexOf('_') !== -1) {
+ //symbol with index (eg. alpha_1)
+ var index = name.indexOf('_');
+ return exports.toSymbol(name.substring(0, index)) + '_{'
+ + exports.toSymbol(name.substring(index + 1)) + '}';
+ }
+ return name;
+ };
+
+
+/***/ },
+/* 27 */
+/***/ function(module, exports) {
+
+ 'use strict';
+
+ function factory(type, config, load, typed) {
+
+ /**
+ * Add two scalar values, `x + y`.
+ * This function is meant for internal use: it is used by the public function
+ * `add`
+ *
+ * This function does not support collections (Array or Matrix), and does
+ * not validate the number of of inputs.
+ *
+ * @param {number | BigNumber | Fraction | Complex | Unit} x First value to add
+ * @param {number | BigNumber | Fraction | Complex} y Second value to add
+ * @return {number | BigNumber | Fraction | Complex | Unit} Sum of `x` and `y`
+ * @private
+ */
+ return typed('add', {
+
+ 'number, number': function (x, y) {
+ return x + y;
+ },
+
+ 'Complex, Complex': function (x, y) {
+ return new type.Complex(
+ x.re + y.re,
+ x.im + y.im
+ );
+ },
+
+ 'BigNumber, BigNumber': function (x, y) {
+ return x.plus(y);
+ },
+
+ 'Fraction, Fraction': function (x, y) {
+ return x.add(y);
+ },
+
+ 'Unit, Unit': function (x, y) {
+ if (x.value == null) throw new Error('Parameter x contains a unit with undefined value');
+ if (y.value == null) throw new Error('Parameter y contains a unit with undefined value');
+ if (!x.equalBase(y)) throw new Error('Units do not match');
+
+ var res = x.clone();
+ res.value += y.value;
+ res.fixPrefix = false;
+ return res;
+ }
+ });
+ }
+
+ exports.factory = factory;
+
+
+/***/ },
+/* 28 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
- module.exports = function (math, config) {
- var util = __webpack_require__(175),
-
- BigNumber = math.type.BigNumber,
- Complex = __webpack_require__(7),
- Unit = __webpack_require__(11),
- collection = math.collection,
-
- isNumber = util.number.isNumber,
- isBoolean = util['boolean'].isBoolean,
- isString = util.string.isString,
- isComplex = Complex.isComplex,
- isUnit = Unit.isUnit,
- isCollection = collection.isCollection;
+ var deepMap = __webpack_require__(29);
+
+ function factory (type, config, load, typed) {
+ var latex = __webpack_require__(26);
/**
* Inverse the sign of a value, apply a unary minus operation.
@@ -13759,1931 +4521,2140 @@
*
* add, subtract, unaryPlus
*
- * @param {Number | BigNumber | Boolean | String | Complex | Unit | Array | Matrix | null} x Number to be inverted.
- * @return {Number | BigNumber | Complex | Unit | Array | Matrix} Returns the value with inverted sign.
+ * @param {number | BigNumber | Fraction | Complex | Unit | Array | Matrix} x Number to be inverted.
+ * @return {number | BigNumber | Fraction | Complex | Unit | Array | Matrix} Returns the value with inverted sign.
*/
- math.unaryMinus = function unaryMinus(x) {
- if (arguments.length != 1) {
- throw new math.error.ArgumentsError('unaryMinus', arguments.length, 1);
- }
-
- if (isNumber(x)) {
+ var unaryMinus = typed('unaryMinus', {
+ 'number': function (x) {
return -x;
- }
-
- if (isComplex(x)) {
- return new Complex(
- -x.re,
- -x.im
- );
- }
-
- if (x instanceof BigNumber) {
+ },
+
+ 'Complex': function (x) {
+ return new type.Complex(-x.re, -x.im);
+ },
+
+ 'BigNumber': function (x) {
return x.neg();
- }
-
- if (isUnit(x)) {
+ },
+
+ 'Fraction': function (x) {
+ var tmp = x.clone();
+ tmp.s = -tmp.s;
+ return tmp;
+ },
+
+ 'Unit': function (x) {
var res = x.clone();
res.value = -x.value;
return res;
- }
+ },
- if (isCollection(x)) {
+ 'Array | Matrix': function (x) {
// deep map collection, skip zeros since unaryMinus(0) = 0
- return collection.deepMap(x, unaryMinus, true);
- }
-
- if (isBoolean(x) || isString(x) || x === null) {
- // convert to a number or bignumber
- return (config.number == 'bignumber') ? new BigNumber(-x): -x;
- }
-
- throw new math.error.UnsupportedTypeError('unaryMinus', math['typeof'](x));
- };
-
- // TODO: function unary is renamed to unaryMinus since version 0.23.0. Cleanup some day
- math.unary = function unary() {
- throw new Error('Function unary is deprecated. Use unaryMinus instead.');
- };
- };
-
-
-/***/ },
-/* 75 */
-/***/ function(module, exports, __webpack_require__) {
-
- 'use strict';
-
- module.exports = function (math, config) {
- var util = __webpack_require__(175),
-
- BigNumber = math.type.BigNumber,
- Complex = __webpack_require__(7),
- Unit = __webpack_require__(11),
- collection = math.collection,
-
- isNumber = util.number.isNumber,
- isBoolean = util['boolean'].isBoolean,
- isString = util.string.isString,
- isComplex = Complex.isComplex,
- isUnit = Unit.isUnit,
- isCollection = collection.isCollection;
-
- /**
- * Unary plus operation.
- * Boolean values and strings will be converted to a number, numeric values will be returned as is.
- *
- * For matrices, the function is evaluated element wise.
- *
- * Syntax:
- *
- * math.unaryPlus(x)
- *
- * Examples:
- *
- * math.unaryPlus(3.5); // returns 3.5
- * math.unaryPlus(1); // returns 1
- *
- * See also:
- *
- * unaryMinus, add, subtract
- *
- * @param {Number | BigNumber | Boolean | String | Complex | Unit | Array | Matrix | null} x
- * Input value
- * @return {Number | BigNumber | Complex | Unit | Array | Matrix}
- * Returns the input value when numeric, converts to a number when input is non-numeric.
- */
- math.unaryPlus = function unaryPlus(x) {
- if (arguments.length != 1) {
- throw new math.error.ArgumentsError('unaryPlus', arguments.length, 1);
- }
-
- if (isNumber(x)) {
- return x;
- }
-
- if (isComplex(x)) {
- return x.clone();
- }
-
- if (x instanceof BigNumber) {
- return x;
- }
-
- if (isUnit(x)) {
- return x.clone();
- }
-
- if (isCollection(x)) {
- // deep map collection, skip zeros since unaryPlus(0) = 0
- return collection.deepMap(x, unaryPlus, true);
- }
-
- if (isBoolean(x) || isString(x) || x === null) {
- // convert to a number or bignumber
- return (config.number == 'bignumber') ? new BigNumber(+x): +x;
- }
-
- throw new math.error.UnsupportedTypeError('unaryPlus', math['typeof'](x));
- };
- };
-
-
-/***/ },
-/* 76 */
-/***/ function(module, exports, __webpack_require__) {
-
- 'use strict';
-
- module.exports = function (math, config) {
- var util = __webpack_require__(175),
-
- Matrix = math.type.Matrix,
- BigNumber = math.type.BigNumber,
-
- isNumber = util.number.isNumber,
- isBoolean = util['boolean'].isBoolean,
- isInteger = util.number.isInteger;
-
- /**
- * Calculate the extended greatest common divisor for two values.
- * See http://en.wikipedia.org/wiki/Extended_Euclidean_algorithm.
- *
- * Syntax:
- *
- * math.xgcd(a, b)
- *
- * Examples:
- *
- * math.xgcd(8, 12); // returns [4, -1, 1]
- * math.gcd(8, 12); // returns 4
- * math.xgcd(36163, 21199); // returns [1247, -7, 12]
- *
- * See also:
- *
- * gcd, lcm
- *
- * @param {Number | BigNumber | Boolean} a An integer number
- * @param {Number | BigNumber | Boolean} b An integer number
- * @return {Array} Returns an array containing 3 integers `[div, m, n]`
- * where `div = gcd(a, b)` and `a*m + b*n = div`
- */
- math.xgcd = function xgcd(a, b) {
- if (arguments.length == 2) {
- // two arguments
- if (isNumber(a) && isNumber(b)) {
- if (!isInteger(a) || !isInteger(b)) {
- throw new Error('Parameters in function xgcd must be integer numbers');
- }
-
- return _xgcd(a, b);
- }
-
- if (a instanceof BigNumber) {
- // try to convert to big number
- if (isNumber(b)) {
- b = BigNumber.convert(b);
- }
- else if (isBoolean(b) || b === null) {
- b = new BigNumber(b ? 1 : 0);
- }
-
- if (b instanceof BigNumber) {
- return _bigXgcd(a, b);
- }
-
- // downgrade to Number
- return xgcd(a.toNumber(), b);
- }
- if (b instanceof BigNumber) {
- // try to convert to big number
- if (i
Follow ups
-
[Merge] lp:~gang65/ubuntu-calculator-app/ubuntu-calculator-app-mathjs-2-upgrade into lp:ubuntu-calculator-app
From: noreply, 2015-09-14
-
Re: [Merge] lp:~gang65/ubuntu-calculator-app/ubuntu-calculator-app-mathjs-2-upgrade into lp:ubuntu-calculator-app
From: Ubuntu Phone Apps Jenkins Bot, 2015-09-14
-
[Merge] lp:~gang65/ubuntu-calculator-app/ubuntu-calculator-app-mathjs-2-upgrade into lp:ubuntu-calculator-app
From: Nicholas Skaggs, 2015-09-14
-
Re: [Merge] lp:~gang65/ubuntu-calculator-app/ubuntu-calculator-app-mathjs-2-upgrade into lp:ubuntu-calculator-app
From: Nicholas Skaggs, 2015-09-14
-
Re: [Merge] lp:~gang65/ubuntu-calculator-app/ubuntu-calculator-app-mathjs-2-upgrade into lp:ubuntu-calculator-app
From: Ubuntu Phone Apps Jenkins Bot, 2015-08-30
-
Re: [Merge] lp:~gang65/ubuntu-calculator-app/ubuntu-calculator-app-mathjs-2-upgrade into lp:ubuntu-calculator-app
From: Ubuntu Phone Apps Jenkins Bot, 2015-08-30
-
[Merge] lp:~gang65/ubuntu-calculator-app/ubuntu-calculator-app-mathjs-2-upgrade into lp:ubuntu-calculator-app
From: Ubuntu Phone Apps Jenkins Bot, 2015-08-30
-
[Merge] lp:~gang65/ubuntu-calculator-app/ubuntu-calculator-app-mathjs-2-upgrade into lp:ubuntu-calculator-app
From: Riccardo Padovani, 2015-08-30
-
Re: [Merge] lp:~gang65/ubuntu-calculator-app/ubuntu-calculator-app-mathjs-2-upgrade into lp:ubuntu-calculator-app
From: Riccardo Padovani, 2015-08-30
-
Re: [Merge] lp:~gang65/ubuntu-calculator-app/ubuntu-calculator-app-mathjs-2-upgrade into lp:ubuntu-calculator-app
From: Ubuntu Phone Apps Jenkins Bot, 2015-08-14