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
1=== modified file 'app/engine/math.js'
2--- app/engine/math.js 2015-08-30 23:09:36 +0000
3+++ app/engine/math.js 2015-10-19 22:40:49 +0000
4@@ -14,8 +14,8 @@
5 * It features real and complex numbers, units, matrices, a large set of
6 * mathematical functions, and a flexible expression parser.
7 *
8- * @version 2.2.0
9- * @date 2015-08-30
10+ * @version 2.4.0
11+ * @date 2015-10-09
12 *
13 * @license
14 * Copyright (C) 2013-2015 Jos de Jong <wjosdejong@gmail.com>
15@@ -133,10 +133,10 @@
16 /* 2 */
17 /***/ function(module, exports, __webpack_require__) {
18
19- var isFactory = __webpack_require__(5).isFactory;
20- var deepExtend = __webpack_require__(5).deepExtend;
21- var typedFactory = __webpack_require__(6);
22- var emitter = __webpack_require__(3);
23+ var isFactory = __webpack_require__(3).isFactory;
24+ var deepExtend = __webpack_require__(3).deepExtend;
25+ var typedFactory = __webpack_require__(4);
26+ var emitter = __webpack_require__(8);
27
28 var importFactory = __webpack_require__(10);
29 var configFactory = __webpack_require__(12);
30@@ -261,101 +261,6 @@
31
32 /***/ },
33 /* 3 */
34-/***/ function(module, exports, __webpack_require__) {
35-
36- var Emitter = __webpack_require__(4);
37-
38- /**
39- * Extend given object with emitter functions `on`, `off`, `once`, `emit`
40- * @param {Object} obj
41- * @return {Object} obj
42- */
43- exports.mixin = function (obj) {
44- // create event emitter
45- var emitter = new Emitter();
46-
47- // bind methods to obj (we don't want to expose the emitter.e Array...)
48- obj.on = emitter.on.bind(emitter);
49- obj.off = emitter.off.bind(emitter);
50- obj.once = emitter.once.bind(emitter);
51- obj.emit = emitter.emit.bind(emitter);
52-
53- return obj;
54- };
55-
56-
57-/***/ },
58-/* 4 */
59-/***/ function(module, exports) {
60-
61- function E () {
62- // Keep this empty so it's easier to inherit from
63- // (via https://github.com/lipsmack from https://github.com/scottcorgan/tiny-emitter/issues/3)
64- }
65-
66- E.prototype = {
67- on: function (name, callback, ctx) {
68- var e = this.e || (this.e = {});
69-
70- (e[name] || (e[name] = [])).push({
71- fn: callback,
72- ctx: ctx
73- });
74-
75- return this;
76- },
77-
78- once: function (name, callback, ctx) {
79- var self = this;
80- var fn = function () {
81- self.off(name, fn);
82- callback.apply(ctx, arguments);
83- };
84-
85- return this.on(name, fn, ctx);
86- },
87-
88- emit: function (name) {
89- var data = [].slice.call(arguments, 1);
90- var evtArr = ((this.e || (this.e = {}))[name] || []).slice();
91- var i = 0;
92- var len = evtArr.length;
93-
94- for (i; i < len; i++) {
95- evtArr[i].fn.apply(evtArr[i].ctx, data);
96- }
97-
98- return this;
99- },
100-
101- off: function (name, callback) {
102- var e = this.e || (this.e = {});
103- var evts = e[name];
104- var liveEvents = [];
105-
106- if (evts && callback) {
107- for (var i = 0, len = evts.length; i < len; i++) {
108- if (evts[i].fn !== callback) liveEvents.push(evts[i]);
109- }
110- }
111-
112- // Remove event from queue to prevent memory leak
113- // Suggested by https://github.com/lazd
114- // Ref: https://github.com/scottcorgan/tiny-emitter/commit/c6ebfaa9bc973b33d110a84a307742b7cf94c953#commitcomment-5024910
115-
116- (liveEvents.length)
117- ? e[name] = liveEvents
118- : delete e[name];
119-
120- return this;
121- }
122- };
123-
124- module.exports = E;
125-
126-
127-/***/ },
128-/* 5 */
129 /***/ function(module, exports) {
130
131 'use strict';
132@@ -602,11 +507,11 @@
133
134
135 /***/ },
136-/* 6 */
137+/* 4 */
138 /***/ function(module, exports, __webpack_require__) {
139
140- var typedFunction = __webpack_require__(7);
141- var digits = __webpack_require__(8).digits;
142+ var typedFunction = __webpack_require__(5);
143+ var digits = __webpack_require__(6).digits;
144
145 // returns a new instance of typed-function
146 var createTyped = function () {
147@@ -765,7 +670,7 @@
148
149
150 /***/ },
151-/* 7 */
152+/* 5 */
153 /***/ function(module, exports, __webpack_require__) {
154
155 var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/**
156@@ -2022,7 +1927,7 @@
157 */
158 function convert (value, type) {
159 var from = getTypeOf(value);
160-
161+
162 // check conversion is needed
163 if (type === from) {
164 return value;
165@@ -2076,12 +1981,12 @@
166
167
168 /***/ },
169-/* 8 */
170+/* 6 */
171 /***/ function(module, exports, __webpack_require__) {
172
173 'use strict';
174
175- var NumberFormatter = __webpack_require__(9);
176+ var NumberFormatter = __webpack_require__(7);
177
178 /**
179 * Test whether value is a number
180@@ -2343,7 +2248,7 @@
181
182
183 /***/ },
184-/* 9 */
185+/* 7 */
186 /***/ function(module, exports) {
187
188 'use strict';
189@@ -2556,15 +2461,110 @@
190
191
192 /***/ },
193+/* 8 */
194+/***/ function(module, exports, __webpack_require__) {
195+
196+ var Emitter = __webpack_require__(9);
197+
198+ /**
199+ * Extend given object with emitter functions `on`, `off`, `once`, `emit`
200+ * @param {Object} obj
201+ * @return {Object} obj
202+ */
203+ exports.mixin = function (obj) {
204+ // create event emitter
205+ var emitter = new Emitter();
206+
207+ // bind methods to obj (we don't want to expose the emitter.e Array...)
208+ obj.on = emitter.on.bind(emitter);
209+ obj.off = emitter.off.bind(emitter);
210+ obj.once = emitter.once.bind(emitter);
211+ obj.emit = emitter.emit.bind(emitter);
212+
213+ return obj;
214+ };
215+
216+
217+/***/ },
218+/* 9 */
219+/***/ function(module, exports) {
220+
221+ function E () {
222+ // Keep this empty so it's easier to inherit from
223+ // (via https://github.com/lipsmack from https://github.com/scottcorgan/tiny-emitter/issues/3)
224+ }
225+
226+ E.prototype = {
227+ on: function (name, callback, ctx) {
228+ var e = this.e || (this.e = {});
229+
230+ (e[name] || (e[name] = [])).push({
231+ fn: callback,
232+ ctx: ctx
233+ });
234+
235+ return this;
236+ },
237+
238+ once: function (name, callback, ctx) {
239+ var self = this;
240+ var fn = function () {
241+ self.off(name, fn);
242+ callback.apply(ctx, arguments);
243+ };
244+
245+ return this.on(name, fn, ctx);
246+ },
247+
248+ emit: function (name) {
249+ var data = [].slice.call(arguments, 1);
250+ var evtArr = ((this.e || (this.e = {}))[name] || []).slice();
251+ var i = 0;
252+ var len = evtArr.length;
253+
254+ for (i; i < len; i++) {
255+ evtArr[i].fn.apply(evtArr[i].ctx, data);
256+ }
257+
258+ return this;
259+ },
260+
261+ off: function (name, callback) {
262+ var e = this.e || (this.e = {});
263+ var evts = e[name];
264+ var liveEvents = [];
265+
266+ if (evts && callback) {
267+ for (var i = 0, len = evts.length; i < len; i++) {
268+ if (evts[i].fn !== callback) liveEvents.push(evts[i]);
269+ }
270+ }
271+
272+ // Remove event from queue to prevent memory leak
273+ // Suggested by https://github.com/lazd
274+ // Ref: https://github.com/scottcorgan/tiny-emitter/commit/c6ebfaa9bc973b33d110a84a307742b7cf94c953#commitcomment-5024910
275+
276+ (liveEvents.length)
277+ ? e[name] = liveEvents
278+ : delete e[name];
279+
280+ return this;
281+ }
282+ };
283+
284+ module.exports = E;
285+
286+
287+/***/ },
288 /* 10 */
289 /***/ function(module, exports, __webpack_require__) {
290
291 'use strict';
292
293- var lazy = __webpack_require__(5).lazy;
294- var isFactory = __webpack_require__(5).isFactory;
295- var traverse = __webpack_require__(5).traverse;
296- var extend = __webpack_require__(5).extend;
297+ var lazy = __webpack_require__(3).lazy;
298+ var isFactory = __webpack_require__(3).isFactory;
299+ var traverse = __webpack_require__(3).traverse;
300+ var extend = __webpack_require__(3).extend;
301 var ArgumentsError = __webpack_require__(11);
302
303 function factory (type, config, load, typed, math) {
304@@ -2863,7 +2863,7 @@
305
306 'use strict';
307
308- var object = __webpack_require__(5);
309+ var object = __webpack_require__(3);
310
311 function factory (type, config, load, typed, math) {
312 /**
313@@ -2915,12 +2915,12 @@
314 /***/ function(module, exports, __webpack_require__) {
315
316 module.exports = [
317- __webpack_require__(244), // data types (Matrix, Complex, Unit, ...)
318- __webpack_require__(281), // constants
319- __webpack_require__(283), // expression parsing
320- __webpack_require__(14), // functions
321- __webpack_require__(489), // serialization utility (math.json.reviver)
322- __webpack_require__(491) // errors
323+ __webpack_require__(14), // data types (Matrix, Complex, Unit, ...)
324+ __webpack_require__(76), // constants
325+ __webpack_require__(80), // expression parsing
326+ __webpack_require__(312), // functions
327+ __webpack_require__(495), // serialization utility (math.json.reviver)
328+ __webpack_require__(497) // errors
329 ];
330
331
332@@ -2929,20 +2929,16 @@
333 /***/ function(module, exports, __webpack_require__) {
334
335 module.exports = [
336- __webpack_require__(61),
337- __webpack_require__(91),
338- __webpack_require__(120),
339- __webpack_require__(136),
340- __webpack_require__(149),
341- __webpack_require__(154),
342- __webpack_require__(156),
343 __webpack_require__(15),
344- __webpack_require__(161),
345- __webpack_require__(173),
346- __webpack_require__(179),
347- __webpack_require__(191),
348- __webpack_require__(232),
349- __webpack_require__(234)
350+ __webpack_require__(20),
351+ __webpack_require__(21),
352+ __webpack_require__(26),
353+ __webpack_require__(31),
354+ __webpack_require__(37),
355+ __webpack_require__(69),
356+ __webpack_require__(70),
357+ __webpack_require__(72),
358+ __webpack_require__(73)
359 ];
360
361
362@@ -2951,23 +2947,11 @@
363 /***/ function(module, exports, __webpack_require__) {
364
365 module.exports = [
366+ // type
367 __webpack_require__(16),
368- __webpack_require__(24),
369- __webpack_require__(43),
370- __webpack_require__(46),
371- __webpack_require__(47),
372- __webpack_require__(48),
373- __webpack_require__(49),
374- __webpack_require__(50),
375- __webpack_require__(52),
376- __webpack_require__(53),
377- __webpack_require__(54),
378- __webpack_require__(55),
379- __webpack_require__(56),
380- __webpack_require__(57),
381- __webpack_require__(58),
382- __webpack_require__(59),
383- __webpack_require__(60)
384+
385+ // construction function
386+ __webpack_require__(18)
387 ];
388
389
390@@ -2975,28177 +2959,8 @@
391 /* 16 */
392 /***/ function(module, exports, __webpack_require__) {
393
394- 'use strict';
395-
396- var clone = __webpack_require__(5).clone;
397- var isInteger = __webpack_require__(8).isInteger;
398- var array = __webpack_require__(18);
399- var IndexError = __webpack_require__(17);
400- var DimensionError = __webpack_require__(22);
401-
402- function factory (type, config, load, typed) {
403- var matrix = load(__webpack_require__(23));
404-
405- /**
406- * Concatenate two or more matrices.
407- *
408- * Syntax:
409- *
410- * math.concat(A, B, C, ...)
411- * math.concat(A, B, C, ..., dim)
412- *
413- * Where:
414- *
415- * - `dim: number` is a zero-based dimension over which to concatenate the matrices.
416- * By default the last dimension of the matrices.
417- *
418- * Examples:
419- *
420- * var A = [[1, 2], [5, 6]];
421- * var B = [[3, 4], [7, 8]];
422- *
423- * math.concat(A, B); // returns [[1, 2, 3, 4], [5, 6, 7, 8]]
424- * math.concat(A, B, 0); // returns [[1, 2], [5, 6], [3, 4], [7, 8]]
425- * math.concat('hello', ' ', 'world'); // returns 'hello world'
426- *
427- * See also:
428- *
429- * size, squeeze, subset, transpose
430- *
431- * @param {... Array | Matrix} args Two or more matrices
432- * @return {Array | Matrix} Concatenated matrix
433- */
434- var concat = typed('concat', {
435- // TODO: change signature to '...Array | Matrix, dim?' when supported
436- '...Array | Matrix | number | BigNumber': function (args) {
437- var i;
438- var len = args.length;
439- var dim = -1; // zero-based dimension
440- var prevDim;
441- var asMatrix = false;
442- var matrices = []; // contains multi dimensional arrays
443-
444- for (i = 0; i < len; i++) {
445- var arg = args[i];
446-
447- // test whether we need to return a Matrix (if not we return an Array)
448- if (arg && arg.isMatrix === true) {
449- asMatrix = true;
450- }
451-
452- if (typeof arg === 'number' || (arg && arg.isBigNumber === true)) {
453- if (i !== len - 1) {
454- throw new Error('Dimension must be specified as last argument');
455- }
456-
457- // last argument contains the dimension on which to concatenate
458- prevDim = dim;
459- dim = arg.valueOf(); // change BigNumber to number
460-
461- if (!isInteger(dim)) {
462- throw new TypeError('Integer number expected for dimension');
463- }
464-
465- if (dim < 0) {
466- // TODO: would be more clear when throwing a DimensionError here
467- throw new IndexError(dim);
468- }
469- if (i > 0 && dim > prevDim) {
470- // TODO: would be more clear when throwing a DimensionError here
471- throw new IndexError(dim, prevDim + 1);
472- }
473- }
474- else {
475- // this is a matrix or array
476- var m = clone(arg).valueOf();
477- var size = array.size(m);
478- matrices[i] = m;
479- prevDim = dim;
480- dim = size.length - 1;
481-
482- // verify whether each of the matrices has the same number of dimensions
483- if (i > 0 && dim != prevDim) {
484- throw new DimensionError(prevDim + 1, dim + 1);
485- }
486- }
487- }
488-
489- if (matrices.length == 0) {
490- throw new SyntaxError('At least one matrix expected');
491- }
492-
493- var res = matrices.shift();
494- while (matrices.length) {
495- res = _concat(res, matrices.shift(), dim, 0);
496- }
497-
498- return asMatrix ? matrix(res) : res;
499- },
500-
501- '...string': function (args) {
502- return args.join('');
503- }
504- });
505-
506- concat.toTex = '\\mathrm{${name}}\\left(${args}\\right)';
507-
508- return concat;
509- }
510-
511- /**
512- * Recursively concatenate two matrices.
513- * The contents of the matrices is not cloned.
514- * @param {Array} a Multi dimensional array
515- * @param {Array} b Multi dimensional array
516- * @param {number} concatDim The dimension on which to concatenate (zero-based)
517- * @param {number} dim The current dim (zero-based)
518- * @return {Array} c The concatenated matrix
519- * @private
520- */
521- function _concat(a, b, concatDim, dim) {
522- if (dim < concatDim) {
523- // recurse into next dimension
524- if (a.length != b.length) {
525- throw new DimensionError(a.length, b.length);
526- }
527-
528- var c = [];
529- for (var i = 0; i < a.length; i++) {
530- c[i] = _concat(a[i], b[i], concatDim, dim + 1);
531- }
532- return c;
533- }
534- else {
535- // concatenate this dimension
536- return a.concat(b);
537- }
538- }
539-
540- exports.name = 'concat';
541- exports.factory = factory;
542-
543-
544-/***/ },
545-/* 17 */
546-/***/ function(module, exports) {
547-
548- 'use strict';
549-
550- /**
551- * Create a range error with the message:
552- * 'Index out of range (index < min)'
553- * 'Index out of range (index < max)'
554- *
555- * @param {number} index The actual index
556- * @param {number} [min=0] Minimum index (included)
557- * @param {number} [max] Maximum index (excluded)
558- * @extends RangeError
559- */
560- function IndexError(index, min, max) {
561- if (!(this instanceof IndexError)) {
562- throw new SyntaxError('Constructor must be called with the new operator');
563- }
564-
565- this.index = index;
566- if (arguments.length < 3) {
567- this.min = 0;
568- this.max = min;
569- }
570- else {
571- this.min = min;
572- this.max = max;
573- }
574-
575- if (this.min !== undefined && this.index < this.min) {
576- this.message = 'Index out of range (' + this.index + ' < ' + this.min + ')';
577- }
578- else if (this.max !== undefined && this.index >= this.max) {
579- this.message = 'Index out of range (' + this.index + ' > ' + (this.max - 1) + ')';
580- }
581- else {
582- this.message = 'Index out of range (' + this.index + ')';
583- }
584-
585- this.stack = (new Error()).stack;
586- }
587-
588- IndexError.prototype = new RangeError();
589- IndexError.prototype.constructor = RangeError;
590- IndexError.prototype.name = 'IndexError';
591- IndexError.prototype.isIndexError = true;
592-
593- module.exports = IndexError;
594-
595-
596-/***/ },
597-/* 18 */
598-/***/ function(module, exports, __webpack_require__) {
599-
600- 'use strict';
601-
602- var number = __webpack_require__(8);
603- var string = __webpack_require__(20);
604- var object = __webpack_require__(5);
605- var types = __webpack_require__(19);
606-
607- var DimensionError = __webpack_require__(22);
608- var IndexError = __webpack_require__(17);
609-
610- /**
611- * Calculate the size of a multi dimensional array.
612- * This function checks the size of the first entry, it does not validate
613- * whether all dimensions match. (use function `validate` for that)
614- * @param {Array} x
615- * @Return {Number[]} size
616- */
617- exports.size = function (x) {
618- var s = [];
619-
620- while (Array.isArray(x)) {
621- s.push(x.length);
622- x = x[0];
623- }
624-
625- return s;
626- };
627-
628- /**
629- * Recursively validate whether each element in a multi dimensional array
630- * has a size corresponding to the provided size array.
631- * @param {Array} array Array to be validated
632- * @param {number[]} size Array with the size of each dimension
633- * @param {number} dim Current dimension
634- * @throws DimensionError
635- * @private
636- */
637- function _validate(array, size, dim) {
638- var i;
639- var len = array.length;
640-
641- if (len != size[dim]) {
642- throw new DimensionError(len, size[dim]);
643- }
644-
645- if (dim < size.length - 1) {
646- // recursively validate each child array
647- var dimNext = dim + 1;
648- for (i = 0; i < len; i++) {
649- var child = array[i];
650- if (!Array.isArray(child)) {
651- throw new DimensionError(size.length - 1, size.length, '<');
652- }
653- _validate(array[i], size, dimNext);
654- }
655- }
656- else {
657- // last dimension. none of the childs may be an array
658- for (i = 0; i < len; i++) {
659- if (Array.isArray(array[i])) {
660- throw new DimensionError(size.length + 1, size.length, '>');
661- }
662- }
663- }
664- }
665-
666- /**
667- * Validate whether each element in a multi dimensional array has
668- * a size corresponding to the provided size array.
669- * @param {Array} array Array to be validated
670- * @param {number[]} size Array with the size of each dimension
671- * @throws DimensionError
672- */
673- exports.validate = function(array, size) {
674- var isScalar = (size.length == 0);
675- if (isScalar) {
676- // scalar
677- if (Array.isArray(array)) {
678- throw new DimensionError(array.length, 0);
679- }
680- }
681- else {
682- // array
683- _validate(array, size, 0);
684- }
685- };
686-
687- /**
688- * Test whether index is an integer number with index >= 0 and index < length
689- * @param {number} index Zero-based index
690- * @param {number} [length] Length of the array
691- */
692- exports.validateIndex = function(index, length) {
693- if (!number.isNumber(index) || !number.isInteger(index)) {
694- throw new TypeError('Index must be an integer (value: ' + index + ')');
695- }
696- if (index < 0) {
697- throw new IndexError(index);
698- }
699- if (length !== undefined && index >= length) {
700- throw new IndexError(index, length);
701- }
702- };
703-
704- // a constant used to specify an undefined defaultValue
705- exports.UNINITIALIZED = {};
706-
707- /**
708- * Resize a multi dimensional array. The resized array is returned.
709- * @param {Array} array Array to be resized
710- * @param {Array.<number>} size Array with the size of each dimension
711- * @param {*} [defaultValue=0] Value to be filled in in new entries,
712- * zero by default. To leave new entries undefined,
713- * specify array.UNINITIALIZED as defaultValue
714- * @return {Array} array The resized array
715- */
716- exports.resize = function(array, size, defaultValue) {
717- // TODO: add support for scalars, having size=[] ?
718-
719- // check the type of the arguments
720- if (!Array.isArray(array) || !Array.isArray(size)) {
721- throw new TypeError('Array expected');
722- }
723- if (size.length === 0) {
724- throw new Error('Resizing to scalar is not supported');
725- }
726-
727- // check whether size contains positive integers
728- size.forEach(function (value) {
729- if (!number.isNumber(value) || !number.isInteger(value) || value < 0) {
730- throw new TypeError('Invalid size, must contain positive integers ' +
731- '(size: ' + string.format(size) + ')');
732- }
733- });
734-
735- // recursively resize the array
736- var _defaultValue = (defaultValue !== undefined) ? defaultValue : 0;
737- _resize(array, size, 0, _defaultValue);
738-
739- return array;
740- };
741-
742- /**
743- * Recursively resize a multi dimensional array
744- * @param {Array} array Array to be resized
745- * @param {number[]} size Array with the size of each dimension
746- * @param {number} dim Current dimension
747- * @param {*} [defaultValue] Value to be filled in in new entries,
748- * undefined by default.
749- * @private
750- */
751- function _resize (array, size, dim, defaultValue) {
752- var i;
753- var elem;
754- var oldLen = array.length;
755- var newLen = size[dim];
756- var minLen = Math.min(oldLen, newLen);
757-
758- // apply new length
759- array.length = newLen;
760-
761- if (dim < size.length - 1) {
762- // non-last dimension
763- var dimNext = dim + 1;
764-
765- // resize existing child arrays
766- for (i = 0; i < minLen; i++) {
767- // resize child array
768- elem = array[i];
769- if (!Array.isArray(elem)) {
770- elem = [elem]; // add a dimension
771- array[i] = elem;
772- }
773- _resize(elem, size, dimNext, defaultValue);
774- }
775-
776- // create new child arrays
777- for (i = minLen; i < newLen; i++) {
778- // get child array
779- elem = [];
780- array[i] = elem;
781-
782- // resize new child array
783- _resize(elem, size, dimNext, defaultValue);
784- }
785- }
786- else {
787- // last dimension
788-
789- // remove dimensions of existing values
790- for (i = 0; i < minLen; i++) {
791- while (Array.isArray(array[i])) {
792- array[i] = array[i][0];
793- }
794- }
795-
796- if(defaultValue !== exports.UNINITIALIZED) {
797- // fill new elements with the default value
798- for (i = minLen; i < newLen; i++) {
799- array[i] = object.clone(defaultValue);
800- }
801- }
802- }
803- }
804-
805- /**
806- * Squeeze a multi dimensional array
807- * @param {Array} array
808- * @param {Array} [size]
809- * @returns {Array} returns the array itself
810- */
811- exports.squeeze = function(array, size) {
812- var s = size || exports.size(array);
813-
814- // squeeze outer dimensions
815- while (Array.isArray(array) && array.length === 1) {
816- array = array[0];
817- s.shift();
818- }
819-
820- // find the first dimension to be squeezed
821- var dims = s.length;
822- while (s[dims - 1] === 1) {
823- dims--;
824- }
825-
826- // squeeze inner dimensions
827- if (dims < s.length) {
828- array = _squeeze(array, dims, 0);
829- s.length = dims;
830- }
831-
832- return array;
833- };
834-
835- /**
836- * Recursively squeeze a multi dimensional array
837- * @param {Array} array
838- * @param {number} dims Required number of dimensions
839- * @param {number} dim Current dimension
840- * @returns {Array | *} Returns the squeezed array
841- * @private
842- */
843- function _squeeze (array, dims, dim) {
844- var i, ii;
845-
846- if (dim < dims) {
847- var next = dim + 1;
848- for (i = 0, ii = array.length; i < ii; i++) {
849- array[i] = _squeeze(array[i], dims, next);
850- }
851- }
852- else {
853- while (Array.isArray(array)) {
854- array = array[0];
855- }
856- }
857-
858- return array;
859- }
860-
861- /**
862- * Unsqueeze a multi dimensional array: add dimensions when missing
863- * @param {Array} array
864- * @param {number} dims Desired number of dimensions of the array
865- * @param {number} [outer] Number of outer dimensions to be added
866- * @param {Array} [size] Current size of array
867- * @returns {Array} returns the array itself
868- * @private
869- */
870- exports.unsqueeze = function(array, dims, outer, size) {
871- var s = size || exports.size(array);
872-
873- // unsqueeze outer dimensions
874- if (outer) {
875- for (var i = 0; i < outer; i++) {
876- array = [array];
877- s.unshift(1);
878- }
879- }
880-
881- // unsqueeze inner dimensions
882- array = _unsqueeze(array, dims, 0);
883- while (s.length < dims) {
884- s.push(1);
885- }
886-
887- return array;
888- };
889-
890- /**
891- * Recursively unsqueeze a multi dimensional array
892- * @param {Array} array
893- * @param {number} dims Required number of dimensions
894- * @param {number} dim Current dimension
895- * @returns {Array | *} Returns the squeezed array
896- * @private
897- */
898- function _unsqueeze (array, dims, dim) {
899- var i, ii;
900-
901- if (Array.isArray(array)) {
902- var next = dim + 1;
903- for (i = 0, ii = array.length; i < ii; i++) {
904- array[i] = _unsqueeze(array[i], dims, next);
905- }
906- }
907- else {
908- for (var d = dim; d < dims; d++) {
909- array = [array];
910- }
911- }
912-
913- return array;
914- }
915- /**
916- * Flatten a multi dimensional array, put all elements in a one dimensional
917- * array
918- * @param {Array} array A multi dimensional array
919- * @return {Array} The flattened array (1 dimensional)
920- */
921- exports.flatten = function(array) {
922- if (!Array.isArray(array)) {
923- //if not an array, return as is
924- return array;
925- }
926- var flat = [];
927-
928- array.forEach(function callback(value) {
929- if (Array.isArray(value)) {
930- value.forEach(callback); //traverse through sub-arrays recursively
931- }
932- else {
933- flat.push(value);
934- }
935- });
936-
937- return flat;
938- };
939-
940- /**
941- * Test whether an object is an array
942- * @param {*} value
943- * @return {boolean} isArray
944- */
945- exports.isArray = Array.isArray;
946-
947-
948-/***/ },
949-/* 19 */
950-/***/ function(module, exports) {
951-
952- 'use strict';
953-
954- /**
955- * Determine the type of a variable
956- *
957- * type(x)
958- *
959- * The following types are recognized:
960- *
961- * 'undefined'
962- * 'null'
963- * 'boolean'
964- * 'number'
965- * 'string'
966- * 'Array'
967- * 'Function'
968- * 'Date'
969- * 'RegExp'
970- * 'Object'
971- *
972- * @param {*} x
973- * @return {string} Returns the name of the type. Primitive types are lower case,
974- * non-primitive types are upper-camel-case.
975- * For example 'number', 'string', 'Array', 'Date'.
976- */
977- exports.type = function(x) {
978- var type = typeof x;
979-
980- if (type === 'object') {
981- if (x === null) return 'null';
982- if (x instanceof Boolean) return 'boolean';
983- if (x instanceof Number) return 'number';
984- if (x instanceof String) return 'string';
985- if (Array.isArray(x)) return 'Array';
986- if (x instanceof Date) return 'Date';
987- if (x instanceof RegExp) return 'RegExp';
988-
989- return 'Object';
990- }
991-
992- if (type === 'function') return 'Function';
993-
994- return type;
995- };
996-
997-
998-/***/ },
999-/* 20 */
1000-/***/ function(module, exports, __webpack_require__) {
1001-
1002- 'use strict';
1003-
1004- var formatNumber = __webpack_require__(8).format;
1005- var formatBigNumber = __webpack_require__(21).format;
1006-
1007- /**
1008- * Test whether value is a string
1009- * @param {*} value
1010- * @return {boolean} isString
1011- */
1012- exports.isString = function(value) {
1013- return typeof value === 'string';
1014- };
1015-
1016- /**
1017- * Check if a text ends with a certain string.
1018- * @param {string} text
1019- * @param {string} search
1020- */
1021- exports.endsWith = function(text, search) {
1022- var start = text.length - search.length;
1023- var end = text.length;
1024- return (text.substring(start, end) === search);
1025- };
1026-
1027- /**
1028- * Format a value of any type into a string.
1029- *
1030- * Usage:
1031- * math.format(value)
1032- * math.format(value, precision)
1033- *
1034- * If value is a function, the returned string is 'function' unless the function
1035- * has a property `description`, in that case this properties value is returned.
1036- *
1037- * Example usage:
1038- * math.format(2/7); // '0.2857142857142857'
1039- * math.format(math.pi, 3); // '3.14'
1040- * math.format(new Complex(2, 3)); // '2 + 3i'
1041- * math.format('hello'); // '"hello"'
1042- *
1043- * @param {*} value Value to be stringified
1044- * @param {Object | number | Function} [options] Formatting options. See
1045- * lib/utils/number:format for a
1046- * description of the available
1047- * options.
1048- * @return {string} str
1049- */
1050- exports.format = function(value, options) {
1051- if (typeof value === 'number') {
1052- return formatNumber(value, options);
1053- }
1054-
1055- if (value && value.isBigNumber === true) {
1056- return formatBigNumber(value, options);
1057- }
1058-
1059- if (value && value.isFraction === true) {
1060- if (!options || options.fraction !== 'decimal') {
1061- // output as ratio, like '1/3'
1062- return (value.s * value.n) + '/' + value.d;
1063- }
1064- else {
1065- // output as decimal, like '0.(3)'
1066- return value.toString();
1067- }
1068- }
1069-
1070- if (Array.isArray(value)) {
1071- return formatArray(value, options);
1072- }
1073-
1074- if (exports.isString(value)) {
1075- return '"' + value + '"';
1076- }
1077-
1078- if (typeof value === 'function') {
1079- return value.syntax ? value.syntax + '' : 'function';
1080- }
1081-
1082- if (typeof value === 'object') {
1083- if (typeof value.format === 'function') {
1084- return value.format(options);
1085- }
1086- else {
1087- return value.toString();
1088- }
1089- }
1090-
1091- return String(value);
1092- };
1093-
1094- /**
1095- * Recursively format an n-dimensional matrix
1096- * Example output: "[[1, 2], [3, 4]]"
1097- * @param {Array} array
1098- * @param {Object | number | Function} [options] Formatting options. See
1099- * lib/utils/number:format for a
1100- * description of the available
1101- * options.
1102- * @returns {string} str
1103- */
1104- function formatArray (array, options) {
1105- if (Array.isArray(array)) {
1106- var str = '[';
1107- var len = array.length;
1108- for (var i = 0; i < len; i++) {
1109- if (i != 0) {
1110- str += ', ';
1111- }
1112- str += formatArray(array[i], options);
1113- }
1114- str += ']';
1115- return str;
1116- }
1117- else {
1118- return exports.format(array, options);
1119- }
1120- }
1121-
1122-
1123-/***/ },
1124-/* 21 */
1125-/***/ function(module, exports) {
1126-
1127- /**
1128- * Convert a BigNumber to a formatted string representation.
1129- *
1130- * Syntax:
1131- *
1132- * format(value)
1133- * format(value, options)
1134- * format(value, precision)
1135- * format(value, fn)
1136- *
1137- * Where:
1138- *
1139- * {number} value The value to be formatted
1140- * {Object} options An object with formatting options. Available options:
1141- * {string} notation
1142- * Number notation. Choose from:
1143- * 'fixed' Always use regular number notation.
1144- * For example '123.40' and '14000000'
1145- * 'exponential' Always use exponential notation.
1146- * For example '1.234e+2' and '1.4e+7'
1147- * 'auto' (default) Regular number notation for numbers
1148- * having an absolute value between
1149- * `lower` and `upper` bounds, and uses
1150- * exponential notation elsewhere.
1151- * Lower bound is included, upper bound
1152- * is excluded.
1153- * For example '123.4' and '1.4e7'.
1154- * {number} precision A number between 0 and 16 to round
1155- * the digits of the number.
1156- * In case of notations 'exponential' and
1157- * 'auto', `precision` defines the total
1158- * number of significant digits returned
1159- * and is undefined by default.
1160- * In case of notation 'fixed',
1161- * `precision` defines the number of
1162- * significant digits after the decimal
1163- * point, and is 0 by default.
1164- * {Object} exponential An object containing two parameters,
1165- * {number} lower and {number} upper,
1166- * used by notation 'auto' to determine
1167- * when to return exponential notation.
1168- * Default values are `lower=1e-3` and
1169- * `upper=1e5`.
1170- * Only applicable for notation `auto`.
1171- * {Function} fn A custom formatting function. Can be used to override the
1172- * built-in notations. Function `fn` is called with `value` as
1173- * parameter and must return a string. Is useful for example to
1174- * format all values inside a matrix in a particular way.
1175- *
1176- * Examples:
1177- *
1178- * format(6.4); // '6.4'
1179- * format(1240000); // '1.24e6'
1180- * format(1/3); // '0.3333333333333333'
1181- * format(1/3, 3); // '0.333'
1182- * format(21385, 2); // '21000'
1183- * format(12.071, {notation: 'fixed'}); // '12'
1184- * format(2.3, {notation: 'fixed', precision: 2}); // '2.30'
1185- * format(52.8, {notation: 'exponential'}); // '5.28e+1'
1186- *
1187- * @param {BigNumber} value
1188- * @param {Object | Function | number} [options]
1189- * @return {string} str The formatted value
1190- */
1191- exports.format = function (value, options) {
1192- if (typeof options === 'function') {
1193- // handle format(value, fn)
1194- return options(value);
1195- }
1196-
1197- // handle special cases
1198- if (!value.isFinite()) {
1199- return value.isNaN() ? 'NaN' : (value.gt(0) ? 'Infinity' : '-Infinity');
1200- }
1201-
1202- // default values for options
1203- var notation = 'auto';
1204- var precision = undefined;
1205-
1206- if (options !== undefined) {
1207- // determine notation from options
1208- if (options.notation) {
1209- notation = options.notation;
1210- }
1211-
1212- // determine precision from options
1213- if (typeof options === 'number') {
1214- precision = options;
1215- }
1216- else if (options.precision) {
1217- precision = options.precision;
1218- }
1219- }
1220-
1221- // handle the various notations
1222- switch (notation) {
1223- case 'fixed':
1224- return exports.toFixed(value, precision);
1225-
1226- case 'exponential':
1227- return exports.toExponential(value, precision);
1228-
1229- case 'auto':
1230- // determine lower and upper bound for exponential notation.
1231- // TODO: implement support for upper and lower to be BigNumbers themselves
1232- var lower = 1e-3;
1233- var upper = 1e5;
1234- if (options && options.exponential) {
1235- if (options.exponential.lower !== undefined) {
1236- lower = options.exponential.lower;
1237- }
1238- if (options.exponential.upper !== undefined) {
1239- upper = options.exponential.upper;
1240- }
1241- }
1242-
1243- // adjust the configuration of the BigNumber constructor (yeah, this is quite tricky...)
1244- var oldConfig = {
1245- toExpNeg: value.constructor.toExpNeg,
1246- toExpPos: value.constructor.toExpPos
1247- };
1248-
1249- value.constructor.config({
1250- toExpNeg: Math.round(Math.log(lower) / Math.LN10),
1251- toExpPos: Math.round(Math.log(upper) / Math.LN10)
1252- });
1253-
1254- // handle special case zero
1255- if (value.isZero()) return '0';
1256-
1257- // determine whether or not to output exponential notation
1258- var str;
1259- var abs = value.abs();
1260- if (abs.gte(lower) && abs.lt(upper)) {
1261- // normal number notation
1262- str = value.toSignificantDigits(precision).toFixed();
1263- }
1264- else {
1265- // exponential notation
1266- str = exports.toExponential(value, precision);
1267- }
1268-
1269- // remove trailing zeros after the decimal point
1270- return str.replace(/((\.\d*?)(0+))($|e)/, function () {
1271- var digits = arguments[2];
1272- var e = arguments[4];
1273- return (digits !== '.') ? digits + e : e;
1274- });
1275-
1276- default:
1277- throw new Error('Unknown notation "' + notation + '". ' +
1278- 'Choose "auto", "exponential", or "fixed".');
1279- }
1280- };
1281-
1282- /**
1283- * Format a number in exponential notation. Like '1.23e+5', '2.3e+0', '3.500e-3'
1284- * @param {BigNumber} value
1285- * @param {number} [precision] Number of digits in formatted output.
1286- * If not provided, the maximum available digits
1287- * is used.
1288- * @returns {string} str
1289- */
1290- exports.toExponential = function (value, precision) {
1291- if (precision !== undefined) {
1292- return value.toExponential(precision - 1); // Note the offset of one
1293- }
1294- else {
1295- return value.toExponential();
1296- }
1297- };
1298-
1299- /**
1300- * Format a number with fixed notation.
1301- * @param {BigNumber} value
1302- * @param {number} [precision=0] Optional number of decimals after the
1303- * decimal point. Zero by default.
1304- */
1305- exports.toFixed = function (value, precision) {
1306- return value.toFixed(precision || 0);
1307- // Note: the (precision || 0) is needed as the toFixed of BigNumber has an
1308- // undefined default precision instead of 0.
1309- }
1310-
1311-
1312-/***/ },
1313-/* 22 */
1314-/***/ function(module, exports) {
1315-
1316- 'use strict';
1317-
1318- /**
1319- * Create a range error with the message:
1320- * 'Dimension mismatch (<actual size> != <expected size>)'
1321- * @param {number | number[]} actual The actual size
1322- * @param {number | number[]} expected The expected size
1323- * @param {string} [relation='!='] Optional relation between actual
1324- * and expected size: '!=', '<', etc.
1325- * @extends RangeError
1326- */
1327- function DimensionError(actual, expected, relation) {
1328- if (!(this instanceof DimensionError)) {
1329- throw new SyntaxError('Constructor must be called with the new operator');
1330- }
1331-
1332- this.actual = actual;
1333- this.expected = expected;
1334- this.relation = relation;
1335-
1336- this.message = 'Dimension mismatch (' +
1337- (Array.isArray(actual) ? ('[' + actual.join(', ') + ']') : actual) +
1338- ' ' + (this.relation || '!=') + ' ' +
1339- (Array.isArray(expected) ? ('[' + expected.join(', ') + ']') : expected) +
1340- ')';
1341-
1342- this.stack = (new Error()).stack;
1343- }
1344-
1345- DimensionError.prototype = new RangeError();
1346- DimensionError.prototype.constructor = RangeError;
1347- DimensionError.prototype.name = 'DimensionError';
1348- DimensionError.prototype.isDimensionError = true;
1349-
1350- module.exports = DimensionError;
1351-
1352-
1353-/***/ },
1354-/* 23 */
1355-/***/ function(module, exports) {
1356-
1357- 'use strict';
1358-
1359- function factory (type, config, load, typed) {
1360- /**
1361- * Create a Matrix. The function creates a new `math.type.Matrix` object from
1362- * an `Array`. A Matrix has utility functions to manipulate the data in the
1363- * matrix, like getting the size and getting or setting values in the matrix.
1364- * Supported storage formats are 'dense' and 'sparse'.
1365- *
1366- * Syntax:
1367- *
1368- * math.matrix() // creates an empty matrix using default storage format (dense).
1369- * math.matrix(data) // creates a matrix with initial data using default storage format (dense).
1370- * math.matrix('dense') // creates an empty matrix using the given storage format.
1371- * math.matrix(data, 'dense') // creates a matrix with initial data using the given storage format.
1372- * math.matrix(data, 'sparse') // creates a sparse matrix with initial data.
1373- * math.matrix(data, 'sparse', 'number') // creates a sparse matrix with initial data, number data type.
1374- *
1375- * Examples:
1376- *
1377- * var m = math.matrix([[1, 2], [3, 4]]);
1378- * m.size(); // Array [2, 2]
1379- * m.resize([3, 2], 5);
1380- * m.valueOf(); // Array [[1, 2], [3, 4], [5, 5]]
1381- * m.get([1, 0]) // number 3
1382- *
1383- * See also:
1384- *
1385- * bignumber, boolean, complex, index, number, string, unit, sparse
1386- *
1387- * @param {Array | Matrix} [data] A multi dimensional array
1388- * @param {string} [format] The Matrix storage format
1389- *
1390- * @return {Matrix} The created matrix
1391- */
1392- var matrix = typed('matrix', {
1393- '': function () {
1394- return _create([]);
1395- },
1396-
1397- 'string': function (format) {
1398- return _create([], format);
1399- },
1400-
1401- 'string, string': function (format, datatype) {
1402- return _create([], format, datatype);
1403- },
1404-
1405- 'Array': function (data) {
1406- return _create(data);
1407- },
1408-
1409- 'Matrix': function (data) {
1410- return _create(data, data.storage());
1411- },
1412-
1413- 'Array | Matrix, string': _create,
1414-
1415- 'Array | Matrix, string, string': _create
1416- });
1417-
1418- matrix.toTex = {
1419- 0: '\\begin{bmatrix}\\end{bmatrix}',
1420- 1: '\\left(${args[0]}\\right)',
1421- 2: '\\left(${args[0]}\\right)'
1422- };
1423-
1424- return matrix;
1425-
1426- /**
1427- * Create a new Matrix with given storage format
1428- * @param {Array} data
1429- * @param {string} [format]
1430- * @param {string} [datatype]
1431- * @returns {Matrix} Returns a new Matrix
1432- * @private
1433- */
1434- function _create(data, format, datatype) {
1435- // get storage format constructor
1436- var M = type.Matrix.storage(format || 'default');
1437-
1438- // create instance
1439- return new M(data, datatype);
1440- }
1441- }
1442-
1443- exports.name = 'matrix';
1444- exports.factory = factory;
1445-
1446-
1447-/***/ },
1448-/* 24 */
1449-/***/ function(module, exports, __webpack_require__) {
1450-
1451- 'use strict';
1452-
1453- var size = __webpack_require__(18).size;
1454-
1455- function factory (type, config, load, typed) {
1456- var matrix = load(__webpack_require__(23));
1457- var subtract = load(__webpack_require__(25));
1458- var multiply = load(__webpack_require__(40));
1459-
1460- /**
1461- * Calculate the cross product for two vectors in three dimensional space.
1462- * The cross product of `A = [a1, a2, a3]` and `B =[b1, b2, b3]` is defined
1463- * as:
1464- *
1465- * cross(A, B) = [
1466- * a2 * b3 - a3 * b2,
1467- * a3 * b1 - a1 * b3,
1468- * a1 * b2 - a2 * b1
1469- * ]
1470- *
1471- * Syntax:
1472- *
1473- * math.cross(x, y)
1474- *
1475- * Examples:
1476- *
1477- * math.cross([1, 1, 0], [0, 1, 1]); // Returns [1, -1, 1]
1478- * math.cross([3, -3, 1], [4, 9, 2]); // Returns [-15, -2, 39]
1479- * math.cross([2, 3, 4], [5, 6, 7]); // Returns [-3, 6, -3]
1480- *
1481- * See also:
1482- *
1483- * dot, multiply
1484- *
1485- * @param {Array | Matrix} x First vector
1486- * @param {Array | Matrix} y Second vector
1487- * @return {Array | Matrix} Returns the cross product of `x` and `y`
1488- */
1489- var cross = typed('cross', {
1490- 'Matrix, Matrix': function (x, y) {
1491- return matrix(_cross(x.toArray(), y.toArray()));
1492- },
1493-
1494- 'Matrix, Array': function (x, y) {
1495- return matrix(_cross(x.toArray(), y));
1496- },
1497-
1498- 'Array, Matrix': function (x, y) {
1499- return matrix(_cross(x, y.toArray()));
1500- },
1501-
1502- 'Array, Array': _cross
1503- });
1504-
1505- cross.toTex = '\\left(${args[0]}\\right)\\times\\left(${args[1]}\\right)';
1506-
1507- return cross;
1508-
1509- /**
1510- * Calculate the cross product for two arrays
1511- * @param {Array} x First vector
1512- * @param {Array} y Second vector
1513- * @returns {Array} Returns the cross product of x and y
1514- * @private
1515- */
1516- function _cross(x, y) {
1517- var xSize= size(x);
1518- var ySize = size(y);
1519-
1520- if (xSize.length != 1 || ySize.length != 1 || xSize[0] != 3 || ySize[0] != 3) {
1521- throw new RangeError('Vectors with length 3 expected ' +
1522- '(Size A = [' + xSize.join(', ') + '], B = [' + ySize.join(', ') + '])');
1523- }
1524-
1525- return [
1526- subtract(multiply(x[1], y[2]), multiply(x[2], y[1])),
1527- subtract(multiply(x[2], y[0]), multiply(x[0], y[2])),
1528- subtract(multiply(x[0], y[1]), multiply(x[1], y[0]))
1529- ];
1530- }
1531- }
1532-
1533- exports.name = 'cross';
1534- exports.factory = factory;
1535-
1536-
1537-/***/ },
1538-/* 25 */
1539-/***/ function(module, exports, __webpack_require__) {
1540-
1541- 'use strict';
1542-
1543- var DimensionError = __webpack_require__(22);
1544-
1545- function factory (type, config, load, typed) {
1546- var latex = __webpack_require__(26);
1547-
1548- var matrix = load(__webpack_require__(23));
1549- var addScalar = load(__webpack_require__(27));
1550- var unaryMinus = load(__webpack_require__(28));
1551-
1552- var algorithm01 = load(__webpack_require__(30));
1553- var algorithm03 = load(__webpack_require__(31));
1554- var algorithm05 = load(__webpack_require__(32));
1555- var algorithm10 = load(__webpack_require__(34));
1556- var algorithm13 = load(__webpack_require__(35));
1557- var algorithm14 = load(__webpack_require__(39));
1558-
1559- /**
1560- * Subtract two values, `x - y`.
1561- * For matrices, the function is evaluated element wise.
1562- *
1563- * Syntax:
1564- *
1565- * math.subtract(x, y)
1566- *
1567- * Examples:
1568- *
1569- * math.subtract(5.3, 2); // returns number 3.3
1570- *
1571- * var a = math.complex(2, 3);
1572- * var b = math.complex(4, 1);
1573- * math.subtract(a, b); // returns Complex -2 + 2i
1574- *
1575- * math.subtract([5, 7, 4], 4); // returns Array [1, 3, 0]
1576- *
1577- * var c = math.unit('2.1 km');
1578- * var d = math.unit('500m');
1579- * math.subtract(c, d); // returns Unit 1.6 km
1580- *
1581- * See also:
1582- *
1583- * add
1584- *
1585- * @param {number | BigNumber | Fraction | Complex | Unit | Array | Matrix} x
1586- * Initial value
1587- * @param {number | BigNumber | Fraction | Complex | Unit | Array | Matrix} y
1588- * Value to subtract from `x`
1589- * @return {number | BigNumber | Fraction | Complex | Unit | Array | Matrix}
1590- * Subtraction of `x` and `y`
1591- */
1592- var subtract = typed('subtract', {
1593-
1594- 'number, number': function (x, y) {
1595- return x - y;
1596- },
1597-
1598- 'Complex, Complex': function (x, y) {
1599- return new type.Complex (
1600- x.re - y.re,
1601- x.im - y.im
1602- );
1603- },
1604-
1605- 'BigNumber, BigNumber': function (x, y) {
1606- return x.minus(y);
1607- },
1608-
1609- 'Fraction, Fraction': function (x, y) {
1610- return x.sub(y);
1611- },
1612-
1613- 'Unit, Unit': function (x, y) {
1614- if (x.value == null) {
1615- throw new Error('Parameter x contains a unit with undefined value');
1616- }
1617-
1618- if (y.value == null) {
1619- throw new Error('Parameter y contains a unit with undefined value');
1620- }
1621-
1622- if (!x.equalBase(y)) {
1623- throw new Error('Units do not match');
1624- }
1625-
1626- var res = x.clone();
1627- res.value -= y.value;
1628- res.fixPrefix = false;
1629-
1630- return res;
1631- },
1632-
1633- 'Matrix, Matrix': function (x, y) {
1634- // matrix sizes
1635- var xsize = x.size();
1636- var ysize = y.size();
1637-
1638- // check dimensions
1639- if (xsize.length !== ysize.length)
1640- throw new DimensionError(xsize.length, ysize.length);
1641-
1642- // result
1643- var c;
1644-
1645- // process matrix storage
1646- switch (x.storage()) {
1647- case 'sparse':
1648- switch (y.storage()) {
1649- case 'sparse':
1650- // sparse - sparse
1651- c = algorithm05(x, y, subtract);
1652- break;
1653- default:
1654- // sparse - dense
1655- c = algorithm03(y, x, subtract, true);
1656- break;
1657- }
1658- break;
1659- default:
1660- switch (y.storage()) {
1661- case 'sparse':
1662- // dense - sparse
1663- c = algorithm01(x, y, subtract, false);
1664- break;
1665- default:
1666- // dense - dense
1667- c = algorithm13(x, y, subtract);
1668- break;
1669- }
1670- break;
1671- }
1672- return c;
1673- },
1674-
1675- 'Array, Array': function (x, y) {
1676- // use matrix implementation
1677- return subtract(matrix(x), matrix(y)).valueOf();
1678- },
1679-
1680- 'Array, Matrix': function (x, y) {
1681- // use matrix implementation
1682- return subtract(matrix(x), y);
1683- },
1684-
1685- 'Matrix, Array': function (x, y) {
1686- // use matrix implementation
1687- return subtract(x, matrix(y));
1688- },
1689-
1690- 'Matrix, any': function (x, y) {
1691- // result
1692- var c;
1693- // check storage format
1694- switch (x.storage()) {
1695- case 'sparse':
1696- // algorithm 7 is faster than 9 since it calls f() for nonzero items only!
1697- c = algorithm10(x, unaryMinus(y), addScalar);
1698- break;
1699- default:
1700- c = algorithm14(x, y, subtract);
1701- break;
1702- }
1703- return c;
1704- },
1705-
1706- 'any, Matrix': function (x, y) {
1707- // result
1708- var c;
1709- // check storage format
1710- switch (y.storage()) {
1711- case 'sparse':
1712- c = algorithm10(y, x, subtract, true);
1713- break;
1714- default:
1715- c = algorithm14(y, x, subtract, true);
1716- break;
1717- }
1718- return c;
1719- },
1720-
1721- 'Array, any': function (x, y) {
1722- // use matrix implementation
1723- return algorithm14(matrix(x), y, subtract, false).valueOf();
1724- },
1725-
1726- 'any, Array': function (x, y) {
1727- // use matrix implementation
1728- return algorithm14(matrix(y), x, subtract, true).valueOf();
1729- }
1730- });
1731-
1732- subtract.toTex = '\\left(${args[0]}' + latex.operators['subtract'] + '${args[1]}\\right)';
1733-
1734- return subtract;
1735- }
1736-
1737- exports.name = 'subtract';
1738- exports.factory = factory;
1739-
1740-
1741-/***/ },
1742-/* 26 */
1743-/***/ function(module, exports) {
1744-
1745- 'use strict';
1746-
1747- exports.symbols = {
1748- // GREEK LETTERS
1749- Alpha: 'A', alpha: '\\alpha',
1750- Beta: 'B', beta: '\\beta',
1751- Gamma: '\\Gamma', gamma: '\\gamma',
1752- Delta: '\\Delta', delta: '\\delta',
1753- Epsilon: 'E', epsilon: '\\epsilon', varepsilon: '\\varepsilon',
1754- Zeta: 'Z', zeta: '\\zeta',
1755- Eta: 'H', eta: '\\eta',
1756- Theta: '\\Theta', theta: '\\theta', vartheta: '\\vartheta',
1757- Iota: 'I', iota: '\\iota',
1758- Kappa: 'K', kappa: '\\kappa', varkappa: '\\varkappa',
1759- Lambda: '\\Lambda', lambda: '\\lambda',
1760- Mu: 'M', mu: '\\mu',
1761- Nu: 'N', nu: '\\nu',
1762- Xi: '\\Xi', xi: '\\xi',
1763- Omicron: 'O', omicron: 'o',
1764- Pi: '\\Pi', pi: '\\pi', varpi: '\\varpi',
1765- Rho: 'P', rho: '\\rho', varrho: '\\varrho',
1766- Sigma: '\\Sigma', sigma: '\\sigma', varsigma: '\\varsigma',
1767- Tau: 'T', tau: '\\tau',
1768- Upsilon: '\\Upsilon', upsilon: '\\upsilon',
1769- Phi: '\\Phi', phi: '\\phi', varphi: '\\varphi',
1770- Chi: 'X', chi: '\\chi',
1771- Psi: '\\Psi', psi: '\\psi',
1772- Omega: '\\Omega', omega: '\\omega',
1773- //logic
1774- 'true': '\\mathrm{True}',
1775- 'false': '\\mathrm{False}',
1776- //other
1777- i: 'i', //TODO use \i ??
1778- inf: '\\infty',
1779- Inf: '\\infty',
1780- infinity: '\\infty',
1781- Infinity: '\\infty',
1782- oo: '\\infty',
1783- lim: '\\lim',
1784- 'undefined': '\\mathbf{?}'
1785- };
1786-
1787- exports.operators = {
1788- 'transpose': '^\\top',
1789- 'factorial': '!',
1790- 'pow': '^',
1791- 'dotPow': '.^\\wedge', //TODO find ideal solution
1792- 'unaryPlus': '+',
1793- 'unaryMinus': '-',
1794- 'bitNot': '~', //TODO find ideal solution
1795- 'not': '\\neg',
1796- 'multiply': '\\cdot',
1797- 'divide': '\\frac', //TODO how to handle that properly?
1798- 'dotMultiply': '.\\cdot', //TODO find ideal solution
1799- 'dotDivide': '.:', //TODO find ideal solution
1800- 'mod': '\\mod',
1801- 'add': '+',
1802- 'subtract': '-',
1803- 'to': '\\rightarrow',
1804- 'leftShift': '<<',
1805- 'rightArithShift': '>>',
1806- 'rightLogShift': '>>>',
1807- 'equal': '=',
1808- 'unequal': '\\neq',
1809- 'smaller': '<',
1810- 'larger': '>',
1811- 'smallerEq': '\\leq',
1812- 'largerEq': '\\geq',
1813- 'bitAnd': '\\&',
1814- 'bitXor': '\\underline{|}',
1815- 'bitOr': '|',
1816- 'and': '\\wedge',
1817- 'xor': '\\veebar',
1818- 'or': '\\vee'
1819- };
1820-
1821- exports.defaultTemplate = '\\mathrm{${name}}\\left(${args}\\right)';
1822-
1823- var units = {
1824- deg: '^\\circ'
1825- };
1826-
1827- //@param {string} name
1828- //@param {boolean} isUnit
1829- exports.toSymbol = function (name, isUnit) {
1830- isUnit = typeof isUnit === 'undefined' ? false : isUnit;
1831- if (isUnit) {
1832- if (units.hasOwnProperty(name)) {
1833- return units[name];
1834- }
1835- return '\\mathrm{' + name + '}';
1836- }
1837-
1838- if (exports.symbols.hasOwnProperty(name)) {
1839- return exports.symbols[name];
1840- }
1841- else if (name.indexOf('_') !== -1) {
1842- //symbol with index (eg. alpha_1)
1843- var index = name.indexOf('_');
1844- return exports.toSymbol(name.substring(0, index)) + '_{'
1845- + exports.toSymbol(name.substring(index + 1)) + '}';
1846- }
1847- return name;
1848- };
1849-
1850-
1851-/***/ },
1852-/* 27 */
1853-/***/ function(module, exports) {
1854-
1855- 'use strict';
1856-
1857- function factory(type, config, load, typed) {
1858-
1859- /**
1860- * Add two scalar values, `x + y`.
1861- * This function is meant for internal use: it is used by the public function
1862- * `add`
1863- *
1864- * This function does not support collections (Array or Matrix), and does
1865- * not validate the number of of inputs.
1866- *
1867- * @param {number | BigNumber | Fraction | Complex | Unit} x First value to add
1868- * @param {number | BigNumber | Fraction | Complex} y Second value to add
1869- * @return {number | BigNumber | Fraction | Complex | Unit} Sum of `x` and `y`
1870- * @private
1871- */
1872- return typed('add', {
1873-
1874- 'number, number': function (x, y) {
1875- return x + y;
1876- },
1877-
1878- 'Complex, Complex': function (x, y) {
1879- return new type.Complex(
1880- x.re + y.re,
1881- x.im + y.im
1882- );
1883- },
1884-
1885- 'BigNumber, BigNumber': function (x, y) {
1886- return x.plus(y);
1887- },
1888-
1889- 'Fraction, Fraction': function (x, y) {
1890- return x.add(y);
1891- },
1892-
1893- 'Unit, Unit': function (x, y) {
1894- if (x.value == null) throw new Error('Parameter x contains a unit with undefined value');
1895- if (y.value == null) throw new Error('Parameter y contains a unit with undefined value');
1896- if (!x.equalBase(y)) throw new Error('Units do not match');
1897-
1898- var res = x.clone();
1899- res.value += y.value;
1900- res.fixPrefix = false;
1901- return res;
1902- }
1903- });
1904- }
1905-
1906- exports.factory = factory;
1907-
1908-
1909-/***/ },
1910-/* 28 */
1911-/***/ function(module, exports, __webpack_require__) {
1912-
1913- 'use strict';
1914-
1915- var deepMap = __webpack_require__(29);
1916-
1917- function factory (type, config, load, typed) {
1918- var latex = __webpack_require__(26);
1919-
1920- /**
1921- * Inverse the sign of a value, apply a unary minus operation.
1922- *
1923- * For matrices, the function is evaluated element wise. Boolean values and
1924- * strings will be converted to a number. For complex numbers, both real and
1925- * complex value are inverted.
1926- *
1927- * Syntax:
1928- *
1929- * math.unaryMinus(x)
1930- *
1931- * Examples:
1932- *
1933- * math.unaryMinus(3.5); // returns -3.5
1934- * math.unaryMinus(-4.2); // returns 4.2
1935- *
1936- * See also:
1937- *
1938- * add, subtract, unaryPlus
1939- *
1940- * @param {number | BigNumber | Fraction | Complex | Unit | Array | Matrix} x Number to be inverted.
1941- * @return {number | BigNumber | Fraction | Complex | Unit | Array | Matrix} Returns the value with inverted sign.
1942- */
1943- var unaryMinus = typed('unaryMinus', {
1944- 'number': function (x) {
1945- return -x;
1946- },
1947-
1948- 'Complex': function (x) {
1949- return new type.Complex(-x.re, -x.im);
1950- },
1951-
1952- 'BigNumber': function (x) {
1953- return x.neg();
1954- },
1955-
1956- 'Fraction': function (x) {
1957- var tmp = x.clone();
1958- tmp.s = -tmp.s;
1959- return tmp;
1960- },
1961-
1962- 'Unit': function (x) {
1963- var res = x.clone();
1964- res.value = -x.value;
1965- return res;
1966- },
1967-
1968- 'Array | Matrix': function (x) {
1969- // deep map collection, skip zeros since unaryMinus(0) = 0
1970- return deepMap(x, unaryMinus, true);
1971- }
1972-
1973- // TODO: add support for string
1974- });
1975-
1976- unaryMinus.toTex = latex.operators['unaryMinus'] + '\\left(${args[0]}\\right)';
1977-
1978- return unaryMinus;
1979- }
1980-
1981- exports.name = 'unaryMinus';
1982- exports.factory = factory;
1983-
1984-
1985-/***/ },
1986-/* 29 */
1987-/***/ function(module, exports) {
1988-
1989- 'use strict';
1990-
1991- /**
1992- * Execute the callback function element wise for each element in array and any
1993- * nested array
1994- * Returns an array with the results
1995- * @param {Array | Matrix} array
1996- * @param {Function} callback The callback is called with two parameters:
1997- * value1 and value2, which contain the current
1998- * element of both arrays.
1999- * @param {boolean} [skipZeros] Invoke callback function for non-zero values only.
2000- *
2001- * @return {Array | Matrix} res
2002- */
2003- module.exports = function deepMap(array, callback, skipZeros) {
2004- if (array && (typeof array.map === 'function')) {
2005- // TODO: replace array.map with a for loop to improve performance
2006- return array.map(function (x) {
2007- return deepMap(x, callback, skipZeros);
2008- });
2009- }
2010- else {
2011- return callback(array);
2012- }
2013- };
2014-
2015-
2016-/***/ },
2017-/* 30 */
2018-/***/ function(module, exports, __webpack_require__) {
2019-
2020- 'use strict';
2021-
2022- var DimensionError = __webpack_require__(22);
2023-
2024- function factory (type, config, load, typed) {
2025-
2026- var DenseMatrix = type.DenseMatrix;
2027-
2028- /**
2029- * Iterates over SparseMatrix nonzero items and invokes the callback function f(Dij, Sij).
2030- * Callback function invoked NNZ times (number of nonzero items in SparseMatrix).
2031- *
2032- *
2033- * ┌ f(Dij, Sij) ; S(i,j) !== 0
2034- * C(i,j) = ┤
2035- * â”” Dij ; otherwise
2036- *
2037- *
2038- * @param {Matrix} denseMatrix The DenseMatrix instance (D)
2039- * @param {Matrix} sparseMatrix The SparseMatrix instance (S)
2040- * @param {Function} callback The f(Dij,Sij) operation to invoke, where Dij = DenseMatrix(i,j) and Sij = SparseMatrix(i,j)
2041- * @param {boolean} inverse A true value indicates callback should be invoked f(Sij,Dij)
2042- *
2043- * @return {Matrix} DenseMatrix (C)
2044- *
2045- * see https://github.com/josdejong/mathjs/pull/346#issuecomment-97477571
2046- */
2047- var algorithm01 = function (denseMatrix, sparseMatrix, callback, inverse) {
2048- // dense matrix arrays
2049- var adata = denseMatrix._data;
2050- var asize = denseMatrix._size;
2051- var adt = denseMatrix._datatype;
2052- // sparse matrix arrays
2053- var bvalues = sparseMatrix._values;
2054- var bindex = sparseMatrix._index;
2055- var bptr = sparseMatrix._ptr;
2056- var bsize = sparseMatrix._size;
2057- var bdt = sparseMatrix._datatype;
2058-
2059- // validate dimensions
2060- if (asize.length !== bsize.length)
2061- throw new DimensionError(asize.length, bsize.length);
2062-
2063- // check rows & columns
2064- if (asize[0] !== bsize[0] || asize[1] !== bsize[1])
2065- throw new RangeError('Dimension mismatch. Matrix A (' + asize + ') must match Matrix B (' + bsize + ')');
2066-
2067- // sparse matrix cannot be a Pattern matrix
2068- if (!bvalues)
2069- throw new Error('Cannot perform operation on Dense Matrix and Pattern Sparse Matrix');
2070-
2071- // rows & columns
2072- var rows = asize[0];
2073- var columns = asize[1];
2074-
2075- // process data types
2076- var dt = typeof adt === 'string' && adt === bdt ? adt : undefined;
2077- // callback function
2078- var cf = dt ? typed.find(callback, [dt, dt]) : callback;
2079-
2080- // vars
2081- var i, j;
2082-
2083- // result (DenseMatrix)
2084- var cdata = [];
2085- // initialize c
2086- for (i = 0; i < rows; i++)
2087- cdata[i] = [];
2088-
2089- // workspace
2090- var x = [];
2091- // marks indicating we have a value in x for a given column
2092- var w = [];
2093-
2094- // loop columns in b
2095- for (j = 0; j < columns; j++) {
2096- // column mark
2097- var mark = j + 1;
2098- // values in column j
2099- for (var k0 = bptr[j], k1 = bptr[j + 1], k = k0; k < k1; k++) {
2100- // row
2101- i = bindex[k];
2102- // update workspace
2103- x[i] = inverse ? cf(bvalues[k], adata[i][j]) : cf(adata[i][j], bvalues[k]);
2104- // mark i as updated
2105- w[i] = mark;
2106- }
2107- // loop rows
2108- for (i = 0; i < rows; i++) {
2109- // check row is in workspace
2110- if (w[i] === mark) {
2111- // c[i][j] was already calculated
2112- cdata[i][j] = x[i];
2113- }
2114- else {
2115- // item does not exist in S
2116- cdata[i][j] = adata[i][j];
2117- }
2118- }
2119- }
2120-
2121- // return dense matrix
2122- return new DenseMatrix({
2123- data: cdata,
2124- size: [rows, columns],
2125- datatype: dt
2126- });
2127- };
2128-
2129- return algorithm01;
2130- }
2131-
2132- exports.name = 'algorithm01';
2133- exports.factory = factory;
2134-
2135-
2136-/***/ },
2137-/* 31 */
2138-/***/ function(module, exports, __webpack_require__) {
2139-
2140- 'use strict';
2141-
2142- var DimensionError = __webpack_require__(22);
2143-
2144- function factory (type, config, load, typed) {
2145-
2146- var DenseMatrix = type.DenseMatrix;
2147-
2148- /**
2149- * Iterates over SparseMatrix items and invokes the callback function f(Dij, Sij).
2150- * Callback function invoked M*N times.
2151- *
2152- *
2153- * ┌ f(Dij, Sij) ; S(i,j) !== 0
2154- * C(i,j) = ┤
2155- * â”” f(Dij, 0) ; otherwise
2156- *
2157- *
2158- * @param {Matrix} denseMatrix The DenseMatrix instance (D)
2159- * @param {Matrix} sparseMatrix The SparseMatrix instance (C)
2160- * @param {Function} callback The f(Dij,Sij) operation to invoke, where Dij = DenseMatrix(i,j) and Sij = SparseMatrix(i,j)
2161- * @param {boolean} inverse A true value indicates callback should be invoked f(Sij,Dij)
2162- *
2163- * @return {Matrix} DenseMatrix (C)
2164- *
2165- * see https://github.com/josdejong/mathjs/pull/346#issuecomment-97477571
2166- */
2167- var algorithm03 = function (denseMatrix, sparseMatrix, callback, inverse) {
2168- // dense matrix arrays
2169- var adata = denseMatrix._data;
2170- var asize = denseMatrix._size;
2171- var adt = denseMatrix._datatype;
2172- // sparse matrix arrays
2173- var bvalues = sparseMatrix._values;
2174- var bindex = sparseMatrix._index;
2175- var bptr = sparseMatrix._ptr;
2176- var bsize = sparseMatrix._size;
2177- var bdt = sparseMatrix._datatype;
2178-
2179- // validate dimensions
2180- if (asize.length !== bsize.length)
2181- throw new DimensionError(asize.length, bsize.length);
2182-
2183- // check rows & columns
2184- if (asize[0] !== bsize[0] || asize[1] !== bsize[1])
2185- throw new RangeError('Dimension mismatch. Matrix A (' + asize + ') must match Matrix B (' + bsize + ')');
2186-
2187- // sparse matrix cannot be a Pattern matrix
2188- if (!bvalues)
2189- throw new Error('Cannot perform operation on Dense Matrix and Pattern Sparse Matrix');
2190-
2191- // rows & columns
2192- var rows = asize[0];
2193- var columns = asize[1];
2194-
2195- // datatype
2196- var dt;
2197- // zero value
2198- var zero = 0;
2199- // callback signature to use
2200- var cf = callback;
2201-
2202- // process data types
2203- if (typeof adt === 'string' && adt === bdt) {
2204- // datatype
2205- dt = adt;
2206- // convert 0 to the same datatype
2207- zero = typed.convert(0, dt);
2208- // callback
2209- cf = typed.find(callback, [dt, dt]);
2210- }
2211-
2212- // result (DenseMatrix)
2213- var cdata = [];
2214-
2215- // initialize dense matrix
2216- for (var z = 0; z < rows; z++) {
2217- // initialize row
2218- cdata[z] = [];
2219- }
2220-
2221- // workspace
2222- var x = [];
2223- // marks indicating we have a value in x for a given column
2224- var w = [];
2225-
2226- // loop columns in b
2227- for (var j = 0; j < columns; j++) {
2228- // column mark
2229- var mark = j + 1;
2230- // values in column j
2231- for (var k0 = bptr[j], k1 = bptr[j + 1], k = k0; k < k1; k++) {
2232- // row
2233- var i = bindex[k];
2234- // update workspace
2235- x[i] = inverse ? cf(bvalues[k], adata[i][j]) : cf(adata[i][j], bvalues[k]);
2236- w[i] = mark;
2237- }
2238- // process workspace
2239- for (var y = 0; y < rows; y++) {
2240- // check we have a calculated value for current row
2241- if (w[y] === mark) {
2242- // use calculated value
2243- cdata[y][j] = x[y];
2244- }
2245- else {
2246- // calculate value
2247- cdata[y][j] = inverse ? cf(zero, adata[y][j]) : cf(adata[y][j], zero);
2248- }
2249- }
2250- }
2251-
2252- // return dense matrix
2253- return new DenseMatrix({
2254- data: cdata,
2255- size: [rows, columns],
2256- datatype: dt
2257- });
2258- };
2259-
2260- return algorithm03;
2261- }
2262-
2263- exports.name = 'algorithm03';
2264- exports.factory = factory;
2265-
2266-
2267-/***/ },
2268-/* 32 */
2269-/***/ function(module, exports, __webpack_require__) {
2270-
2271- 'use strict';
2272-
2273- var DimensionError = __webpack_require__(22);
2274-
2275- function factory (type, config, load, typed) {
2276-
2277- var equalScalar = load(__webpack_require__(33));
2278-
2279- var SparseMatrix = type.SparseMatrix;
2280-
2281- /**
2282- * Iterates over SparseMatrix A and SparseMatrix B nonzero items and invokes the callback function f(Aij, Bij).
2283- * Callback function invoked MAX(NNZA, NNZB) times
2284- *
2285- *
2286- * ┌ f(Aij, Bij) ; A(i,j) !== 0 || B(i,j) !== 0
2287- * C(i,j) = ┤
2288- * â”” 0 ; otherwise
2289- *
2290- *
2291- * @param {Matrix} a The SparseMatrix instance (A)
2292- * @param {Matrix} b The SparseMatrix instance (B)
2293- * @param {Function} callback The f(Aij,Bij) operation to invoke
2294- *
2295- * @return {Matrix} SparseMatrix (C)
2296- *
2297- * see https://github.com/josdejong/mathjs/pull/346#issuecomment-97620294
2298- */
2299- var algorithm05 = function (a, b, callback) {
2300- // sparse matrix arrays
2301- var avalues = a._values;
2302- var aindex = a._index;
2303- var aptr = a._ptr;
2304- var asize = a._size;
2305- var adt = a._datatype;
2306- // sparse matrix arrays
2307- var bvalues = b._values;
2308- var bindex = b._index;
2309- var bptr = b._ptr;
2310- var bsize = b._size;
2311- var bdt = b._datatype;
2312-
2313- // validate dimensions
2314- if (asize.length !== bsize.length)
2315- throw new DimensionError(asize.length, bsize.length);
2316-
2317- // check rows & columns
2318- if (asize[0] !== bsize[0] || asize[1] !== bsize[1])
2319- throw new RangeError('Dimension mismatch. Matrix A (' + asize + ') must match Matrix B (' + bsize + ')');
2320-
2321- // rows & columns
2322- var rows = asize[0];
2323- var columns = asize[1];
2324-
2325- // datatype
2326- var dt;
2327- // equal signature to use
2328- var eq = equalScalar;
2329- // zero value
2330- var zero = 0;
2331- // callback signature to use
2332- var cf = callback;
2333-
2334- // process data types
2335- if (typeof adt === 'string' && adt === bdt) {
2336- // datatype
2337- dt = adt;
2338- // find signature that matches (dt, dt)
2339- eq = typed.find(equalScalar, [dt, dt]);
2340- // convert 0 to the same datatype
2341- zero = typed.convert(0, dt);
2342- // callback
2343- cf = typed.find(callback, [dt, dt]);
2344- }
2345-
2346- // result arrays
2347- var cvalues = avalues && bvalues ? [] : undefined;
2348- var cindex = [];
2349- var cptr = [];
2350- // matrix
2351- var c = new SparseMatrix({
2352- values: cvalues,
2353- index: cindex,
2354- ptr: cptr,
2355- size: [rows, columns],
2356- datatype: dt
2357- });
2358-
2359- // workspaces
2360- var xa = cvalues ? [] : undefined;
2361- var xb = cvalues ? [] : undefined;
2362- // marks indicating we have a value in x for a given column
2363- var wa = [];
2364- var wb = [];
2365-
2366- // vars
2367- var i, j, k, k1;
2368-
2369- // loop columns
2370- for (j = 0; j < columns; j++) {
2371- // update cptr
2372- cptr[j] = cindex.length;
2373- // columns mark
2374- var mark = j + 1;
2375- // loop values A(:,j)
2376- for (k = aptr[j], k1 = aptr[j + 1]; k < k1; k++) {
2377- // row
2378- i = aindex[k];
2379- // push index
2380- cindex.push(i);
2381- // update workspace
2382- wa[i] = mark;
2383- // check we need to process values
2384- if (xa)
2385- xa[i] = avalues[k];
2386- }
2387- // loop values B(:,j)
2388- for (k = bptr[j], k1 = bptr[j + 1]; k < k1; k++) {
2389- // row
2390- i = bindex[k];
2391- // check row existed in A
2392- if (wa[i] !== mark) {
2393- // push index
2394- cindex.push(i);
2395- }
2396- // update workspace
2397- wb[i] = mark;
2398- // check we need to process values
2399- if (xb)
2400- xb[i] = bvalues[k];
2401- }
2402- // check we need to process values (non pattern matrix)
2403- if (cvalues) {
2404- // initialize first index in j
2405- k = cptr[j];
2406- // loop index in j
2407- while (k < cindex.length) {
2408- // row
2409- i = cindex[k];
2410- // marks
2411- var wai = wa[i];
2412- var wbi = wb[i];
2413- // check Aij or Bij are nonzero
2414- if (wai === mark || wbi === mark) {
2415- // matrix values @ i,j
2416- var va = wai === mark ? xa[i] : zero;
2417- var vb = wbi === mark ? xb[i] : zero;
2418- // Cij
2419- var vc = cf(va, vb);
2420- // check for zero
2421- if (!eq(vc, zero)) {
2422- // push value
2423- cvalues.push(vc);
2424- // increment pointer
2425- k++;
2426- }
2427- else {
2428- // remove value @ i, do not increment pointer
2429- cindex.splice(k, 1);
2430- }
2431- }
2432- }
2433- }
2434- }
2435- // update cptr
2436- cptr[columns] = cindex.length;
2437-
2438- // return sparse matrix
2439- return c;
2440- };
2441-
2442- return algorithm05;
2443- }
2444-
2445- exports.name = 'algorithm05';
2446- exports.factory = factory;
2447-
2448-
2449-/***/ },
2450-/* 33 */
2451-/***/ function(module, exports, __webpack_require__) {
2452-
2453- 'use strict';
2454-
2455- var nearlyEqual = __webpack_require__(8).nearlyEqual;
2456-
2457- function factory (type, config, load, typed) {
2458-
2459- /**
2460- * Test whether two values are equal.
2461- *
2462- * @param {number | BigNumber | Fraction | boolean | Complex | Unit} x First value to compare
2463- * @param {number | BigNumber | Fraction | boolean | Complex} y Second value to compare
2464- * @return {boolean} Returns true when the compared values are equal, else returns false
2465- * @private
2466- */
2467- var equalScalar = typed('equalScalar', {
2468-
2469- 'boolean, boolean': function (x, y) {
2470- return x === y;
2471- },
2472-
2473- 'number, number': function (x, y) {
2474- return x === y || nearlyEqual(x, y, config.epsilon);
2475- },
2476-
2477- 'BigNumber, BigNumber': function (x, y) {
2478- return x.eq(y);
2479- },
2480-
2481- 'Fraction, Fraction': function (x, y) {
2482- return x.equals(y);
2483- },
2484-
2485- 'Complex, Complex': function (x, y) {
2486- return (x.re === y.re || nearlyEqual(x.re, y.re, config.epsilon)) &&
2487- (x.im === y.im || nearlyEqual(x.im, y.im, config.epsilon));
2488- },
2489-
2490- 'Unit, Unit': function (x, y) {
2491- if (!x.equalBase(y)) {
2492- throw new Error('Cannot compare units with different base');
2493- }
2494- return x.value === y.value || nearlyEqual(x.value, y.value, config.epsilon);
2495- },
2496-
2497- 'string, string': function (x, y) {
2498- return x === y;
2499- }
2500- });
2501-
2502- return equalScalar;
2503- }
2504-
2505- exports.factory = factory;
2506-
2507-
2508-/***/ },
2509-/* 34 */
2510-/***/ function(module, exports) {
2511-
2512- 'use strict';
2513-
2514- function factory (type, config, load, typed) {
2515-
2516- var DenseMatrix = type.DenseMatrix;
2517-
2518- /**
2519- * Iterates over SparseMatrix S nonzero items and invokes the callback function f(Sij, b).
2520- * Callback function invoked NZ times (number of nonzero items in S).
2521- *
2522- *
2523- * ┌ f(Sij, b) ; S(i,j) !== 0
2524- * C(i,j) = ┤
2525- * â”” b ; otherwise
2526- *
2527- *
2528- * @param {Matrix} s The SparseMatrix instance (S)
2529- * @param {Scalar} b The Scalar value
2530- * @param {Function} callback The f(Aij,b) operation to invoke
2531- * @param {boolean} inverse A true value indicates callback should be invoked f(b,Sij)
2532- *
2533- * @return {Matrix} DenseMatrix (C)
2534- *
2535- * https://github.com/josdejong/mathjs/pull/346#issuecomment-97626813
2536- */
2537- var algorithm10 = function (s, b, callback, inverse) {
2538- // sparse matrix arrays
2539- var avalues = s._values;
2540- var aindex = s._index;
2541- var aptr = s._ptr;
2542- var asize = s._size;
2543- var adt = s._datatype;
2544-
2545- // sparse matrix cannot be a Pattern matrix
2546- if (!avalues)
2547- throw new Error('Cannot perform operation on Pattern Sparse Matrix and Scalar value');
2548-
2549- // rows & columns
2550- var rows = asize[0];
2551- var columns = asize[1];
2552-
2553- // datatype
2554- var dt;
2555- // callback signature to use
2556- var cf = callback;
2557-
2558- // process data types
2559- if (typeof adt === 'string') {
2560- // datatype
2561- dt = adt;
2562- // convert b to the same datatype
2563- b = typed.convert(b, dt);
2564- // callback
2565- cf = typed.find(callback, [dt, dt]);
2566- }
2567-
2568- // result arrays
2569- var cdata = [];
2570- // matrix
2571- var c = new DenseMatrix({
2572- data: cdata,
2573- size: [rows, columns],
2574- datatype: dt
2575- });
2576-
2577- // workspaces
2578- var x = [];
2579- // marks indicating we have a value in x for a given column
2580- var w = [];
2581-
2582- // loop columns
2583- for (var j = 0; j < columns; j++) {
2584- // columns mark
2585- var mark = j + 1;
2586- // values in j
2587- for (var k0 = aptr[j], k1 = aptr[j + 1], k = k0; k < k1; k++) {
2588- // row
2589- var r = aindex[k];
2590- // update workspace
2591- x[r] = avalues[k];
2592- w[r] = mark;
2593- }
2594- // loop rows
2595- for (var i = 0; i < rows; i++) {
2596- // initialize C on first column
2597- if (j === 0) {
2598- // create row array
2599- cdata[i] = [];
2600- }
2601- // check sparse matrix has a value @ i,j
2602- if (w[i] === mark) {
2603- // invoke callback, update C
2604- cdata[i][j] = inverse ? cf(b, x[i]) : cf(x[i], b);
2605- }
2606- else {
2607- // dense matrix value @ i, j
2608- cdata[i][j] = b;
2609- }
2610- }
2611- }
2612-
2613- // return sparse matrix
2614- return c;
2615- };
2616-
2617- return algorithm10;
2618- }
2619-
2620- exports.name = 'algorithm10';
2621- exports.factory = factory;
2622-
2623-
2624-/***/ },
2625-/* 35 */
2626-/***/ function(module, exports, __webpack_require__) {
2627-
2628- 'use strict';
2629-
2630- var util = __webpack_require__(36);
2631- var DimensionError = __webpack_require__(22);
2632-
2633- var string = util.string,
2634- isString = string.isString;
2635-
2636- function factory (type, config, load, typed) {
2637-
2638- var DenseMatrix = type.DenseMatrix;
2639-
2640- /**
2641- * Iterates over DenseMatrix items and invokes the callback function f(Aij..z, Bij..z).
2642- * Callback function invoked MxN times.
2643- *
2644- * C(i,j,...z) = f(Aij..z, Bij..z)
2645- *
2646- * @param {Matrix} a The DenseMatrix instance (A)
2647- * @param {Matrix} b The DenseMatrix instance (B)
2648- * @param {Function} callback The f(Aij..z,Bij..z) operation to invoke
2649- *
2650- * @return {Matrix} DenseMatrix (C)
2651- *
2652- * https://github.com/josdejong/mathjs/pull/346#issuecomment-97658658
2653- */
2654- var algorithm13 = function (a, b, callback) {
2655- // a arrays
2656- var adata = a._data;
2657- var asize = a._size;
2658- var adt = a._datatype;
2659- // b arrays
2660- var bdata = b._data;
2661- var bsize = b._size;
2662- var bdt = b._datatype;
2663- // c arrays
2664- var csize = [];
2665-
2666- // validate dimensions
2667- if (asize.length !== bsize.length)
2668- throw new DimensionError(asize.length, bsize.length);
2669-
2670- // validate each one of the dimension sizes
2671- for (var s = 0; s < asize.length; s++) {
2672- // must match
2673- if (asize[s] !== bsize[s])
2674- throw new RangeError('Dimension mismatch. Matrix A (' + asize + ') must match Matrix B (' + bsize + ')');
2675- // update dimension in c
2676- csize[s] = asize[s];
2677- }
2678-
2679- // datatype
2680- var dt;
2681- // callback signature to use
2682- var cf = callback;
2683-
2684- // process data types
2685- if (typeof adt === 'string' && adt === bdt) {
2686- // datatype
2687- dt = adt;
2688- // convert b to the same datatype
2689- b = typed.convert(b, dt);
2690- // callback
2691- cf = typed.find(callback, [dt, dt]);
2692- }
2693-
2694- // populate cdata, iterate through dimensions
2695- var cdata = csize.length > 0 ? _iterate(cf, 0, csize, csize[0], adata, bdata) : [];
2696-
2697- // c matrix
2698- return new DenseMatrix({
2699- data: cdata,
2700- size: csize,
2701- datatype: dt
2702- });
2703- };
2704-
2705- // recursive function
2706- var _iterate = function (f, level, s, n, av, bv) {
2707- // initialize array for this level
2708- var cv = [];
2709- // check we reach the last level
2710- if (level === s.length - 1) {
2711- // loop arrays in last level
2712- for (var i = 0; i < n; i++) {
2713- // invoke callback and store value
2714- cv[i] = f(av[i], bv[i]);
2715- }
2716- }
2717- else {
2718- // iterate current level
2719- for (var j = 0; j < n; j++) {
2720- // iterate next level
2721- cv[j] = _iterate(f, level + 1, s, s[level + 1], av[j], bv[j]);
2722- }
2723- }
2724- return cv;
2725- };
2726-
2727- return algorithm13;
2728- }
2729-
2730- exports.name = 'algorithm13';
2731- exports.factory = factory;
2732-
2733-
2734-/***/ },
2735-/* 36 */
2736-/***/ function(module, exports, __webpack_require__) {
2737-
2738- 'use strict';
2739-
2740- exports.array = __webpack_require__(18);
2741- exports['boolean'] = __webpack_require__(37);
2742- exports['function'] = __webpack_require__(38);
2743- exports.number = __webpack_require__(8);
2744- exports.object = __webpack_require__(5);
2745- exports.string = __webpack_require__(20);
2746- exports.types = __webpack_require__(19);
2747- exports.emitter = __webpack_require__(3);
2748-
2749-
2750-/***/ },
2751-/* 37 */
2752-/***/ function(module, exports) {
2753-
2754- 'use strict';
2755-
2756- /**
2757- * Test whether value is a boolean
2758- * @param {*} value
2759- * @return {boolean} isBoolean
2760- */
2761- exports.isBoolean = function(value) {
2762- return typeof value == 'boolean';
2763- };
2764-
2765-
2766-/***/ },
2767-/* 38 */
2768-/***/ function(module, exports) {
2769-
2770- // function utils
2771-
2772- /*
2773- * Memoize a given function by caching the computed result.
2774- * The cache of a memoized function can be cleared by deleting the `cache`
2775- * property of the function.
2776- *
2777- * @param {function} fn The function to be memoized.
2778- * Must be a pure function.
2779- * @param {function(args: Array)} [hasher] A custom hash builder.
2780- * Is JSON.stringify by default.
2781- * @return {function} Returns the memoized function
2782- */
2783- exports.memoize = function(fn, hasher) {
2784- return function memoize() {
2785- if (typeof memoize.cache !== 'object') {
2786- memoize.cache = {};
2787- }
2788-
2789- var args = [];
2790- for (var i = 0; i < arguments.length; i++) {
2791- args[i] = arguments[i];
2792- }
2793-
2794- var hash = hasher ? hasher(args) : JSON.stringify(args);
2795- if (!(hash in memoize.cache)) {
2796- return memoize.cache[hash] = fn.apply(fn, args);
2797- }
2798- return memoize.cache[hash];
2799- };
2800- };
2801-
2802-
2803-/***/ },
2804-/* 39 */
2805-/***/ function(module, exports, __webpack_require__) {
2806-
2807- 'use strict';
2808-
2809- var clone = __webpack_require__(5).clone;
2810-
2811- function factory (type, config, load, typed) {
2812-
2813- var DenseMatrix = type.DenseMatrix;
2814-
2815- /**
2816- * Iterates over DenseMatrix items and invokes the callback function f(Aij..z, b).
2817- * Callback function invoked MxN times.
2818- *
2819- * C(i,j,...z) = f(Aij..z, b)
2820- *
2821- * @param {Matrix} a The DenseMatrix instance (A)
2822- * @param {Scalar} b The Scalar value
2823- * @param {Function} callback The f(Aij..z,b) operation to invoke
2824- * @param {boolean} inverse A true value indicates callback should be invoked f(b,Aij..z)
2825- *
2826- * @return {Matrix} DenseMatrix (C)
2827- *
2828- * https://github.com/josdejong/mathjs/pull/346#issuecomment-97659042
2829- */
2830- var algorithm14 = function (a, b, callback, inverse) {
2831- // a arrays
2832- var adata = a._data;
2833- var asize = a._size;
2834- var adt = a._datatype;
2835-
2836- // datatype
2837- var dt;
2838- // callback signature to use
2839- var cf = callback;
2840-
2841- // process data types
2842- if (typeof adt === 'string') {
2843- // datatype
2844- dt = adt;
2845- // convert b to the same datatype
2846- b = typed.convert(b, dt);
2847- // callback
2848- cf = typed.find(callback, [dt, dt]);
2849- }
2850-
2851- // populate cdata, iterate through dimensions
2852- var cdata = asize.length > 0 ? _iterate(cf, 0, asize, asize[0], adata, b, inverse) : [];
2853-
2854- // c matrix
2855- return new DenseMatrix({
2856- data: cdata,
2857- size: clone(asize),
2858- datatype: dt
2859- });
2860- };
2861-
2862- // recursive function
2863- var _iterate = function (f, level, s, n, av, bv, inverse) {
2864- // initialize array for this level
2865- var cv = [];
2866- // check we reach the last level
2867- if (level === s.length - 1) {
2868- // loop arrays in last level
2869- for (var i = 0; i < n; i++) {
2870- // invoke callback and store value
2871- cv[i] = inverse ? f(bv, av[i]) : f(av[i], bv);
2872- }
2873- }
2874- else {
2875- // iterate current level
2876- for (var j = 0; j < n; j++) {
2877- // iterate next level
2878- cv[j] = _iterate(f, level + 1, s, s[level + 1], av[j], bv, inverse);
2879- }
2880- }
2881- return cv;
2882- };
2883-
2884- return algorithm14;
2885- }
2886-
2887- exports.name = 'algorithm14';
2888- exports.factory = factory;
2889-
2890-
2891-/***/ },
2892-/* 40 */
2893-/***/ function(module, exports, __webpack_require__) {
2894-
2895- 'use strict';
2896-
2897- var extend = __webpack_require__(5).extend;
2898- var array = __webpack_require__(18);
2899-
2900- function factory (type, config, load, typed) {
2901- var latex = __webpack_require__(26);
2902-
2903- var matrix = load(__webpack_require__(23));
2904- var addScalar = load(__webpack_require__(27));
2905- var multiplyScalar = load(__webpack_require__(41));
2906- var equalScalar = load(__webpack_require__(33));
2907-
2908- var algorithm11 = load(__webpack_require__(42));
2909- var algorithm14 = load(__webpack_require__(39));
2910-
2911- var DenseMatrix = type.DenseMatrix;
2912- var SparseMatrix = type.SparseMatrix;
2913-
2914- /**
2915- * Multiply two values, `x * y`. The result is squeezed.
2916- * For matrices, the matrix product is calculated.
2917- *
2918- * Syntax:
2919- *
2920- * math.multiply(x, y)
2921- *
2922- * Examples:
2923- *
2924- * math.multiply(4, 5.2); // returns number 20.8
2925- *
2926- * var a = math.complex(2, 3);
2927- * var b = math.complex(4, 1);
2928- * math.multiply(a, b); // returns Complex 5 + 14i
2929- *
2930- * var c = [[1, 2], [4, 3]];
2931- * var d = [[1, 2, 3], [3, -4, 7]];
2932- * math.multiply(c, d); // returns Array [[7, -6, 17], [13, -4, 33]]
2933- *
2934- * var e = math.unit('2.1 km');
2935- * math.multiply(3, e); // returns Unit 6.3 km
2936- *
2937- * See also:
2938- *
2939- * divide
2940- *
2941- * @param {number | BigNumber | Fraction | Complex | Unit | Array | Matrix} x First value to multiply
2942- * @param {number | BigNumber | Fraction | Complex | Unit | Array | Matrix} y Second value to multiply
2943- * @return {number | BigNumber | Fraction | Complex | Unit | Array | Matrix} Multiplication of `x` and `y`
2944- */
2945- var multiply = typed('multiply', extend({
2946- // we extend the signatures of multiplyScalar with signatures dealing with matrices
2947-
2948- 'Array, Array': function (x, y) {
2949- // check dimensions
2950- _validateMatrixDimensions(array.size(x), array.size(y));
2951-
2952- // use dense matrix implementation
2953- var m = multiply(matrix(x), matrix(y));
2954- // return array or scalar
2955- return (m && m.isMatrix === true) ? m.valueOf() : m;
2956- },
2957-
2958- 'Matrix, Matrix': function (x, y) {
2959- // dimensions
2960- var xsize = x.size();
2961- var ysize = y.size();
2962-
2963- // check dimensions
2964- _validateMatrixDimensions(xsize, ysize);
2965-
2966- // process dimensions
2967- if (xsize.length === 1) {
2968- // process y dimensions
2969- if (ysize.length === 1) {
2970- // Vector * Vector
2971- return _multiplyVectorVector(x, y, xsize[0]);
2972- }
2973- // Vector * Matrix
2974- return _multiplyVectorMatrix(x, y);
2975- }
2976- // process y dimensions
2977- if (ysize.length === 1) {
2978- // Matrix * Vector
2979- return _multiplyMatrixVector(x, y);
2980- }
2981- // Matrix * Matrix
2982- return _multiplyMatrixMatrix(x, y);
2983- },
2984-
2985- 'Matrix, Array': function (x, y) {
2986- // use Matrix * Matrix implementation
2987- return multiply(x, matrix(y));
2988- },
2989-
2990- 'Array, Matrix': function (x, y) {
2991- // use Matrix * Matrix implementation
2992- return multiply(matrix(x, y.storage()), y);
2993- },
2994-
2995- 'Matrix, any': function (x, y) {
2996- // result
2997- var c;
2998-
2999- // process storage format
3000- switch (x.storage()) {
3001- case 'sparse':
3002- c = algorithm11(x, y, multiplyScalar, false);
3003- break;
3004- case 'dense':
3005- c = algorithm14(x, y, multiplyScalar, false);
3006- break;
3007- }
3008- return c;
3009- },
3010-
3011- 'any, Matrix': function (x, y) {
3012- // result
3013- var c;
3014- // check storage format
3015- switch (y.storage()) {
3016- case 'sparse':
3017- c = algorithm11(y, x, multiplyScalar, true);
3018- break;
3019- case 'dense':
3020- c = algorithm14(y, x, multiplyScalar, true);
3021- break;
3022- }
3023- return c;
3024- },
3025-
3026- 'Array, any': function (x, y) {
3027- // use matrix implementation
3028- return algorithm14(matrix(x), y, multiplyScalar, false).valueOf();
3029- },
3030-
3031- 'any, Array': function (x, y) {
3032- // use matrix implementation
3033- return algorithm14(matrix(y), x, multiplyScalar, true).valueOf();
3034- }
3035- }, multiplyScalar.signatures));
3036-
3037- var _validateMatrixDimensions = function (size1, size2) {
3038- // check left operand dimensions
3039- switch (size1.length) {
3040- case 1:
3041- // check size2
3042- switch (size2.length) {
3043- case 1:
3044- // Vector x Vector
3045- if (size1[0] !== size2[0]) {
3046- // throw error
3047- throw new RangeError('Dimension mismatch in multiplication. Vectors must have the same length');
3048- }
3049- break;
3050- case 2:
3051- // Vector x Matrix
3052- if (size1[0] !== size2[0]) {
3053- // throw error
3054- throw new RangeError('Dimension mismatch in multiplication. Vector length (' + size1[0] + ') must match Matrix rows (' + size2[0] + ')');
3055- }
3056- break;
3057- default:
3058- throw new Error('Can only multiply a 1 or 2 dimensional matrix (Matrix B has ' + size2.length + ' dimensions)');
3059- }
3060- break;
3061- case 2:
3062- // check size2
3063- switch (size2.length) {
3064- case 1:
3065- // Matrix x Vector
3066- if (size1[1] !== size2[0]) {
3067- // throw error
3068- throw new RangeError('Dimension mismatch in multiplication. Matrix columns (' + size1[1] + ') must match Vector length (' + size2[0] + ')');
3069- }
3070- break;
3071- case 2:
3072- // Matrix x Matrix
3073- if (size1[1] !== size2[0]) {
3074- // throw error
3075- throw new RangeError('Dimension mismatch in multiplication. Matrix A columns (' + size1[1] + ') must match Matrix B rows (' + size2[0] + ')');
3076- }
3077- break;
3078- default:
3079- throw new Error('Can only multiply a 1 or 2 dimensional matrix (Matrix B has ' + size2.length + ' dimensions)');
3080- }
3081- break;
3082- default:
3083- throw new Error('Can only multiply a 1 or 2 dimensional matrix (Matrix A has ' + size1.length + ' dimensions)');
3084- }
3085- };
3086-
3087- /**
3088- * C = A * B
3089- *
3090- * @param {Matrix} a Dense Vector (N)
3091- * @param {Matrix} b Dense Vector (N)
3092- *
3093- * @return {number} Scalar value
3094- */
3095- var _multiplyVectorVector = function (a, b, n) {
3096- // check empty vector
3097- if (n === 0)
3098- throw new Error('Cannot multiply two empty vectors');
3099-
3100- // a dense
3101- var adata = a._data;
3102- var adt = a._datatype;
3103- // b dense
3104- var bdata = b._data;
3105- var bdt = b._datatype;
3106-
3107- // datatype
3108- var dt;
3109- // addScalar signature to use
3110- var af = addScalar;
3111- // multiplyScalar signature to use
3112- var mf = multiplyScalar;
3113-
3114- // process data types
3115- if (adt && bdt && adt === bdt && typeof adt === 'string') {
3116- // datatype
3117- dt = adt;
3118- // find signatures that matches (dt, dt)
3119- af = typed.find(addScalar, [dt, dt]);
3120- mf = typed.find(multiplyScalar, [dt, dt]);
3121- }
3122-
3123- // result (do not initialize it with zero)
3124- var c = mf(adata[0], bdata[0]);
3125- // loop data
3126- for (var i = 1; i < n; i++) {
3127- // multiply and accumulate
3128- c = af(c, mf(adata[i], bdata[i]));
3129- }
3130- return c;
3131- };
3132-
3133- /**
3134- * C = A * B
3135- *
3136- * @param {Matrix} a Dense Vector (M)
3137- * @param {Matrix} b Matrix (MxN)
3138- *
3139- * @return {Matrix} Dense Vector (N)
3140- */
3141- var _multiplyVectorMatrix = function (a, b) {
3142- // process storage
3143- switch (b.storage()) {
3144- case 'dense':
3145- return _multiplyVectorDenseMatrix(a, b);
3146- }
3147- throw new Error('Not implemented');
3148- };
3149-
3150- /**
3151- * C = A * B
3152- *
3153- * @param {Matrix} a Dense Vector (M)
3154- * @param {Matrix} b Dense Matrix (MxN)
3155- *
3156- * @return {Matrix} Dense Vector (N)
3157- */
3158- var _multiplyVectorDenseMatrix = function (a, b) {
3159- // a dense
3160- var adata = a._data;
3161- var asize = a._size;
3162- var adt = a._datatype;
3163- // b dense
3164- var bdata = b._data;
3165- var bsize = b._size;
3166- var bdt = b._datatype;
3167- // rows & columns
3168- var alength = asize[0];
3169- var bcolumns = bsize[1];
3170-
3171- // datatype
3172- var dt;
3173- // addScalar signature to use
3174- var af = addScalar;
3175- // multiplyScalar signature to use
3176- var mf = multiplyScalar;
3177-
3178- // process data types
3179- if (adt && bdt && adt === bdt && typeof adt === 'string') {
3180- // datatype
3181- dt = adt;
3182- // find signatures that matches (dt, dt)
3183- af = typed.find(addScalar, [dt, dt]);
3184- mf = typed.find(multiplyScalar, [dt, dt]);
3185- }
3186-
3187- // result
3188- var c = [];
3189-
3190- // loop matrix columns
3191- for (var j = 0; j < bcolumns; j++) {
3192- // sum (do not initialize it with zero)
3193- var sum = mf(adata[0], bdata[0][j]);
3194- // loop vector
3195- for (var i = 1; i < alength; i++) {
3196- // multiply & accumulate
3197- sum = af(sum, mf(adata[i], bdata[i][j]));
3198- }
3199- c[j] = sum;
3200- }
3201-
3202- // check we need to squeeze the result into a scalar
3203- if (bcolumns === 1)
3204- return c[0];
3205-
3206- // return matrix
3207- return new DenseMatrix({
3208- data: c,
3209- size: [bcolumns],
3210- datatype: dt
3211- });
3212- };
3213-
3214- /**
3215- * C = A * B
3216- *
3217- * @param {Matrix} a Matrix (MxN)
3218- * @param {Matrix} b Dense Vector (N)
3219- *
3220- * @return {Matrix} Dense Vector (M)
3221- */
3222- var _multiplyMatrixVector = function (a, b) {
3223- // process storage
3224- switch (a.storage()) {
3225- case 'dense':
3226- return _multiplyDenseMatrixVector(a, b);
3227- case 'sparse':
3228- return _multiplySparseMatrixVector(a, b);
3229- }
3230- };
3231-
3232- /**
3233- * C = A * B
3234- *
3235- * @param {Matrix} a Matrix (MxN)
3236- * @param {Matrix} b Matrix (NxC)
3237- *
3238- * @return {Matrix} Matrix (MxC)
3239- */
3240- var _multiplyMatrixMatrix = function (a, b) {
3241- // process storage
3242- switch (a.storage()) {
3243- case 'dense':
3244- // process storage
3245- switch (b.storage()) {
3246- case 'dense':
3247- return _multiplyDenseMatrixDenseMatrix(a, b);
3248- case 'sparse':
3249- return _multiplyDenseMatrixSparseMatrix(a, b);
3250- }
3251- break;
3252- case 'sparse':
3253- // process storage
3254- switch (b.storage()) {
3255- case 'dense':
3256- return _multiplySparseMatrixDenseMatrix(a, b);
3257- case 'sparse':
3258- return _multiplySparseMatrixSparseMatrix(a, b);
3259- }
3260- break;
3261- }
3262- };
3263-
3264- /**
3265- * C = A * B
3266- *
3267- * @param {Matrix} a DenseMatrix (MxN)
3268- * @param {Matrix} b Dense Vector (N)
3269- *
3270- * @return {Matrix} Dense Vector (M)
3271- */
3272- var _multiplyDenseMatrixVector = function (a, b) {
3273- // a dense
3274- var adata = a._data;
3275- var asize = a._size;
3276- var adt = a._datatype;
3277- // b dense
3278- var bdata = b._data;
3279- var bdt = b._datatype;
3280- // rows & columns
3281- var arows = asize[0];
3282- var acolumns = asize[1];
3283-
3284- // datatype
3285- var dt;
3286- // addScalar signature to use
3287- var af = addScalar;
3288- // multiplyScalar signature to use
3289- var mf = multiplyScalar;
3290-
3291- // process data types
3292- if (adt && bdt && adt === bdt && typeof adt === 'string') {
3293- // datatype
3294- dt = adt;
3295- // find signatures that matches (dt, dt)
3296- af = typed.find(addScalar, [dt, dt]);
3297- mf = typed.find(multiplyScalar, [dt, dt]);
3298- }
3299-
3300- // result
3301- var c = [];
3302-
3303- // loop matrix a rows
3304- for (var i = 0; i < arows; i++) {
3305- // current row
3306- var row = adata[i];
3307- // sum (do not initialize it with zero)
3308- var sum = mf(row[0], bdata[0]);
3309- // loop matrix a columns
3310- for (var j = 1; j < acolumns; j++) {
3311- // multiply & accumulate
3312- sum = af(sum, mf(row[j], bdata[j]));
3313- }
3314- c[i] = sum;
3315- }
3316- // check we need to squeeze the result into a scalar
3317- if (arows === 1)
3318- return c[0];
3319-
3320- // return matrix
3321- return new DenseMatrix({
3322- data: c,
3323- size: [arows],
3324- datatype: dt
3325- });
3326- };
3327-
3328- /**
3329- * C = A * B
3330- *
3331- * @param {Matrix} a DenseMatrix (MxN)
3332- * @param {Matrix} b DenseMatrix (NxC)
3333- *
3334- * @return {Matrix} DenseMatrix (MxC)
3335- */
3336- var _multiplyDenseMatrixDenseMatrix = function (a, b) {
3337- // a dense
3338- var adata = a._data;
3339- var asize = a._size;
3340- var adt = a._datatype;
3341- // b dense
3342- var bdata = b._data;
3343- var bsize = b._size;
3344- var bdt = b._datatype;
3345- // rows & columns
3346- var arows = asize[0];
3347- var acolumns = asize[1];
3348- var bcolumns = bsize[1];
3349-
3350- // datatype
3351- var dt;
3352- // addScalar signature to use
3353- var af = addScalar;
3354- // multiplyScalar signature to use
3355- var mf = multiplyScalar;
3356-
3357- // process data types
3358- if (adt && bdt && adt === bdt && typeof adt === 'string') {
3359- // datatype
3360- dt = adt;
3361- // find signatures that matches (dt, dt)
3362- af = typed.find(addScalar, [dt, dt]);
3363- mf = typed.find(multiplyScalar, [dt, dt]);
3364- }
3365-
3366- // result
3367- var c = [];
3368-
3369- // loop matrix a rows
3370- for (var i = 0; i < arows; i++) {
3371- // current row
3372- var row = adata[i];
3373- // initialize row array
3374- c[i] = [];
3375- // loop matrix b columns
3376- for (var j = 0; j < bcolumns; j++) {
3377- // sum (avoid initializing sum to zero)
3378- var sum = mf(row[0], bdata[0][j]);
3379- // loop matrix a columns
3380- for (var x = 1; x < acolumns; x++) {
3381- // multiply & accumulate
3382- sum = af(sum, mf(row[x], bdata[x][j]));
3383- }
3384- c[i][j] = sum;
3385- }
3386- }
3387- // check we need to squeeze the result into a scalar
3388- if (arows === 1 && bcolumns === 1)
3389- return c[0][0];
3390-
3391- // return matrix
3392- return new DenseMatrix({
3393- data: c,
3394- size: [arows, bcolumns],
3395- datatype: dt
3396- });
3397- };
3398-
3399- /**
3400- * C = A * B
3401- *
3402- * @param {Matrix} a DenseMatrix (MxN)
3403- * @param {Matrix} b SparseMatrix (NxC)
3404- *
3405- * @return {Matrix} SparseMatrix (MxC)
3406- */
3407- var _multiplyDenseMatrixSparseMatrix = function (a, b) {
3408- // a dense
3409- var adata = a._data;
3410- var asize = a._size;
3411- var adt = a._datatype;
3412- // b sparse
3413- var bvalues = b._values;
3414- var bindex = b._index;
3415- var bptr = b._ptr;
3416- var bsize = b._size;
3417- var bdt = b._datatype;
3418- // validate b matrix
3419- if (!bvalues)
3420- throw new Error('Cannot multiply Dense Matrix times Pattern only Matrix');
3421- // rows & columns
3422- var arows = asize[0];
3423- var bcolumns = bsize[1];
3424-
3425- // datatype
3426- var dt;
3427- // addScalar signature to use
3428- var af = addScalar;
3429- // multiplyScalar signature to use
3430- var mf = multiplyScalar;
3431- // equalScalar signature to use
3432- var eq = equalScalar;
3433- // zero value
3434- var zero = 0;
3435-
3436- // process data types
3437- if (adt && bdt && adt === bdt && typeof adt === 'string') {
3438- // datatype
3439- dt = adt;
3440- // find signatures that matches (dt, dt)
3441- af = typed.find(addScalar, [dt, dt]);
3442- mf = typed.find(multiplyScalar, [dt, dt]);
3443- eq = typed.find(equalScalar, [dt, dt]);
3444- // convert 0 to the same datatype
3445- zero = typed.convert(0, dt);
3446- }
3447-
3448- // result
3449- var cvalues = [];
3450- var cindex = [];
3451- var cptr = [];
3452- // c matrix
3453- var c = new SparseMatrix({
3454- values : cvalues,
3455- index: cindex,
3456- ptr: cptr,
3457- size: [arows, bcolumns],
3458- datatype: dt
3459- });
3460-
3461- // loop b columns
3462- for (var jb = 0; jb < bcolumns; jb++) {
3463- // update ptr
3464- cptr[jb] = cindex.length;
3465- // indeces in column jb
3466- var kb0 = bptr[jb];
3467- var kb1 = bptr[jb + 1];
3468- // do not process column jb if no data exists
3469- if (kb1 > kb0) {
3470- // last row mark processed
3471- var last = 0;
3472- // loop a rows
3473- for (var i = 0; i < arows; i++) {
3474- // column mark
3475- var mark = i + 1;
3476- // C[i, jb]
3477- var cij;
3478- // values in b column j
3479- for (var kb = kb0; kb < kb1; kb++) {
3480- // row
3481- var ib = bindex[kb];
3482- // check value has been initialized
3483- if (last !== mark) {
3484- // first value in column jb
3485- cij = mf(adata[i][ib], bvalues[kb]);
3486- // update mark
3487- last = mark;
3488- }
3489- else {
3490- // accumulate value
3491- cij = af(cij, mf(adata[i][ib], bvalues[kb]));
3492- }
3493- }
3494- // check column has been processed and value != 0
3495- if (last === mark && !eq(cij, zero)) {
3496- // push row & value
3497- cindex.push(i);
3498- cvalues.push(cij);
3499- }
3500- }
3501- }
3502- }
3503- // update ptr
3504- cptr[bcolumns] = cindex.length;
3505-
3506- // check we need to squeeze the result into a scalar
3507- if (arows === 1 && bcolumns === 1)
3508- return cvalues.length === 1 ? cvalues[0] : 0;
3509-
3510- // return sparse matrix
3511- return c;
3512- };
3513-
3514- /**
3515- * C = A * B
3516- *
3517- * @param {Matrix} a SparseMatrix (MxN)
3518- * @param {Matrix} b Dense Vector (N)
3519- *
3520- * @return {Matrix} SparseMatrix (M, 1)
3521- */
3522- var _multiplySparseMatrixVector = function (a, b) {
3523- // a sparse
3524- var avalues = a._values;
3525- var aindex = a._index;
3526- var aptr = a._ptr;
3527- var adt = a._datatype;
3528- // validate a matrix
3529- if (!avalues)
3530- throw new Error('Cannot multiply Pattern only Matrix times Dense Matrix');
3531- // b dense
3532- var bdata = b._data;
3533- var bdt = b._datatype;
3534- // rows & columns
3535- var arows = a._size[0];
3536- var brows = b._size[0];
3537- // result
3538- var cvalues = [];
3539- var cindex = [];
3540- var cptr = [];
3541-
3542- // datatype
3543- var dt;
3544- // addScalar signature to use
3545- var af = addScalar;
3546- // multiplyScalar signature to use
3547- var mf = multiplyScalar;
3548- // equalScalar signature to use
3549- var eq = equalScalar;
3550- // zero value
3551- var zero = 0;
3552-
3553- // process data types
3554- if (adt && bdt && adt === bdt && typeof adt === 'string') {
3555- // datatype
3556- dt = adt;
3557- // find signatures that matches (dt, dt)
3558- af = typed.find(addScalar, [dt, dt]);
3559- mf = typed.find(multiplyScalar, [dt, dt]);
3560- eq = typed.find(equalScalar, [dt, dt]);
3561- // convert 0 to the same datatype
3562- zero = typed.convert(0, dt);
3563- }
3564-
3565- // workspace
3566- var x = [];
3567- // vector with marks indicating a value x[i] exists in a given column
3568- var w = [];
3569-
3570- // update ptr
3571- cptr[0] = 0;
3572- // rows in b
3573- for (var ib = 0; ib < brows; ib++) {
3574- // b[ib]
3575- var vbi = bdata[ib];
3576- // check b[ib] != 0, avoid loops
3577- if (!eq(vbi, zero)) {
3578- // A values & index in ib column
3579- for (var ka0 = aptr[ib], ka1 = aptr[ib + 1], ka = ka0; ka < ka1; ka++) {
3580- // a row
3581- var ia = aindex[ka];
3582- // check value exists in current j
3583- if (!w[ia]) {
3584- // ia is new entry in j
3585- w[ia] = true;
3586- // add i to pattern of C
3587- cindex.push(ia);
3588- // x(ia) = A
3589- x[ia] = mf(vbi, avalues[ka]);
3590- }
3591- else {
3592- // i exists in C already
3593- x[ia] = af(x[ia], mf(vbi, avalues[ka]));
3594- }
3595- }
3596- }
3597- }
3598- // copy values from x to column jb of c
3599- for (var p1 = cindex.length, p = 0; p < p1; p++) {
3600- // row
3601- var ic = cindex[p];
3602- // copy value
3603- cvalues[p] = x[ic];
3604- }
3605- // update ptr
3606- cptr[1] = cindex.length;
3607-
3608- // check we need to squeeze the result into a scalar
3609- if (arows === 1)
3610- return cvalues.length === 1 ? cvalues[0] : 0;
3611-
3612- // return sparse matrix
3613- return new SparseMatrix({
3614- values : cvalues,
3615- index: cindex,
3616- ptr: cptr,
3617- size: [arows, 1],
3618- datatype: dt
3619- });
3620- };
3621-
3622- /**
3623- * C = A * B
3624- *
3625- * @param {Matrix} a SparseMatrix (MxN)
3626- * @param {Matrix} b DenseMatrix (NxC)
3627- *
3628- * @return {Matrix} SparseMatrix (MxC)
3629- */
3630- var _multiplySparseMatrixDenseMatrix = function (a, b) {
3631- // a sparse
3632- var avalues = a._values;
3633- var aindex = a._index;
3634- var aptr = a._ptr;
3635- var adt = a._datatype;
3636- // validate a matrix
3637- if (!avalues)
3638- throw new Error('Cannot multiply Pattern only Matrix times Dense Matrix');
3639- // b dense
3640- var bdata = b._data;
3641- var bdt = b._datatype;
3642- // rows & columns
3643- var arows = a._size[0];
3644- var brows = b._size[0];
3645- var bcolumns = b._size[1];
3646-
3647- // datatype
3648- var dt;
3649- // addScalar signature to use
3650- var af = addScalar;
3651- // multiplyScalar signature to use
3652- var mf = multiplyScalar;
3653- // equalScalar signature to use
3654- var eq = equalScalar;
3655- // zero value
3656- var zero = 0;
3657-
3658- // process data types
3659- if (adt && bdt && adt === bdt && typeof adt === 'string') {
3660- // datatype
3661- dt = adt;
3662- // find signatures that matches (dt, dt)
3663- af = typed.find(addScalar, [dt, dt]);
3664- mf = typed.find(multiplyScalar, [dt, dt]);
3665- eq = typed.find(equalScalar, [dt, dt]);
3666- // convert 0 to the same datatype
3667- zero = typed.convert(0, dt);
3668- }
3669-
3670- // result
3671- var cvalues = [];
3672- var cindex = [];
3673- var cptr = [];
3674- // c matrix
3675- var c = new SparseMatrix({
3676- values : cvalues,
3677- index: cindex,
3678- ptr: cptr,
3679- size: [arows, bcolumns],
3680- datatype: dt
3681- });
3682-
3683- // workspace
3684- var x = [];
3685- // vector with marks indicating a value x[i] exists in a given column
3686- var w = [];
3687-
3688- // loop b columns
3689- for (var jb = 0; jb < bcolumns; jb++) {
3690- // update ptr
3691- cptr[jb] = cindex.length;
3692- // mark in workspace for current column
3693- var mark = jb + 1;
3694- // rows in jb
3695- for (var ib = 0; ib < brows; ib++) {
3696- // b[ib, jb]
3697- var vbij = bdata[ib][jb];
3698- // check b[ib, jb] != 0, avoid loops
3699- if (!eq(vbij, zero)) {
3700- // A values & index in ib column
3701- for (var ka0 = aptr[ib], ka1 = aptr[ib + 1], ka = ka0; ka < ka1; ka++) {
3702- // a row
3703- var ia = aindex[ka];
3704- // check value exists in current j
3705- if (w[ia] !== mark) {
3706- // ia is new entry in j
3707- w[ia] = mark;
3708- // add i to pattern of C
3709- cindex.push(ia);
3710- // x(ia) = A
3711- x[ia] = mf(vbij, avalues[ka]);
3712- }
3713- else {
3714- // i exists in C already
3715- x[ia] = af(x[ia], mf(vbij, avalues[ka]));
3716- }
3717- }
3718- }
3719- }
3720- // copy values from x to column jb of c
3721- for (var p0 = cptr[jb], p1 = cindex.length, p = p0; p < p1; p++) {
3722- // row
3723- var ic = cindex[p];
3724- // copy value
3725- cvalues[p] = x[ic];
3726- }
3727- }
3728- // update ptr
3729- cptr[bcolumns] = cindex.length;
3730-
3731- // check we need to squeeze the result into a scalar
3732- if (arows === 1 && bcolumns === 1)
3733- return cvalues.length === 1 ? cvalues[0] : 0;
3734-
3735- // return sparse matrix
3736- return c;
3737- };
3738-
3739- /**
3740- * C = A * B
3741- *
3742- * @param {Matrix} a SparseMatrix (MxN)
3743- * @param {Matrix} b SparseMatrix (NxC)
3744- *
3745- * @return {Matrix} SparseMatrix (MxC)
3746- */
3747- var _multiplySparseMatrixSparseMatrix = function (a, b) {
3748- // a sparse
3749- var avalues = a._values;
3750- var aindex = a._index;
3751- var aptr = a._ptr;
3752- var adt = a._datatype;
3753- // b sparse
3754- var bvalues = b._values;
3755- var bindex = b._index;
3756- var bptr = b._ptr;
3757- var bdt = b._datatype;
3758-
3759- // rows & columns
3760- var arows = a._size[0];
3761- var bcolumns = b._size[1];
3762- // flag indicating both matrices (a & b) contain data
3763- var values = avalues && bvalues;
3764-
3765- // datatype
3766- var dt;
3767- // addScalar signature to use
3768- var af = addScalar;
3769- // multiplyScalar signature to use
3770- var mf = multiplyScalar;
3771-
3772- // process data types
3773- if (adt && bdt && adt === bdt && typeof adt === 'string') {
3774- // datatype
3775- dt = adt;
3776- // find signatures that matches (dt, dt)
3777- af = typed.find(addScalar, [dt, dt]);
3778- mf = typed.find(multiplyScalar, [dt, dt]);
3779- }
3780-
3781- // result
3782- var cvalues = values ? [] : undefined;
3783- var cindex = [];
3784- var cptr = [];
3785- // c matrix
3786- var c = new SparseMatrix({
3787- values : cvalues,
3788- index: cindex,
3789- ptr: cptr,
3790- size: [arows, bcolumns],
3791- datatype: dt
3792- });
3793-
3794- // workspace
3795- var x = values ? [] : undefined;
3796- // vector with marks indicating a value x[i] exists in a given column
3797- var w = [];
3798- // variables
3799- var ka, ka0, ka1, kb, kb0, kb1, ia, ib;
3800- // loop b columns
3801- for (var jb = 0; jb < bcolumns; jb++) {
3802- // update ptr
3803- cptr[jb] = cindex.length;
3804- // mark in workspace for current column
3805- var mark = jb + 1;
3806- // B values & index in j
3807- for (kb0 = bptr[jb], kb1 = bptr[jb + 1], kb = kb0; kb < kb1; kb++) {
3808- // b row
3809- ib = bindex[kb];
3810- // check we need to process values
3811- if (values) {
3812- // loop values in a[:,ib]
3813- for (ka0 = aptr[ib], ka1 = aptr[ib + 1], ka = ka0; ka < ka1; ka++) {
3814- // row
3815- ia = aindex[ka];
3816- // check value exists in current j
3817- if (w[ia] !== mark) {
3818- // ia is new entry in j
3819- w[ia] = mark;
3820- // add i to pattern of C
3821- cindex.push(ia);
3822- // x(ia) = A
3823- x[ia] = mf(bvalues[kb], avalues[ka]);
3824- }
3825- else {
3826- // i exists in C already
3827- x[ia] = af(x[ia], mf(bvalues[kb], avalues[ka]));
3828- }
3829- }
3830- }
3831- else {
3832- // loop values in a[:,ib]
3833- for (ka0 = aptr[ib], ka1 = aptr[ib + 1], ka = ka0; ka < ka1; ka++) {
3834- // row
3835- ia = aindex[ka];
3836- // check value exists in current j
3837- if (w[ia] !== mark) {
3838- // ia is new entry in j
3839- w[ia] = mark;
3840- // add i to pattern of C
3841- cindex.push(ia);
3842- }
3843- }
3844- }
3845- }
3846- // check we need to process matrix values (pattern matrix)
3847- if (values) {
3848- // copy values from x to column jb of c
3849- for (var p0 = cptr[jb], p1 = cindex.length, p = p0; p < p1; p++) {
3850- // row
3851- var ic = cindex[p];
3852- // copy value
3853- cvalues[p] = x[ic];
3854- }
3855- }
3856- }
3857- // update ptr
3858- cptr[bcolumns] = cindex.length;
3859-
3860- // check we need to squeeze the result into a scalar
3861- if (arows === 1 && bcolumns === 1 && values)
3862- return cvalues.length === 1 ? cvalues[0] : 0;
3863-
3864- // return sparse matrix
3865- return c;
3866- };
3867-
3868- multiply.toTex = '\\left(${args[0]}' + latex.operators['multiply'] + '${args[1]}\\right)';
3869-
3870- return multiply;
3871- }
3872-
3873- exports.name = 'multiply';
3874- exports.factory = factory;
3875-
3876-
3877-/***/ },
3878-/* 41 */
3879-/***/ function(module, exports) {
3880-
3881- 'use strict';
3882-
3883- function factory(type, config, load, typed) {
3884-
3885- /**
3886- * Multiply two scalar values, `x * y`.
3887- * This function is meant for internal use: it is used by the public function
3888- * `multiply`
3889- *
3890- * This function does not support collections (Array or Matrix), and does
3891- * not validate the number of of inputs.
3892- *
3893- * @param {number | BigNumber | Fraction | Complex | Unit} x First value to multiply
3894- * @param {number | BigNumber | Fraction | Complex} y Second value to multiply
3895- * @return {number | BigNumber | Fraction | Complex | Unit} Multiplication of `x` and `y`
3896- * @private
3897- */
3898- var multiplyScalar = typed('multiplyScalar', {
3899-
3900- 'number, number': function (x, y) {
3901- return x * y;
3902- },
3903-
3904- 'Complex, Complex': function (x, y) {
3905- return new type.Complex(
3906- x.re * y.re - x.im * y.im,
3907- x.re * y.im + x.im * y.re
3908- );
3909- },
3910-
3911- 'BigNumber, BigNumber': function (x, y) {
3912- return x.times(y);
3913- },
3914-
3915- 'Fraction, Fraction': function (x, y) {
3916- return x.mul(y);
3917- },
3918-
3919- 'number, Unit': function (x, y) {
3920- var res = y.clone();
3921- res.value = (res.value === null) ? res._normalize(x) : (res.value * x);
3922- return res;
3923- },
3924-
3925- 'Unit, number': function (x, y) {
3926- var res = x.clone();
3927- res.value = (res.value === null) ? res._normalize(y) : (res.value * y);
3928- return res;
3929- },
3930-
3931- 'Unit, Unit': function (x, y) {
3932- return x.multiply(y);
3933- }
3934-
3935- });
3936-
3937- return multiplyScalar;
3938- }
3939-
3940- exports.factory = factory;
3941-
3942-
3943-/***/ },
3944-/* 42 */
3945-/***/ function(module, exports, __webpack_require__) {
3946-
3947- 'use strict';
3948-
3949- function factory (type, config, load, typed) {
3950-
3951- var equalScalar = load(__webpack_require__(33));
3952-
3953- var SparseMatrix = type.SparseMatrix;
3954-
3955- /**
3956- * Iterates over SparseMatrix S nonzero items and invokes the callback function f(Sij, b).
3957- * Callback function invoked NZ times (number of nonzero items in S).
3958- *
3959- *
3960- * ┌ f(Sij, b) ; S(i,j) !== 0
3961- * C(i,j) = ┤
3962- * â”” 0 ; otherwise
3963- *
3964- *
3965- * @param {Matrix} s The SparseMatrix instance (S)
3966- * @param {Scalar} b The Scalar value
3967- * @param {Function} callback The f(Aij,b) operation to invoke
3968- * @param {boolean} inverse A true value indicates callback should be invoked f(b,Sij)
3969- *
3970- * @return {Matrix} SparseMatrix (C)
3971- *
3972- * https://github.com/josdejong/mathjs/pull/346#issuecomment-97626813
3973- */
3974- var algorithm11 = function (s, b, callback, inverse) {
3975- // sparse matrix arrays
3976- var avalues = s._values;
3977- var aindex = s._index;
3978- var aptr = s._ptr;
3979- var asize = s._size;
3980- var adt = s._datatype;
3981-
3982- // sparse matrix cannot be a Pattern matrix
3983- if (!avalues)
3984- throw new Error('Cannot perform operation on Pattern Sparse Matrix and Scalar value');
3985-
3986- // rows & columns
3987- var rows = asize[0];
3988- var columns = asize[1];
3989-
3990- // datatype
3991- var dt;
3992- // equal signature to use
3993- var eq = equalScalar;
3994- // zero value
3995- var zero = 0;
3996- // callback signature to use
3997- var cf = callback;
3998-
3999- // process data types
4000- if (typeof adt === 'string') {
4001- // datatype
4002- dt = adt;
4003- // find signature that matches (dt, dt)
4004- eq = typed.find(equalScalar, [dt, dt]);
4005- // convert 0 to the same datatype
4006- zero = typed.convert(0, dt);
4007- // convert b to the same datatype
4008- b = typed.convert(b, dt);
4009- // callback
4010- cf = typed.find(callback, [dt, dt]);
4011- }
4012-
4013- // result arrays
4014- var cvalues = [];
4015- var cindex = [];
4016- var cptr = [];
4017- // matrix
4018- var c = new SparseMatrix({
4019- values: cvalues,
4020- index: cindex,
4021- ptr: cptr,
4022- size: [rows, columns],
4023- datatype: dt
4024- });
4025-
4026- // loop columns
4027- for (var j = 0; j < columns; j++) {
4028- // initialize ptr
4029- cptr[j] = cindex.length;
4030- // values in j
4031- for (var k0 = aptr[j], k1 = aptr[j + 1], k = k0; k < k1; k++) {
4032- // row
4033- var i = aindex[k];
4034- // invoke callback
4035- var v = inverse ? cf(b, avalues[k]) : cf(avalues[k], b);
4036- // check value is zero
4037- if (!eq(v, zero)) {
4038- // push index & value
4039- cindex.push(i);
4040- cvalues.push(v);
4041- }
4042- }
4043- }
4044- // update ptr
4045- cptr[columns] = cindex.length;
4046-
4047- // return sparse matrix
4048- return c;
4049- };
4050-
4051- return algorithm11;
4052- }
4053-
4054- exports.name = 'algorithm11';
4055- exports.factory = factory;
4056-
4057-
4058-/***/ },
4059-/* 43 */
4060-/***/ function(module, exports, __webpack_require__) {
4061-
4062- 'use strict';
4063-
4064- var util = __webpack_require__(36);
4065- var object = util.object;
4066- var string = util.string;
4067-
4068- function factory (type, config, load, typed) {
4069- var matrix = load(__webpack_require__(23));
4070- var add = load(__webpack_require__(44));
4071- var subtract = load(__webpack_require__(25));
4072- var multiply = load(__webpack_require__(40));
4073- var unaryMinus = load(__webpack_require__(28));
4074-
4075- /**
4076- * Calculate the determinant of a matrix.
4077- *
4078- * Syntax:
4079- *
4080- * math.det(x)
4081- *
4082- * Examples:
4083- *
4084- * math.det([[1, 2], [3, 4]]); // returns -2
4085- *
4086- * var A = [
4087- * [-2, 2, 3],
4088- * [-1, 1, 3],
4089- * [2, 0, -1]
4090- * ]
4091- * math.det(A); // returns 6
4092- *
4093- * See also:
4094- *
4095- * inv
4096- *
4097- * @param {Array | Matrix} x A matrix
4098- * @return {number} The determinant of `x`
4099- */
4100- var det = typed('det', {
4101- 'any': function (x) {
4102- return object.clone(x);
4103- },
4104-
4105- 'Array | Matrix': function det (x) {
4106- var size;
4107- if (x && x.isMatrix === true) {
4108- size = x.size();
4109- }
4110- else if (Array.isArray(x)) {
4111- x = matrix(x);
4112- size = x.size();
4113- }
4114- else {
4115- // a scalar
4116- size = [];
4117- }
4118-
4119- switch (size.length) {
4120- case 0:
4121- // scalar
4122- return object.clone(x);
4123-
4124- case 1:
4125- // vector
4126- if (size[0] == 1) {
4127- return object.clone(x.valueOf()[0]);
4128- }
4129- else {
4130- throw new RangeError('Matrix must be square ' +
4131- '(size: ' + string.format(size) + ')');
4132- }
4133-
4134- case 2:
4135- // two dimensional array
4136- var rows = size[0];
4137- var cols = size[1];
4138- if (rows == cols) {
4139- return _det(x.clone().valueOf(), rows, cols);
4140- }
4141- else {
4142- throw new RangeError('Matrix must be square ' +
4143- '(size: ' + string.format(size) + ')');
4144- }
4145-
4146- default:
4147- // multi dimensional array
4148- throw new RangeError('Matrix must be two dimensional ' +
4149- '(size: ' + string.format(size) + ')');
4150- }
4151- }
4152- });
4153-
4154- det.toTex = '\\det\\left(${args[0]}\\right)';
4155-
4156- return det;
4157-
4158- /**
4159- * Calculate the determinant of a matrix
4160- * @param {Array[]} matrix A square, two dimensional matrix
4161- * @param {number} rows Number of rows of the matrix (zero-based)
4162- * @param {number} cols Number of columns of the matrix (zero-based)
4163- * @returns {number} det
4164- * @private
4165- */
4166- function _det (matrix, rows, cols) {
4167- if (rows == 1) {
4168- // this is a 1 x 1 matrix
4169- return object.clone(matrix[0][0]);
4170- }
4171- else if (rows == 2) {
4172- // this is a 2 x 2 matrix
4173- // the determinant of [a11,a12;a21,a22] is det = a11*a22-a21*a12
4174- return subtract(
4175- multiply(matrix[0][0], matrix[1][1]),
4176- multiply(matrix[1][0], matrix[0][1])
4177- );
4178- }
4179- else {
4180- // this is an n x n matrix
4181- var compute_mu = function (matrix) {
4182- var i, j;
4183-
4184- // Compute the matrix with zero lower triangle, same upper triangle,
4185- // and diagonals given by the negated sum of the below diagonal
4186- // elements.
4187- var mu = new Array(matrix.length);
4188- var sum = 0;
4189- for (i = 1; i < matrix.length; i++) {
4190- sum = add(sum, matrix[i][i]);
4191- }
4192-
4193- for (i = 0; i < matrix.length; i++) {
4194- mu[i] = new Array(matrix.length);
4195- mu[i][i] = unaryMinus(sum);
4196-
4197- for (j = 0; j < i; j++) {
4198- mu[i][j] = 0; // TODO: make bignumber 0 in case of bignumber computation
4199- }
4200-
4201- for (j = i + 1; j < matrix.length; j++) {
4202- mu[i][j] = matrix[i][j];
4203- }
4204-
4205- if (i+1 < matrix.length) {
4206- sum = subtract(sum, matrix[i + 1][i + 1]);
4207- }
4208- }
4209-
4210- return mu;
4211- };
4212-
4213- var fa = matrix;
4214- for (var i = 0; i < rows - 1; i++) {
4215- fa = multiply(compute_mu(fa), matrix);
4216- }
4217-
4218- if (rows % 2 == 0) {
4219- return unaryMinus(fa[0][0]);
4220- } else {
4221- return fa[0][0];
4222- }
4223- }
4224- }
4225- }
4226-
4227- exports.name = 'det';
4228- exports.factory = factory;
4229-
4230-
4231-
4232-/***/ },
4233-/* 44 */
4234-/***/ function(module, exports, __webpack_require__) {
4235-
4236- 'use strict';
4237-
4238- var extend = __webpack_require__(5).extend;
4239-
4240- function factory (type, config, load, typed) {
4241-
4242- var matrix = load(__webpack_require__(23));
4243- var addScalar = load(__webpack_require__(27));
4244- var latex = __webpack_require__(26);
4245-
4246- var algorithm01 = load(__webpack_require__(30));
4247- var algorithm04 = load(__webpack_require__(45));
4248- var algorithm10 = load(__webpack_require__(34));
4249- var algorithm13 = load(__webpack_require__(35));
4250- var algorithm14 = load(__webpack_require__(39));
4251-
4252- /**
4253- * Add two values, `x + y`.
4254- * For matrices, the function is evaluated element wise.
4255- *
4256- * Syntax:
4257- *
4258- * math.add(x, y)
4259- *
4260- * Examples:
4261- *
4262- * math.add(2, 3); // returns number 5
4263- *
4264- * var a = math.complex(2, 3);
4265- * var b = math.complex(-4, 1);
4266- * math.add(a, b); // returns Complex -2 + 4i
4267- *
4268- * math.add([1, 2, 3], 4); // returns Array [5, 6, 7]
4269- *
4270- * var c = math.unit('5 cm');
4271- * var d = math.unit('2.1 mm');
4272- * math.add(c, d); // returns Unit 52.1 mm
4273- *
4274- * math.add("2.3", "4"); // returns number 6.3
4275- *
4276- * See also:
4277- *
4278- * subtract
4279- *
4280- * @param {number | BigNumber | Fraction | Complex | Unit | Array | Matrix} x First value to add
4281- * @param {number | BigNumber | Fraction | Complex | Unit | Array | Matrix} y Second value to add
4282- * @return {number | BigNumber | Fraction | Complex | Unit | Array | Matrix} Sum of `x` and `y`
4283- */
4284- var add = typed('add', extend({
4285- // we extend the signatures of addScalar with signatures dealing with matrices
4286-
4287- 'Matrix, Matrix': function (x, y) {
4288- // result
4289- var c;
4290-
4291- // process matrix storage
4292- switch (x.storage()) {
4293- case 'sparse':
4294- switch (y.storage()) {
4295- case 'sparse':
4296- // sparse + sparse
4297- c = algorithm04(x, y, addScalar);
4298- break;
4299- default:
4300- // sparse + dense
4301- c = algorithm01(y, x, addScalar, true);
4302- break;
4303- }
4304- break;
4305- default:
4306- switch (y.storage()) {
4307- case 'sparse':
4308- // dense + sparse
4309- c = algorithm01(x, y, addScalar, false);
4310- break;
4311- default:
4312- // dense + dense
4313- c = algorithm13(x, y, addScalar);
4314- break;
4315- }
4316- break;
4317- }
4318- return c;
4319- },
4320-
4321- 'Array, Array': function (x, y) {
4322- // use matrix implementation
4323- return add(matrix(x), matrix(y)).valueOf();
4324- },
4325-
4326- 'Array, Matrix': function (x, y) {
4327- // use matrix implementation
4328- return add(matrix(x), y);
4329- },
4330-
4331- 'Matrix, Array': function (x, y) {
4332- // use matrix implementation
4333- return add(x, matrix(y));
4334- },
4335-
4336- 'Matrix, any': function (x, y) {
4337- // result
4338- var c;
4339- // check storage format
4340- switch (x.storage()) {
4341- case 'sparse':
4342- c = algorithm10(x, y, addScalar, false);
4343- break;
4344- default:
4345- c = algorithm14(x, y, addScalar, false);
4346- break;
4347- }
4348- return c;
4349- },
4350-
4351- 'any, Matrix': function (x, y) {
4352- // result
4353- var c;
4354- // check storage format
4355- switch (y.storage()) {
4356- case 'sparse':
4357- c = algorithm10(y, x, addScalar, true);
4358- break;
4359- default:
4360- c = algorithm14(y, x, addScalar, true);
4361- break;
4362- }
4363- return c;
4364- },
4365-
4366- 'Array, any': function (x, y) {
4367- // use matrix implementation
4368- return algorithm14(matrix(x), y, addScalar, false).valueOf();
4369- },
4370-
4371- 'any, Array': function (x, y) {
4372- // use matrix implementation
4373- return algorithm14(matrix(y), x, addScalar, true).valueOf();
4374- }
4375- }, addScalar.signatures));
4376-
4377- add.toTex = '\\left(${args[0]}' + latex.operators['add'] + '${args[1]}\\right)';
4378-
4379- return add;
4380- }
4381-
4382- exports.name = 'add';
4383- exports.factory = factory;
4384-
4385-
4386-/***/ },
4387-/* 45 */
4388-/***/ function(module, exports, __webpack_require__) {
4389-
4390- 'use strict';
4391-
4392- var DimensionError = __webpack_require__(22);
4393-
4394- function factory (type, config, load, typed) {
4395-
4396- var equalScalar = load(__webpack_require__(33));
4397-
4398- var SparseMatrix = type.SparseMatrix;
4399-
4400- /**
4401- * Iterates over SparseMatrix A and SparseMatrix B nonzero items and invokes the callback function f(Aij, Bij).
4402- * Callback function invoked MAX(NNZA, NNZB) times
4403- *
4404- *
4405- * ┌ f(Aij, Bij) ; A(i,j) !== 0 && B(i,j) !== 0
4406- * C(i,j) = ┤ A(i,j) ; A(i,j) !== 0
4407- * â”” B(i,j) ; B(i,j) !== 0
4408- *
4409- *
4410- * @param {Matrix} a The SparseMatrix instance (A)
4411- * @param {Matrix} b The SparseMatrix instance (B)
4412- * @param {Function} callback The f(Aij,Bij) operation to invoke
4413- *
4414- * @return {Matrix} SparseMatrix (C)
4415- *
4416- * see https://github.com/josdejong/mathjs/pull/346#issuecomment-97620294
4417- */
4418- var algorithm04 = function (a, b, callback) {
4419- // sparse matrix arrays
4420- var avalues = a._values;
4421- var aindex = a._index;
4422- var aptr = a._ptr;
4423- var asize = a._size;
4424- var adt = a._datatype;
4425- // sparse matrix arrays
4426- var bvalues = b._values;
4427- var bindex = b._index;
4428- var bptr = b._ptr;
4429- var bsize = b._size;
4430- var bdt = b._datatype;
4431-
4432- // validate dimensions
4433- if (asize.length !== bsize.length)
4434- throw new DimensionError(asize.length, bsize.length);
4435-
4436- // check rows & columns
4437- if (asize[0] !== bsize[0] || asize[1] !== bsize[1])
4438- throw new RangeError('Dimension mismatch. Matrix A (' + asize + ') must match Matrix B (' + bsize + ')');
4439-
4440- // rows & columns
4441- var rows = asize[0];
4442- var columns = asize[1];
4443-
4444- // datatype
4445- var dt;
4446- // equal signature to use
4447- var eq = equalScalar;
4448- // zero value
4449- var zero = 0;
4450- // callback signature to use
4451- var cf = callback;
4452-
4453- // process data types
4454- if (typeof adt === 'string' && adt === bdt) {
4455- // datatype
4456- dt = adt;
4457- // find signature that matches (dt, dt)
4458- eq = typed.find(equalScalar, [dt, dt]);
4459- // convert 0 to the same datatype
4460- zero = typed.convert(0, dt);
4461- // callback
4462- cf = typed.find(callback, [dt, dt]);
4463- }
4464-
4465- // result arrays
4466- var cvalues = avalues && bvalues ? [] : undefined;
4467- var cindex = [];
4468- var cptr = [];
4469- // matrix
4470- var c = new SparseMatrix({
4471- values: cvalues,
4472- index: cindex,
4473- ptr: cptr,
4474- size: [rows, columns],
4475- datatype: dt
4476- });
4477-
4478- // workspace
4479- var xa = avalues && bvalues ? [] : undefined;
4480- var xb = avalues && bvalues ? [] : undefined;
4481- // marks indicating we have a value in x for a given column
4482- var wa = [];
4483- var wb = [];
4484-
4485- // vars
4486- var i, j, k, k0, k1;
4487-
4488- // loop columns
4489- for (j = 0; j < columns; j++) {
4490- // update cptr
4491- cptr[j] = cindex.length;
4492- // columns mark
4493- var mark = j + 1;
4494- // loop A(:,j)
4495- for (k0 = aptr[j], k1 = aptr[j + 1], k = k0; k < k1; k++) {
4496- // row
4497- i = aindex[k];
4498- // update c
4499- cindex.push(i);
4500- // update workspace
4501- wa[i] = mark;
4502- // check we need to process values
4503- if (xa)
4504- xa[i] = avalues[k];
4505- }
4506- // loop B(:,j)
4507- for (k0 = bptr[j], k1 = bptr[j + 1], k = k0; k < k1; k++) {
4508- // row
4509- i = bindex[k];
4510- // check row exists in A
4511- if (wa[i] === mark) {
4512- // update record in xa @ i
4513- if (xa) {
4514- // invoke callback
4515- var v = cf(xa[i], bvalues[k]);
4516- // check for zero
4517- if (!eq(v, zero)) {
4518- // update workspace
4519- xa[i] = v;
4520- }
4521- else {
4522- // remove mark (index will be removed later)
4523- wa[i] = null;
4524- }
4525- }
4526- }
4527- else {
4528- // update c
4529- cindex.push(i);
4530- // update workspace
4531- wb[i] = mark;
4532- // check we need to process values
4533- if (xb)
4534- xb[i] = bvalues[k];
4535- }
4536- }
4537- // check we need to process values (non pattern matrix)
4538- if (xa && xb) {
4539- // initialize first index in j
4540- k = cptr[j];
4541- // loop index in j
4542- while (k < cindex.length) {
4543- // row
4544- i = cindex[k];
4545- // check workspace has value @ i
4546- if (wa[i] === mark) {
4547- // push value (Aij != 0 || (Aij != 0 && Bij != 0))
4548- cvalues[k] = xa[i];
4549- // increment pointer
4550- k++;
4551- }
4552- else if (wb[i] === mark) {
4553- // push value (bij != 0)
4554- cvalues[k] = xb[i];
4555- // increment pointer
4556- k++;
4557- }
4558- else {
4559- // remove index @ k
4560- cindex.splice(k, 1);
4561- }
4562- }
4563- }
4564- }
4565- // update cptr
4566- cptr[columns] = cindex.length;
4567-
4568- // return sparse matrix
4569- return c;
4570- };
4571-
4572- return algorithm04;
4573- }
4574-
4575- exports.name = 'algorithm04';
4576- exports.factory = factory;
4577-
4578-
4579-/***/ },
4580-/* 46 */
4581-/***/ function(module, exports, __webpack_require__) {
4582-
4583- 'use strict';
4584-
4585- var array = __webpack_require__(18);
4586- var clone = __webpack_require__(5).clone;
4587- var isInteger = __webpack_require__(8).isInteger;
4588-
4589- function factory (type, config, load, typed) {
4590-
4591- var matrix = load(__webpack_require__(23));
4592-
4593- /**
4594- * Create a diagonal matrix or retrieve the diagonal of a matrix
4595- *
4596- * When `x` is a vector, a matrix with vector `x` on the diagonal will be returned.
4597- * When `x` is a two dimensional matrix, the matrixes `k`th diagonal will be returned as vector.
4598- * When k is positive, the values are placed on the super diagonal.
4599- * When k is negative, the values are placed on the sub diagonal.
4600- *
4601- * Syntax:
4602- *
4603- * math.diag(X)
4604- * math.diag(X, format)
4605- * math.diag(X, k)
4606- * math.diag(X, k, format)
4607- *
4608- * Examples:
4609- *
4610- * // create a diagonal matrix
4611- * math.diag([1, 2, 3]); // returns [[1, 0, 0], [0, 2, 0], [0, 0, 3]]
4612- * math.diag([1, 2, 3], 1); // returns [[0, 1, 0, 0], [0, 0, 2, 0], [0, 0, 0, 3]]
4613- * math.diag([1, 2, 3], -1); // returns [[0, 0, 0], [1, 0, 0], [0, 2, 0], [0, 0, 3]]
4614- *
4615- * // retrieve the diagonal from a matrix
4616- * var a = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
4617- * math.diag(a); // returns [1, 5, 9]
4618- *
4619- * See also:
4620- *
4621- * ones, zeros, eye
4622- *
4623- * @param {Matrix | Array} x A two dimensional matrix or a vector
4624- * @param {number | BigNumber} [k=0] The diagonal where the vector will be filled
4625- * in or retrieved.
4626- * @param {string} [format='dense'] The matrix storage format.
4627- *
4628- * @returns {Matrix | Array} Diagonal matrix from input vector, or diagonal from input matrix.
4629- */
4630- var diag = typed('diag', {
4631- // FIXME: simplify this huge amount of signatures as soon as typed-function supports optional arguments
4632-
4633- 'Array': function (x) {
4634- return _diag(x, 0, array.size(x), null);
4635- },
4636-
4637- 'Array, number': function (x, k) {
4638- return _diag(x, k, array.size(x), null);
4639- },
4640-
4641- 'Array, BigNumber': function (x, k) {
4642- return _diag(x, k.toNumber(), array.size(x), null);
4643- },
4644-
4645- 'Array, string': function (x, format) {
4646- return _diag(x, 0, array.size(x), format);
4647- },
4648-
4649- 'Array, number, string': function (x, k, format) {
4650- return _diag(x, k, array.size(x), format);
4651- },
4652-
4653- 'Array, BigNumber, string': function (x, k, format) {
4654- return _diag(x, k.toNumber(), array.size(x), format);
4655- },
4656-
4657- 'Matrix': function (x) {
4658- return _diag(x, 0, x.size(), x.storage());
4659- },
4660-
4661- 'Matrix, number': function (x, k) {
4662- return _diag(x, k, x.size(), x.storage());
4663- },
4664-
4665- 'Matrix, BigNumber': function (x, k) {
4666- return _diag(x, k.toNumber(), x.size(), x.storage());
4667- },
4668-
4669- 'Matrix, string': function (x, format) {
4670- return _diag(x, 0, x.size(), format);
4671- },
4672-
4673- 'Matrix, number, string': function (x, k, format) {
4674- return _diag(x, k, x.size(), format);
4675- },
4676-
4677- 'Matrix, BigNumber, string': function (x, k, format) {
4678- return _diag(x, k.toNumber(), x.size(), format);
4679- }
4680- });
4681-
4682- diag.toTex = '\\mathrm{${name}}\\left(${args}\\right)';
4683-
4684- return diag;
4685-
4686- /**
4687- * Creeate diagonal matrix from a vector or vice versa
4688- * @param {Array | Matrix} x
4689- * @param {number} k
4690- * @param {string} format Storage format for matrix. If null,
4691- * an Array is returned
4692- * @returns {Array | Matrix}
4693- * @private
4694- */
4695- function _diag (x, k, size, format) {
4696- if (!isInteger(k)) {
4697- throw new TypeError ('Second parameter in function diag must be an integer');
4698- }
4699-
4700- var kSuper = k > 0 ? k : 0;
4701- var kSub = k < 0 ? -k : 0;
4702-
4703- // check dimensions
4704- switch (size.length) {
4705- case 1:
4706- return _createDiagonalMatrix(x, k, format, size[0], kSub, kSuper);
4707- case 2:
4708- return _getDiagonal(x, k, format, size, kSub, kSuper);
4709- }
4710- throw new RangeError('Matrix for function diag must be 2 dimensional');
4711- }
4712-
4713- function _createDiagonalMatrix(x, k, format, l, kSub, kSuper) {
4714- // matrix size
4715- var ms = [l + kSub, l + kSuper];
4716- // get matrix constructor
4717- var F = type.Matrix.storage(format || 'dense');
4718- // create diagonal matrix
4719- var m = F.diagonal(ms, x, k);
4720- // check we need to return a matrix
4721- return format !== null ? m : m.valueOf();
4722- }
4723-
4724- function _getDiagonal(x, k, format, s, kSub, kSuper) {
4725- // check x is a Matrix
4726- if (x && x.isMatrix === true) {
4727- // get diagonal matrix
4728- var dm = x.diagonal(k);
4729- // check we need to return a matrix
4730- if (format !== null) {
4731- // check we need to change matrix format
4732- if (format !== dm.storage())
4733- return matrix(dm, format);
4734- return dm;
4735- }
4736- return dm.valueOf();
4737- }
4738- // vector size
4739- var n = Math.min(s[0] - kSub, s[1] - kSuper);
4740- // diagonal values
4741- var vector = [];
4742- // loop diagonal
4743- for (var i = 0; i < n; i++) {
4744- vector[i] = clone(x[i + kSub][i + kSuper]);
4745- }
4746- // check we need to return a matrix
4747- return format !== null ? matrix(vector) : vector;
4748- }
4749- }
4750-
4751- exports.name = 'diag';
4752- exports.factory = factory;
4753-
4754-
4755-/***/ },
4756-/* 47 */
4757-/***/ function(module, exports, __webpack_require__) {
4758-
4759- 'use strict';
4760-
4761- var size = __webpack_require__(18).size;
4762-
4763- function factory (type, config, load, typed) {
4764- var add = load(__webpack_require__(44));
4765- var multiply = load(__webpack_require__(40));
4766-
4767- /**
4768- * Calculate the dot product of two vectors. The dot product of
4769- * `A = [a1, a2, a3, ..., an]` and `B = [b1, b2, b3, ..., bn]` is defined as:
4770- *
4771- * dot(A, B) = a1 * b1 + a2 * b2 + a3 * b3 + ... + an * bn
4772- *
4773- * Syntax:
4774- *
4775- * math.dot(x, y)
4776- *
4777- * Examples:
4778- *
4779- * math.dot([2, 4, 1], [2, 2, 3]); // returns number 15
4780- * math.multiply([2, 4, 1], [2, 2, 3]); // returns number 15
4781- *
4782- * See also:
4783- *
4784- * multiply, cross
4785- *
4786- * @param {Array | Matrix} x First vector
4787- * @param {Array | Matrix} y Second vector
4788- * @return {number} Returns the dot product of `x` and `y`
4789- */
4790- var dot = typed('dot', {
4791- 'Matrix, Matrix': function (x, y) {
4792- return _dot(x.toArray(), y.toArray());
4793- },
4794-
4795- 'Matrix, Array': function (x, y) {
4796- return _dot(x.toArray(), y);
4797- },
4798-
4799- 'Array, Matrix': function (x, y) {
4800- return _dot(x, y.toArray());
4801- },
4802-
4803- 'Array, Array': _dot
4804- });
4805-
4806- dot.toTex = '\\left(${args[0]}\\cdot${args[1]}\\right)';
4807-
4808- return dot;
4809-
4810- /**
4811- * Calculate the dot product for two arrays
4812- * @param {Array} x First vector
4813- * @param {Array} y Second vector
4814- * @returns {number} Returns the dot product of x and y
4815- * @private
4816- */
4817- // TODO: double code with math.multiply
4818- function _dot(x, y) {
4819- var xSize= size(x);
4820- var ySize = size(y);
4821- var len = xSize[0];
4822-
4823- if (xSize.length !== 1 || ySize.length !== 1) throw new RangeError('Vector expected'); // TODO: better error message
4824- if (xSize[0] != ySize[0]) throw new RangeError('Vectors must have equal length (' + xSize[0] + ' != ' + ySize[0] + ')');
4825- if (len == 0) throw new RangeError('Cannot calculate the dot product of empty vectors');
4826-
4827- var prod = 0;
4828- for (var i = 0; i < len; i++) {
4829- prod = add(prod, multiply(x[i], y[i]));
4830- }
4831-
4832- return prod;
4833- }
4834- }
4835-
4836- exports.name = 'dot';
4837- exports.factory = factory;
4838-
4839-
4840-/***/ },
4841-/* 48 */
4842-/***/ function(module, exports, __webpack_require__) {
4843-
4844- 'use strict';
4845-
4846- var array = __webpack_require__(18);
4847- var isInteger = __webpack_require__(8).isInteger;
4848-
4849- function factory (type, config, load, typed) {
4850-
4851- var matrix = load(__webpack_require__(23));
4852-
4853- /**
4854- * Create a 2-dimensional identity matrix with size m x n or n x n.
4855- * The matrix has ones on the diagonal and zeros elsewhere.
4856- *
4857- * Syntax:
4858- *
4859- * math.eye(n)
4860- * math.eye(n, format)
4861- * math.eye(m, n)
4862- * math.eye(m, n, format)
4863- * math.eye([m, n])
4864- * math.eye([m, n], format)
4865- *
4866- * Examples:
4867- *
4868- * math.eye(3); // returns [[1, 0, 0], [0, 1, 0], [0, 0, 1]]
4869- * math.eye(3, 2); // returns [[1, 0], [0, 1], [0, 0]]
4870- *
4871- * var A = [[1, 2, 3], [4, 5, 6]];
4872- * math.eye(math.size(b)); // returns [[1, 0, 0], [0, 1, 0]]
4873- *
4874- * See also:
4875- *
4876- * diag, ones, zeros, size, range
4877- *
4878- * @param {...number | Matrix | Array} size The size for the matrix
4879- * @param {string} [format] The Matrix storage format
4880- *
4881- * @return {Matrix | Array | number} A matrix with ones on the diagonal.
4882- */
4883- var eye = typed('eye', {
4884- '': function () {
4885- return (config.matrix === 'matrix') ? matrix([]) : [];
4886- },
4887-
4888- 'string': function (format) {
4889- return matrix(format);
4890- },
4891-
4892- 'number | BigNumber': function (rows) {
4893- return _eye(rows, rows, config.matrix === 'matrix' ? 'default' : undefined);
4894- },
4895-
4896- 'number | BigNumber, string': function (rows, format) {
4897- return _eye(rows, rows, format);
4898- },
4899-
4900- 'number | BigNumber, number | BigNumber': function (rows, cols) {
4901- return _eye(rows, cols, config.matrix === 'matrix' ? 'default' : undefined);
4902- },
4903-
4904- 'number | BigNumber, number | BigNumber, string': function (rows, cols, format) {
4905- return _eye(rows, cols, format);
4906- },
4907-
4908- 'Array': function (size) {
4909- return _eyeVector(size);
4910- },
4911-
4912- 'Array, string': function (size, format) {
4913- return _eyeVector(size, format);
4914- },
4915-
4916- 'Matrix': function (size) {
4917- return _eyeVector(size.valueOf(), size.storage());
4918- },
4919-
4920- 'Matrix, string': function (size, format) {
4921- return _eyeVector(size.valueOf(), format);
4922- }
4923- });
4924-
4925- eye.toTex = '\\mathrm{${name}}\\left(${args}\\right)';
4926-
4927- return eye;
4928-
4929- function _eyeVector (size, format) {
4930- switch (size.length) {
4931- case 0: return format ? matrix(format) : [];
4932- case 1: return _eye(size[0], size[0], format);
4933- case 2: return _eye(size[0], size[1], format);
4934- default: throw new Error('Vector containing two values expected');
4935- }
4936- }
4937-
4938- /**
4939- * Create an identity matrix
4940- * @param {number | BigNumber} rows
4941- * @param {number | BigNumber} cols
4942- * @param {string} [format]
4943- * @returns {Matrix}
4944- * @private
4945- */
4946- function _eye (rows, cols, format) {
4947- // BigNumber constructor with the right precision
4948- var Big = (rows && rows.isBigNumber === true)
4949- ? type.BigNumber
4950- : (cols && cols.isBigNumber === true)
4951- ? type.BigNumber
4952- : null;
4953-
4954- if (rows && rows.isBigNumber === true) rows = rows.toNumber();
4955- if (cols && cols.isBigNumber === true) cols = cols.toNumber();
4956-
4957- if (!isInteger(rows) || rows < 1) {
4958- throw new Error('Parameters in function eye must be positive integers');
4959- }
4960- if (!isInteger(cols) || cols < 1) {
4961- throw new Error('Parameters in function eye must be positive integers');
4962- }
4963-
4964- var one = Big ? new type.BigNumber(1) : 1;
4965- var defaultValue = Big ? new Big(0) : 0;
4966- var size = [rows, cols];
4967-
4968- // check we need to return a matrix
4969- if (format) {
4970- // get matrix storage constructor
4971- var F = type.Matrix.storage(format);
4972- // create diagonal matrix (use optimized implementation for storage format)
4973- return F.diagonal(size, one, 0, defaultValue);
4974- }
4975-
4976- // create and resize array
4977- var res = array.resize([], size, defaultValue);
4978- // fill in ones on the diagonal
4979- var minimum = rows < cols ? rows : cols;
4980- // fill diagonal
4981- for (var d = 0; d < minimum; d++) {
4982- res[d][d] = one;
4983- }
4984- return res;
4985- }
4986- }
4987-
4988- exports.name = 'eye';
4989- exports.factory = factory;
4990-
4991-
4992-/***/ },
4993-/* 49 */
4994-/***/ function(module, exports, __webpack_require__) {
4995-
4996- 'use strict';
4997-
4998- var clone = __webpack_require__(5).clone;
4999- var _flatten = __webpack_require__(18).flatten;
5000-
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches