Merge lp:~gang65/ubuntu-calculator-app/ubuntu-calculator-app-math-2.4-upgrade into lp:ubuntu-calculator-app

Proposed by Bartosz Kosiorek
Status: Merged
Approved by: Bartosz Kosiorek
Approved revision: 230
Merge reported by: Bartosz Kosiorek
Merged at revision: not available
Proposed branch: lp:~gang65/ubuntu-calculator-app/ubuntu-calculator-app-math-2.4-upgrade
Merge into: lp:ubuntu-calculator-app
Diff against target: 62095 lines (+30259/-29499)
3 files modified
app/engine/math.js (+30243/-29485)
debian/changelog (+2/-0)
po/com.ubuntu.calculator.pot (+14/-14)
To merge this branch: bzr merge lp:~gang65/ubuntu-calculator-app/ubuntu-calculator-app-math-2.4-upgrade
Reviewer Review Type Date Requested Status
Niklas Wenzel (community) Approve
Jenkins Bot continuous-integration Approve
Ubuntu Phone Apps Jenkins Bot continuous-integration Approve
Review via email: mp+274958@code.launchpad.net

Commit message

Upgrade math.js to 2.4.0 to resolve wrong calculation of sin and cos functions,
for values around multiples of tau (i.e. sin(7)) (LP: #1507799)

Description of the change

Upgrade math.js to 2.4.0 to resolve wrong calculation of sin and cos functions,
for values around multiples of tau (i.e. sin(7)) (LP: #1507799)

To post a comment you must log in.
230. By Bartosz Kosiorek

Updated translation template

Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
Jenkins Bot (ubuntu-core-apps-jenkins-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Jenkins Bot (ubuntu-core-apps-jenkins-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
Nicholas Skaggs (nskaggs) wrote :

Let me know if you have further troubles. I'll be fixing the messages jenkins leaves to be a bit saner.

Revision history for this message
Niklas Wenzel (nikwen) wrote :

Thank you for the patch, Bartosz! :)

I gave it a try and couldn't manage to find any regressions. :p I can confirm that the bug this is supposed to fix is indeed fixed and that the autopilot tests ran fine on my machine.
Looking at math.js's issue list on Github, I can also not find any regression in version 2.4 that would be relevant to our case.

Therefore, I'd say, let's get this in. :)

Good job, Bartosz!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'app/engine/math.js'
--- app/engine/math.js 2015-08-30 23:09:36 +0000
+++ app/engine/math.js 2015-10-19 22:40:49 +0000
@@ -14,8 +14,8 @@
14 * It features real and complex numbers, units, matrices, a large set of14 * It features real and complex numbers, units, matrices, a large set of
15 * mathematical functions, and a flexible expression parser.15 * mathematical functions, and a flexible expression parser.
16 *16 *
17 * @version 2.2.017 * @version 2.4.0
18 * @date 2015-08-3018 * @date 2015-10-09
19 *19 *
20 * @license20 * @license
21 * Copyright (C) 2013-2015 Jos de Jong <wjosdejong@gmail.com>21 * Copyright (C) 2013-2015 Jos de Jong <wjosdejong@gmail.com>
@@ -133,10 +133,10 @@
133/* 2 */133/* 2 */
134/***/ function(module, exports, __webpack_require__) {134/***/ function(module, exports, __webpack_require__) {
135135
136 var isFactory = __webpack_require__(5).isFactory;136 var isFactory = __webpack_require__(3).isFactory;
137 var deepExtend = __webpack_require__(5).deepExtend;137 var deepExtend = __webpack_require__(3).deepExtend;
138 var typedFactory = __webpack_require__(6);138 var typedFactory = __webpack_require__(4);
139 var emitter = __webpack_require__(3);139 var emitter = __webpack_require__(8);
140140
141 var importFactory = __webpack_require__(10);141 var importFactory = __webpack_require__(10);
142 var configFactory = __webpack_require__(12);142 var configFactory = __webpack_require__(12);
@@ -261,101 +261,6 @@
261261
262/***/ },262/***/ },
263/* 3 */263/* 3 */
264/***/ function(module, exports, __webpack_require__) {
265
266 var Emitter = __webpack_require__(4);
267
268 /**
269 * Extend given object with emitter functions `on`, `off`, `once`, `emit`
270 * @param {Object} obj
271 * @return {Object} obj
272 */
273 exports.mixin = function (obj) {
274 // create event emitter
275 var emitter = new Emitter();
276
277 // bind methods to obj (we don't want to expose the emitter.e Array...)
278 obj.on = emitter.on.bind(emitter);
279 obj.off = emitter.off.bind(emitter);
280 obj.once = emitter.once.bind(emitter);
281 obj.emit = emitter.emit.bind(emitter);
282
283 return obj;
284 };
285
286
287/***/ },
288/* 4 */
289/***/ function(module, exports) {
290
291 function E () {
292 // Keep this empty so it's easier to inherit from
293 // (via https://github.com/lipsmack from https://github.com/scottcorgan/tiny-emitter/issues/3)
294 }
295
296 E.prototype = {
297 on: function (name, callback, ctx) {
298 var e = this.e || (this.e = {});
299
300 (e[name] || (e[name] = [])).push({
301 fn: callback,
302 ctx: ctx
303 });
304
305 return this;
306 },
307
308 once: function (name, callback, ctx) {
309 var self = this;
310 var fn = function () {
311 self.off(name, fn);
312 callback.apply(ctx, arguments);
313 };
314
315 return this.on(name, fn, ctx);
316 },
317
318 emit: function (name) {
319 var data = [].slice.call(arguments, 1);
320 var evtArr = ((this.e || (this.e = {}))[name] || []).slice();
321 var i = 0;
322 var len = evtArr.length;
323
324 for (i; i < len; i++) {
325 evtArr[i].fn.apply(evtArr[i].ctx, data);
326 }
327
328 return this;
329 },
330
331 off: function (name, callback) {
332 var e = this.e || (this.e = {});
333 var evts = e[name];
334 var liveEvents = [];
335
336 if (evts && callback) {
337 for (var i = 0, len = evts.length; i < len; i++) {
338 if (evts[i].fn !== callback) liveEvents.push(evts[i]);
339 }
340 }
341
342 // Remove event from queue to prevent memory leak
343 // Suggested by https://github.com/lazd
344 // Ref: https://github.com/scottcorgan/tiny-emitter/commit/c6ebfaa9bc973b33d110a84a307742b7cf94c953#commitcomment-5024910
345
346 (liveEvents.length)
347 ? e[name] = liveEvents
348 : delete e[name];
349
350 return this;
351 }
352 };
353
354 module.exports = E;
355
356
357/***/ },
358/* 5 */
359/***/ function(module, exports) {264/***/ function(module, exports) {
360265
361 'use strict';266 'use strict';
@@ -602,11 +507,11 @@
602507
603508
604/***/ },509/***/ },
605/* 6 */510/* 4 */
606/***/ function(module, exports, __webpack_require__) {511/***/ function(module, exports, __webpack_require__) {
607512
608 var typedFunction = __webpack_require__(7);513 var typedFunction = __webpack_require__(5);
609 var digits = __webpack_require__(8).digits;514 var digits = __webpack_require__(6).digits;
610515
611 // returns a new instance of typed-function516 // returns a new instance of typed-function
612 var createTyped = function () {517 var createTyped = function () {
@@ -765,7 +670,7 @@
765670
766671
767/***/ },672/***/ },
768/* 7 */673/* 5 */
769/***/ function(module, exports, __webpack_require__) {674/***/ function(module, exports, __webpack_require__) {
770675
771 var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/**676 var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/**
@@ -2022,7 +1927,7 @@
2022 */1927 */
2023 function convert (value, type) {1928 function convert (value, type) {
2024 var from = getTypeOf(value);1929 var from = getTypeOf(value);
2025 1930
2026 // check conversion is needed1931 // check conversion is needed
2027 if (type === from) {1932 if (type === from) {
2028 return value;1933 return value;
@@ -2076,12 +1981,12 @@
20761981
20771982
2078/***/ },1983/***/ },
2079/* 8 */1984/* 6 */
2080/***/ function(module, exports, __webpack_require__) {1985/***/ function(module, exports, __webpack_require__) {
20811986
2082 'use strict';1987 'use strict';
20831988
2084 var NumberFormatter = __webpack_require__(9);1989 var NumberFormatter = __webpack_require__(7);
20851990
2086 /**1991 /**
2087 * Test whether value is a number1992 * Test whether value is a number
@@ -2343,7 +2248,7 @@
23432248
23442249
2345/***/ },2250/***/ },
2346/* 9 */2251/* 7 */
2347/***/ function(module, exports) {2252/***/ function(module, exports) {
23482253
2349 'use strict';2254 'use strict';
@@ -2556,15 +2461,110 @@
25562461
25572462
2558/***/ },2463/***/ },
2464/* 8 */
2465/***/ function(module, exports, __webpack_require__) {
2466
2467 var Emitter = __webpack_require__(9);
2468
2469 /**
2470 * Extend given object with emitter functions `on`, `off`, `once`, `emit`
2471 * @param {Object} obj
2472 * @return {Object} obj
2473 */
2474 exports.mixin = function (obj) {
2475 // create event emitter
2476 var emitter = new Emitter();
2477
2478 // bind methods to obj (we don't want to expose the emitter.e Array...)
2479 obj.on = emitter.on.bind(emitter);
2480 obj.off = emitter.off.bind(emitter);
2481 obj.once = emitter.once.bind(emitter);
2482 obj.emit = emitter.emit.bind(emitter);
2483
2484 return obj;
2485 };
2486
2487
2488/***/ },
2489/* 9 */
2490/***/ function(module, exports) {
2491
2492 function E () {
2493 // Keep this empty so it's easier to inherit from
2494 // (via https://github.com/lipsmack from https://github.com/scottcorgan/tiny-emitter/issues/3)
2495 }
2496
2497 E.prototype = {
2498 on: function (name, callback, ctx) {
2499 var e = this.e || (this.e = {});
2500
2501 (e[name] || (e[name] = [])).push({
2502 fn: callback,
2503 ctx: ctx
2504 });
2505
2506 return this;
2507 },
2508
2509 once: function (name, callback, ctx) {
2510 var self = this;
2511 var fn = function () {
2512 self.off(name, fn);
2513 callback.apply(ctx, arguments);
2514 };
2515
2516 return this.on(name, fn, ctx);
2517 },
2518
2519 emit: function (name) {
2520 var data = [].slice.call(arguments, 1);
2521 var evtArr = ((this.e || (this.e = {}))[name] || []).slice();
2522 var i = 0;
2523 var len = evtArr.length;
2524
2525 for (i; i < len; i++) {
2526 evtArr[i].fn.apply(evtArr[i].ctx, data);
2527 }
2528
2529 return this;
2530 },
2531
2532 off: function (name, callback) {
2533 var e = this.e || (this.e = {});
2534 var evts = e[name];
2535 var liveEvents = [];
2536
2537 if (evts && callback) {
2538 for (var i = 0, len = evts.length; i < len; i++) {
2539 if (evts[i].fn !== callback) liveEvents.push(evts[i]);
2540 }
2541 }
2542
2543 // Remove event from queue to prevent memory leak
2544 // Suggested by https://github.com/lazd
2545 // Ref: https://github.com/scottcorgan/tiny-emitter/commit/c6ebfaa9bc973b33d110a84a307742b7cf94c953#commitcomment-5024910
2546
2547 (liveEvents.length)
2548 ? e[name] = liveEvents
2549 : delete e[name];
2550
2551 return this;
2552 }
2553 };
2554
2555 module.exports = E;
2556
2557
2558/***/ },
2559/* 10 */2559/* 10 */
2560/***/ function(module, exports, __webpack_require__) {2560/***/ function(module, exports, __webpack_require__) {
25612561
2562 'use strict';2562 'use strict';
25632563
2564 var lazy = __webpack_require__(5).lazy;2564 var lazy = __webpack_require__(3).lazy;
2565 var isFactory = __webpack_require__(5).isFactory;2565 var isFactory = __webpack_require__(3).isFactory;
2566 var traverse = __webpack_require__(5).traverse;2566 var traverse = __webpack_require__(3).traverse;
2567 var extend = __webpack_require__(5).extend;2567 var extend = __webpack_require__(3).extend;
2568 var ArgumentsError = __webpack_require__(11);2568 var ArgumentsError = __webpack_require__(11);
25692569
2570 function factory (type, config, load, typed, math) {2570 function factory (type, config, load, typed, math) {
@@ -2863,7 +2863,7 @@
28632863
2864 'use strict';2864 'use strict';
28652865
2866 var object = __webpack_require__(5);2866 var object = __webpack_require__(3);
28672867
2868 function factory (type, config, load, typed, math) {2868 function factory (type, config, load, typed, math) {
2869 /**2869 /**
@@ -2915,12 +2915,12 @@
2915/***/ function(module, exports, __webpack_require__) {2915/***/ function(module, exports, __webpack_require__) {
29162916
2917 module.exports = [2917 module.exports = [
2918 __webpack_require__(244), // data types (Matrix, Complex, Unit, ...)2918 __webpack_require__(14), // data types (Matrix, Complex, Unit, ...)
2919 __webpack_require__(281), // constants2919 __webpack_require__(76), // constants
2920 __webpack_require__(283), // expression parsing2920 __webpack_require__(80), // expression parsing
2921 __webpack_require__(14), // functions2921 __webpack_require__(312), // functions
2922 __webpack_require__(489), // serialization utility (math.json.reviver)2922 __webpack_require__(495), // serialization utility (math.json.reviver)
2923 __webpack_require__(491) // errors2923 __webpack_require__(497) // errors
2924 ];2924 ];
29252925
29262926
@@ -2929,20 +2929,16 @@
2929/***/ function(module, exports, __webpack_require__) {2929/***/ function(module, exports, __webpack_require__) {
29302930
2931 module.exports = [2931 module.exports = [
2932 __webpack_require__(61),
2933 __webpack_require__(91),
2934 __webpack_require__(120),
2935 __webpack_require__(136),
2936 __webpack_require__(149),
2937 __webpack_require__(154),
2938 __webpack_require__(156),
2939 __webpack_require__(15),2932 __webpack_require__(15),
2940 __webpack_require__(161),2933 __webpack_require__(20),
2941 __webpack_require__(173),2934 __webpack_require__(21),
2942 __webpack_require__(179),2935 __webpack_require__(26),
2943 __webpack_require__(191),2936 __webpack_require__(31),
2944 __webpack_require__(232),2937 __webpack_require__(37),
2945 __webpack_require__(234)2938 __webpack_require__(69),
2939 __webpack_require__(70),
2940 __webpack_require__(72),
2941 __webpack_require__(73)
2946 ];2942 ];
29472943
29482944
@@ -2951,23 +2947,11 @@
2951/***/ function(module, exports, __webpack_require__) {2947/***/ function(module, exports, __webpack_require__) {
29522948
2953 module.exports = [2949 module.exports = [
2950 // type
2954 __webpack_require__(16),2951 __webpack_require__(16),
2955 __webpack_require__(24),2952
2956 __webpack_require__(43),2953 // construction function
2957 __webpack_require__(46),2954 __webpack_require__(18)
2958 __webpack_require__(47),
2959 __webpack_require__(48),
2960 __webpack_require__(49),
2961 __webpack_require__(50),
2962 __webpack_require__(52),
2963 __webpack_require__(53),
2964 __webpack_require__(54),
2965 __webpack_require__(55),
2966 __webpack_require__(56),
2967 __webpack_require__(57),
2968 __webpack_require__(58),
2969 __webpack_require__(59),
2970 __webpack_require__(60)
2971 ];2955 ];
29722956
29732957
@@ -2975,28177 +2959,8 @@
2975/* 16 */2959/* 16 */
2976/***/ function(module, exports, __webpack_require__) {2960/***/ function(module, exports, __webpack_require__) {
29772961
2978 'use strict';
2979
2980 var clone = __webpack_require__(5).clone;
2981 var isInteger = __webpack_require__(8).isInteger;
2982 var array = __webpack_require__(18);
2983 var IndexError = __webpack_require__(17);
2984 var DimensionError = __webpack_require__(22);
2985
2986 function factory (type, config, load, typed) {
2987 var matrix = load(__webpack_require__(23));
2988
2989 /**
2990 * Concatenate two or more matrices.
2991 *
2992 * Syntax:
2993 *
2994 * math.concat(A, B, C, ...)
2995 * math.concat(A, B, C, ..., dim)
2996 *
2997 * Where:
2998 *
2999 * - `dim: number` is a zero-based dimension over which to concatenate the matrices.
3000 * By default the last dimension of the matrices.
3001 *
3002 * Examples:
3003 *
3004 * var A = [[1, 2], [5, 6]];
3005 * var B = [[3, 4], [7, 8]];
3006 *
3007 * math.concat(A, B); // returns [[1, 2, 3, 4], [5, 6, 7, 8]]
3008 * math.concat(A, B, 0); // returns [[1, 2], [5, 6], [3, 4], [7, 8]]
3009 * math.concat('hello', ' ', 'world'); // returns 'hello world'
3010 *
3011 * See also:
3012 *
3013 * size, squeeze, subset, transpose
3014 *
3015 * @param {... Array | Matrix} args Two or more matrices
3016 * @return {Array | Matrix} Concatenated matrix
3017 */
3018 var concat = typed('concat', {
3019 // TODO: change signature to '...Array | Matrix, dim?' when supported
3020 '...Array | Matrix | number | BigNumber': function (args) {
3021 var i;
3022 var len = args.length;
3023 var dim = -1; // zero-based dimension
3024 var prevDim;
3025 var asMatrix = false;
3026 var matrices = []; // contains multi dimensional arrays
3027
3028 for (i = 0; i < len; i++) {
3029 var arg = args[i];
3030
3031 // test whether we need to return a Matrix (if not we return an Array)
3032 if (arg && arg.isMatrix === true) {
3033 asMatrix = true;
3034 }
3035
3036 if (typeof arg === 'number' || (arg && arg.isBigNumber === true)) {
3037 if (i !== len - 1) {
3038 throw new Error('Dimension must be specified as last argument');
3039 }
3040
3041 // last argument contains the dimension on which to concatenate
3042 prevDim = dim;
3043 dim = arg.valueOf(); // change BigNumber to number
3044
3045 if (!isInteger(dim)) {
3046 throw new TypeError('Integer number expected for dimension');
3047 }
3048
3049 if (dim < 0) {
3050 // TODO: would be more clear when throwing a DimensionError here
3051 throw new IndexError(dim);
3052 }
3053 if (i > 0 && dim > prevDim) {
3054 // TODO: would be more clear when throwing a DimensionError here
3055 throw new IndexError(dim, prevDim + 1);
3056 }
3057 }
3058 else {
3059 // this is a matrix or array
3060 var m = clone(arg).valueOf();
3061 var size = array.size(m);
3062 matrices[i] = m;
3063 prevDim = dim;
3064 dim = size.length - 1;
3065
3066 // verify whether each of the matrices has the same number of dimensions
3067 if (i > 0 && dim != prevDim) {
3068 throw new DimensionError(prevDim + 1, dim + 1);
3069 }
3070 }
3071 }
3072
3073 if (matrices.length == 0) {
3074 throw new SyntaxError('At least one matrix expected');
3075 }
3076
3077 var res = matrices.shift();
3078 while (matrices.length) {
3079 res = _concat(res, matrices.shift(), dim, 0);
3080 }
3081
3082 return asMatrix ? matrix(res) : res;
3083 },
3084
3085 '...string': function (args) {
3086 return args.join('');
3087 }
3088 });
3089
3090 concat.toTex = '\\mathrm{${name}}\\left(${args}\\right)';
3091
3092 return concat;
3093 }
3094
3095 /**
3096 * Recursively concatenate two matrices.
3097 * The contents of the matrices is not cloned.
3098 * @param {Array} a Multi dimensional array
3099 * @param {Array} b Multi dimensional array
3100 * @param {number} concatDim The dimension on which to concatenate (zero-based)
3101 * @param {number} dim The current dim (zero-based)
3102 * @return {Array} c The concatenated matrix
3103 * @private
3104 */
3105 function _concat(a, b, concatDim, dim) {
3106 if (dim < concatDim) {
3107 // recurse into next dimension
3108 if (a.length != b.length) {
3109 throw new DimensionError(a.length, b.length);
3110 }
3111
3112 var c = [];
3113 for (var i = 0; i < a.length; i++) {
3114 c[i] = _concat(a[i], b[i], concatDim, dim + 1);
3115 }
3116 return c;
3117 }
3118 else {
3119 // concatenate this dimension
3120 return a.concat(b);
3121 }
3122 }
3123
3124 exports.name = 'concat';
3125 exports.factory = factory;
3126
3127
3128/***/ },
3129/* 17 */
3130/***/ function(module, exports) {
3131
3132 'use strict';
3133
3134 /**
3135 * Create a range error with the message:
3136 * 'Index out of range (index < min)'
3137 * 'Index out of range (index < max)'
3138 *
3139 * @param {number} index The actual index
3140 * @param {number} [min=0] Minimum index (included)
3141 * @param {number} [max] Maximum index (excluded)
3142 * @extends RangeError
3143 */
3144 function IndexError(index, min, max) {
3145 if (!(this instanceof IndexError)) {
3146 throw new SyntaxError('Constructor must be called with the new operator');
3147 }
3148
3149 this.index = index;
3150 if (arguments.length < 3) {
3151 this.min = 0;
3152 this.max = min;
3153 }
3154 else {
3155 this.min = min;
3156 this.max = max;
3157 }
3158
3159 if (this.min !== undefined && this.index < this.min) {
3160 this.message = 'Index out of range (' + this.index + ' < ' + this.min + ')';
3161 }
3162 else if (this.max !== undefined && this.index >= this.max) {
3163 this.message = 'Index out of range (' + this.index + ' > ' + (this.max - 1) + ')';
3164 }
3165 else {
3166 this.message = 'Index out of range (' + this.index + ')';
3167 }
3168
3169 this.stack = (new Error()).stack;
3170 }
3171
3172 IndexError.prototype = new RangeError();
3173 IndexError.prototype.constructor = RangeError;
3174 IndexError.prototype.name = 'IndexError';
3175 IndexError.prototype.isIndexError = true;
3176
3177 module.exports = IndexError;
3178
3179
3180/***/ },
3181/* 18 */
3182/***/ function(module, exports, __webpack_require__) {
3183
3184 'use strict';
3185
3186 var number = __webpack_require__(8);
3187 var string = __webpack_require__(20);
3188 var object = __webpack_require__(5);
3189 var types = __webpack_require__(19);
3190
3191 var DimensionError = __webpack_require__(22);
3192 var IndexError = __webpack_require__(17);
3193
3194 /**
3195 * Calculate the size of a multi dimensional array.
3196 * This function checks the size of the first entry, it does not validate
3197 * whether all dimensions match. (use function `validate` for that)
3198 * @param {Array} x
3199 * @Return {Number[]} size
3200 */
3201 exports.size = function (x) {
3202 var s = [];
3203
3204 while (Array.isArray(x)) {
3205 s.push(x.length);
3206 x = x[0];
3207 }
3208
3209 return s;
3210 };
3211
3212 /**
3213 * Recursively validate whether each element in a multi dimensional array
3214 * has a size corresponding to the provided size array.
3215 * @param {Array} array Array to be validated
3216 * @param {number[]} size Array with the size of each dimension
3217 * @param {number} dim Current dimension
3218 * @throws DimensionError
3219 * @private
3220 */
3221 function _validate(array, size, dim) {
3222 var i;
3223 var len = array.length;
3224
3225 if (len != size[dim]) {
3226 throw new DimensionError(len, size[dim]);
3227 }
3228
3229 if (dim < size.length - 1) {
3230 // recursively validate each child array
3231 var dimNext = dim + 1;
3232 for (i = 0; i < len; i++) {
3233 var child = array[i];
3234 if (!Array.isArray(child)) {
3235 throw new DimensionError(size.length - 1, size.length, '<');
3236 }
3237 _validate(array[i], size, dimNext);
3238 }
3239 }
3240 else {
3241 // last dimension. none of the childs may be an array
3242 for (i = 0; i < len; i++) {
3243 if (Array.isArray(array[i])) {
3244 throw new DimensionError(size.length + 1, size.length, '>');
3245 }
3246 }
3247 }
3248 }
3249
3250 /**
3251 * Validate whether each element in a multi dimensional array has
3252 * a size corresponding to the provided size array.
3253 * @param {Array} array Array to be validated
3254 * @param {number[]} size Array with the size of each dimension
3255 * @throws DimensionError
3256 */
3257 exports.validate = function(array, size) {
3258 var isScalar = (size.length == 0);
3259 if (isScalar) {
3260 // scalar
3261 if (Array.isArray(array)) {
3262 throw new DimensionError(array.length, 0);
3263 }
3264 }
3265 else {
3266 // array
3267 _validate(array, size, 0);
3268 }
3269 };
3270
3271 /**
3272 * Test whether index is an integer number with index >= 0 and index < length
3273 * @param {number} index Zero-based index
3274 * @param {number} [length] Length of the array
3275 */
3276 exports.validateIndex = function(index, length) {
3277 if (!number.isNumber(index) || !number.isInteger(index)) {
3278 throw new TypeError('Index must be an integer (value: ' + index + ')');
3279 }
3280 if (index < 0) {
3281 throw new IndexError(index);
3282 }
3283 if (length !== undefined && index >= length) {
3284 throw new IndexError(index, length);
3285 }
3286 };
3287
3288 // a constant used to specify an undefined defaultValue
3289 exports.UNINITIALIZED = {};
3290
3291 /**
3292 * Resize a multi dimensional array. The resized array is returned.
3293 * @param {Array} array Array to be resized
3294 * @param {Array.<number>} size Array with the size of each dimension
3295 * @param {*} [defaultValue=0] Value to be filled in in new entries,
3296 * zero by default. To leave new entries undefined,
3297 * specify array.UNINITIALIZED as defaultValue
3298 * @return {Array} array The resized array
3299 */
3300 exports.resize = function(array, size, defaultValue) {
3301 // TODO: add support for scalars, having size=[] ?
3302
3303 // check the type of the arguments
3304 if (!Array.isArray(array) || !Array.isArray(size)) {
3305 throw new TypeError('Array expected');
3306 }
3307 if (size.length === 0) {
3308 throw new Error('Resizing to scalar is not supported');
3309 }
3310
3311 // check whether size contains positive integers
3312 size.forEach(function (value) {
3313 if (!number.isNumber(value) || !number.isInteger(value) || value < 0) {
3314 throw new TypeError('Invalid size, must contain positive integers ' +
3315 '(size: ' + string.format(size) + ')');
3316 }
3317 });
3318
3319 // recursively resize the array
3320 var _defaultValue = (defaultValue !== undefined) ? defaultValue : 0;
3321 _resize(array, size, 0, _defaultValue);
3322
3323 return array;
3324 };
3325
3326 /**
3327 * Recursively resize a multi dimensional array
3328 * @param {Array} array Array to be resized
3329 * @param {number[]} size Array with the size of each dimension
3330 * @param {number} dim Current dimension
3331 * @param {*} [defaultValue] Value to be filled in in new entries,
3332 * undefined by default.
3333 * @private
3334 */
3335 function _resize (array, size, dim, defaultValue) {
3336 var i;
3337 var elem;
3338 var oldLen = array.length;
3339 var newLen = size[dim];
3340 var minLen = Math.min(oldLen, newLen);
3341
3342 // apply new length
3343 array.length = newLen;
3344
3345 if (dim < size.length - 1) {
3346 // non-last dimension
3347 var dimNext = dim + 1;
3348
3349 // resize existing child arrays
3350 for (i = 0; i < minLen; i++) {
3351 // resize child array
3352 elem = array[i];
3353 if (!Array.isArray(elem)) {
3354 elem = [elem]; // add a dimension
3355 array[i] = elem;
3356 }
3357 _resize(elem, size, dimNext, defaultValue);
3358 }
3359
3360 // create new child arrays
3361 for (i = minLen; i < newLen; i++) {
3362 // get child array
3363 elem = [];
3364 array[i] = elem;
3365
3366 // resize new child array
3367 _resize(elem, size, dimNext, defaultValue);
3368 }
3369 }
3370 else {
3371 // last dimension
3372
3373 // remove dimensions of existing values
3374 for (i = 0; i < minLen; i++) {
3375 while (Array.isArray(array[i])) {
3376 array[i] = array[i][0];
3377 }
3378 }
3379
3380 if(defaultValue !== exports.UNINITIALIZED) {
3381 // fill new elements with the default value
3382 for (i = minLen; i < newLen; i++) {
3383 array[i] = object.clone(defaultValue);
3384 }
3385 }
3386 }
3387 }
3388
3389 /**
3390 * Squeeze a multi dimensional array
3391 * @param {Array} array
3392 * @param {Array} [size]
3393 * @returns {Array} returns the array itself
3394 */
3395 exports.squeeze = function(array, size) {
3396 var s = size || exports.size(array);
3397
3398 // squeeze outer dimensions
3399 while (Array.isArray(array) && array.length === 1) {
3400 array = array[0];
3401 s.shift();
3402 }
3403
3404 // find the first dimension to be squeezed
3405 var dims = s.length;
3406 while (s[dims - 1] === 1) {
3407 dims--;
3408 }
3409
3410 // squeeze inner dimensions
3411 if (dims < s.length) {
3412 array = _squeeze(array, dims, 0);
3413 s.length = dims;
3414 }
3415
3416 return array;
3417 };
3418
3419 /**
3420 * Recursively squeeze a multi dimensional array
3421 * @param {Array} array
3422 * @param {number} dims Required number of dimensions
3423 * @param {number} dim Current dimension
3424 * @returns {Array | *} Returns the squeezed array
3425 * @private
3426 */
3427 function _squeeze (array, dims, dim) {
3428 var i, ii;
3429
3430 if (dim < dims) {
3431 var next = dim + 1;
3432 for (i = 0, ii = array.length; i < ii; i++) {
3433 array[i] = _squeeze(array[i], dims, next);
3434 }
3435 }
3436 else {
3437 while (Array.isArray(array)) {
3438 array = array[0];
3439 }
3440 }
3441
3442 return array;
3443 }
3444
3445 /**
3446 * Unsqueeze a multi dimensional array: add dimensions when missing
3447 * @param {Array} array
3448 * @param {number} dims Desired number of dimensions of the array
3449 * @param {number} [outer] Number of outer dimensions to be added
3450 * @param {Array} [size] Current size of array
3451 * @returns {Array} returns the array itself
3452 * @private
3453 */
3454 exports.unsqueeze = function(array, dims, outer, size) {
3455 var s = size || exports.size(array);
3456
3457 // unsqueeze outer dimensions
3458 if (outer) {
3459 for (var i = 0; i < outer; i++) {
3460 array = [array];
3461 s.unshift(1);
3462 }
3463 }
3464
3465 // unsqueeze inner dimensions
3466 array = _unsqueeze(array, dims, 0);
3467 while (s.length < dims) {
3468 s.push(1);
3469 }
3470
3471 return array;
3472 };
3473
3474 /**
3475 * Recursively unsqueeze a multi dimensional array
3476 * @param {Array} array
3477 * @param {number} dims Required number of dimensions
3478 * @param {number} dim Current dimension
3479 * @returns {Array | *} Returns the squeezed array
3480 * @private
3481 */
3482 function _unsqueeze (array, dims, dim) {
3483 var i, ii;
3484
3485 if (Array.isArray(array)) {
3486 var next = dim + 1;
3487 for (i = 0, ii = array.length; i < ii; i++) {
3488 array[i] = _unsqueeze(array[i], dims, next);
3489 }
3490 }
3491 else {
3492 for (var d = dim; d < dims; d++) {
3493 array = [array];
3494 }
3495 }
3496
3497 return array;
3498 }
3499 /**
3500 * Flatten a multi dimensional array, put all elements in a one dimensional
3501 * array
3502 * @param {Array} array A multi dimensional array
3503 * @return {Array} The flattened array (1 dimensional)
3504 */
3505 exports.flatten = function(array) {
3506 if (!Array.isArray(array)) {
3507 //if not an array, return as is
3508 return array;
3509 }
3510 var flat = [];
3511
3512 array.forEach(function callback(value) {
3513 if (Array.isArray(value)) {
3514 value.forEach(callback); //traverse through sub-arrays recursively
3515 }
3516 else {
3517 flat.push(value);
3518 }
3519 });
3520
3521 return flat;
3522 };
3523
3524 /**
3525 * Test whether an object is an array
3526 * @param {*} value
3527 * @return {boolean} isArray
3528 */
3529 exports.isArray = Array.isArray;
3530
3531
3532/***/ },
3533/* 19 */
3534/***/ function(module, exports) {
3535
3536 'use strict';
3537
3538 /**
3539 * Determine the type of a variable
3540 *
3541 * type(x)
3542 *
3543 * The following types are recognized:
3544 *
3545 * 'undefined'
3546 * 'null'
3547 * 'boolean'
3548 * 'number'
3549 * 'string'
3550 * 'Array'
3551 * 'Function'
3552 * 'Date'
3553 * 'RegExp'
3554 * 'Object'
3555 *
3556 * @param {*} x
3557 * @return {string} Returns the name of the type. Primitive types are lower case,
3558 * non-primitive types are upper-camel-case.
3559 * For example 'number', 'string', 'Array', 'Date'.
3560 */
3561 exports.type = function(x) {
3562 var type = typeof x;
3563
3564 if (type === 'object') {
3565 if (x === null) return 'null';
3566 if (x instanceof Boolean) return 'boolean';
3567 if (x instanceof Number) return 'number';
3568 if (x instanceof String) return 'string';
3569 if (Array.isArray(x)) return 'Array';
3570 if (x instanceof Date) return 'Date';
3571 if (x instanceof RegExp) return 'RegExp';
3572
3573 return 'Object';
3574 }
3575
3576 if (type === 'function') return 'Function';
3577
3578 return type;
3579 };
3580
3581
3582/***/ },
3583/* 20 */
3584/***/ function(module, exports, __webpack_require__) {
3585
3586 'use strict';
3587
3588 var formatNumber = __webpack_require__(8).format;
3589 var formatBigNumber = __webpack_require__(21).format;
3590
3591 /**
3592 * Test whether value is a string
3593 * @param {*} value
3594 * @return {boolean} isString
3595 */
3596 exports.isString = function(value) {
3597 return typeof value === 'string';
3598 };
3599
3600 /**
3601 * Check if a text ends with a certain string.
3602 * @param {string} text
3603 * @param {string} search
3604 */
3605 exports.endsWith = function(text, search) {
3606 var start = text.length - search.length;
3607 var end = text.length;
3608 return (text.substring(start, end) === search);
3609 };
3610
3611 /**
3612 * Format a value of any type into a string.
3613 *
3614 * Usage:
3615 * math.format(value)
3616 * math.format(value, precision)
3617 *
3618 * If value is a function, the returned string is 'function' unless the function
3619 * has a property `description`, in that case this properties value is returned.
3620 *
3621 * Example usage:
3622 * math.format(2/7); // '0.2857142857142857'
3623 * math.format(math.pi, 3); // '3.14'
3624 * math.format(new Complex(2, 3)); // '2 + 3i'
3625 * math.format('hello'); // '"hello"'
3626 *
3627 * @param {*} value Value to be stringified
3628 * @param {Object | number | Function} [options] Formatting options. See
3629 * lib/utils/number:format for a
3630 * description of the available
3631 * options.
3632 * @return {string} str
3633 */
3634 exports.format = function(value, options) {
3635 if (typeof value === 'number') {
3636 return formatNumber(value, options);
3637 }
3638
3639 if (value && value.isBigNumber === true) {
3640 return formatBigNumber(value, options);
3641 }
3642
3643 if (value && value.isFraction === true) {
3644 if (!options || options.fraction !== 'decimal') {
3645 // output as ratio, like '1/3'
3646 return (value.s * value.n) + '/' + value.d;
3647 }
3648 else {
3649 // output as decimal, like '0.(3)'
3650 return value.toString();
3651 }
3652 }
3653
3654 if (Array.isArray(value)) {
3655 return formatArray(value, options);
3656 }
3657
3658 if (exports.isString(value)) {
3659 return '"' + value + '"';
3660 }
3661
3662 if (typeof value === 'function') {
3663 return value.syntax ? value.syntax + '' : 'function';
3664 }
3665
3666 if (typeof value === 'object') {
3667 if (typeof value.format === 'function') {
3668 return value.format(options);
3669 }
3670 else {
3671 return value.toString();
3672 }
3673 }
3674
3675 return String(value);
3676 };
3677
3678 /**
3679 * Recursively format an n-dimensional matrix
3680 * Example output: "[[1, 2], [3, 4]]"
3681 * @param {Array} array
3682 * @param {Object | number | Function} [options] Formatting options. See
3683 * lib/utils/number:format for a
3684 * description of the available
3685 * options.
3686 * @returns {string} str
3687 */
3688 function formatArray (array, options) {
3689 if (Array.isArray(array)) {
3690 var str = '[';
3691 var len = array.length;
3692 for (var i = 0; i < len; i++) {
3693 if (i != 0) {
3694 str += ', ';
3695 }
3696 str += formatArray(array[i], options);
3697 }
3698 str += ']';
3699 return str;
3700 }
3701 else {
3702 return exports.format(array, options);
3703 }
3704 }
3705
3706
3707/***/ },
3708/* 21 */
3709/***/ function(module, exports) {
3710
3711 /**
3712 * Convert a BigNumber to a formatted string representation.
3713 *
3714 * Syntax:
3715 *
3716 * format(value)
3717 * format(value, options)
3718 * format(value, precision)
3719 * format(value, fn)
3720 *
3721 * Where:
3722 *
3723 * {number} value The value to be formatted
3724 * {Object} options An object with formatting options. Available options:
3725 * {string} notation
3726 * Number notation. Choose from:
3727 * 'fixed' Always use regular number notation.
3728 * For example '123.40' and '14000000'
3729 * 'exponential' Always use exponential notation.
3730 * For example '1.234e+2' and '1.4e+7'
3731 * 'auto' (default) Regular number notation for numbers
3732 * having an absolute value between
3733 * `lower` and `upper` bounds, and uses
3734 * exponential notation elsewhere.
3735 * Lower bound is included, upper bound
3736 * is excluded.
3737 * For example '123.4' and '1.4e7'.
3738 * {number} precision A number between 0 and 16 to round
3739 * the digits of the number.
3740 * In case of notations 'exponential' and
3741 * 'auto', `precision` defines the total
3742 * number of significant digits returned
3743 * and is undefined by default.
3744 * In case of notation 'fixed',
3745 * `precision` defines the number of
3746 * significant digits after the decimal
3747 * point, and is 0 by default.
3748 * {Object} exponential An object containing two parameters,
3749 * {number} lower and {number} upper,
3750 * used by notation 'auto' to determine
3751 * when to return exponential notation.
3752 * Default values are `lower=1e-3` and
3753 * `upper=1e5`.
3754 * Only applicable for notation `auto`.
3755 * {Function} fn A custom formatting function. Can be used to override the
3756 * built-in notations. Function `fn` is called with `value` as
3757 * parameter and must return a string. Is useful for example to
3758 * format all values inside a matrix in a particular way.
3759 *
3760 * Examples:
3761 *
3762 * format(6.4); // '6.4'
3763 * format(1240000); // '1.24e6'
3764 * format(1/3); // '0.3333333333333333'
3765 * format(1/3, 3); // '0.333'
3766 * format(21385, 2); // '21000'
3767 * format(12.071, {notation: 'fixed'}); // '12'
3768 * format(2.3, {notation: 'fixed', precision: 2}); // '2.30'
3769 * format(52.8, {notation: 'exponential'}); // '5.28e+1'
3770 *
3771 * @param {BigNumber} value
3772 * @param {Object | Function | number} [options]
3773 * @return {string} str The formatted value
3774 */
3775 exports.format = function (value, options) {
3776 if (typeof options === 'function') {
3777 // handle format(value, fn)
3778 return options(value);
3779 }
3780
3781 // handle special cases
3782 if (!value.isFinite()) {
3783 return value.isNaN() ? 'NaN' : (value.gt(0) ? 'Infinity' : '-Infinity');
3784 }
3785
3786 // default values for options
3787 var notation = 'auto';
3788 var precision = undefined;
3789
3790 if (options !== undefined) {
3791 // determine notation from options
3792 if (options.notation) {
3793 notation = options.notation;
3794 }
3795
3796 // determine precision from options
3797 if (typeof options === 'number') {
3798 precision = options;
3799 }
3800 else if (options.precision) {
3801 precision = options.precision;
3802 }
3803 }
3804
3805 // handle the various notations
3806 switch (notation) {
3807 case 'fixed':
3808 return exports.toFixed(value, precision);
3809
3810 case 'exponential':
3811 return exports.toExponential(value, precision);
3812
3813 case 'auto':
3814 // determine lower and upper bound for exponential notation.
3815 // TODO: implement support for upper and lower to be BigNumbers themselves
3816 var lower = 1e-3;
3817 var upper = 1e5;
3818 if (options && options.exponential) {
3819 if (options.exponential.lower !== undefined) {
3820 lower = options.exponential.lower;
3821 }
3822 if (options.exponential.upper !== undefined) {
3823 upper = options.exponential.upper;
3824 }
3825 }
3826
3827 // adjust the configuration of the BigNumber constructor (yeah, this is quite tricky...)
3828 var oldConfig = {
3829 toExpNeg: value.constructor.toExpNeg,
3830 toExpPos: value.constructor.toExpPos
3831 };
3832
3833 value.constructor.config({
3834 toExpNeg: Math.round(Math.log(lower) / Math.LN10),
3835 toExpPos: Math.round(Math.log(upper) / Math.LN10)
3836 });
3837
3838 // handle special case zero
3839 if (value.isZero()) return '0';
3840
3841 // determine whether or not to output exponential notation
3842 var str;
3843 var abs = value.abs();
3844 if (abs.gte(lower) && abs.lt(upper)) {
3845 // normal number notation
3846 str = value.toSignificantDigits(precision).toFixed();
3847 }
3848 else {
3849 // exponential notation
3850 str = exports.toExponential(value, precision);
3851 }
3852
3853 // remove trailing zeros after the decimal point
3854 return str.replace(/((\.\d*?)(0+))($|e)/, function () {
3855 var digits = arguments[2];
3856 var e = arguments[4];
3857 return (digits !== '.') ? digits + e : e;
3858 });
3859
3860 default:
3861 throw new Error('Unknown notation "' + notation + '". ' +
3862 'Choose "auto", "exponential", or "fixed".');
3863 }
3864 };
3865
3866 /**
3867 * Format a number in exponential notation. Like '1.23e+5', '2.3e+0', '3.500e-3'
3868 * @param {BigNumber} value
3869 * @param {number} [precision] Number of digits in formatted output.
3870 * If not provided, the maximum available digits
3871 * is used.
3872 * @returns {string} str
3873 */
3874 exports.toExponential = function (value, precision) {
3875 if (precision !== undefined) {
3876 return value.toExponential(precision - 1); // Note the offset of one
3877 }
3878 else {
3879 return value.toExponential();
3880 }
3881 };
3882
3883 /**
3884 * Format a number with fixed notation.
3885 * @param {BigNumber} value
3886 * @param {number} [precision=0] Optional number of decimals after the
3887 * decimal point. Zero by default.
3888 */
3889 exports.toFixed = function (value, precision) {
3890 return value.toFixed(precision || 0);
3891 // Note: the (precision || 0) is needed as the toFixed of BigNumber has an
3892 // undefined default precision instead of 0.
3893 }
3894
3895
3896/***/ },
3897/* 22 */
3898/***/ function(module, exports) {
3899
3900 'use strict';
3901
3902 /**
3903 * Create a range error with the message:
3904 * 'Dimension mismatch (<actual size> != <expected size>)'
3905 * @param {number | number[]} actual The actual size
3906 * @param {number | number[]} expected The expected size
3907 * @param {string} [relation='!='] Optional relation between actual
3908 * and expected size: '!=', '<', etc.
3909 * @extends RangeError
3910 */
3911 function DimensionError(actual, expected, relation) {
3912 if (!(this instanceof DimensionError)) {
3913 throw new SyntaxError('Constructor must be called with the new operator');
3914 }
3915
3916 this.actual = actual;
3917 this.expected = expected;
3918 this.relation = relation;
3919
3920 this.message = 'Dimension mismatch (' +
3921 (Array.isArray(actual) ? ('[' + actual.join(', ') + ']') : actual) +
3922 ' ' + (this.relation || '!=') + ' ' +
3923 (Array.isArray(expected) ? ('[' + expected.join(', ') + ']') : expected) +
3924 ')';
3925
3926 this.stack = (new Error()).stack;
3927 }
3928
3929 DimensionError.prototype = new RangeError();
3930 DimensionError.prototype.constructor = RangeError;
3931 DimensionError.prototype.name = 'DimensionError';
3932 DimensionError.prototype.isDimensionError = true;
3933
3934 module.exports = DimensionError;
3935
3936
3937/***/ },
3938/* 23 */
3939/***/ function(module, exports) {
3940
3941 'use strict';
3942
3943 function factory (type, config, load, typed) {
3944 /**
3945 * Create a Matrix. The function creates a new `math.type.Matrix` object from
3946 * an `Array`. A Matrix has utility functions to manipulate the data in the
3947 * matrix, like getting the size and getting or setting values in the matrix.
3948 * Supported storage formats are 'dense' and 'sparse'.
3949 *
3950 * Syntax:
3951 *
3952 * math.matrix() // creates an empty matrix using default storage format (dense).
3953 * math.matrix(data) // creates a matrix with initial data using default storage format (dense).
3954 * math.matrix('dense') // creates an empty matrix using the given storage format.
3955 * math.matrix(data, 'dense') // creates a matrix with initial data using the given storage format.
3956 * math.matrix(data, 'sparse') // creates a sparse matrix with initial data.
3957 * math.matrix(data, 'sparse', 'number') // creates a sparse matrix with initial data, number data type.
3958 *
3959 * Examples:
3960 *
3961 * var m = math.matrix([[1, 2], [3, 4]]);
3962 * m.size(); // Array [2, 2]
3963 * m.resize([3, 2], 5);
3964 * m.valueOf(); // Array [[1, 2], [3, 4], [5, 5]]
3965 * m.get([1, 0]) // number 3
3966 *
3967 * See also:
3968 *
3969 * bignumber, boolean, complex, index, number, string, unit, sparse
3970 *
3971 * @param {Array | Matrix} [data] A multi dimensional array
3972 * @param {string} [format] The Matrix storage format
3973 *
3974 * @return {Matrix} The created matrix
3975 */
3976 var matrix = typed('matrix', {
3977 '': function () {
3978 return _create([]);
3979 },
3980
3981 'string': function (format) {
3982 return _create([], format);
3983 },
3984
3985 'string, string': function (format, datatype) {
3986 return _create([], format, datatype);
3987 },
3988
3989 'Array': function (data) {
3990 return _create(data);
3991 },
3992
3993 'Matrix': function (data) {
3994 return _create(data, data.storage());
3995 },
3996
3997 'Array | Matrix, string': _create,
3998
3999 'Array | Matrix, string, string': _create
4000 });
4001
4002 matrix.toTex = {
4003 0: '\\begin{bmatrix}\\end{bmatrix}',
4004 1: '\\left(${args[0]}\\right)',
4005 2: '\\left(${args[0]}\\right)'
4006 };
4007
4008 return matrix;
4009
4010 /**
4011 * Create a new Matrix with given storage format
4012 * @param {Array} data
4013 * @param {string} [format]
4014 * @param {string} [datatype]
4015 * @returns {Matrix} Returns a new Matrix
4016 * @private
4017 */
4018 function _create(data, format, datatype) {
4019 // get storage format constructor
4020 var M = type.Matrix.storage(format || 'default');
4021
4022 // create instance
4023 return new M(data, datatype);
4024 }
4025 }
4026
4027 exports.name = 'matrix';
4028 exports.factory = factory;
4029
4030
4031/***/ },
4032/* 24 */
4033/***/ function(module, exports, __webpack_require__) {
4034
4035 'use strict';
4036
4037 var size = __webpack_require__(18).size;
4038
4039 function factory (type, config, load, typed) {
4040 var matrix = load(__webpack_require__(23));
4041 var subtract = load(__webpack_require__(25));
4042 var multiply = load(__webpack_require__(40));
4043
4044 /**
4045 * Calculate the cross product for two vectors in three dimensional space.
4046 * The cross product of `A = [a1, a2, a3]` and `B =[b1, b2, b3]` is defined
4047 * as:
4048 *
4049 * cross(A, B) = [
4050 * a2 * b3 - a3 * b2,
4051 * a3 * b1 - a1 * b3,
4052 * a1 * b2 - a2 * b1
4053 * ]
4054 *
4055 * Syntax:
4056 *
4057 * math.cross(x, y)
4058 *
4059 * Examples:
4060 *
4061 * math.cross([1, 1, 0], [0, 1, 1]); // Returns [1, -1, 1]
4062 * math.cross([3, -3, 1], [4, 9, 2]); // Returns [-15, -2, 39]
4063 * math.cross([2, 3, 4], [5, 6, 7]); // Returns [-3, 6, -3]
4064 *
4065 * See also:
4066 *
4067 * dot, multiply
4068 *
4069 * @param {Array | Matrix} x First vector
4070 * @param {Array | Matrix} y Second vector
4071 * @return {Array | Matrix} Returns the cross product of `x` and `y`
4072 */
4073 var cross = typed('cross', {
4074 'Matrix, Matrix': function (x, y) {
4075 return matrix(_cross(x.toArray(), y.toArray()));
4076 },
4077
4078 'Matrix, Array': function (x, y) {
4079 return matrix(_cross(x.toArray(), y));
4080 },
4081
4082 'Array, Matrix': function (x, y) {
4083 return matrix(_cross(x, y.toArray()));
4084 },
4085
4086 'Array, Array': _cross
4087 });
4088
4089 cross.toTex = '\\left(${args[0]}\\right)\\times\\left(${args[1]}\\right)';
4090
4091 return cross;
4092
4093 /**
4094 * Calculate the cross product for two arrays
4095 * @param {Array} x First vector
4096 * @param {Array} y Second vector
4097 * @returns {Array} Returns the cross product of x and y
4098 * @private
4099 */
4100 function _cross(x, y) {
4101 var xSize= size(x);
4102 var ySize = size(y);
4103
4104 if (xSize.length != 1 || ySize.length != 1 || xSize[0] != 3 || ySize[0] != 3) {
4105 throw new RangeError('Vectors with length 3 expected ' +
4106 '(Size A = [' + xSize.join(', ') + '], B = [' + ySize.join(', ') + '])');
4107 }
4108
4109 return [
4110 subtract(multiply(x[1], y[2]), multiply(x[2], y[1])),
4111 subtract(multiply(x[2], y[0]), multiply(x[0], y[2])),
4112 subtract(multiply(x[0], y[1]), multiply(x[1], y[0]))
4113 ];
4114 }
4115 }
4116
4117 exports.name = 'cross';
4118 exports.factory = factory;
4119
4120
4121/***/ },
4122/* 25 */
4123/***/ function(module, exports, __webpack_require__) {
4124
4125 'use strict';
4126
4127 var DimensionError = __webpack_require__(22);
4128
4129 function factory (type, config, load, typed) {
4130 var latex = __webpack_require__(26);
4131
4132 var matrix = load(__webpack_require__(23));
4133 var addScalar = load(__webpack_require__(27));
4134 var unaryMinus = load(__webpack_require__(28));
4135
4136 var algorithm01 = load(__webpack_require__(30));
4137 var algorithm03 = load(__webpack_require__(31));
4138 var algorithm05 = load(__webpack_require__(32));
4139 var algorithm10 = load(__webpack_require__(34));
4140 var algorithm13 = load(__webpack_require__(35));
4141 var algorithm14 = load(__webpack_require__(39));
4142
4143 /**
4144 * Subtract two values, `x - y`.
4145 * For matrices, the function is evaluated element wise.
4146 *
4147 * Syntax:
4148 *
4149 * math.subtract(x, y)
4150 *
4151 * Examples:
4152 *
4153 * math.subtract(5.3, 2); // returns number 3.3
4154 *
4155 * var a = math.complex(2, 3);
4156 * var b = math.complex(4, 1);
4157 * math.subtract(a, b); // returns Complex -2 + 2i
4158 *
4159 * math.subtract([5, 7, 4], 4); // returns Array [1, 3, 0]
4160 *
4161 * var c = math.unit('2.1 km');
4162 * var d = math.unit('500m');
4163 * math.subtract(c, d); // returns Unit 1.6 km
4164 *
4165 * See also:
4166 *
4167 * add
4168 *
4169 * @param {number | BigNumber | Fraction | Complex | Unit | Array | Matrix} x
4170 * Initial value
4171 * @param {number | BigNumber | Fraction | Complex | Unit | Array | Matrix} y
4172 * Value to subtract from `x`
4173 * @return {number | BigNumber | Fraction | Complex | Unit | Array | Matrix}
4174 * Subtraction of `x` and `y`
4175 */
4176 var subtract = typed('subtract', {
4177
4178 'number, number': function (x, y) {
4179 return x - y;
4180 },
4181
4182 'Complex, Complex': function (x, y) {
4183 return new type.Complex (
4184 x.re - y.re,
4185 x.im - y.im
4186 );
4187 },
4188
4189 'BigNumber, BigNumber': function (x, y) {
4190 return x.minus(y);
4191 },
4192
4193 'Fraction, Fraction': function (x, y) {
4194 return x.sub(y);
4195 },
4196
4197 'Unit, Unit': function (x, y) {
4198 if (x.value == null) {
4199 throw new Error('Parameter x contains a unit with undefined value');
4200 }
4201
4202 if (y.value == null) {
4203 throw new Error('Parameter y contains a unit with undefined value');
4204 }
4205
4206 if (!x.equalBase(y)) {
4207 throw new Error('Units do not match');
4208 }
4209
4210 var res = x.clone();
4211 res.value -= y.value;
4212 res.fixPrefix = false;
4213
4214 return res;
4215 },
4216
4217 'Matrix, Matrix': function (x, y) {
4218 // matrix sizes
4219 var xsize = x.size();
4220 var ysize = y.size();
4221
4222 // check dimensions
4223 if (xsize.length !== ysize.length)
4224 throw new DimensionError(xsize.length, ysize.length);
4225
4226 // result
4227 var c;
4228
4229 // process matrix storage
4230 switch (x.storage()) {
4231 case 'sparse':
4232 switch (y.storage()) {
4233 case 'sparse':
4234 // sparse - sparse
4235 c = algorithm05(x, y, subtract);
4236 break;
4237 default:
4238 // sparse - dense
4239 c = algorithm03(y, x, subtract, true);
4240 break;
4241 }
4242 break;
4243 default:
4244 switch (y.storage()) {
4245 case 'sparse':
4246 // dense - sparse
4247 c = algorithm01(x, y, subtract, false);
4248 break;
4249 default:
4250 // dense - dense
4251 c = algorithm13(x, y, subtract);
4252 break;
4253 }
4254 break;
4255 }
4256 return c;
4257 },
4258
4259 'Array, Array': function (x, y) {
4260 // use matrix implementation
4261 return subtract(matrix(x), matrix(y)).valueOf();
4262 },
4263
4264 'Array, Matrix': function (x, y) {
4265 // use matrix implementation
4266 return subtract(matrix(x), y);
4267 },
4268
4269 'Matrix, Array': function (x, y) {
4270 // use matrix implementation
4271 return subtract(x, matrix(y));
4272 },
4273
4274 'Matrix, any': function (x, y) {
4275 // result
4276 var c;
4277 // check storage format
4278 switch (x.storage()) {
4279 case 'sparse':
4280 // algorithm 7 is faster than 9 since it calls f() for nonzero items only!
4281 c = algorithm10(x, unaryMinus(y), addScalar);
4282 break;
4283 default:
4284 c = algorithm14(x, y, subtract);
4285 break;
4286 }
4287 return c;
4288 },
4289
4290 'any, Matrix': function (x, y) {
4291 // result
4292 var c;
4293 // check storage format
4294 switch (y.storage()) {
4295 case 'sparse':
4296 c = algorithm10(y, x, subtract, true);
4297 break;
4298 default:
4299 c = algorithm14(y, x, subtract, true);
4300 break;
4301 }
4302 return c;
4303 },
4304
4305 'Array, any': function (x, y) {
4306 // use matrix implementation
4307 return algorithm14(matrix(x), y, subtract, false).valueOf();
4308 },
4309
4310 'any, Array': function (x, y) {
4311 // use matrix implementation
4312 return algorithm14(matrix(y), x, subtract, true).valueOf();
4313 }
4314 });
4315
4316 subtract.toTex = '\\left(${args[0]}' + latex.operators['subtract'] + '${args[1]}\\right)';
4317
4318 return subtract;
4319 }
4320
4321 exports.name = 'subtract';
4322 exports.factory = factory;
4323
4324
4325/***/ },
4326/* 26 */
4327/***/ function(module, exports) {
4328
4329 'use strict';
4330
4331 exports.symbols = {
4332 // GREEK LETTERS
4333 Alpha: 'A', alpha: '\\alpha',
4334 Beta: 'B', beta: '\\beta',
4335 Gamma: '\\Gamma', gamma: '\\gamma',
4336 Delta: '\\Delta', delta: '\\delta',
4337 Epsilon: 'E', epsilon: '\\epsilon', varepsilon: '\\varepsilon',
4338 Zeta: 'Z', zeta: '\\zeta',
4339 Eta: 'H', eta: '\\eta',
4340 Theta: '\\Theta', theta: '\\theta', vartheta: '\\vartheta',
4341 Iota: 'I', iota: '\\iota',
4342 Kappa: 'K', kappa: '\\kappa', varkappa: '\\varkappa',
4343 Lambda: '\\Lambda', lambda: '\\lambda',
4344 Mu: 'M', mu: '\\mu',
4345 Nu: 'N', nu: '\\nu',
4346 Xi: '\\Xi', xi: '\\xi',
4347 Omicron: 'O', omicron: 'o',
4348 Pi: '\\Pi', pi: '\\pi', varpi: '\\varpi',
4349 Rho: 'P', rho: '\\rho', varrho: '\\varrho',
4350 Sigma: '\\Sigma', sigma: '\\sigma', varsigma: '\\varsigma',
4351 Tau: 'T', tau: '\\tau',
4352 Upsilon: '\\Upsilon', upsilon: '\\upsilon',
4353 Phi: '\\Phi', phi: '\\phi', varphi: '\\varphi',
4354 Chi: 'X', chi: '\\chi',
4355 Psi: '\\Psi', psi: '\\psi',
4356 Omega: '\\Omega', omega: '\\omega',
4357 //logic
4358 'true': '\\mathrm{True}',
4359 'false': '\\mathrm{False}',
4360 //other
4361 i: 'i', //TODO use \i ??
4362 inf: '\\infty',
4363 Inf: '\\infty',
4364 infinity: '\\infty',
4365 Infinity: '\\infty',
4366 oo: '\\infty',
4367 lim: '\\lim',
4368 'undefined': '\\mathbf{?}'
4369 };
4370
4371 exports.operators = {
4372 'transpose': '^\\top',
4373 'factorial': '!',
4374 'pow': '^',
4375 'dotPow': '.^\\wedge', //TODO find ideal solution
4376 'unaryPlus': '+',
4377 'unaryMinus': '-',
4378 'bitNot': '~', //TODO find ideal solution
4379 'not': '\\neg',
4380 'multiply': '\\cdot',
4381 'divide': '\\frac', //TODO how to handle that properly?
4382 'dotMultiply': '.\\cdot', //TODO find ideal solution
4383 'dotDivide': '.:', //TODO find ideal solution
4384 'mod': '\\mod',
4385 'add': '+',
4386 'subtract': '-',
4387 'to': '\\rightarrow',
4388 'leftShift': '<<',
4389 'rightArithShift': '>>',
4390 'rightLogShift': '>>>',
4391 'equal': '=',
4392 'unequal': '\\neq',
4393 'smaller': '<',
4394 'larger': '>',
4395 'smallerEq': '\\leq',
4396 'largerEq': '\\geq',
4397 'bitAnd': '\\&',
4398 'bitXor': '\\underline{|}',
4399 'bitOr': '|',
4400 'and': '\\wedge',
4401 'xor': '\\veebar',
4402 'or': '\\vee'
4403 };
4404
4405 exports.defaultTemplate = '\\mathrm{${name}}\\left(${args}\\right)';
4406
4407 var units = {
4408 deg: '^\\circ'
4409 };
4410
4411 //@param {string} name
4412 //@param {boolean} isUnit
4413 exports.toSymbol = function (name, isUnit) {
4414 isUnit = typeof isUnit === 'undefined' ? false : isUnit;
4415 if (isUnit) {
4416 if (units.hasOwnProperty(name)) {
4417 return units[name];
4418 }
4419 return '\\mathrm{' + name + '}';
4420 }
4421
4422 if (exports.symbols.hasOwnProperty(name)) {
4423 return exports.symbols[name];
4424 }
4425 else if (name.indexOf('_') !== -1) {
4426 //symbol with index (eg. alpha_1)
4427 var index = name.indexOf('_');
4428 return exports.toSymbol(name.substring(0, index)) + '_{'
4429 + exports.toSymbol(name.substring(index + 1)) + '}';
4430 }
4431 return name;
4432 };
4433
4434
4435/***/ },
4436/* 27 */
4437/***/ function(module, exports) {
4438
4439 'use strict';
4440
4441 function factory(type, config, load, typed) {
4442
4443 /**
4444 * Add two scalar values, `x + y`.
4445 * This function is meant for internal use: it is used by the public function
4446 * `add`
4447 *
4448 * This function does not support collections (Array or Matrix), and does
4449 * not validate the number of of inputs.
4450 *
4451 * @param {number | BigNumber | Fraction | Complex | Unit} x First value to add
4452 * @param {number | BigNumber | Fraction | Complex} y Second value to add
4453 * @return {number | BigNumber | Fraction | Complex | Unit} Sum of `x` and `y`
4454 * @private
4455 */
4456 return typed('add', {
4457
4458 'number, number': function (x, y) {
4459 return x + y;
4460 },
4461
4462 'Complex, Complex': function (x, y) {
4463 return new type.Complex(
4464 x.re + y.re,
4465 x.im + y.im
4466 );
4467 },
4468
4469 'BigNumber, BigNumber': function (x, y) {
4470 return x.plus(y);
4471 },
4472
4473 'Fraction, Fraction': function (x, y) {
4474 return x.add(y);
4475 },
4476
4477 'Unit, Unit': function (x, y) {
4478 if (x.value == null) throw new Error('Parameter x contains a unit with undefined value');
4479 if (y.value == null) throw new Error('Parameter y contains a unit with undefined value');
4480 if (!x.equalBase(y)) throw new Error('Units do not match');
4481
4482 var res = x.clone();
4483 res.value += y.value;
4484 res.fixPrefix = false;
4485 return res;
4486 }
4487 });
4488 }
4489
4490 exports.factory = factory;
4491
4492
4493/***/ },
4494/* 28 */
4495/***/ function(module, exports, __webpack_require__) {
4496
4497 'use strict';
4498
4499 var deepMap = __webpack_require__(29);
4500
4501 function factory (type, config, load, typed) {
4502 var latex = __webpack_require__(26);
4503
4504 /**
4505 * Inverse the sign of a value, apply a unary minus operation.
4506 *
4507 * For matrices, the function is evaluated element wise. Boolean values and
4508 * strings will be converted to a number. For complex numbers, both real and
4509 * complex value are inverted.
4510 *
4511 * Syntax:
4512 *
4513 * math.unaryMinus(x)
4514 *
4515 * Examples:
4516 *
4517 * math.unaryMinus(3.5); // returns -3.5
4518 * math.unaryMinus(-4.2); // returns 4.2
4519 *
4520 * See also:
4521 *
4522 * add, subtract, unaryPlus
4523 *
4524 * @param {number | BigNumber | Fraction | Complex | Unit | Array | Matrix} x Number to be inverted.
4525 * @return {number | BigNumber | Fraction | Complex | Unit | Array | Matrix} Returns the value with inverted sign.
4526 */
4527 var unaryMinus = typed('unaryMinus', {
4528 'number': function (x) {
4529 return -x;
4530 },
4531
4532 'Complex': function (x) {
4533 return new type.Complex(-x.re, -x.im);
4534 },
4535
4536 'BigNumber': function (x) {
4537 return x.neg();
4538 },
4539
4540 'Fraction': function (x) {
4541 var tmp = x.clone();
4542 tmp.s = -tmp.s;
4543 return tmp;
4544 },
4545
4546 'Unit': function (x) {
4547 var res = x.clone();
4548 res.value = -x.value;
4549 return res;
4550 },
4551
4552 'Array | Matrix': function (x) {
4553 // deep map collection, skip zeros since unaryMinus(0) = 0
4554 return deepMap(x, unaryMinus, true);
4555 }
4556
4557 // TODO: add support for string
4558 });
4559
4560 unaryMinus.toTex = latex.operators['unaryMinus'] + '\\left(${args[0]}\\right)';
4561
4562 return unaryMinus;
4563 }
4564
4565 exports.name = 'unaryMinus';
4566 exports.factory = factory;
4567
4568
4569/***/ },
4570/* 29 */
4571/***/ function(module, exports) {
4572
4573 'use strict';
4574
4575 /**
4576 * Execute the callback function element wise for each element in array and any
4577 * nested array
4578 * Returns an array with the results
4579 * @param {Array | Matrix} array
4580 * @param {Function} callback The callback is called with two parameters:
4581 * value1 and value2, which contain the current
4582 * element of both arrays.
4583 * @param {boolean} [skipZeros] Invoke callback function for non-zero values only.
4584 *
4585 * @return {Array | Matrix} res
4586 */
4587 module.exports = function deepMap(array, callback, skipZeros) {
4588 if (array && (typeof array.map === 'function')) {
4589 // TODO: replace array.map with a for loop to improve performance
4590 return array.map(function (x) {
4591 return deepMap(x, callback, skipZeros);
4592 });
4593 }
4594 else {
4595 return callback(array);
4596 }
4597 };
4598
4599
4600/***/ },
4601/* 30 */
4602/***/ function(module, exports, __webpack_require__) {
4603
4604 'use strict';
4605
4606 var DimensionError = __webpack_require__(22);
4607
4608 function factory (type, config, load, typed) {
4609
4610 var DenseMatrix = type.DenseMatrix;
4611
4612 /**
4613 * Iterates over SparseMatrix nonzero items and invokes the callback function f(Dij, Sij).
4614 * Callback function invoked NNZ times (number of nonzero items in SparseMatrix).
4615 *
4616 *
4617 * ┌ f(Dij, Sij) ; S(i,j) !== 0
4618 * C(i,j) = ┤
4619 * â”” Dij ; otherwise
4620 *
4621 *
4622 * @param {Matrix} denseMatrix The DenseMatrix instance (D)
4623 * @param {Matrix} sparseMatrix The SparseMatrix instance (S)
4624 * @param {Function} callback The f(Dij,Sij) operation to invoke, where Dij = DenseMatrix(i,j) and Sij = SparseMatrix(i,j)
4625 * @param {boolean} inverse A true value indicates callback should be invoked f(Sij,Dij)
4626 *
4627 * @return {Matrix} DenseMatrix (C)
4628 *
4629 * see https://github.com/josdejong/mathjs/pull/346#issuecomment-97477571
4630 */
4631 var algorithm01 = function (denseMatrix, sparseMatrix, callback, inverse) {
4632 // dense matrix arrays
4633 var adata = denseMatrix._data;
4634 var asize = denseMatrix._size;
4635 var adt = denseMatrix._datatype;
4636 // sparse matrix arrays
4637 var bvalues = sparseMatrix._values;
4638 var bindex = sparseMatrix._index;
4639 var bptr = sparseMatrix._ptr;
4640 var bsize = sparseMatrix._size;
4641 var bdt = sparseMatrix._datatype;
4642
4643 // validate dimensions
4644 if (asize.length !== bsize.length)
4645 throw new DimensionError(asize.length, bsize.length);
4646
4647 // check rows & columns
4648 if (asize[0] !== bsize[0] || asize[1] !== bsize[1])
4649 throw new RangeError('Dimension mismatch. Matrix A (' + asize + ') must match Matrix B (' + bsize + ')');
4650
4651 // sparse matrix cannot be a Pattern matrix
4652 if (!bvalues)
4653 throw new Error('Cannot perform operation on Dense Matrix and Pattern Sparse Matrix');
4654
4655 // rows & columns
4656 var rows = asize[0];
4657 var columns = asize[1];
4658
4659 // process data types
4660 var dt = typeof adt === 'string' && adt === bdt ? adt : undefined;
4661 // callback function
4662 var cf = dt ? typed.find(callback, [dt, dt]) : callback;
4663
4664 // vars
4665 var i, j;
4666
4667 // result (DenseMatrix)
4668 var cdata = [];
4669 // initialize c
4670 for (i = 0; i < rows; i++)
4671 cdata[i] = [];
4672
4673 // workspace
4674 var x = [];
4675 // marks indicating we have a value in x for a given column
4676 var w = [];
4677
4678 // loop columns in b
4679 for (j = 0; j < columns; j++) {
4680 // column mark
4681 var mark = j + 1;
4682 // values in column j
4683 for (var k0 = bptr[j], k1 = bptr[j + 1], k = k0; k < k1; k++) {
4684 // row
4685 i = bindex[k];
4686 // update workspace
4687 x[i] = inverse ? cf(bvalues[k], adata[i][j]) : cf(adata[i][j], bvalues[k]);
4688 // mark i as updated
4689 w[i] = mark;
4690 }
4691 // loop rows
4692 for (i = 0; i < rows; i++) {
4693 // check row is in workspace
4694 if (w[i] === mark) {
4695 // c[i][j] was already calculated
4696 cdata[i][j] = x[i];
4697 }
4698 else {
4699 // item does not exist in S
4700 cdata[i][j] = adata[i][j];
4701 }
4702 }
4703 }
4704
4705 // return dense matrix
4706 return new DenseMatrix({
4707 data: cdata,
4708 size: [rows, columns],
4709 datatype: dt
4710 });
4711 };
4712
4713 return algorithm01;
4714 }
4715
4716 exports.name = 'algorithm01';
4717 exports.factory = factory;
4718
4719
4720/***/ },
4721/* 31 */
4722/***/ function(module, exports, __webpack_require__) {
4723
4724 'use strict';
4725
4726 var DimensionError = __webpack_require__(22);
4727
4728 function factory (type, config, load, typed) {
4729
4730 var DenseMatrix = type.DenseMatrix;
4731
4732 /**
4733 * Iterates over SparseMatrix items and invokes the callback function f(Dij, Sij).
4734 * Callback function invoked M*N times.
4735 *
4736 *
4737 * ┌ f(Dij, Sij) ; S(i,j) !== 0
4738 * C(i,j) = ┤
4739 * â”” f(Dij, 0) ; otherwise
4740 *
4741 *
4742 * @param {Matrix} denseMatrix The DenseMatrix instance (D)
4743 * @param {Matrix} sparseMatrix The SparseMatrix instance (C)
4744 * @param {Function} callback The f(Dij,Sij) operation to invoke, where Dij = DenseMatrix(i,j) and Sij = SparseMatrix(i,j)
4745 * @param {boolean} inverse A true value indicates callback should be invoked f(Sij,Dij)
4746 *
4747 * @return {Matrix} DenseMatrix (C)
4748 *
4749 * see https://github.com/josdejong/mathjs/pull/346#issuecomment-97477571
4750 */
4751 var algorithm03 = function (denseMatrix, sparseMatrix, callback, inverse) {
4752 // dense matrix arrays
4753 var adata = denseMatrix._data;
4754 var asize = denseMatrix._size;
4755 var adt = denseMatrix._datatype;
4756 // sparse matrix arrays
4757 var bvalues = sparseMatrix._values;
4758 var bindex = sparseMatrix._index;
4759 var bptr = sparseMatrix._ptr;
4760 var bsize = sparseMatrix._size;
4761 var bdt = sparseMatrix._datatype;
4762
4763 // validate dimensions
4764 if (asize.length !== bsize.length)
4765 throw new DimensionError(asize.length, bsize.length);
4766
4767 // check rows & columns
4768 if (asize[0] !== bsize[0] || asize[1] !== bsize[1])
4769 throw new RangeError('Dimension mismatch. Matrix A (' + asize + ') must match Matrix B (' + bsize + ')');
4770
4771 // sparse matrix cannot be a Pattern matrix
4772 if (!bvalues)
4773 throw new Error('Cannot perform operation on Dense Matrix and Pattern Sparse Matrix');
4774
4775 // rows & columns
4776 var rows = asize[0];
4777 var columns = asize[1];
4778
4779 // datatype
4780 var dt;
4781 // zero value
4782 var zero = 0;
4783 // callback signature to use
4784 var cf = callback;
4785
4786 // process data types
4787 if (typeof adt === 'string' && adt === bdt) {
4788 // datatype
4789 dt = adt;
4790 // convert 0 to the same datatype
4791 zero = typed.convert(0, dt);
4792 // callback
4793 cf = typed.find(callback, [dt, dt]);
4794 }
4795
4796 // result (DenseMatrix)
4797 var cdata = [];
4798
4799 // initialize dense matrix
4800 for (var z = 0; z < rows; z++) {
4801 // initialize row
4802 cdata[z] = [];
4803 }
4804
4805 // workspace
4806 var x = [];
4807 // marks indicating we have a value in x for a given column
4808 var w = [];
4809
4810 // loop columns in b
4811 for (var j = 0; j < columns; j++) {
4812 // column mark
4813 var mark = j + 1;
4814 // values in column j
4815 for (var k0 = bptr[j], k1 = bptr[j + 1], k = k0; k < k1; k++) {
4816 // row
4817 var i = bindex[k];
4818 // update workspace
4819 x[i] = inverse ? cf(bvalues[k], adata[i][j]) : cf(adata[i][j], bvalues[k]);
4820 w[i] = mark;
4821 }
4822 // process workspace
4823 for (var y = 0; y < rows; y++) {
4824 // check we have a calculated value for current row
4825 if (w[y] === mark) {
4826 // use calculated value
4827 cdata[y][j] = x[y];
4828 }
4829 else {
4830 // calculate value
4831 cdata[y][j] = inverse ? cf(zero, adata[y][j]) : cf(adata[y][j], zero);
4832 }
4833 }
4834 }
4835
4836 // return dense matrix
4837 return new DenseMatrix({
4838 data: cdata,
4839 size: [rows, columns],
4840 datatype: dt
4841 });
4842 };
4843
4844 return algorithm03;
4845 }
4846
4847 exports.name = 'algorithm03';
4848 exports.factory = factory;
4849
4850
4851/***/ },
4852/* 32 */
4853/***/ function(module, exports, __webpack_require__) {
4854
4855 'use strict';
4856
4857 var DimensionError = __webpack_require__(22);
4858
4859 function factory (type, config, load, typed) {
4860
4861 var equalScalar = load(__webpack_require__(33));
4862
4863 var SparseMatrix = type.SparseMatrix;
4864
4865 /**
4866 * Iterates over SparseMatrix A and SparseMatrix B nonzero items and invokes the callback function f(Aij, Bij).
4867 * Callback function invoked MAX(NNZA, NNZB) times
4868 *
4869 *
4870 * ┌ f(Aij, Bij) ; A(i,j) !== 0 || B(i,j) !== 0
4871 * C(i,j) = ┤
4872 * â”” 0 ; otherwise
4873 *
4874 *
4875 * @param {Matrix} a The SparseMatrix instance (A)
4876 * @param {Matrix} b The SparseMatrix instance (B)
4877 * @param {Function} callback The f(Aij,Bij) operation to invoke
4878 *
4879 * @return {Matrix} SparseMatrix (C)
4880 *
4881 * see https://github.com/josdejong/mathjs/pull/346#issuecomment-97620294
4882 */
4883 var algorithm05 = function (a, b, callback) {
4884 // sparse matrix arrays
4885 var avalues = a._values;
4886 var aindex = a._index;
4887 var aptr = a._ptr;
4888 var asize = a._size;
4889 var adt = a._datatype;
4890 // sparse matrix arrays
4891 var bvalues = b._values;
4892 var bindex = b._index;
4893 var bptr = b._ptr;
4894 var bsize = b._size;
4895 var bdt = b._datatype;
4896
4897 // validate dimensions
4898 if (asize.length !== bsize.length)
4899 throw new DimensionError(asize.length, bsize.length);
4900
4901 // check rows & columns
4902 if (asize[0] !== bsize[0] || asize[1] !== bsize[1])
4903 throw new RangeError('Dimension mismatch. Matrix A (' + asize + ') must match Matrix B (' + bsize + ')');
4904
4905 // rows & columns
4906 var rows = asize[0];
4907 var columns = asize[1];
4908
4909 // datatype
4910 var dt;
4911 // equal signature to use
4912 var eq = equalScalar;
4913 // zero value
4914 var zero = 0;
4915 // callback signature to use
4916 var cf = callback;
4917
4918 // process data types
4919 if (typeof adt === 'string' && adt === bdt) {
4920 // datatype
4921 dt = adt;
4922 // find signature that matches (dt, dt)
4923 eq = typed.find(equalScalar, [dt, dt]);
4924 // convert 0 to the same datatype
4925 zero = typed.convert(0, dt);
4926 // callback
4927 cf = typed.find(callback, [dt, dt]);
4928 }
4929
4930 // result arrays
4931 var cvalues = avalues && bvalues ? [] : undefined;
4932 var cindex = [];
4933 var cptr = [];
4934 // matrix
4935 var c = new SparseMatrix({
4936 values: cvalues,
4937 index: cindex,
4938 ptr: cptr,
4939 size: [rows, columns],
4940 datatype: dt
4941 });
4942
4943 // workspaces
4944 var xa = cvalues ? [] : undefined;
4945 var xb = cvalues ? [] : undefined;
4946 // marks indicating we have a value in x for a given column
4947 var wa = [];
4948 var wb = [];
4949
4950 // vars
4951 var i, j, k, k1;
4952
4953 // loop columns
4954 for (j = 0; j < columns; j++) {
4955 // update cptr
4956 cptr[j] = cindex.length;
4957 // columns mark
4958 var mark = j + 1;
4959 // loop values A(:,j)
4960 for (k = aptr[j], k1 = aptr[j + 1]; k < k1; k++) {
4961 // row
4962 i = aindex[k];
4963 // push index
4964 cindex.push(i);
4965 // update workspace
4966 wa[i] = mark;
4967 // check we need to process values
4968 if (xa)
4969 xa[i] = avalues[k];
4970 }
4971 // loop values B(:,j)
4972 for (k = bptr[j], k1 = bptr[j + 1]; k < k1; k++) {
4973 // row
4974 i = bindex[k];
4975 // check row existed in A
4976 if (wa[i] !== mark) {
4977 // push index
4978 cindex.push(i);
4979 }
4980 // update workspace
4981 wb[i] = mark;
4982 // check we need to process values
4983 if (xb)
4984 xb[i] = bvalues[k];
4985 }
4986 // check we need to process values (non pattern matrix)
4987 if (cvalues) {
4988 // initialize first index in j
4989 k = cptr[j];
4990 // loop index in j
4991 while (k < cindex.length) {
4992 // row
4993 i = cindex[k];
4994 // marks
4995 var wai = wa[i];
4996 var wbi = wb[i];
4997 // check Aij or Bij are nonzero
4998 if (wai === mark || wbi === mark) {
4999 // matrix values @ i,j
5000 var va = wai === mark ? xa[i] : zero;
5001 var vb = wbi === mark ? xb[i] : zero;
5002 // Cij
5003 var vc = cf(va, vb);
5004 // check for zero
5005 if (!eq(vc, zero)) {
5006 // push value
5007 cvalues.push(vc);
5008 // increment pointer
5009 k++;
5010 }
5011 else {
5012 // remove value @ i, do not increment pointer
5013 cindex.splice(k, 1);
5014 }
5015 }
5016 }
5017 }
5018 }
5019 // update cptr
5020 cptr[columns] = cindex.length;
5021
5022 // return sparse matrix
5023 return c;
5024 };
5025
5026 return algorithm05;
5027 }
5028
5029 exports.name = 'algorithm05';
5030 exports.factory = factory;
5031
5032
5033/***/ },
5034/* 33 */
5035/***/ function(module, exports, __webpack_require__) {
5036
5037 'use strict';
5038
5039 var nearlyEqual = __webpack_require__(8).nearlyEqual;
5040
5041 function factory (type, config, load, typed) {
5042
5043 /**
5044 * Test whether two values are equal.
5045 *
5046 * @param {number | BigNumber | Fraction | boolean | Complex | Unit} x First value to compare
5047 * @param {number | BigNumber | Fraction | boolean | Complex} y Second value to compare
5048 * @return {boolean} Returns true when the compared values are equal, else returns false
5049 * @private
5050 */
5051 var equalScalar = typed('equalScalar', {
5052
5053 'boolean, boolean': function (x, y) {
5054 return x === y;
5055 },
5056
5057 'number, number': function (x, y) {
5058 return x === y || nearlyEqual(x, y, config.epsilon);
5059 },
5060
5061 'BigNumber, BigNumber': function (x, y) {
5062 return x.eq(y);
5063 },
5064
5065 'Fraction, Fraction': function (x, y) {
5066 return x.equals(y);
5067 },
5068
5069 'Complex, Complex': function (x, y) {
5070 return (x.re === y.re || nearlyEqual(x.re, y.re, config.epsilon)) &&
5071 (x.im === y.im || nearlyEqual(x.im, y.im, config.epsilon));
5072 },
5073
5074 'Unit, Unit': function (x, y) {
5075 if (!x.equalBase(y)) {
5076 throw new Error('Cannot compare units with different base');
5077 }
5078 return x.value === y.value || nearlyEqual(x.value, y.value, config.epsilon);
5079 },
5080
5081 'string, string': function (x, y) {
5082 return x === y;
5083 }
5084 });
5085
5086 return equalScalar;
5087 }
5088
5089 exports.factory = factory;
5090
5091
5092/***/ },
5093/* 34 */
5094/***/ function(module, exports) {
5095
5096 'use strict';
5097
5098 function factory (type, config, load, typed) {
5099
5100 var DenseMatrix = type.DenseMatrix;
5101
5102 /**
5103 * Iterates over SparseMatrix S nonzero items and invokes the callback function f(Sij, b).
5104 * Callback function invoked NZ times (number of nonzero items in S).
5105 *
5106 *
5107 * ┌ f(Sij, b) ; S(i,j) !== 0
5108 * C(i,j) = ┤
5109 * â”” b ; otherwise
5110 *
5111 *
5112 * @param {Matrix} s The SparseMatrix instance (S)
5113 * @param {Scalar} b The Scalar value
5114 * @param {Function} callback The f(Aij,b) operation to invoke
5115 * @param {boolean} inverse A true value indicates callback should be invoked f(b,Sij)
5116 *
5117 * @return {Matrix} DenseMatrix (C)
5118 *
5119 * https://github.com/josdejong/mathjs/pull/346#issuecomment-97626813
5120 */
5121 var algorithm10 = function (s, b, callback, inverse) {
5122 // sparse matrix arrays
5123 var avalues = s._values;
5124 var aindex = s._index;
5125 var aptr = s._ptr;
5126 var asize = s._size;
5127 var adt = s._datatype;
5128
5129 // sparse matrix cannot be a Pattern matrix
5130 if (!avalues)
5131 throw new Error('Cannot perform operation on Pattern Sparse Matrix and Scalar value');
5132
5133 // rows & columns
5134 var rows = asize[0];
5135 var columns = asize[1];
5136
5137 // datatype
5138 var dt;
5139 // callback signature to use
5140 var cf = callback;
5141
5142 // process data types
5143 if (typeof adt === 'string') {
5144 // datatype
5145 dt = adt;
5146 // convert b to the same datatype
5147 b = typed.convert(b, dt);
5148 // callback
5149 cf = typed.find(callback, [dt, dt]);
5150 }
5151
5152 // result arrays
5153 var cdata = [];
5154 // matrix
5155 var c = new DenseMatrix({
5156 data: cdata,
5157 size: [rows, columns],
5158 datatype: dt
5159 });
5160
5161 // workspaces
5162 var x = [];
5163 // marks indicating we have a value in x for a given column
5164 var w = [];
5165
5166 // loop columns
5167 for (var j = 0; j < columns; j++) {
5168 // columns mark
5169 var mark = j + 1;
5170 // values in j
5171 for (var k0 = aptr[j], k1 = aptr[j + 1], k = k0; k < k1; k++) {
5172 // row
5173 var r = aindex[k];
5174 // update workspace
5175 x[r] = avalues[k];
5176 w[r] = mark;
5177 }
5178 // loop rows
5179 for (var i = 0; i < rows; i++) {
5180 // initialize C on first column
5181 if (j === 0) {
5182 // create row array
5183 cdata[i] = [];
5184 }
5185 // check sparse matrix has a value @ i,j
5186 if (w[i] === mark) {
5187 // invoke callback, update C
5188 cdata[i][j] = inverse ? cf(b, x[i]) : cf(x[i], b);
5189 }
5190 else {
5191 // dense matrix value @ i, j
5192 cdata[i][j] = b;
5193 }
5194 }
5195 }
5196
5197 // return sparse matrix
5198 return c;
5199 };
5200
5201 return algorithm10;
5202 }
5203
5204 exports.name = 'algorithm10';
5205 exports.factory = factory;
5206
5207
5208/***/ },
5209/* 35 */
5210/***/ function(module, exports, __webpack_require__) {
5211
5212 'use strict';
5213
5214 var util = __webpack_require__(36);
5215 var DimensionError = __webpack_require__(22);
5216
5217 var string = util.string,
5218 isString = string.isString;
5219
5220 function factory (type, config, load, typed) {
5221
5222 var DenseMatrix = type.DenseMatrix;
5223
5224 /**
5225 * Iterates over DenseMatrix items and invokes the callback function f(Aij..z, Bij..z).
5226 * Callback function invoked MxN times.
5227 *
5228 * C(i,j,...z) = f(Aij..z, Bij..z)
5229 *
5230 * @param {Matrix} a The DenseMatrix instance (A)
5231 * @param {Matrix} b The DenseMatrix instance (B)
5232 * @param {Function} callback The f(Aij..z,Bij..z) operation to invoke
5233 *
5234 * @return {Matrix} DenseMatrix (C)
5235 *
5236 * https://github.com/josdejong/mathjs/pull/346#issuecomment-97658658
5237 */
5238 var algorithm13 = function (a, b, callback) {
5239 // a arrays
5240 var adata = a._data;
5241 var asize = a._size;
5242 var adt = a._datatype;
5243 // b arrays
5244 var bdata = b._data;
5245 var bsize = b._size;
5246 var bdt = b._datatype;
5247 // c arrays
5248 var csize = [];
5249
5250 // validate dimensions
5251 if (asize.length !== bsize.length)
5252 throw new DimensionError(asize.length, bsize.length);
5253
5254 // validate each one of the dimension sizes
5255 for (var s = 0; s < asize.length; s++) {
5256 // must match
5257 if (asize[s] !== bsize[s])
5258 throw new RangeError('Dimension mismatch. Matrix A (' + asize + ') must match Matrix B (' + bsize + ')');
5259 // update dimension in c
5260 csize[s] = asize[s];
5261 }
5262
5263 // datatype
5264 var dt;
5265 // callback signature to use
5266 var cf = callback;
5267
5268 // process data types
5269 if (typeof adt === 'string' && adt === bdt) {
5270 // datatype
5271 dt = adt;
5272 // convert b to the same datatype
5273 b = typed.convert(b, dt);
5274 // callback
5275 cf = typed.find(callback, [dt, dt]);
5276 }
5277
5278 // populate cdata, iterate through dimensions
5279 var cdata = csize.length > 0 ? _iterate(cf, 0, csize, csize[0], adata, bdata) : [];
5280
5281 // c matrix
5282 return new DenseMatrix({
5283 data: cdata,
5284 size: csize,
5285 datatype: dt
5286 });
5287 };
5288
5289 // recursive function
5290 var _iterate = function (f, level, s, n, av, bv) {
5291 // initialize array for this level
5292 var cv = [];
5293 // check we reach the last level
5294 if (level === s.length - 1) {
5295 // loop arrays in last level
5296 for (var i = 0; i < n; i++) {
5297 // invoke callback and store value
5298 cv[i] = f(av[i], bv[i]);
5299 }
5300 }
5301 else {
5302 // iterate current level
5303 for (var j = 0; j < n; j++) {
5304 // iterate next level
5305 cv[j] = _iterate(f, level + 1, s, s[level + 1], av[j], bv[j]);
5306 }
5307 }
5308 return cv;
5309 };
5310
5311 return algorithm13;
5312 }
5313
5314 exports.name = 'algorithm13';
5315 exports.factory = factory;
5316
5317
5318/***/ },
5319/* 36 */
5320/***/ function(module, exports, __webpack_require__) {
5321
5322 'use strict';
5323
5324 exports.array = __webpack_require__(18);
5325 exports['boolean'] = __webpack_require__(37);
5326 exports['function'] = __webpack_require__(38);
5327 exports.number = __webpack_require__(8);
5328 exports.object = __webpack_require__(5);
5329 exports.string = __webpack_require__(20);
5330 exports.types = __webpack_require__(19);
5331 exports.emitter = __webpack_require__(3);
5332
5333
5334/***/ },
5335/* 37 */
5336/***/ function(module, exports) {
5337
5338 'use strict';
5339
5340 /**
5341 * Test whether value is a boolean
5342 * @param {*} value
5343 * @return {boolean} isBoolean
5344 */
5345 exports.isBoolean = function(value) {
5346 return typeof value == 'boolean';
5347 };
5348
5349
5350/***/ },
5351/* 38 */
5352/***/ function(module, exports) {
5353
5354 // function utils
5355
5356 /*
5357 * Memoize a given function by caching the computed result.
5358 * The cache of a memoized function can be cleared by deleting the `cache`
5359 * property of the function.
5360 *
5361 * @param {function} fn The function to be memoized.
5362 * Must be a pure function.
5363 * @param {function(args: Array)} [hasher] A custom hash builder.
5364 * Is JSON.stringify by default.
5365 * @return {function} Returns the memoized function
5366 */
5367 exports.memoize = function(fn, hasher) {
5368 return function memoize() {
5369 if (typeof memoize.cache !== 'object') {
5370 memoize.cache = {};
5371 }
5372
5373 var args = [];
5374 for (var i = 0; i < arguments.length; i++) {
5375 args[i] = arguments[i];
5376 }
5377
5378 var hash = hasher ? hasher(args) : JSON.stringify(args);
5379 if (!(hash in memoize.cache)) {
5380 return memoize.cache[hash] = fn.apply(fn, args);
5381 }
5382 return memoize.cache[hash];
5383 };
5384 };
5385
5386
5387/***/ },
5388/* 39 */
5389/***/ function(module, exports, __webpack_require__) {
5390
5391 'use strict';
5392
5393 var clone = __webpack_require__(5).clone;
5394
5395 function factory (type, config, load, typed) {
5396
5397 var DenseMatrix = type.DenseMatrix;
5398
5399 /**
5400 * Iterates over DenseMatrix items and invokes the callback function f(Aij..z, b).
5401 * Callback function invoked MxN times.
5402 *
5403 * C(i,j,...z) = f(Aij..z, b)
5404 *
5405 * @param {Matrix} a The DenseMatrix instance (A)
5406 * @param {Scalar} b The Scalar value
5407 * @param {Function} callback The f(Aij..z,b) operation to invoke
5408 * @param {boolean} inverse A true value indicates callback should be invoked f(b,Aij..z)
5409 *
5410 * @return {Matrix} DenseMatrix (C)
5411 *
5412 * https://github.com/josdejong/mathjs/pull/346#issuecomment-97659042
5413 */
5414 var algorithm14 = function (a, b, callback, inverse) {
5415 // a arrays
5416 var adata = a._data;
5417 var asize = a._size;
5418 var adt = a._datatype;
5419
5420 // datatype
5421 var dt;
5422 // callback signature to use
5423 var cf = callback;
5424
5425 // process data types
5426 if (typeof adt === 'string') {
5427 // datatype
5428 dt = adt;
5429 // convert b to the same datatype
5430 b = typed.convert(b, dt);
5431 // callback
5432 cf = typed.find(callback, [dt, dt]);
5433 }
5434
5435 // populate cdata, iterate through dimensions
5436 var cdata = asize.length > 0 ? _iterate(cf, 0, asize, asize[0], adata, b, inverse) : [];
5437
5438 // c matrix
5439 return new DenseMatrix({
5440 data: cdata,
5441 size: clone(asize),
5442 datatype: dt
5443 });
5444 };
5445
5446 // recursive function
5447 var _iterate = function (f, level, s, n, av, bv, inverse) {
5448 // initialize array for this level
5449 var cv = [];
5450 // check we reach the last level
5451 if (level === s.length - 1) {
5452 // loop arrays in last level
5453 for (var i = 0; i < n; i++) {
5454 // invoke callback and store value
5455 cv[i] = inverse ? f(bv, av[i]) : f(av[i], bv);
5456 }
5457 }
5458 else {
5459 // iterate current level
5460 for (var j = 0; j < n; j++) {
5461 // iterate next level
5462 cv[j] = _iterate(f, level + 1, s, s[level + 1], av[j], bv, inverse);
5463 }
5464 }
5465 return cv;
5466 };
5467
5468 return algorithm14;
5469 }
5470
5471 exports.name = 'algorithm14';
5472 exports.factory = factory;
5473
5474
5475/***/ },
5476/* 40 */
5477/***/ function(module, exports, __webpack_require__) {
5478
5479 'use strict';
5480
5481 var extend = __webpack_require__(5).extend;
5482 var array = __webpack_require__(18);
5483
5484 function factory (type, config, load, typed) {
5485 var latex = __webpack_require__(26);
5486
5487 var matrix = load(__webpack_require__(23));
5488 var addScalar = load(__webpack_require__(27));
5489 var multiplyScalar = load(__webpack_require__(41));
5490 var equalScalar = load(__webpack_require__(33));
5491
5492 var algorithm11 = load(__webpack_require__(42));
5493 var algorithm14 = load(__webpack_require__(39));
5494
5495 var DenseMatrix = type.DenseMatrix;
5496 var SparseMatrix = type.SparseMatrix;
5497
5498 /**
5499 * Multiply two values, `x * y`. The result is squeezed.
5500 * For matrices, the matrix product is calculated.
5501 *
5502 * Syntax:
5503 *
5504 * math.multiply(x, y)
5505 *
5506 * Examples:
5507 *
5508 * math.multiply(4, 5.2); // returns number 20.8
5509 *
5510 * var a = math.complex(2, 3);
5511 * var b = math.complex(4, 1);
5512 * math.multiply(a, b); // returns Complex 5 + 14i
5513 *
5514 * var c = [[1, 2], [4, 3]];
5515 * var d = [[1, 2, 3], [3, -4, 7]];
5516 * math.multiply(c, d); // returns Array [[7, -6, 17], [13, -4, 33]]
5517 *
5518 * var e = math.unit('2.1 km');
5519 * math.multiply(3, e); // returns Unit 6.3 km
5520 *
5521 * See also:
5522 *
5523 * divide
5524 *
5525 * @param {number | BigNumber | Fraction | Complex | Unit | Array | Matrix} x First value to multiply
5526 * @param {number | BigNumber | Fraction | Complex | Unit | Array | Matrix} y Second value to multiply
5527 * @return {number | BigNumber | Fraction | Complex | Unit | Array | Matrix} Multiplication of `x` and `y`
5528 */
5529 var multiply = typed('multiply', extend({
5530 // we extend the signatures of multiplyScalar with signatures dealing with matrices
5531
5532 'Array, Array': function (x, y) {
5533 // check dimensions
5534 _validateMatrixDimensions(array.size(x), array.size(y));
5535
5536 // use dense matrix implementation
5537 var m = multiply(matrix(x), matrix(y));
5538 // return array or scalar
5539 return (m && m.isMatrix === true) ? m.valueOf() : m;
5540 },
5541
5542 'Matrix, Matrix': function (x, y) {
5543 // dimensions
5544 var xsize = x.size();
5545 var ysize = y.size();
5546
5547 // check dimensions
5548 _validateMatrixDimensions(xsize, ysize);
5549
5550 // process dimensions
5551 if (xsize.length === 1) {
5552 // process y dimensions
5553 if (ysize.length === 1) {
5554 // Vector * Vector
5555 return _multiplyVectorVector(x, y, xsize[0]);
5556 }
5557 // Vector * Matrix
5558 return _multiplyVectorMatrix(x, y);
5559 }
5560 // process y dimensions
5561 if (ysize.length === 1) {
5562 // Matrix * Vector
5563 return _multiplyMatrixVector(x, y);
5564 }
5565 // Matrix * Matrix
5566 return _multiplyMatrixMatrix(x, y);
5567 },
5568
5569 'Matrix, Array': function (x, y) {
5570 // use Matrix * Matrix implementation
5571 return multiply(x, matrix(y));
5572 },
5573
5574 'Array, Matrix': function (x, y) {
5575 // use Matrix * Matrix implementation
5576 return multiply(matrix(x, y.storage()), y);
5577 },
5578
5579 'Matrix, any': function (x, y) {
5580 // result
5581 var c;
5582
5583 // process storage format
5584 switch (x.storage()) {
5585 case 'sparse':
5586 c = algorithm11(x, y, multiplyScalar, false);
5587 break;
5588 case 'dense':
5589 c = algorithm14(x, y, multiplyScalar, false);
5590 break;
5591 }
5592 return c;
5593 },
5594
5595 'any, Matrix': function (x, y) {
5596 // result
5597 var c;
5598 // check storage format
5599 switch (y.storage()) {
5600 case 'sparse':
5601 c = algorithm11(y, x, multiplyScalar, true);
5602 break;
5603 case 'dense':
5604 c = algorithm14(y, x, multiplyScalar, true);
5605 break;
5606 }
5607 return c;
5608 },
5609
5610 'Array, any': function (x, y) {
5611 // use matrix implementation
5612 return algorithm14(matrix(x), y, multiplyScalar, false).valueOf();
5613 },
5614
5615 'any, Array': function (x, y) {
5616 // use matrix implementation
5617 return algorithm14(matrix(y), x, multiplyScalar, true).valueOf();
5618 }
5619 }, multiplyScalar.signatures));
5620
5621 var _validateMatrixDimensions = function (size1, size2) {
5622 // check left operand dimensions
5623 switch (size1.length) {
5624 case 1:
5625 // check size2
5626 switch (size2.length) {
5627 case 1:
5628 // Vector x Vector
5629 if (size1[0] !== size2[0]) {
5630 // throw error
5631 throw new RangeError('Dimension mismatch in multiplication. Vectors must have the same length');
5632 }
5633 break;
5634 case 2:
5635 // Vector x Matrix
5636 if (size1[0] !== size2[0]) {
5637 // throw error
5638 throw new RangeError('Dimension mismatch in multiplication. Vector length (' + size1[0] + ') must match Matrix rows (' + size2[0] + ')');
5639 }
5640 break;
5641 default:
5642 throw new Error('Can only multiply a 1 or 2 dimensional matrix (Matrix B has ' + size2.length + ' dimensions)');
5643 }
5644 break;
5645 case 2:
5646 // check size2
5647 switch (size2.length) {
5648 case 1:
5649 // Matrix x Vector
5650 if (size1[1] !== size2[0]) {
5651 // throw error
5652 throw new RangeError('Dimension mismatch in multiplication. Matrix columns (' + size1[1] + ') must match Vector length (' + size2[0] + ')');
5653 }
5654 break;
5655 case 2:
5656 // Matrix x Matrix
5657 if (size1[1] !== size2[0]) {
5658 // throw error
5659 throw new RangeError('Dimension mismatch in multiplication. Matrix A columns (' + size1[1] + ') must match Matrix B rows (' + size2[0] + ')');
5660 }
5661 break;
5662 default:
5663 throw new Error('Can only multiply a 1 or 2 dimensional matrix (Matrix B has ' + size2.length + ' dimensions)');
5664 }
5665 break;
5666 default:
5667 throw new Error('Can only multiply a 1 or 2 dimensional matrix (Matrix A has ' + size1.length + ' dimensions)');
5668 }
5669 };
5670
5671 /**
5672 * C = A * B
5673 *
5674 * @param {Matrix} a Dense Vector (N)
5675 * @param {Matrix} b Dense Vector (N)
5676 *
5677 * @return {number} Scalar value
5678 */
5679 var _multiplyVectorVector = function (a, b, n) {
5680 // check empty vector
5681 if (n === 0)
5682 throw new Error('Cannot multiply two empty vectors');
5683
5684 // a dense
5685 var adata = a._data;
5686 var adt = a._datatype;
5687 // b dense
5688 var bdata = b._data;
5689 var bdt = b._datatype;
5690
5691 // datatype
5692 var dt;
5693 // addScalar signature to use
5694 var af = addScalar;
5695 // multiplyScalar signature to use
5696 var mf = multiplyScalar;
5697
5698 // process data types
5699 if (adt && bdt && adt === bdt && typeof adt === 'string') {
5700 // datatype
5701 dt = adt;
5702 // find signatures that matches (dt, dt)
5703 af = typed.find(addScalar, [dt, dt]);
5704 mf = typed.find(multiplyScalar, [dt, dt]);
5705 }
5706
5707 // result (do not initialize it with zero)
5708 var c = mf(adata[0], bdata[0]);
5709 // loop data
5710 for (var i = 1; i < n; i++) {
5711 // multiply and accumulate
5712 c = af(c, mf(adata[i], bdata[i]));
5713 }
5714 return c;
5715 };
5716
5717 /**
5718 * C = A * B
5719 *
5720 * @param {Matrix} a Dense Vector (M)
5721 * @param {Matrix} b Matrix (MxN)
5722 *
5723 * @return {Matrix} Dense Vector (N)
5724 */
5725 var _multiplyVectorMatrix = function (a, b) {
5726 // process storage
5727 switch (b.storage()) {
5728 case 'dense':
5729 return _multiplyVectorDenseMatrix(a, b);
5730 }
5731 throw new Error('Not implemented');
5732 };
5733
5734 /**
5735 * C = A * B
5736 *
5737 * @param {Matrix} a Dense Vector (M)
5738 * @param {Matrix} b Dense Matrix (MxN)
5739 *
5740 * @return {Matrix} Dense Vector (N)
5741 */
5742 var _multiplyVectorDenseMatrix = function (a, b) {
5743 // a dense
5744 var adata = a._data;
5745 var asize = a._size;
5746 var adt = a._datatype;
5747 // b dense
5748 var bdata = b._data;
5749 var bsize = b._size;
5750 var bdt = b._datatype;
5751 // rows & columns
5752 var alength = asize[0];
5753 var bcolumns = bsize[1];
5754
5755 // datatype
5756 var dt;
5757 // addScalar signature to use
5758 var af = addScalar;
5759 // multiplyScalar signature to use
5760 var mf = multiplyScalar;
5761
5762 // process data types
5763 if (adt && bdt && adt === bdt && typeof adt === 'string') {
5764 // datatype
5765 dt = adt;
5766 // find signatures that matches (dt, dt)
5767 af = typed.find(addScalar, [dt, dt]);
5768 mf = typed.find(multiplyScalar, [dt, dt]);
5769 }
5770
5771 // result
5772 var c = [];
5773
5774 // loop matrix columns
5775 for (var j = 0; j < bcolumns; j++) {
5776 // sum (do not initialize it with zero)
5777 var sum = mf(adata[0], bdata[0][j]);
5778 // loop vector
5779 for (var i = 1; i < alength; i++) {
5780 // multiply & accumulate
5781 sum = af(sum, mf(adata[i], bdata[i][j]));
5782 }
5783 c[j] = sum;
5784 }
5785
5786 // check we need to squeeze the result into a scalar
5787 if (bcolumns === 1)
5788 return c[0];
5789
5790 // return matrix
5791 return new DenseMatrix({
5792 data: c,
5793 size: [bcolumns],
5794 datatype: dt
5795 });
5796 };
5797
5798 /**
5799 * C = A * B
5800 *
5801 * @param {Matrix} a Matrix (MxN)
5802 * @param {Matrix} b Dense Vector (N)
5803 *
5804 * @return {Matrix} Dense Vector (M)
5805 */
5806 var _multiplyMatrixVector = function (a, b) {
5807 // process storage
5808 switch (a.storage()) {
5809 case 'dense':
5810 return _multiplyDenseMatrixVector(a, b);
5811 case 'sparse':
5812 return _multiplySparseMatrixVector(a, b);
5813 }
5814 };
5815
5816 /**
5817 * C = A * B
5818 *
5819 * @param {Matrix} a Matrix (MxN)
5820 * @param {Matrix} b Matrix (NxC)
5821 *
5822 * @return {Matrix} Matrix (MxC)
5823 */
5824 var _multiplyMatrixMatrix = function (a, b) {
5825 // process storage
5826 switch (a.storage()) {
5827 case 'dense':
5828 // process storage
5829 switch (b.storage()) {
5830 case 'dense':
5831 return _multiplyDenseMatrixDenseMatrix(a, b);
5832 case 'sparse':
5833 return _multiplyDenseMatrixSparseMatrix(a, b);
5834 }
5835 break;
5836 case 'sparse':
5837 // process storage
5838 switch (b.storage()) {
5839 case 'dense':
5840 return _multiplySparseMatrixDenseMatrix(a, b);
5841 case 'sparse':
5842 return _multiplySparseMatrixSparseMatrix(a, b);
5843 }
5844 break;
5845 }
5846 };
5847
5848 /**
5849 * C = A * B
5850 *
5851 * @param {Matrix} a DenseMatrix (MxN)
5852 * @param {Matrix} b Dense Vector (N)
5853 *
5854 * @return {Matrix} Dense Vector (M)
5855 */
5856 var _multiplyDenseMatrixVector = function (a, b) {
5857 // a dense
5858 var adata = a._data;
5859 var asize = a._size;
5860 var adt = a._datatype;
5861 // b dense
5862 var bdata = b._data;
5863 var bdt = b._datatype;
5864 // rows & columns
5865 var arows = asize[0];
5866 var acolumns = asize[1];
5867
5868 // datatype
5869 var dt;
5870 // addScalar signature to use
5871 var af = addScalar;
5872 // multiplyScalar signature to use
5873 var mf = multiplyScalar;
5874
5875 // process data types
5876 if (adt && bdt && adt === bdt && typeof adt === 'string') {
5877 // datatype
5878 dt = adt;
5879 // find signatures that matches (dt, dt)
5880 af = typed.find(addScalar, [dt, dt]);
5881 mf = typed.find(multiplyScalar, [dt, dt]);
5882 }
5883
5884 // result
5885 var c = [];
5886
5887 // loop matrix a rows
5888 for (var i = 0; i < arows; i++) {
5889 // current row
5890 var row = adata[i];
5891 // sum (do not initialize it with zero)
5892 var sum = mf(row[0], bdata[0]);
5893 // loop matrix a columns
5894 for (var j = 1; j < acolumns; j++) {
5895 // multiply & accumulate
5896 sum = af(sum, mf(row[j], bdata[j]));
5897 }
5898 c[i] = sum;
5899 }
5900 // check we need to squeeze the result into a scalar
5901 if (arows === 1)
5902 return c[0];
5903
5904 // return matrix
5905 return new DenseMatrix({
5906 data: c,
5907 size: [arows],
5908 datatype: dt
5909 });
5910 };
5911
5912 /**
5913 * C = A * B
5914 *
5915 * @param {Matrix} a DenseMatrix (MxN)
5916 * @param {Matrix} b DenseMatrix (NxC)
5917 *
5918 * @return {Matrix} DenseMatrix (MxC)
5919 */
5920 var _multiplyDenseMatrixDenseMatrix = function (a, b) {
5921 // a dense
5922 var adata = a._data;
5923 var asize = a._size;
5924 var adt = a._datatype;
5925 // b dense
5926 var bdata = b._data;
5927 var bsize = b._size;
5928 var bdt = b._datatype;
5929 // rows & columns
5930 var arows = asize[0];
5931 var acolumns = asize[1];
5932 var bcolumns = bsize[1];
5933
5934 // datatype
5935 var dt;
5936 // addScalar signature to use
5937 var af = addScalar;
5938 // multiplyScalar signature to use
5939 var mf = multiplyScalar;
5940
5941 // process data types
5942 if (adt && bdt && adt === bdt && typeof adt === 'string') {
5943 // datatype
5944 dt = adt;
5945 // find signatures that matches (dt, dt)
5946 af = typed.find(addScalar, [dt, dt]);
5947 mf = typed.find(multiplyScalar, [dt, dt]);
5948 }
5949
5950 // result
5951 var c = [];
5952
5953 // loop matrix a rows
5954 for (var i = 0; i < arows; i++) {
5955 // current row
5956 var row = adata[i];
5957 // initialize row array
5958 c[i] = [];
5959 // loop matrix b columns
5960 for (var j = 0; j < bcolumns; j++) {
5961 // sum (avoid initializing sum to zero)
5962 var sum = mf(row[0], bdata[0][j]);
5963 // loop matrix a columns
5964 for (var x = 1; x < acolumns; x++) {
5965 // multiply & accumulate
5966 sum = af(sum, mf(row[x], bdata[x][j]));
5967 }
5968 c[i][j] = sum;
5969 }
5970 }
5971 // check we need to squeeze the result into a scalar
5972 if (arows === 1 && bcolumns === 1)
5973 return c[0][0];
5974
5975 // return matrix
5976 return new DenseMatrix({
5977 data: c,
5978 size: [arows, bcolumns],
5979 datatype: dt
5980 });
5981 };
5982
5983 /**
5984 * C = A * B
5985 *
5986 * @param {Matrix} a DenseMatrix (MxN)
5987 * @param {Matrix} b SparseMatrix (NxC)
5988 *
5989 * @return {Matrix} SparseMatrix (MxC)
5990 */
5991 var _multiplyDenseMatrixSparseMatrix = function (a, b) {
5992 // a dense
5993 var adata = a._data;
5994 var asize = a._size;
5995 var adt = a._datatype;
5996 // b sparse
5997 var bvalues = b._values;
5998 var bindex = b._index;
5999 var bptr = b._ptr;
6000 var bsize = b._size;
6001 var bdt = b._datatype;
6002 // validate b matrix
6003 if (!bvalues)
6004 throw new Error('Cannot multiply Dense Matrix times Pattern only Matrix');
6005 // rows & columns
6006 var arows = asize[0];
6007 var bcolumns = bsize[1];
6008
6009 // datatype
6010 var dt;
6011 // addScalar signature to use
6012 var af = addScalar;
6013 // multiplyScalar signature to use
6014 var mf = multiplyScalar;
6015 // equalScalar signature to use
6016 var eq = equalScalar;
6017 // zero value
6018 var zero = 0;
6019
6020 // process data types
6021 if (adt && bdt && adt === bdt && typeof adt === 'string') {
6022 // datatype
6023 dt = adt;
6024 // find signatures that matches (dt, dt)
6025 af = typed.find(addScalar, [dt, dt]);
6026 mf = typed.find(multiplyScalar, [dt, dt]);
6027 eq = typed.find(equalScalar, [dt, dt]);
6028 // convert 0 to the same datatype
6029 zero = typed.convert(0, dt);
6030 }
6031
6032 // result
6033 var cvalues = [];
6034 var cindex = [];
6035 var cptr = [];
6036 // c matrix
6037 var c = new SparseMatrix({
6038 values : cvalues,
6039 index: cindex,
6040 ptr: cptr,
6041 size: [arows, bcolumns],
6042 datatype: dt
6043 });
6044
6045 // loop b columns
6046 for (var jb = 0; jb < bcolumns; jb++) {
6047 // update ptr
6048 cptr[jb] = cindex.length;
6049 // indeces in column jb
6050 var kb0 = bptr[jb];
6051 var kb1 = bptr[jb + 1];
6052 // do not process column jb if no data exists
6053 if (kb1 > kb0) {
6054 // last row mark processed
6055 var last = 0;
6056 // loop a rows
6057 for (var i = 0; i < arows; i++) {
6058 // column mark
6059 var mark = i + 1;
6060 // C[i, jb]
6061 var cij;
6062 // values in b column j
6063 for (var kb = kb0; kb < kb1; kb++) {
6064 // row
6065 var ib = bindex[kb];
6066 // check value has been initialized
6067 if (last !== mark) {
6068 // first value in column jb
6069 cij = mf(adata[i][ib], bvalues[kb]);
6070 // update mark
6071 last = mark;
6072 }
6073 else {
6074 // accumulate value
6075 cij = af(cij, mf(adata[i][ib], bvalues[kb]));
6076 }
6077 }
6078 // check column has been processed and value != 0
6079 if (last === mark && !eq(cij, zero)) {
6080 // push row & value
6081 cindex.push(i);
6082 cvalues.push(cij);
6083 }
6084 }
6085 }
6086 }
6087 // update ptr
6088 cptr[bcolumns] = cindex.length;
6089
6090 // check we need to squeeze the result into a scalar
6091 if (arows === 1 && bcolumns === 1)
6092 return cvalues.length === 1 ? cvalues[0] : 0;
6093
6094 // return sparse matrix
6095 return c;
6096 };
6097
6098 /**
6099 * C = A * B
6100 *
6101 * @param {Matrix} a SparseMatrix (MxN)
6102 * @param {Matrix} b Dense Vector (N)
6103 *
6104 * @return {Matrix} SparseMatrix (M, 1)
6105 */
6106 var _multiplySparseMatrixVector = function (a, b) {
6107 // a sparse
6108 var avalues = a._values;
6109 var aindex = a._index;
6110 var aptr = a._ptr;
6111 var adt = a._datatype;
6112 // validate a matrix
6113 if (!avalues)
6114 throw new Error('Cannot multiply Pattern only Matrix times Dense Matrix');
6115 // b dense
6116 var bdata = b._data;
6117 var bdt = b._datatype;
6118 // rows & columns
6119 var arows = a._size[0];
6120 var brows = b._size[0];
6121 // result
6122 var cvalues = [];
6123 var cindex = [];
6124 var cptr = [];
6125
6126 // datatype
6127 var dt;
6128 // addScalar signature to use
6129 var af = addScalar;
6130 // multiplyScalar signature to use
6131 var mf = multiplyScalar;
6132 // equalScalar signature to use
6133 var eq = equalScalar;
6134 // zero value
6135 var zero = 0;
6136
6137 // process data types
6138 if (adt && bdt && adt === bdt && typeof adt === 'string') {
6139 // datatype
6140 dt = adt;
6141 // find signatures that matches (dt, dt)
6142 af = typed.find(addScalar, [dt, dt]);
6143 mf = typed.find(multiplyScalar, [dt, dt]);
6144 eq = typed.find(equalScalar, [dt, dt]);
6145 // convert 0 to the same datatype
6146 zero = typed.convert(0, dt);
6147 }
6148
6149 // workspace
6150 var x = [];
6151 // vector with marks indicating a value x[i] exists in a given column
6152 var w = [];
6153
6154 // update ptr
6155 cptr[0] = 0;
6156 // rows in b
6157 for (var ib = 0; ib < brows; ib++) {
6158 // b[ib]
6159 var vbi = bdata[ib];
6160 // check b[ib] != 0, avoid loops
6161 if (!eq(vbi, zero)) {
6162 // A values & index in ib column
6163 for (var ka0 = aptr[ib], ka1 = aptr[ib + 1], ka = ka0; ka < ka1; ka++) {
6164 // a row
6165 var ia = aindex[ka];
6166 // check value exists in current j
6167 if (!w[ia]) {
6168 // ia is new entry in j
6169 w[ia] = true;
6170 // add i to pattern of C
6171 cindex.push(ia);
6172 // x(ia) = A
6173 x[ia] = mf(vbi, avalues[ka]);
6174 }
6175 else {
6176 // i exists in C already
6177 x[ia] = af(x[ia], mf(vbi, avalues[ka]));
6178 }
6179 }
6180 }
6181 }
6182 // copy values from x to column jb of c
6183 for (var p1 = cindex.length, p = 0; p < p1; p++) {
6184 // row
6185 var ic = cindex[p];
6186 // copy value
6187 cvalues[p] = x[ic];
6188 }
6189 // update ptr
6190 cptr[1] = cindex.length;
6191
6192 // check we need to squeeze the result into a scalar
6193 if (arows === 1)
6194 return cvalues.length === 1 ? cvalues[0] : 0;
6195
6196 // return sparse matrix
6197 return new SparseMatrix({
6198 values : cvalues,
6199 index: cindex,
6200 ptr: cptr,
6201 size: [arows, 1],
6202 datatype: dt
6203 });
6204 };
6205
6206 /**
6207 * C = A * B
6208 *
6209 * @param {Matrix} a SparseMatrix (MxN)
6210 * @param {Matrix} b DenseMatrix (NxC)
6211 *
6212 * @return {Matrix} SparseMatrix (MxC)
6213 */
6214 var _multiplySparseMatrixDenseMatrix = function (a, b) {
6215 // a sparse
6216 var avalues = a._values;
6217 var aindex = a._index;
6218 var aptr = a._ptr;
6219 var adt = a._datatype;
6220 // validate a matrix
6221 if (!avalues)
6222 throw new Error('Cannot multiply Pattern only Matrix times Dense Matrix');
6223 // b dense
6224 var bdata = b._data;
6225 var bdt = b._datatype;
6226 // rows & columns
6227 var arows = a._size[0];
6228 var brows = b._size[0];
6229 var bcolumns = b._size[1];
6230
6231 // datatype
6232 var dt;
6233 // addScalar signature to use
6234 var af = addScalar;
6235 // multiplyScalar signature to use
6236 var mf = multiplyScalar;
6237 // equalScalar signature to use
6238 var eq = equalScalar;
6239 // zero value
6240 var zero = 0;
6241
6242 // process data types
6243 if (adt && bdt && adt === bdt && typeof adt === 'string') {
6244 // datatype
6245 dt = adt;
6246 // find signatures that matches (dt, dt)
6247 af = typed.find(addScalar, [dt, dt]);
6248 mf = typed.find(multiplyScalar, [dt, dt]);
6249 eq = typed.find(equalScalar, [dt, dt]);
6250 // convert 0 to the same datatype
6251 zero = typed.convert(0, dt);
6252 }
6253
6254 // result
6255 var cvalues = [];
6256 var cindex = [];
6257 var cptr = [];
6258 // c matrix
6259 var c = new SparseMatrix({
6260 values : cvalues,
6261 index: cindex,
6262 ptr: cptr,
6263 size: [arows, bcolumns],
6264 datatype: dt
6265 });
6266
6267 // workspace
6268 var x = [];
6269 // vector with marks indicating a value x[i] exists in a given column
6270 var w = [];
6271
6272 // loop b columns
6273 for (var jb = 0; jb < bcolumns; jb++) {
6274 // update ptr
6275 cptr[jb] = cindex.length;
6276 // mark in workspace for current column
6277 var mark = jb + 1;
6278 // rows in jb
6279 for (var ib = 0; ib < brows; ib++) {
6280 // b[ib, jb]
6281 var vbij = bdata[ib][jb];
6282 // check b[ib, jb] != 0, avoid loops
6283 if (!eq(vbij, zero)) {
6284 // A values & index in ib column
6285 for (var ka0 = aptr[ib], ka1 = aptr[ib + 1], ka = ka0; ka < ka1; ka++) {
6286 // a row
6287 var ia = aindex[ka];
6288 // check value exists in current j
6289 if (w[ia] !== mark) {
6290 // ia is new entry in j
6291 w[ia] = mark;
6292 // add i to pattern of C
6293 cindex.push(ia);
6294 // x(ia) = A
6295 x[ia] = mf(vbij, avalues[ka]);
6296 }
6297 else {
6298 // i exists in C already
6299 x[ia] = af(x[ia], mf(vbij, avalues[ka]));
6300 }
6301 }
6302 }
6303 }
6304 // copy values from x to column jb of c
6305 for (var p0 = cptr[jb], p1 = cindex.length, p = p0; p < p1; p++) {
6306 // row
6307 var ic = cindex[p];
6308 // copy value
6309 cvalues[p] = x[ic];
6310 }
6311 }
6312 // update ptr
6313 cptr[bcolumns] = cindex.length;
6314
6315 // check we need to squeeze the result into a scalar
6316 if (arows === 1 && bcolumns === 1)
6317 return cvalues.length === 1 ? cvalues[0] : 0;
6318
6319 // return sparse matrix
6320 return c;
6321 };
6322
6323 /**
6324 * C = A * B
6325 *
6326 * @param {Matrix} a SparseMatrix (MxN)
6327 * @param {Matrix} b SparseMatrix (NxC)
6328 *
6329 * @return {Matrix} SparseMatrix (MxC)
6330 */
6331 var _multiplySparseMatrixSparseMatrix = function (a, b) {
6332 // a sparse
6333 var avalues = a._values;
6334 var aindex = a._index;
6335 var aptr = a._ptr;
6336 var adt = a._datatype;
6337 // b sparse
6338 var bvalues = b._values;
6339 var bindex = b._index;
6340 var bptr = b._ptr;
6341 var bdt = b._datatype;
6342
6343 // rows & columns
6344 var arows = a._size[0];
6345 var bcolumns = b._size[1];
6346 // flag indicating both matrices (a & b) contain data
6347 var values = avalues && bvalues;
6348
6349 // datatype
6350 var dt;
6351 // addScalar signature to use
6352 var af = addScalar;
6353 // multiplyScalar signature to use
6354 var mf = multiplyScalar;
6355
6356 // process data types
6357 if (adt && bdt && adt === bdt && typeof adt === 'string') {
6358 // datatype
6359 dt = adt;
6360 // find signatures that matches (dt, dt)
6361 af = typed.find(addScalar, [dt, dt]);
6362 mf = typed.find(multiplyScalar, [dt, dt]);
6363 }
6364
6365 // result
6366 var cvalues = values ? [] : undefined;
6367 var cindex = [];
6368 var cptr = [];
6369 // c matrix
6370 var c = new SparseMatrix({
6371 values : cvalues,
6372 index: cindex,
6373 ptr: cptr,
6374 size: [arows, bcolumns],
6375 datatype: dt
6376 });
6377
6378 // workspace
6379 var x = values ? [] : undefined;
6380 // vector with marks indicating a value x[i] exists in a given column
6381 var w = [];
6382 // variables
6383 var ka, ka0, ka1, kb, kb0, kb1, ia, ib;
6384 // loop b columns
6385 for (var jb = 0; jb < bcolumns; jb++) {
6386 // update ptr
6387 cptr[jb] = cindex.length;
6388 // mark in workspace for current column
6389 var mark = jb + 1;
6390 // B values & index in j
6391 for (kb0 = bptr[jb], kb1 = bptr[jb + 1], kb = kb0; kb < kb1; kb++) {
6392 // b row
6393 ib = bindex[kb];
6394 // check we need to process values
6395 if (values) {
6396 // loop values in a[:,ib]
6397 for (ka0 = aptr[ib], ka1 = aptr[ib + 1], ka = ka0; ka < ka1; ka++) {
6398 // row
6399 ia = aindex[ka];
6400 // check value exists in current j
6401 if (w[ia] !== mark) {
6402 // ia is new entry in j
6403 w[ia] = mark;
6404 // add i to pattern of C
6405 cindex.push(ia);
6406 // x(ia) = A
6407 x[ia] = mf(bvalues[kb], avalues[ka]);
6408 }
6409 else {
6410 // i exists in C already
6411 x[ia] = af(x[ia], mf(bvalues[kb], avalues[ka]));
6412 }
6413 }
6414 }
6415 else {
6416 // loop values in a[:,ib]
6417 for (ka0 = aptr[ib], ka1 = aptr[ib + 1], ka = ka0; ka < ka1; ka++) {
6418 // row
6419 ia = aindex[ka];
6420 // check value exists in current j
6421 if (w[ia] !== mark) {
6422 // ia is new entry in j
6423 w[ia] = mark;
6424 // add i to pattern of C
6425 cindex.push(ia);
6426 }
6427 }
6428 }
6429 }
6430 // check we need to process matrix values (pattern matrix)
6431 if (values) {
6432 // copy values from x to column jb of c
6433 for (var p0 = cptr[jb], p1 = cindex.length, p = p0; p < p1; p++) {
6434 // row
6435 var ic = cindex[p];
6436 // copy value
6437 cvalues[p] = x[ic];
6438 }
6439 }
6440 }
6441 // update ptr
6442 cptr[bcolumns] = cindex.length;
6443
6444 // check we need to squeeze the result into a scalar
6445 if (arows === 1 && bcolumns === 1 && values)
6446 return cvalues.length === 1 ? cvalues[0] : 0;
6447
6448 // return sparse matrix
6449 return c;
6450 };
6451
6452 multiply.toTex = '\\left(${args[0]}' + latex.operators['multiply'] + '${args[1]}\\right)';
6453
6454 return multiply;
6455 }
6456
6457 exports.name = 'multiply';
6458 exports.factory = factory;
6459
6460
6461/***/ },
6462/* 41 */
6463/***/ function(module, exports) {
6464
6465 'use strict';
6466
6467 function factory(type, config, load, typed) {
6468
6469 /**
6470 * Multiply two scalar values, `x * y`.
6471 * This function is meant for internal use: it is used by the public function
6472 * `multiply`
6473 *
6474 * This function does not support collections (Array or Matrix), and does
6475 * not validate the number of of inputs.
6476 *
6477 * @param {number | BigNumber | Fraction | Complex | Unit} x First value to multiply
6478 * @param {number | BigNumber | Fraction | Complex} y Second value to multiply
6479 * @return {number | BigNumber | Fraction | Complex | Unit} Multiplication of `x` and `y`
6480 * @private
6481 */
6482 var multiplyScalar = typed('multiplyScalar', {
6483
6484 'number, number': function (x, y) {
6485 return x * y;
6486 },
6487
6488 'Complex, Complex': function (x, y) {
6489 return new type.Complex(
6490 x.re * y.re - x.im * y.im,
6491 x.re * y.im + x.im * y.re
6492 );
6493 },
6494
6495 'BigNumber, BigNumber': function (x, y) {
6496 return x.times(y);
6497 },
6498
6499 'Fraction, Fraction': function (x, y) {
6500 return x.mul(y);
6501 },
6502
6503 'number, Unit': function (x, y) {
6504 var res = y.clone();
6505 res.value = (res.value === null) ? res._normalize(x) : (res.value * x);
6506 return res;
6507 },
6508
6509 'Unit, number': function (x, y) {
6510 var res = x.clone();
6511 res.value = (res.value === null) ? res._normalize(y) : (res.value * y);
6512 return res;
6513 },
6514
6515 'Unit, Unit': function (x, y) {
6516 return x.multiply(y);
6517 }
6518
6519 });
6520
6521 return multiplyScalar;
6522 }
6523
6524 exports.factory = factory;
6525
6526
6527/***/ },
6528/* 42 */
6529/***/ function(module, exports, __webpack_require__) {
6530
6531 'use strict';
6532
6533 function factory (type, config, load, typed) {
6534
6535 var equalScalar = load(__webpack_require__(33));
6536
6537 var SparseMatrix = type.SparseMatrix;
6538
6539 /**
6540 * Iterates over SparseMatrix S nonzero items and invokes the callback function f(Sij, b).
6541 * Callback function invoked NZ times (number of nonzero items in S).
6542 *
6543 *
6544 * ┌ f(Sij, b) ; S(i,j) !== 0
6545 * C(i,j) = ┤
6546 * â”” 0 ; otherwise
6547 *
6548 *
6549 * @param {Matrix} s The SparseMatrix instance (S)
6550 * @param {Scalar} b The Scalar value
6551 * @param {Function} callback The f(Aij,b) operation to invoke
6552 * @param {boolean} inverse A true value indicates callback should be invoked f(b,Sij)
6553 *
6554 * @return {Matrix} SparseMatrix (C)
6555 *
6556 * https://github.com/josdejong/mathjs/pull/346#issuecomment-97626813
6557 */
6558 var algorithm11 = function (s, b, callback, inverse) {
6559 // sparse matrix arrays
6560 var avalues = s._values;
6561 var aindex = s._index;
6562 var aptr = s._ptr;
6563 var asize = s._size;
6564 var adt = s._datatype;
6565
6566 // sparse matrix cannot be a Pattern matrix
6567 if (!avalues)
6568 throw new Error('Cannot perform operation on Pattern Sparse Matrix and Scalar value');
6569
6570 // rows & columns
6571 var rows = asize[0];
6572 var columns = asize[1];
6573
6574 // datatype
6575 var dt;
6576 // equal signature to use
6577 var eq = equalScalar;
6578 // zero value
6579 var zero = 0;
6580 // callback signature to use
6581 var cf = callback;
6582
6583 // process data types
6584 if (typeof adt === 'string') {
6585 // datatype
6586 dt = adt;
6587 // find signature that matches (dt, dt)
6588 eq = typed.find(equalScalar, [dt, dt]);
6589 // convert 0 to the same datatype
6590 zero = typed.convert(0, dt);
6591 // convert b to the same datatype
6592 b = typed.convert(b, dt);
6593 // callback
6594 cf = typed.find(callback, [dt, dt]);
6595 }
6596
6597 // result arrays
6598 var cvalues = [];
6599 var cindex = [];
6600 var cptr = [];
6601 // matrix
6602 var c = new SparseMatrix({
6603 values: cvalues,
6604 index: cindex,
6605 ptr: cptr,
6606 size: [rows, columns],
6607 datatype: dt
6608 });
6609
6610 // loop columns
6611 for (var j = 0; j < columns; j++) {
6612 // initialize ptr
6613 cptr[j] = cindex.length;
6614 // values in j
6615 for (var k0 = aptr[j], k1 = aptr[j + 1], k = k0; k < k1; k++) {
6616 // row
6617 var i = aindex[k];
6618 // invoke callback
6619 var v = inverse ? cf(b, avalues[k]) : cf(avalues[k], b);
6620 // check value is zero
6621 if (!eq(v, zero)) {
6622 // push index & value
6623 cindex.push(i);
6624 cvalues.push(v);
6625 }
6626 }
6627 }
6628 // update ptr
6629 cptr[columns] = cindex.length;
6630
6631 // return sparse matrix
6632 return c;
6633 };
6634
6635 return algorithm11;
6636 }
6637
6638 exports.name = 'algorithm11';
6639 exports.factory = factory;
6640
6641
6642/***/ },
6643/* 43 */
6644/***/ function(module, exports, __webpack_require__) {
6645
6646 'use strict';
6647
6648 var util = __webpack_require__(36);
6649 var object = util.object;
6650 var string = util.string;
6651
6652 function factory (type, config, load, typed) {
6653 var matrix = load(__webpack_require__(23));
6654 var add = load(__webpack_require__(44));
6655 var subtract = load(__webpack_require__(25));
6656 var multiply = load(__webpack_require__(40));
6657 var unaryMinus = load(__webpack_require__(28));
6658
6659 /**
6660 * Calculate the determinant of a matrix.
6661 *
6662 * Syntax:
6663 *
6664 * math.det(x)
6665 *
6666 * Examples:
6667 *
6668 * math.det([[1, 2], [3, 4]]); // returns -2
6669 *
6670 * var A = [
6671 * [-2, 2, 3],
6672 * [-1, 1, 3],
6673 * [2, 0, -1]
6674 * ]
6675 * math.det(A); // returns 6
6676 *
6677 * See also:
6678 *
6679 * inv
6680 *
6681 * @param {Array | Matrix} x A matrix
6682 * @return {number} The determinant of `x`
6683 */
6684 var det = typed('det', {
6685 'any': function (x) {
6686 return object.clone(x);
6687 },
6688
6689 'Array | Matrix': function det (x) {
6690 var size;
6691 if (x && x.isMatrix === true) {
6692 size = x.size();
6693 }
6694 else if (Array.isArray(x)) {
6695 x = matrix(x);
6696 size = x.size();
6697 }
6698 else {
6699 // a scalar
6700 size = [];
6701 }
6702
6703 switch (size.length) {
6704 case 0:
6705 // scalar
6706 return object.clone(x);
6707
6708 case 1:
6709 // vector
6710 if (size[0] == 1) {
6711 return object.clone(x.valueOf()[0]);
6712 }
6713 else {
6714 throw new RangeError('Matrix must be square ' +
6715 '(size: ' + string.format(size) + ')');
6716 }
6717
6718 case 2:
6719 // two dimensional array
6720 var rows = size[0];
6721 var cols = size[1];
6722 if (rows == cols) {
6723 return _det(x.clone().valueOf(), rows, cols);
6724 }
6725 else {
6726 throw new RangeError('Matrix must be square ' +
6727 '(size: ' + string.format(size) + ')');
6728 }
6729
6730 default:
6731 // multi dimensional array
6732 throw new RangeError('Matrix must be two dimensional ' +
6733 '(size: ' + string.format(size) + ')');
6734 }
6735 }
6736 });
6737
6738 det.toTex = '\\det\\left(${args[0]}\\right)';
6739
6740 return det;
6741
6742 /**
6743 * Calculate the determinant of a matrix
6744 * @param {Array[]} matrix A square, two dimensional matrix
6745 * @param {number} rows Number of rows of the matrix (zero-based)
6746 * @param {number} cols Number of columns of the matrix (zero-based)
6747 * @returns {number} det
6748 * @private
6749 */
6750 function _det (matrix, rows, cols) {
6751 if (rows == 1) {
6752 // this is a 1 x 1 matrix
6753 return object.clone(matrix[0][0]);
6754 }
6755 else if (rows == 2) {
6756 // this is a 2 x 2 matrix
6757 // the determinant of [a11,a12;a21,a22] is det = a11*a22-a21*a12
6758 return subtract(
6759 multiply(matrix[0][0], matrix[1][1]),
6760 multiply(matrix[1][0], matrix[0][1])
6761 );
6762 }
6763 else {
6764 // this is an n x n matrix
6765 var compute_mu = function (matrix) {
6766 var i, j;
6767
6768 // Compute the matrix with zero lower triangle, same upper triangle,
6769 // and diagonals given by the negated sum of the below diagonal
6770 // elements.
6771 var mu = new Array(matrix.length);
6772 var sum = 0;
6773 for (i = 1; i < matrix.length; i++) {
6774 sum = add(sum, matrix[i][i]);
6775 }
6776
6777 for (i = 0; i < matrix.length; i++) {
6778 mu[i] = new Array(matrix.length);
6779 mu[i][i] = unaryMinus(sum);
6780
6781 for (j = 0; j < i; j++) {
6782 mu[i][j] = 0; // TODO: make bignumber 0 in case of bignumber computation
6783 }
6784
6785 for (j = i + 1; j < matrix.length; j++) {
6786 mu[i][j] = matrix[i][j];
6787 }
6788
6789 if (i+1 < matrix.length) {
6790 sum = subtract(sum, matrix[i + 1][i + 1]);
6791 }
6792 }
6793
6794 return mu;
6795 };
6796
6797 var fa = matrix;
6798 for (var i = 0; i < rows - 1; i++) {
6799 fa = multiply(compute_mu(fa), matrix);
6800 }
6801
6802 if (rows % 2 == 0) {
6803 return unaryMinus(fa[0][0]);
6804 } else {
6805 return fa[0][0];
6806 }
6807 }
6808 }
6809 }
6810
6811 exports.name = 'det';
6812 exports.factory = factory;
6813
6814
6815
6816/***/ },
6817/* 44 */
6818/***/ function(module, exports, __webpack_require__) {
6819
6820 'use strict';
6821
6822 var extend = __webpack_require__(5).extend;
6823
6824 function factory (type, config, load, typed) {
6825
6826 var matrix = load(__webpack_require__(23));
6827 var addScalar = load(__webpack_require__(27));
6828 var latex = __webpack_require__(26);
6829
6830 var algorithm01 = load(__webpack_require__(30));
6831 var algorithm04 = load(__webpack_require__(45));
6832 var algorithm10 = load(__webpack_require__(34));
6833 var algorithm13 = load(__webpack_require__(35));
6834 var algorithm14 = load(__webpack_require__(39));
6835
6836 /**
6837 * Add two values, `x + y`.
6838 * For matrices, the function is evaluated element wise.
6839 *
6840 * Syntax:
6841 *
6842 * math.add(x, y)
6843 *
6844 * Examples:
6845 *
6846 * math.add(2, 3); // returns number 5
6847 *
6848 * var a = math.complex(2, 3);
6849 * var b = math.complex(-4, 1);
6850 * math.add(a, b); // returns Complex -2 + 4i
6851 *
6852 * math.add([1, 2, 3], 4); // returns Array [5, 6, 7]
6853 *
6854 * var c = math.unit('5 cm');
6855 * var d = math.unit('2.1 mm');
6856 * math.add(c, d); // returns Unit 52.1 mm
6857 *
6858 * math.add("2.3", "4"); // returns number 6.3
6859 *
6860 * See also:
6861 *
6862 * subtract
6863 *
6864 * @param {number | BigNumber | Fraction | Complex | Unit | Array | Matrix} x First value to add
6865 * @param {number | BigNumber | Fraction | Complex | Unit | Array | Matrix} y Second value to add
6866 * @return {number | BigNumber | Fraction | Complex | Unit | Array | Matrix} Sum of `x` and `y`
6867 */
6868 var add = typed('add', extend({
6869 // we extend the signatures of addScalar with signatures dealing with matrices
6870
6871 'Matrix, Matrix': function (x, y) {
6872 // result
6873 var c;
6874
6875 // process matrix storage
6876 switch (x.storage()) {
6877 case 'sparse':
6878 switch (y.storage()) {
6879 case 'sparse':
6880 // sparse + sparse
6881 c = algorithm04(x, y, addScalar);
6882 break;
6883 default:
6884 // sparse + dense
6885 c = algorithm01(y, x, addScalar, true);
6886 break;
6887 }
6888 break;
6889 default:
6890 switch (y.storage()) {
6891 case 'sparse':
6892 // dense + sparse
6893 c = algorithm01(x, y, addScalar, false);
6894 break;
6895 default:
6896 // dense + dense
6897 c = algorithm13(x, y, addScalar);
6898 break;
6899 }
6900 break;
6901 }
6902 return c;
6903 },
6904
6905 'Array, Array': function (x, y) {
6906 // use matrix implementation
6907 return add(matrix(x), matrix(y)).valueOf();
6908 },
6909
6910 'Array, Matrix': function (x, y) {
6911 // use matrix implementation
6912 return add(matrix(x), y);
6913 },
6914
6915 'Matrix, Array': function (x, y) {
6916 // use matrix implementation
6917 return add(x, matrix(y));
6918 },
6919
6920 'Matrix, any': function (x, y) {
6921 // result
6922 var c;
6923 // check storage format
6924 switch (x.storage()) {
6925 case 'sparse':
6926 c = algorithm10(x, y, addScalar, false);
6927 break;
6928 default:
6929 c = algorithm14(x, y, addScalar, false);
6930 break;
6931 }
6932 return c;
6933 },
6934
6935 'any, Matrix': function (x, y) {
6936 // result
6937 var c;
6938 // check storage format
6939 switch (y.storage()) {
6940 case 'sparse':
6941 c = algorithm10(y, x, addScalar, true);
6942 break;
6943 default:
6944 c = algorithm14(y, x, addScalar, true);
6945 break;
6946 }
6947 return c;
6948 },
6949
6950 'Array, any': function (x, y) {
6951 // use matrix implementation
6952 return algorithm14(matrix(x), y, addScalar, false).valueOf();
6953 },
6954
6955 'any, Array': function (x, y) {
6956 // use matrix implementation
6957 return algorithm14(matrix(y), x, addScalar, true).valueOf();
6958 }
6959 }, addScalar.signatures));
6960
6961 add.toTex = '\\left(${args[0]}' + latex.operators['add'] + '${args[1]}\\right)';
6962
6963 return add;
6964 }
6965
6966 exports.name = 'add';
6967 exports.factory = factory;
6968
6969
6970/***/ },
6971/* 45 */
6972/***/ function(module, exports, __webpack_require__) {
6973
6974 'use strict';
6975
6976 var DimensionError = __webpack_require__(22);
6977
6978 function factory (type, config, load, typed) {
6979
6980 var equalScalar = load(__webpack_require__(33));
6981
6982 var SparseMatrix = type.SparseMatrix;
6983
6984 /**
6985 * Iterates over SparseMatrix A and SparseMatrix B nonzero items and invokes the callback function f(Aij, Bij).
6986 * Callback function invoked MAX(NNZA, NNZB) times
6987 *
6988 *
6989 * ┌ f(Aij, Bij) ; A(i,j) !== 0 && B(i,j) !== 0
6990 * C(i,j) = ┤ A(i,j) ; A(i,j) !== 0
6991 * â”” B(i,j) ; B(i,j) !== 0
6992 *
6993 *
6994 * @param {Matrix} a The SparseMatrix instance (A)
6995 * @param {Matrix} b The SparseMatrix instance (B)
6996 * @param {Function} callback The f(Aij,Bij) operation to invoke
6997 *
6998 * @return {Matrix} SparseMatrix (C)
6999 *
7000 * see https://github.com/josdejong/mathjs/pull/346#issuecomment-97620294
7001 */
7002 var algorithm04 = function (a, b, callback) {
7003 // sparse matrix arrays
7004 var avalues = a._values;
7005 var aindex = a._index;
7006 var aptr = a._ptr;
7007 var asize = a._size;
7008 var adt = a._datatype;
7009 // sparse matrix arrays
7010 var bvalues = b._values;
7011 var bindex = b._index;
7012 var bptr = b._ptr;
7013 var bsize = b._size;
7014 var bdt = b._datatype;
7015
7016 // validate dimensions
7017 if (asize.length !== bsize.length)
7018 throw new DimensionError(asize.length, bsize.length);
7019
7020 // check rows & columns
7021 if (asize[0] !== bsize[0] || asize[1] !== bsize[1])
7022 throw new RangeError('Dimension mismatch. Matrix A (' + asize + ') must match Matrix B (' + bsize + ')');
7023
7024 // rows & columns
7025 var rows = asize[0];
7026 var columns = asize[1];
7027
7028 // datatype
7029 var dt;
7030 // equal signature to use
7031 var eq = equalScalar;
7032 // zero value
7033 var zero = 0;
7034 // callback signature to use
7035 var cf = callback;
7036
7037 // process data types
7038 if (typeof adt === 'string' && adt === bdt) {
7039 // datatype
7040 dt = adt;
7041 // find signature that matches (dt, dt)
7042 eq = typed.find(equalScalar, [dt, dt]);
7043 // convert 0 to the same datatype
7044 zero = typed.convert(0, dt);
7045 // callback
7046 cf = typed.find(callback, [dt, dt]);
7047 }
7048
7049 // result arrays
7050 var cvalues = avalues && bvalues ? [] : undefined;
7051 var cindex = [];
7052 var cptr = [];
7053 // matrix
7054 var c = new SparseMatrix({
7055 values: cvalues,
7056 index: cindex,
7057 ptr: cptr,
7058 size: [rows, columns],
7059 datatype: dt
7060 });
7061
7062 // workspace
7063 var xa = avalues && bvalues ? [] : undefined;
7064 var xb = avalues && bvalues ? [] : undefined;
7065 // marks indicating we have a value in x for a given column
7066 var wa = [];
7067 var wb = [];
7068
7069 // vars
7070 var i, j, k, k0, k1;
7071
7072 // loop columns
7073 for (j = 0; j < columns; j++) {
7074 // update cptr
7075 cptr[j] = cindex.length;
7076 // columns mark
7077 var mark = j + 1;
7078 // loop A(:,j)
7079 for (k0 = aptr[j], k1 = aptr[j + 1], k = k0; k < k1; k++) {
7080 // row
7081 i = aindex[k];
7082 // update c
7083 cindex.push(i);
7084 // update workspace
7085 wa[i] = mark;
7086 // check we need to process values
7087 if (xa)
7088 xa[i] = avalues[k];
7089 }
7090 // loop B(:,j)
7091 for (k0 = bptr[j], k1 = bptr[j + 1], k = k0; k < k1; k++) {
7092 // row
7093 i = bindex[k];
7094 // check row exists in A
7095 if (wa[i] === mark) {
7096 // update record in xa @ i
7097 if (xa) {
7098 // invoke callback
7099 var v = cf(xa[i], bvalues[k]);
7100 // check for zero
7101 if (!eq(v, zero)) {
7102 // update workspace
7103 xa[i] = v;
7104 }
7105 else {
7106 // remove mark (index will be removed later)
7107 wa[i] = null;
7108 }
7109 }
7110 }
7111 else {
7112 // update c
7113 cindex.push(i);
7114 // update workspace
7115 wb[i] = mark;
7116 // check we need to process values
7117 if (xb)
7118 xb[i] = bvalues[k];
7119 }
7120 }
7121 // check we need to process values (non pattern matrix)
7122 if (xa && xb) {
7123 // initialize first index in j
7124 k = cptr[j];
7125 // loop index in j
7126 while (k < cindex.length) {
7127 // row
7128 i = cindex[k];
7129 // check workspace has value @ i
7130 if (wa[i] === mark) {
7131 // push value (Aij != 0 || (Aij != 0 && Bij != 0))
7132 cvalues[k] = xa[i];
7133 // increment pointer
7134 k++;
7135 }
7136 else if (wb[i] === mark) {
7137 // push value (bij != 0)
7138 cvalues[k] = xb[i];
7139 // increment pointer
7140 k++;
7141 }
7142 else {
7143 // remove index @ k
7144 cindex.splice(k, 1);
7145 }
7146 }
7147 }
7148 }
7149 // update cptr
7150 cptr[columns] = cindex.length;
7151
7152 // return sparse matrix
7153 return c;
7154 };
7155
7156 return algorithm04;
7157 }
7158
7159 exports.name = 'algorithm04';
7160 exports.factory = factory;
7161
7162
7163/***/ },
7164/* 46 */
7165/***/ function(module, exports, __webpack_require__) {
7166
7167 'use strict';
7168
7169 var array = __webpack_require__(18);
7170 var clone = __webpack_require__(5).clone;
7171 var isInteger = __webpack_require__(8).isInteger;
7172
7173 function factory (type, config, load, typed) {
7174
7175 var matrix = load(__webpack_require__(23));
7176
7177 /**
7178 * Create a diagonal matrix or retrieve the diagonal of a matrix
7179 *
7180 * When `x` is a vector, a matrix with vector `x` on the diagonal will be returned.
7181 * When `x` is a two dimensional matrix, the matrixes `k`th diagonal will be returned as vector.
7182 * When k is positive, the values are placed on the super diagonal.
7183 * When k is negative, the values are placed on the sub diagonal.
7184 *
7185 * Syntax:
7186 *
7187 * math.diag(X)
7188 * math.diag(X, format)
7189 * math.diag(X, k)
7190 * math.diag(X, k, format)
7191 *
7192 * Examples:
7193 *
7194 * // create a diagonal matrix
7195 * math.diag([1, 2, 3]); // returns [[1, 0, 0], [0, 2, 0], [0, 0, 3]]
7196 * math.diag([1, 2, 3], 1); // returns [[0, 1, 0, 0], [0, 0, 2, 0], [0, 0, 0, 3]]
7197 * math.diag([1, 2, 3], -1); // returns [[0, 0, 0], [1, 0, 0], [0, 2, 0], [0, 0, 3]]
7198 *
7199 * // retrieve the diagonal from a matrix
7200 * var a = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
7201 * math.diag(a); // returns [1, 5, 9]
7202 *
7203 * See also:
7204 *
7205 * ones, zeros, eye
7206 *
7207 * @param {Matrix | Array} x A two dimensional matrix or a vector
7208 * @param {number | BigNumber} [k=0] The diagonal where the vector will be filled
7209 * in or retrieved.
7210 * @param {string} [format='dense'] The matrix storage format.
7211 *
7212 * @returns {Matrix | Array} Diagonal matrix from input vector, or diagonal from input matrix.
7213 */
7214 var diag = typed('diag', {
7215 // FIXME: simplify this huge amount of signatures as soon as typed-function supports optional arguments
7216
7217 'Array': function (x) {
7218 return _diag(x, 0, array.size(x), null);
7219 },
7220
7221 'Array, number': function (x, k) {
7222 return _diag(x, k, array.size(x), null);
7223 },
7224
7225 'Array, BigNumber': function (x, k) {
7226 return _diag(x, k.toNumber(), array.size(x), null);
7227 },
7228
7229 'Array, string': function (x, format) {
7230 return _diag(x, 0, array.size(x), format);
7231 },
7232
7233 'Array, number, string': function (x, k, format) {
7234 return _diag(x, k, array.size(x), format);
7235 },
7236
7237 'Array, BigNumber, string': function (x, k, format) {
7238 return _diag(x, k.toNumber(), array.size(x), format);
7239 },
7240
7241 'Matrix': function (x) {
7242 return _diag(x, 0, x.size(), x.storage());
7243 },
7244
7245 'Matrix, number': function (x, k) {
7246 return _diag(x, k, x.size(), x.storage());
7247 },
7248
7249 'Matrix, BigNumber': function (x, k) {
7250 return _diag(x, k.toNumber(), x.size(), x.storage());
7251 },
7252
7253 'Matrix, string': function (x, format) {
7254 return _diag(x, 0, x.size(), format);
7255 },
7256
7257 'Matrix, number, string': function (x, k, format) {
7258 return _diag(x, k, x.size(), format);
7259 },
7260
7261 'Matrix, BigNumber, string': function (x, k, format) {
7262 return _diag(x, k.toNumber(), x.size(), format);
7263 }
7264 });
7265
7266 diag.toTex = '\\mathrm{${name}}\\left(${args}\\right)';
7267
7268 return diag;
7269
7270 /**
7271 * Creeate diagonal matrix from a vector or vice versa
7272 * @param {Array | Matrix} x
7273 * @param {number} k
7274 * @param {string} format Storage format for matrix. If null,
7275 * an Array is returned
7276 * @returns {Array | Matrix}
7277 * @private
7278 */
7279 function _diag (x, k, size, format) {
7280 if (!isInteger(k)) {
7281 throw new TypeError ('Second parameter in function diag must be an integer');
7282 }
7283
7284 var kSuper = k > 0 ? k : 0;
7285 var kSub = k < 0 ? -k : 0;
7286
7287 // check dimensions
7288 switch (size.length) {
7289 case 1:
7290 return _createDiagonalMatrix(x, k, format, size[0], kSub, kSuper);
7291 case 2:
7292 return _getDiagonal(x, k, format, size, kSub, kSuper);
7293 }
7294 throw new RangeError('Matrix for function diag must be 2 dimensional');
7295 }
7296
7297 function _createDiagonalMatrix(x, k, format, l, kSub, kSuper) {
7298 // matrix size
7299 var ms = [l + kSub, l + kSuper];
7300 // get matrix constructor
7301 var F = type.Matrix.storage(format || 'dense');
7302 // create diagonal matrix
7303 var m = F.diagonal(ms, x, k);
7304 // check we need to return a matrix
7305 return format !== null ? m : m.valueOf();
7306 }
7307
7308 function _getDiagonal(x, k, format, s, kSub, kSuper) {
7309 // check x is a Matrix
7310 if (x && x.isMatrix === true) {
7311 // get diagonal matrix
7312 var dm = x.diagonal(k);
7313 // check we need to return a matrix
7314 if (format !== null) {
7315 // check we need to change matrix format
7316 if (format !== dm.storage())
7317 return matrix(dm, format);
7318 return dm;
7319 }
7320 return dm.valueOf();
7321 }
7322 // vector size
7323 var n = Math.min(s[0] - kSub, s[1] - kSuper);
7324 // diagonal values
7325 var vector = [];
7326 // loop diagonal
7327 for (var i = 0; i < n; i++) {
7328 vector[i] = clone(x[i + kSub][i + kSuper]);
7329 }
7330 // check we need to return a matrix
7331 return format !== null ? matrix(vector) : vector;
7332 }
7333 }
7334
7335 exports.name = 'diag';
7336 exports.factory = factory;
7337
7338
7339/***/ },
7340/* 47 */
7341/***/ function(module, exports, __webpack_require__) {
7342
7343 'use strict';
7344
7345 var size = __webpack_require__(18).size;
7346
7347 function factory (type, config, load, typed) {
7348 var add = load(__webpack_require__(44));
7349 var multiply = load(__webpack_require__(40));
7350
7351 /**
7352 * Calculate the dot product of two vectors. The dot product of
7353 * `A = [a1, a2, a3, ..., an]` and `B = [b1, b2, b3, ..., bn]` is defined as:
7354 *
7355 * dot(A, B) = a1 * b1 + a2 * b2 + a3 * b3 + ... + an * bn
7356 *
7357 * Syntax:
7358 *
7359 * math.dot(x, y)
7360 *
7361 * Examples:
7362 *
7363 * math.dot([2, 4, 1], [2, 2, 3]); // returns number 15
7364 * math.multiply([2, 4, 1], [2, 2, 3]); // returns number 15
7365 *
7366 * See also:
7367 *
7368 * multiply, cross
7369 *
7370 * @param {Array | Matrix} x First vector
7371 * @param {Array | Matrix} y Second vector
7372 * @return {number} Returns the dot product of `x` and `y`
7373 */
7374 var dot = typed('dot', {
7375 'Matrix, Matrix': function (x, y) {
7376 return _dot(x.toArray(), y.toArray());
7377 },
7378
7379 'Matrix, Array': function (x, y) {
7380 return _dot(x.toArray(), y);
7381 },
7382
7383 'Array, Matrix': function (x, y) {
7384 return _dot(x, y.toArray());
7385 },
7386
7387 'Array, Array': _dot
7388 });
7389
7390 dot.toTex = '\\left(${args[0]}\\cdot${args[1]}\\right)';
7391
7392 return dot;
7393
7394 /**
7395 * Calculate the dot product for two arrays
7396 * @param {Array} x First vector
7397 * @param {Array} y Second vector
7398 * @returns {number} Returns the dot product of x and y
7399 * @private
7400 */
7401 // TODO: double code with math.multiply
7402 function _dot(x, y) {
7403 var xSize= size(x);
7404 var ySize = size(y);
7405 var len = xSize[0];
7406
7407 if (xSize.length !== 1 || ySize.length !== 1) throw new RangeError('Vector expected'); // TODO: better error message
7408 if (xSize[0] != ySize[0]) throw new RangeError('Vectors must have equal length (' + xSize[0] + ' != ' + ySize[0] + ')');
7409 if (len == 0) throw new RangeError('Cannot calculate the dot product of empty vectors');
7410
7411 var prod = 0;
7412 for (var i = 0; i < len; i++) {
7413 prod = add(prod, multiply(x[i], y[i]));
7414 }
7415
7416 return prod;
7417 }
7418 }
7419
7420 exports.name = 'dot';
7421 exports.factory = factory;
7422
7423
7424/***/ },
7425/* 48 */
7426/***/ function(module, exports, __webpack_require__) {
7427
7428 'use strict';
7429
7430 var array = __webpack_require__(18);
7431 var isInteger = __webpack_require__(8).isInteger;
7432
7433 function factory (type, config, load, typed) {
7434
7435 var matrix = load(__webpack_require__(23));
7436
7437 /**
7438 * Create a 2-dimensional identity matrix with size m x n or n x n.
7439 * The matrix has ones on the diagonal and zeros elsewhere.
7440 *
7441 * Syntax:
7442 *
7443 * math.eye(n)
7444 * math.eye(n, format)
7445 * math.eye(m, n)
7446 * math.eye(m, n, format)
7447 * math.eye([m, n])
7448 * math.eye([m, n], format)
7449 *
7450 * Examples:
7451 *
7452 * math.eye(3); // returns [[1, 0, 0], [0, 1, 0], [0, 0, 1]]
7453 * math.eye(3, 2); // returns [[1, 0], [0, 1], [0, 0]]
7454 *
7455 * var A = [[1, 2, 3], [4, 5, 6]];
7456 * math.eye(math.size(b)); // returns [[1, 0, 0], [0, 1, 0]]
7457 *
7458 * See also:
7459 *
7460 * diag, ones, zeros, size, range
7461 *
7462 * @param {...number | Matrix | Array} size The size for the matrix
7463 * @param {string} [format] The Matrix storage format
7464 *
7465 * @return {Matrix | Array | number} A matrix with ones on the diagonal.
7466 */
7467 var eye = typed('eye', {
7468 '': function () {
7469 return (config.matrix === 'matrix') ? matrix([]) : [];
7470 },
7471
7472 'string': function (format) {
7473 return matrix(format);
7474 },
7475
7476 'number | BigNumber': function (rows) {
7477 return _eye(rows, rows, config.matrix === 'matrix' ? 'default' : undefined);
7478 },
7479
7480 'number | BigNumber, string': function (rows, format) {
7481 return _eye(rows, rows, format);
7482 },
7483
7484 'number | BigNumber, number | BigNumber': function (rows, cols) {
7485 return _eye(rows, cols, config.matrix === 'matrix' ? 'default' : undefined);
7486 },
7487
7488 'number | BigNumber, number | BigNumber, string': function (rows, cols, format) {
7489 return _eye(rows, cols, format);
7490 },
7491
7492 'Array': function (size) {
7493 return _eyeVector(size);
7494 },
7495
7496 'Array, string': function (size, format) {
7497 return _eyeVector(size, format);
7498 },
7499
7500 'Matrix': function (size) {
7501 return _eyeVector(size.valueOf(), size.storage());
7502 },
7503
7504 'Matrix, string': function (size, format) {
7505 return _eyeVector(size.valueOf(), format);
7506 }
7507 });
7508
7509 eye.toTex = '\\mathrm{${name}}\\left(${args}\\right)';
7510
7511 return eye;
7512
7513 function _eyeVector (size, format) {
7514 switch (size.length) {
7515 case 0: return format ? matrix(format) : [];
7516 case 1: return _eye(size[0], size[0], format);
7517 case 2: return _eye(size[0], size[1], format);
7518 default: throw new Error('Vector containing two values expected');
7519 }
7520 }
7521
7522 /**
7523 * Create an identity matrix
7524 * @param {number | BigNumber} rows
7525 * @param {number | BigNumber} cols
7526 * @param {string} [format]
7527 * @returns {Matrix}
7528 * @private
7529 */
7530 function _eye (rows, cols, format) {
7531 // BigNumber constructor with the right precision
7532 var Big = (rows && rows.isBigNumber === true)
7533 ? type.BigNumber
7534 : (cols && cols.isBigNumber === true)
7535 ? type.BigNumber
7536 : null;
7537
7538 if (rows && rows.isBigNumber === true) rows = rows.toNumber();
7539 if (cols && cols.isBigNumber === true) cols = cols.toNumber();
7540
7541 if (!isInteger(rows) || rows < 1) {
7542 throw new Error('Parameters in function eye must be positive integers');
7543 }
7544 if (!isInteger(cols) || cols < 1) {
7545 throw new Error('Parameters in function eye must be positive integers');
7546 }
7547
7548 var one = Big ? new type.BigNumber(1) : 1;
7549 var defaultValue = Big ? new Big(0) : 0;
7550 var size = [rows, cols];
7551
7552 // check we need to return a matrix
7553 if (format) {
7554 // get matrix storage constructor
7555 var F = type.Matrix.storage(format);
7556 // create diagonal matrix (use optimized implementation for storage format)
7557 return F.diagonal(size, one, 0, defaultValue);
7558 }
7559
7560 // create and resize array
7561 var res = array.resize([], size, defaultValue);
7562 // fill in ones on the diagonal
7563 var minimum = rows < cols ? rows : cols;
7564 // fill diagonal
7565 for (var d = 0; d < minimum; d++) {
7566 res[d][d] = one;
7567 }
7568 return res;
7569 }
7570 }
7571
7572 exports.name = 'eye';
7573 exports.factory = factory;
7574
7575
7576/***/ },
7577/* 49 */
7578/***/ function(module, exports, __webpack_require__) {
7579
7580 'use strict';
7581
7582 var clone = __webpack_require__(5).clone;
7583 var _flatten = __webpack_require__(18).flatten;
7584
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches