qics
Version:
A Javascript Idealistic Quantum Computer Simulation Library
1,744 lines (1,516 loc) • 1.6 MB
JavaScript
var qics =
/******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId])
/******/ return installedModules[moduleId].exports;
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ exports: {},
/******/ id: moduleId,
/******/ loaded: false
/******/ };
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/ // Flag the module as loaded
/******/ module.loaded = true;
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/ // Load entry module and return exports
/******/ return __webpack_require__(0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var gates = __webpack_require__(80);
var Register = __webpack_require__(138);
// Exports the Gates class and the Register Class
module.exports = {
gates: gates,
Register: Register
};
/***/ },
/* 1 */
/***/ function(module, exports) {
'use strict';
/**
* Execute the callback function element wise for each element in array and any
* nested array
* Returns an array with the results
* @param {Array | Matrix} array
* @param {Function} callback The callback is called with two parameters:
* value1 and value2, which contain the current
* element of both arrays.
* @param {boolean} [skipZeros] Invoke callback function for non-zero values only.
*
* @return {Array | Matrix} res
*/
module.exports = function deepMap(array, callback, skipZeros) {
if (array && (typeof array.map === 'function')) {
// TODO: replace array.map with a for loop to improve performance
return array.map(function (x) {
return deepMap(x, callback, skipZeros);
});
}
else {
return callback(array);
}
};
/***/ },
/* 2 */
/***/ function(module, exports) {
'use strict';
function factory (type, config, load, typed) {
/**
* Create a Matrix. The function creates a new `math.type.Matrix` object from
* an `Array`. A Matrix has utility functions to manipulate the data in the
* matrix, like getting the size and getting or setting values in the matrix.
* Supported storage formats are 'dense' and 'sparse'.
*
* Syntax:
*
* math.matrix() // creates an empty matrix using default storage format (dense).
* math.matrix(data) // creates a matrix with initial data using default storage format (dense).
* math.matrix('dense') // creates an empty matrix using the given storage format.
* math.matrix(data, 'dense') // creates a matrix with initial data using the given storage format.
* math.matrix(data, 'sparse') // creates a sparse matrix with initial data.
* math.matrix(data, 'sparse', 'number') // creates a sparse matrix with initial data, number data type.
*
* Examples:
*
* var m = math.matrix([[1, 2], [3, 4]]);
* m.size(); // Array [2, 2]
* m.resize([3, 2], 5);
* m.valueOf(); // Array [[1, 2], [3, 4], [5, 5]]
* m.get([1, 0]) // number 3
*
* See also:
*
* bignumber, boolean, complex, index, number, string, unit, sparse
*
* @param {Array | Matrix} [data] A multi dimensional array
* @param {string} [format] The Matrix storage format
*
* @return {Matrix} The created matrix
*/
var matrix = typed('matrix', {
'': function () {
return _create([]);
},
'string': function (format) {
return _create([], format);
},
'string, string': function (format, datatype) {
return _create([], format, datatype);
},
'Array': function (data) {
return _create(data);
},
'Matrix': function (data) {
return _create(data, data.storage());
},
'Array | Matrix, string': _create,
'Array | Matrix, string, string': _create
});
matrix.toTex = {
0: '\\begin{bmatrix}\\end{bmatrix}',
1: '\\left(${args[0]}\\right)',
2: '\\left(${args[0]}\\right)'
};
return matrix;
/**
* Create a new Matrix with given storage format
* @param {Array} data
* @param {string} [format]
* @param {string} [datatype]
* @returns {Matrix} Returns a new Matrix
* @private
*/
function _create(data, format, datatype) {
// get storage format constructor
var M = type.Matrix.storage(format || 'default');
// create instance
return new M(data, datatype);
}
}
exports.name = 'matrix';
exports.factory = factory;
/***/ },
/* 3 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var NumberFormatter = __webpack_require__(505);
/**
* Test whether value is a number
* @param {*} value
* @return {boolean} isNumber
*/
exports.isNumber = function(value) {
return typeof value === 'number';
};
/**
* Check if a number is integer
* @param {number | boolean} value
* @return {boolean} isInteger
*/
exports.isInteger = function(value) {
return isFinite(value)
? (value == Math.round(value))
: false;
// Note: we use ==, not ===, as we can have Booleans as well
};
/**
* Calculate the sign of a number
* @param {number} x
* @returns {*}
*/
exports.sign = Math.sign || function(x) {
if (x > 0) {
return 1;
}
else if (x < 0) {
return -1;
}
else {
return 0;
}
};
/**
* Convert a number to a formatted string representation.
*
* Syntax:
*
* format(value)
* format(value, options)
* format(value, precision)
* format(value, fn)
*
* Where:
*
* {number} value The value to be formatted
* {Object} options An object with formatting options. Available options:
* {string} notation
* Number notation. Choose from:
* 'fixed' Always use regular number notation.
* For example '123.40' and '14000000'
* 'exponential' Always use exponential notation.
* For example '1.234e+2' and '1.4e+7'
* 'engineering' Always use engineering notation.
* For example '123.4e+0' and '14.0e+6'
* 'auto' (default) Regular number notation for numbers
* having an absolute value between
* `lower` and `upper` bounds, and uses
* exponential notation elsewhere.
* Lower bound is included, upper bound
* is excluded.
* For example '123.4' and '1.4e7'.
* {number} precision A number between 0 and 16 to round
* the digits of the number.
* In case of notations 'exponential' and
* 'auto', `precision` defines the total
* number of significant digits returned
* and is undefined by default.
* In case of notation 'fixed',
* `precision` defines the number of
* significant digits after the decimal
* point, and is 0 by default.
* {Object} exponential An object containing two parameters,
* {number} lower and {number} upper,
* used by notation 'auto' to determine
* when to return exponential notation.
* Default values are `lower=1e-3` and
* `upper=1e5`.
* Only applicable for notation `auto`.
* {Function} fn A custom formatting function. Can be used to override the
* built-in notations. Function `fn` is called with `value` as
* parameter and must return a string. Is useful for example to
* format all values inside a matrix in a particular way.
*
* Examples:
*
* format(6.4); // '6.4'
* format(1240000); // '1.24e6'
* format(1/3); // '0.3333333333333333'
* format(1/3, 3); // '0.333'
* format(21385, 2); // '21000'
* format(12.071, {notation: 'fixed'}); // '12'
* format(2.3, {notation: 'fixed', precision: 2}); // '2.30'
* format(52.8, {notation: 'exponential'}); // '5.28e+1'
* format(12345678, {notation: 'engineering'}); // '12.345678e+6'
*
* @param {number} value
* @param {Object | Function | number} [options]
* @return {string} str The formatted value
*/
exports.format = function(value, options) {
if (typeof options === 'function') {
// handle format(value, fn)
return options(value);
}
// handle special cases
if (value === Infinity) {
return 'Infinity';
}
else if (value === -Infinity) {
return '-Infinity';
}
else if (isNaN(value)) {
return 'NaN';
}
// default values for options
var notation = 'auto';
var precision = undefined;
if (options) {
// determine notation from options
if (options.notation) {
notation = options.notation;
}
// determine precision from options
if (exports.isNumber(options)) {
precision = options;
}
else if (options.precision) {
precision = options.precision;
}
}
// handle the various notations
switch (notation) {
case 'fixed':
return exports.toFixed(value, precision);
case 'exponential':
return exports.toExponential(value, precision);
case 'engineering':
return exports.toEngineering(value, precision);
case 'auto':
return exports
.toPrecision(value, precision, options && options.exponential)
// remove trailing zeros after the decimal point
.replace(/((\.\d*?)(0+))($|e)/, function () {
var digits = arguments[2];
var e = arguments[4];
return (digits !== '.') ? digits + e : e;
});
default:
throw new Error('Unknown notation "' + notation + '". ' +
'Choose "auto", "exponential", or "fixed".');
}
};
/**
* Format a number in exponential notation. Like '1.23e+5', '2.3e+0', '3.500e-3'
* @param {number} value
* @param {number} [precision] Number of digits in formatted output.
* If not provided, the maximum available digits
* is used.
* @returns {string} str
*/
exports.toExponential = function(value, precision) {
return new NumberFormatter(value).toExponential(precision);
};
/**
* Format a number in engineering notation. Like '1.23e+6', '2.3e+0', '3.500e-3'
* @param {number} value
* @param {number} [precision] Number of digits in formatted output.
* If not provided, the maximum available digits
* is used.
* @returns {string} str
*/
exports.toEngineering = function(value, precision) {
return new NumberFormatter(value).toEngineering(precision);
};
/**
* Format a number with fixed notation.
* @param {number} value
* @param {number} [precision=0] Optional number of decimals after the
* decimal point. Zero by default.
*/
exports.toFixed = function(value, precision) {
return new NumberFormatter(value).toFixed(precision);
};
/**
* Format a number with a certain precision
* @param {number} value
* @param {number} [precision=undefined] Optional number of digits.
* @param {{lower: number, upper: number}} [options] By default:
* lower = 1e-3 (excl)
* upper = 1e+5 (incl)
* @return {string}
*/
exports.toPrecision = function(value, precision, options) {
return new NumberFormatter(value).toPrecision(precision, options);
};
/**
* Count the number of significant digits of a number.
*
* For example:
* 2.34 returns 3
* 0.0034 returns 2
* 120.5e+30 returns 4
*
* @param {number} value
* @return {number} digits Number of significant digits
*/
exports.digits = function(value) {
return value
.toExponential()
.replace(/e.*$/, '') // remove exponential notation
.replace( /^0\.?0*|\./, '') // remove decimal point and leading zeros
.length
};
/**
* Minimum number added to one that makes the result different than one
*/
exports.DBL_EPSILON = Number.EPSILON || 2.2204460492503130808472633361816E-16;
/**
* Compares two floating point numbers.
* @param {number} x First value to compare
* @param {number} y Second value to compare
* @param {number} [epsilon] The maximum relative difference between x and y
* If epsilon is undefined or null, the function will
* test whether x and y are exactly equal.
* @return {boolean} whether the two numbers are nearly equal
*/
exports.nearlyEqual = function(x, y, epsilon) {
// if epsilon is null or undefined, test whether x and y are exactly equal
if (epsilon == null) {
return x == y;
}
// use "==" operator, handles infinities
if (x == y) {
return true;
}
// NaN
if (isNaN(x) || isNaN(y)) {
return false;
}
// at this point x and y should be finite
if(isFinite(x) && isFinite(y)) {
// check numbers are very close, needed when comparing numbers near zero
var diff = Math.abs(x - y);
if (diff < exports.DBL_EPSILON) {
return true;
}
else {
// use relative error
return diff <= Math.max(Math.abs(x), Math.abs(y)) * epsilon;
}
}
// Infinite and Number or negative Infinite and positive Infinite cases
return false;
};
/***/ },
/* 4 */
/***/ 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;
};
/***/ },
/* 5 */
/***/ function(module, exports) {
'use strict';
/**
* Clone an object
*
* clone(x)
*
* Can clone any primitive type, array, and object.
* If x has a function clone, this function will be invoked to clone the object.
*
* @param {*} x
* @return {*} clone
*/
exports.clone = function clone(x) {
var type = typeof x;
// immutable primitive types
if (type === 'number' || type === 'string' || type === 'boolean' ||
x === null || x === undefined) {
return x;
}
// use clone function of the object when available
if (typeof x.clone === 'function') {
return x.clone();
}
// array
if (Array.isArray(x)) {
return x.map(function (value) {
return clone(value);
});
}
if (x instanceof Number) return new Number(x.valueOf());
if (x instanceof String) return new String(x.valueOf());
if (x instanceof Boolean) return new Boolean(x.valueOf());
if (x instanceof Date) return new Date(x.valueOf());
if (x && x.isBigNumber === true) return x; // bignumbers are immutable
if (x instanceof RegExp) throw new TypeError('Cannot clone ' + x); // TODO: clone a RegExp
// object
var m = {};
for (var key in x) {
if (x.hasOwnProperty(key)) {
m[key] = clone(x[key]);
}
}
return m;
};
/**
* Extend object a with the properties of object b
* @param {Object} a
* @param {Object} b
* @return {Object} a
*/
exports.extend = function(a, b) {
for (var prop in b) {
if (b.hasOwnProperty(prop)) {
a[prop] = b[prop];
}
}
return a;
};
/**
* Deep extend an object a with the properties of object b
* @param {Object} a
* @param {Object} b
* @returns {Object}
*/
exports.deepExtend = function deepExtend (a, b) {
// TODO: add support for Arrays to deepExtend
if (Array.isArray(b)) {
throw new TypeError('Arrays are not supported by deepExtend');
}
for (var prop in b) {
if (b.hasOwnProperty(prop)) {
if (b[prop] && b[prop].constructor === Object) {
if (a[prop] === undefined) {
a[prop] = {};
}
if (a[prop].constructor === Object) {
deepExtend(a[prop], b[prop]);
}
else {
a[prop] = b[prop];
}
} else if (Array.isArray(b[prop])) {
throw new TypeError('Arrays are not supported by deepExtend');
} else {
a[prop] = b[prop];
}
}
}
return a;
};
/**
* Deep test equality of all fields in two pairs of arrays or objects.
* @param {Array | Object} a
* @param {Array | Object} b
* @returns {boolean}
*/
exports.deepEqual = function deepEqual (a, b) {
var prop, i, len;
if (Array.isArray(a)) {
if (!Array.isArray(b)) {
return false;
}
if (a.length != b.length) {
return false;
}
for (i = 0, len = a.length; i < len; i++) {
if (!exports.deepEqual(a[i], b[i])) {
return false;
}
}
return true;
}
else if (a instanceof Object) {
if (Array.isArray(b) || !(b instanceof Object)) {
return false;
}
for (prop in a) {
//noinspection JSUnfilteredForInLoop
if (!exports.deepEqual(a[prop], b[prop])) {
return false;
}
}
for (prop in b) {
//noinspection JSUnfilteredForInLoop
if (!exports.deepEqual(a[prop], b[prop])) {
return false;
}
}
return true;
}
else {
return (typeof a === typeof b) && (a == b);
}
};
/**
* Test whether the current JavaScript engine supports Object.defineProperty
* @returns {boolean} returns true if supported
*/
exports.canDefineProperty = function () {
// test needed for broken IE8 implementation
try {
if (Object.defineProperty) {
Object.defineProperty({}, 'x', { get: function () {} });
return true;
}
} catch (e) {}
return false;
};
/**
* Attach a lazy loading property to a constant.
* The given function `fn` is called once when the property is first requested.
* On older browsers (<IE8), the function will fall back to direct evaluation
* of the properties value.
* @param {Object} object Object where to add the property
* @param {string} prop Property name
* @param {Function} fn Function returning the property value. Called
* without arguments.
*/
exports.lazy = function (object, prop, fn) {
if (exports.canDefineProperty()) {
var _uninitialized = true;
var _value;
Object.defineProperty(object, prop, {
get: function () {
if (_uninitialized) {
_value = fn();
_uninitialized = false;
}
return _value;
},
set: function (value) {
_value = value;
_uninitialized = false;
},
configurable: true,
enumerable: true
});
}
else {
// fall back to immediate evaluation
object[prop] = fn();
}
};
/**
* Traverse a path into an object.
* When a namespace is missing, it will be created
* @param {Object} object
* @param {string} path A dot separated string like 'name.space'
* @return {Object} Returns the object at the end of the path
*/
exports.traverse = function(object, path) {
var obj = object;
if (path) {
var names = path.split('.');
for (var i = 0; i < names.length; i++) {
var name = names[i];
if (!(name in obj)) {
obj[name] = {};
}
obj = obj[name];
}
}
return obj;
};
/**
* Test whether an object is a factory. a factory has fields:
*
* - factory: function (type: Object, config: Object, load: function, typed: function [, math: Object]) (required)
* - name: string (optional)
* - path: string A dot separated path (optional)
* - math: boolean If true (false by default), the math namespace is passed
* as fifth argument of the factory function
*
* @param {*} object
* @returns {boolean}
*/
exports.isFactory = function (object) {
return object && typeof object.factory === 'function';
};
/***/ },
/* 6 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var clone = __webpack_require__(5).clone;
function factory (type, config, load, typed) {
var DenseMatrix = type.DenseMatrix;
/**
* Iterates over DenseMatrix items and invokes the callback function f(Aij..z, b).
* Callback function invoked MxN times.
*
* C(i,j,...z) = f(Aij..z, b)
*
* @param {Matrix} a The DenseMatrix instance (A)
* @param {Scalar} b The Scalar value
* @param {Function} callback The f(Aij..z,b) operation to invoke
* @param {boolean} inverse A true value indicates callback should be invoked f(b,Aij..z)
*
* @return {Matrix} DenseMatrix (C)
*
* https://github.com/josdejong/mathjs/pull/346#issuecomment-97659042
*/
var algorithm14 = function (a, b, callback, inverse) {
// a arrays
var adata = a._data;
var asize = a._size;
var adt = a._datatype;
// datatype
var dt;
// callback signature to use
var cf = callback;
// process data types
if (typeof adt === 'string') {
// datatype
dt = adt;
// convert b to the same datatype
b = typed.convert(b, dt);
// callback
cf = typed.find(callback, [dt, dt]);
}
// populate cdata, iterate through dimensions
var cdata = asize.length > 0 ? _iterate(cf, 0, asize, asize[0], adata, b, inverse) : [];
// c matrix
return new DenseMatrix({
data: cdata,
size: clone(asize),
datatype: dt
});
};
// recursive function
var _iterate = function (f, level, s, n, av, bv, inverse) {
// initialize array for this level
var cv = [];
// check we reach the last level
if (level === s.length - 1) {
// loop arrays in last level
for (var i = 0; i < n; i++) {
// invoke callback and store value
cv[i] = inverse ? f(bv, av[i]) : f(av[i], bv);
}
}
else {
// iterate current level
for (var j = 0; j < n; j++) {
// iterate next level
cv[j] = _iterate(f, level + 1, s, s[level + 1], av[j], bv, inverse);
}
}
return cv;
};
return algorithm14;
}
exports.name = 'algorithm14';
exports.factory = factory;
/***/ },
/* 7 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var util = __webpack_require__(24);
var DimensionError = __webpack_require__(10);
var string = util.string,
isString = string.isString;
function factory (type, config, load, typed) {
var DenseMatrix = type.DenseMatrix;
/**
* Iterates over DenseMatrix items and invokes the callback function f(Aij..z, Bij..z).
* Callback function invoked MxN times.
*
* C(i,j,...z) = f(Aij..z, Bij..z)
*
* @param {Matrix} a The DenseMatrix instance (A)
* @param {Matrix} b The DenseMatrix instance (B)
* @param {Function} callback The f(Aij..z,Bij..z) operation to invoke
*
* @return {Matrix} DenseMatrix (C)
*
* https://github.com/josdejong/mathjs/pull/346#issuecomment-97658658
*/
var algorithm13 = function (a, b, callback) {
// a arrays
var adata = a._data;
var asize = a._size;
var adt = a._datatype;
// b arrays
var bdata = b._data;
var bsize = b._size;
var bdt = b._datatype;
// c arrays
var csize = [];
// validate dimensions
if (asize.length !== bsize.length)
throw new DimensionError(asize.length, bsize.length);
// validate each one of the dimension sizes
for (var s = 0; s < asize.length; s++) {
// must match
if (asize[s] !== bsize[s])
throw new RangeError('Dimension mismatch. Matrix A (' + asize + ') must match Matrix B (' + bsize + ')');
// update dimension in c
csize[s] = asize[s];
}
// datatype
var dt;
// callback signature to use
var cf = callback;
// process data types
if (typeof adt === 'string' && adt === bdt) {
// datatype
dt = adt;
// convert b to the same datatype
b = typed.convert(b, dt);
// callback
cf = typed.find(callback, [dt, dt]);
}
// populate cdata, iterate through dimensions
var cdata = csize.length > 0 ? _iterate(cf, 0, csize, csize[0], adata, bdata) : [];
// c matrix
return new DenseMatrix({
data: cdata,
size: csize,
datatype: dt
});
};
// recursive function
var _iterate = function (f, level, s, n, av, bv) {
// initialize array for this level
var cv = [];
// check we reach the last level
if (level === s.length - 1) {
// loop arrays in last level
for (var i = 0; i < n; i++) {
// invoke callback and store value
cv[i] = f(av[i], bv[i]);
}
}
else {
// iterate current level
for (var j = 0; j < n; j++) {
// iterate next level
cv[j] = _iterate(f, level + 1, s, s[level + 1], av[j], bv[j]);
}
}
return cv;
};
return algorithm13;
}
exports.name = 'algorithm13';
exports.factory = factory;
/***/ },
/* 8 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var number = __webpack_require__(3);
var string = __webpack_require__(20);
var object = __webpack_require__(5);
var types = __webpack_require__(61);
var DimensionError = __webpack_require__(10);
var IndexError = __webpack_require__(43);
/**
* Calculate the size of a multi dimensional array.
* This function checks the size of the first entry, it does not validate
* whether all dimensions match. (use function `validate` for that)
* @param {Array} x
* @Return {Number[]} size
*/
exports.size = function (x) {
var s = [];
while (Array.isArray(x)) {
s.push(x.length);
x = x[0];
}
return s;
};
/**
* Recursively validate whether each element in a multi dimensional array
* has a size corresponding to the provided size array.
* @param {Array} array Array to be validated
* @param {number[]} size Array with the size of each dimension
* @param {number} dim Current dimension
* @throws DimensionError
* @private
*/
function _validate(array, size, dim) {
var i;
var len = array.length;
if (len != size[dim]) {
throw new DimensionError(len, size[dim]);
}
if (dim < size.length - 1) {
// recursively validate each child array
var dimNext = dim + 1;
for (i = 0; i < len; i++) {
var child = array[i];
if (!Array.isArray(child)) {
throw new DimensionError(size.length - 1, size.length, '<');
}
_validate(array[i], size, dimNext);
}
}
else {
// last dimension. none of the childs may be an array
for (i = 0; i < len; i++) {
if (Array.isArray(array[i])) {
throw new DimensionError(size.length + 1, size.length, '>');
}
}
}
}
/**
* Validate whether each element in a multi dimensional array has
* a size corresponding to the provided size array.
* @param {Array} array Array to be validated
* @param {number[]} size Array with the size of each dimension
* @throws DimensionError
*/
exports.validate = function(array, size) {
var isScalar = (size.length == 0);
if (isScalar) {
// scalar
if (Array.isArray(array)) {
throw new DimensionError(array.length, 0);
}
}
else {
// array
_validate(array, size, 0);
}
};
/**
* Test whether index is an integer number with index >= 0 and index < length
* when length is provided
* @param {number} index Zero-based index
* @param {number} [length] Length of the array
*/
exports.validateIndex = function(index, length) {
if (!number.isNumber(index) || !number.isInteger(index)) {
throw new TypeError('Index must be an integer (value: ' + index + ')');
}
if (index < 0 || (typeof length === 'number' && index >= length)) {
throw new IndexError(index, length);
}
};
// a constant used to specify an undefined defaultValue
exports.UNINITIALIZED = {};
/**
* Resize a multi dimensional array. The resized array is returned.
* @param {Array} array Array to be resized
* @param {Array.<number>} size Array with the size of each dimension
* @param {*} [defaultValue=0] Value to be filled in in new entries,
* zero by default. To leave new entries undefined,
* specify array.UNINITIALIZED as defaultValue
* @return {Array} array The resized array
*/
exports.resize = function(array, size, defaultValue) {
// TODO: add support for scalars, having size=[] ?
// check the type of the arguments
if (!Array.isArray(array) || !Array.isArray(size)) {
throw new TypeError('Array expected');
}
if (size.length === 0) {
throw new Error('Resizing to scalar is not supported');
}
// check whether size contains positive integers
size.forEach(function (value) {
if (!number.isNumber(value) || !number.isInteger(value) || value < 0) {
throw new TypeError('Invalid size, must contain positive integers ' +
'(size: ' + string.format(size) + ')');
}
});
// recursively resize the array
var _defaultValue = (defaultValue !== undefined) ? defaultValue : 0;
_resize(array, size, 0, _defaultValue);
return array;
};
/**
* Recursively resize a multi dimensional array
* @param {Array} array Array to be resized
* @param {number[]} size Array with the size of each dimension
* @param {number} dim Current dimension
* @param {*} [defaultValue] Value to be filled in in new entries,
* undefined by default.
* @private
*/
function _resize (array, size, dim, defaultValue) {
var i;
var elem;
var oldLen = array.length;
var newLen = size[dim];
var minLen = Math.min(oldLen, newLen);
// apply new length
array.length = newLen;
if (dim < size.length - 1) {
// non-last dimension
var dimNext = dim + 1;
// resize existing child arrays
for (i = 0; i < minLen; i++) {
// resize child array
elem = array[i];
if (!Array.isArray(elem)) {
elem = [elem]; // add a dimension
array[i] = elem;
}
_resize(elem, size, dimNext, defaultValue);
}
// create new child arrays
for (i = minLen; i < newLen; i++) {
// get child array
elem = [];
array[i] = elem;
// resize new child array
_resize(elem, size, dimNext, defaultValue);
}
}
else {
// last dimension
// remove dimensions of existing values
for (i = 0; i < minLen; i++) {
while (Array.isArray(array[i])) {
array[i] = array[i][0];
}
}
if(defaultValue !== exports.UNINITIALIZED) {
// fill new elements with the default value
for (i = minLen; i < newLen; i++) {
array[i] = defaultValue;
}
}
}
}
/**
* Squeeze a multi dimensional array
* @param {Array} array
* @param {Array} [size]
* @returns {Array} returns the array itself
*/
exports.squeeze = function(array, size) {
var s = size || exports.size(array);
// squeeze outer dimensions
while (Array.isArray(array) && array.length === 1) {
array = array[0];
s.shift();
}
// find the first dimension to be squeezed
var dims = s.length;
while (s[dims - 1] === 1) {
dims--;
}
// squeeze inner dimensions
if (dims < s.length) {
array = _squeeze(array, dims, 0);
s.length = dims;
}
return array;
};
/**
* Recursively squeeze a multi dimensional array
* @param {Array} array
* @param {number} dims Required number of dimensions
* @param {number} dim Current dimension
* @returns {Array | *} Returns the squeezed array
* @private
*/
function _squeeze (array, dims, dim) {
var i, ii;
if (dim < dims) {
var next = dim + 1;
for (i = 0, ii = array.length; i < ii; i++) {
array[i] = _squeeze(array[i], dims, next);
}
}
else {
while (Array.isArray(array)) {
array = array[0];
}
}
return array;
}
/**
* Unsqueeze a multi dimensional array: add dimensions when missing
*
* Paramter `size` will be mutated to match the new, unqueezed matrix size.
*
* @param {Array} array
* @param {number} dims Desired number of dimensions of the array
* @param {number} [outer] Number of outer dimensions to be added
* @param {Array} [size] Current size of array.
* @returns {Array} returns the array itself
* @private
*/
exports.unsqueeze = function(array, dims, outer, size) {
var s = size || exports.size(array);
// unsqueeze outer dimensions
if (outer) {
for (var i = 0; i < outer; i++) {
array = [array];
s.unshift(1);
}
}
// unsqueeze inner dimensions
array = _unsqueeze(array, dims, 0);
while (s.length < dims) {
s.push(1);
}
return array;
};
/**
* Recursively unsqueeze a multi dimensional array
* @param {Array} array
* @param {number} dims Required number of dimensions
* @param {number} dim Current dimension
* @returns {Array | *} Returns the squeezed array
* @private
*/
function _unsqueeze (array, dims, dim) {
var i, ii;
if (Array.isArray(array)) {
var next = dim + 1;
for (i = 0, ii = array.length; i < ii; i++) {
array[i] = _unsqueeze(array[i], dims, next);
}
}
else {
for (var d = dim; d < dims; d++) {
array = [array];
}
}
return array;
}
/**
* Flatten a multi dimensional array, put all elements in a one dimensional
* array
* @param {Array} array A multi dimensional array
* @return {Array} The flattened array (1 dimensional)
*/
exports.flatten = function(array) {
if (!Array.isArray(array)) {
//if not an array, return as is
return array;
}
var flat = [];
array.forEach(function callback(value) {
if (Array.isArray(value)) {
value.forEach(callback); //traverse through sub-arrays recursively
}
else {
flat.push(value);
}
});
return flat;
};
/**
* Test whether an object is an array
* @param {*} value
* @return {boolean} isArray
*/
exports.isArray = Array.isArray;
/***/ },
/* 9 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var nearlyEqual = __webpack_require__(3).nearlyEqual;
var bigNearlyEqual = __webpack_require__(32);
function factory (type, config, load, typed) {
/**
* Test whether two values are equal.
*
* @param {number | BigNumber | Fraction | boolean | Complex | Unit} x First value to compare
* @param {number | BigNumber | Fraction | boolean | Complex} y Second value to compare
* @return {boolean} Returns true when the compared values are equal, else returns false
* @private
*/
var equalScalar = typed('equalScalar', {
'boolean, boolean': function (x, y) {
return x === y;
},
'number, number': function (x, y) {
return x === y || nearlyEqual(x, y, config.epsilon);
},
'BigNumber, BigNumber': function (x, y) {
return x.eq(y) || bigNearlyEqual(x, y, config.epsilon);
},
'Fraction, Fraction': function (x, y) {
return x.equals(y);
},
'Complex, Complex': function (x, y) {
return x.equals(y);
},
'Unit, Unit': function (x, y) {
if (!x.equalBase(y)) {
throw new Error('Cannot compare units with different base');
}
return equalScalar(x.value, y.value);
},
'string, string': function (x, y) {
return x === y;
}
});
return equalScalar;
}
exports.factory = factory;
/***/ },
/* 10 */
/***/ function(module, exports) {
'use strict';
/**
* Create a range error with the message:
* 'Dimension mismatch (<actual size> != <expected size>)'
* @param {number | number[]} actual The actual size
* @param {number | number[]} expected The expected size
* @param {string} [relation='!='] Optional relation between actual
* and expected size: '!=', '<', etc.
* @extends RangeError
*/
function DimensionError(actual, expected, relation) {
if (!(this instanceof DimensionError)) {
throw new SyntaxError('Constructor must be called with the new operator');
}
this.actual = actual;
this.expected = expected;
this.relation = relation;
this.message = 'Dimension mismatch (' +
(Array.isArray(actual) ? ('[' + actual.join(', ') + ']') : actual) +
' ' + (this.relation || '!=') + ' ' +
(Array.isArray(expected) ? ('[' + expected.join(', ') + ']') : expected) +
')';
this.stack = (new Error()).stack;
}
DimensionError.prototype = new RangeError();
DimensionError.prototype.constructor = RangeError;
DimensionError.prototype.name = 'DimensionError';
DimensionError.prototype.isDimensionError = true;
module.exports = DimensionError;
/***/ },
/* 11 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var extend = __webpack_require__(5).extend;
var array = __webpack_require__(8);
function factory (type, config, load, typed) {
var latex = __webpack_require__(4);
var matrix = load(__webpack_require__(2));
var addScalar = load(__webpack_require__(18));
var multiplyScalar = load(__webpack_require__(21));
var equalScalar = load(__webpack_require__(9));
var algorithm11 = load(__webpack_require__(14));
var algorithm14 = load(__webpack_require__(6));
var DenseMatrix = type.DenseMatrix;
var SparseMatrix = type.SparseMatrix;
/**
* Multiply two or more values, `x * y`.
* For matrices, the matrix product is calculated.
*
* Syntax:
*
* math.multiply(x, y)
* math.multiply(x, y, z, ...)
*
* Examples:
*
* math.multiply(4, 5.2); // returns number 20.8
* math.multiply(2, 3, 4); // returns number 24
*
* 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, prod, cross, dot
*
* @param {number | BigNumber | Fraction | Complex | Unit | Array | Matrix} x First value to multiply
* @param {number | BigNumber | Fraction | Complex | Unit | Array | Matrix} y Second value to multiply
* @return {number | BigNumber | Fraction | Complex | Unit | Array | Matrix} Multiplication of `x` and `y`
*/
var multiply = typed('multiply', extend({
// we extend the signatures of multiplyScalar with signatures dealing with matrices
'Array, Array': function (x, y) {
// check dimensions
_validateMatrixDimensions(array.size(x), array.size(y));
// use dense matrix implementation
var m = multiply(matrix(x), matrix(y));
// return array or scalar
return (m && m.isMatrix === true) ? m.valueOf() : m;
},
'Matrix, Matrix': function (x, y) {
// dimensions
var xsize = x.size();
var ysize = y.size();
// check dimensions
_validateMatrixDimensions(xsize, ysize);
// process dimensions
if (xsize.length === 1) {
// process y dimensions
if (ysize.length === 1) {
// Vector * Vector
return _multiplyVectorVector(x, y, xsize[0]);
}
// Vector * Matrix
return _multiplyVectorMatrix(x, y);
}
// process y dimensions
if (ysize.length === 1) {
// Matrix * Vector
return _multiplyMatrixVector(x, y);
}
// Matrix * Matrix
return _multiplyMatrixMatrix(x, y);
},
'Matrix, Array': function (x, y) {
// use Matrix * Matrix implementation
return multiply(x, matrix(y));
},
'Array, Matrix': function (x, y) {
// use Matrix * Matrix implementation
return multiply(matrix(x, y.storage()), y);
},
'Matrix, any': function (x, y) {
// result
var c;
// process storage format
switch (x.storage()) {
case 'sparse':
c = algorithm11(x, y, multiplyScalar, false);
break;
case 'dense':
c = algorithm14(x, y, multiplyScalar, false);
break;
}
return c;
},
'any, Matrix': function (x, y) {
// result
var c;
// check storage format
switch (y.storage()) {
case 'sparse':
c = algorithm11(y, x, multiplyScalar, true);
break;
case 'dense':
c = algorithm14(y, x, multiplyScalar, true);
break;
}
return c;
},
'Array, any': function (x, y) {
// use matrix implementation
return algorithm14(matrix(x), y, multiplyScalar, false).valueOf();
},
'any, Array': function (x, y) {
// use matrix implementation
return algorithm14(matrix(y), x, multiplyScalar, true).valueOf();
},
'any, any': multiplyScalar,
'any, any, ...any': function (x, y, rest) {
var result = multiply(x, y);
for (var i = 0; i < rest.length; i++) {
result = multiply(result, rest[i]);
}
return result;
}
}, multiplyScalar.signatures));
var _validateMatrixDimensions = function (size1, size2) {
// check left operand dimensions
switch (size1.length) {
case 1:
// check size2
switch (size2.length) {
case 1:
// Vector x Vector
if (size1[0] !== size2[0]) {
// throw error
throw new RangeError('Dimension mismatch in multiplication. Vectors must have the same length');
}
break;
case 2:
// Vector x Matrix
if (size1[0] !== size2[0]) {
// throw error
throw new RangeError('Dimension mismatch in multiplication. Vector length (' + size1[0] + ') must match Matrix rows (' + size2[0] + ')');
}
break;
default:
throw new Error('Can only multiply a 1 or 2 dimensional matrix (Matrix B has ' + size2.length + ' dimensions)');
}
break;
case 2:
// check size2
switch (size2.length) {
case 1:
// Matrix x Vector
if (size1[1] !== size2[0]) {
// throw error
throw new RangeError('Dimension mismatch in multiplication. Matrix columns (' + size1[1] + ') must match Vector length (' + size2[0] + ')');
}
break;
case 2:
// Matrix x Matrix
if (size1[1] !== size2[0]) {
// throw error
throw new RangeError('Dimension mismatch in multiplication. Matrix A columns (' + size1[1] + ') must match Matrix B rows (' + size2[0] + ')');
}
break;
default:
throw new Error('Can only multiply a 1 or 2 dimensional matrix (Matrix B has ' + size2.length + ' dimensions)');
}
break;
default:
throw new Error('Can only multiply a 1 or 2 dimensional matrix (Matrix A has ' + size1.length + ' dimensions)');
}
};
/**
* C = A * B
*
* @param {Matrix} a Dense Vector (N)
* @param {Matrix} b Dense Vector (N)
*
* @return {number} Scalar value
*/
var _multiplyVectorVector = function (a, b, n) {
// check empty vector
if (n === 0)
throw new Error('Cannot multiply two empty vectors');
// a dense
var adata = a._data;
var adt = a._datatype;
// b dense
var bdata = b._data;
var bdt = b._datatype;
// datatype
var dt;
// addScalar signature to use
var af = addScalar;
// multiplyScalar signature to use
var mf = multiplyScalar;
// process data types
if (adt && bdt && adt === bdt && typeof adt === 'string') {
// datatype
dt = adt;
// find signatures that matches (dt, dt)
af = typed.find(addScalar, [dt, dt]);
mf = typed.find(multiplyScalar, [dt, dt]);
}
// result (do not initialize it with zero)
var c = mf(adata[0], bdata[0]);
// loop data
for (var i = 1; i < n; i++) {
// multiply and accumulate
c = af(c, mf(adata[i], bdata[i]));
}
return c;
};
/**
* C = A * B
*
* @param {Matrix} a Dense Vector (M)
* @param {Matrix} b Matrix (MxN)