UNPKG

24.1 kBJavaScriptView Raw
1import { factory } from '../../utils/factory.js';
2import { isMatrix } from '../../utils/is.js';
3import { extend } from '../../utils/object.js';
4import { arraySize } from '../../utils/array.js';
5import { createAlgorithm11 } from '../../type/matrix/utils/algorithm11.js';
6import { createAlgorithm14 } from '../../type/matrix/utils/algorithm14.js';
7var name = 'multiply';
8var dependencies = ['typed', 'matrix', 'addScalar', 'multiplyScalar', 'equalScalar', 'dot'];
9export var createMultiply = /* #__PURE__ */factory(name, dependencies, (_ref) => {
10 var {
11 typed,
12 matrix,
13 addScalar,
14 multiplyScalar,
15 equalScalar,
16 dot
17 } = _ref;
18 var algorithm11 = createAlgorithm11({
19 typed,
20 equalScalar
21 });
22 var algorithm14 = createAlgorithm14({
23 typed
24 });
25
26 function _validateMatrixDimensions(size1, size2) {
27 // check left operand dimensions
28 switch (size1.length) {
29 case 1:
30 // check size2
31 switch (size2.length) {
32 case 1:
33 // Vector x Vector
34 if (size1[0] !== size2[0]) {
35 // throw error
36 throw new RangeError('Dimension mismatch in multiplication. Vectors must have the same length');
37 }
38
39 break;
40
41 case 2:
42 // Vector x Matrix
43 if (size1[0] !== size2[0]) {
44 // throw error
45 throw new RangeError('Dimension mismatch in multiplication. Vector length (' + size1[0] + ') must match Matrix rows (' + size2[0] + ')');
46 }
47
48 break;
49
50 default:
51 throw new Error('Can only multiply a 1 or 2 dimensional matrix (Matrix B has ' + size2.length + ' dimensions)');
52 }
53
54 break;
55
56 case 2:
57 // check size2
58 switch (size2.length) {
59 case 1:
60 // Matrix x Vector
61 if (size1[1] !== size2[0]) {
62 // throw error
63 throw new RangeError('Dimension mismatch in multiplication. Matrix columns (' + size1[1] + ') must match Vector length (' + size2[0] + ')');
64 }
65
66 break;
67
68 case 2:
69 // Matrix x Matrix
70 if (size1[1] !== size2[0]) {
71 // throw error
72 throw new RangeError('Dimension mismatch in multiplication. Matrix A columns (' + size1[1] + ') must match Matrix B rows (' + size2[0] + ')');
73 }
74
75 break;
76
77 default:
78 throw new Error('Can only multiply a 1 or 2 dimensional matrix (Matrix B has ' + size2.length + ' dimensions)');
79 }
80
81 break;
82
83 default:
84 throw new Error('Can only multiply a 1 or 2 dimensional matrix (Matrix A has ' + size1.length + ' dimensions)');
85 }
86 }
87 /**
88 * C = A * B
89 *
90 * @param {Matrix} a Dense Vector (N)
91 * @param {Matrix} b Dense Vector (N)
92 *
93 * @return {number} Scalar value
94 */
95
96
97 function _multiplyVectorVector(a, b, n) {
98 // check empty vector
99 if (n === 0) {
100 throw new Error('Cannot multiply two empty vectors');
101 }
102
103 return dot(a, b);
104 }
105 /**
106 * C = A * B
107 *
108 * @param {Matrix} a Dense Vector (M)
109 * @param {Matrix} b Matrix (MxN)
110 *
111 * @return {Matrix} Dense Vector (N)
112 */
113
114
115 function _multiplyVectorMatrix(a, b) {
116 // process storage
117 if (b.storage() !== 'dense') {
118 throw new Error('Support for SparseMatrix not implemented');
119 }
120
121 return _multiplyVectorDenseMatrix(a, b);
122 }
123 /**
124 * C = A * B
125 *
126 * @param {Matrix} a Dense Vector (M)
127 * @param {Matrix} b Dense Matrix (MxN)
128 *
129 * @return {Matrix} Dense Vector (N)
130 */
131
132
133 function _multiplyVectorDenseMatrix(a, b) {
134 // a dense
135 var adata = a._data;
136 var asize = a._size;
137 var adt = a._datatype; // b dense
138
139 var bdata = b._data;
140 var bsize = b._size;
141 var bdt = b._datatype; // rows & columns
142
143 var alength = asize[0];
144 var bcolumns = bsize[1]; // datatype
145
146 var dt; // addScalar signature to use
147
148 var af = addScalar; // multiplyScalar signature to use
149
150 var mf = multiplyScalar; // process data types
151
152 if (adt && bdt && adt === bdt && typeof adt === 'string') {
153 // datatype
154 dt = adt; // find signatures that matches (dt, dt)
155
156 af = typed.find(addScalar, [dt, dt]);
157 mf = typed.find(multiplyScalar, [dt, dt]);
158 } // result
159
160
161 var c = []; // loop matrix columns
162
163 for (var j = 0; j < bcolumns; j++) {
164 // sum (do not initialize it with zero)
165 var sum = mf(adata[0], bdata[0][j]); // loop vector
166
167 for (var i = 1; i < alength; i++) {
168 // multiply & accumulate
169 sum = af(sum, mf(adata[i], bdata[i][j]));
170 }
171
172 c[j] = sum;
173 } // return matrix
174
175
176 return a.createDenseMatrix({
177 data: c,
178 size: [bcolumns],
179 datatype: dt
180 });
181 }
182 /**
183 * C = A * B
184 *
185 * @param {Matrix} a Matrix (MxN)
186 * @param {Matrix} b Dense Vector (N)
187 *
188 * @return {Matrix} Dense Vector (M)
189 */
190
191
192 var _multiplyMatrixVector = typed('_multiplyMatrixVector', {
193 'DenseMatrix, any': _multiplyDenseMatrixVector,
194 'SparseMatrix, any': _multiplySparseMatrixVector
195 });
196 /**
197 * C = A * B
198 *
199 * @param {Matrix} a Matrix (MxN)
200 * @param {Matrix} b Matrix (NxC)
201 *
202 * @return {Matrix} Matrix (MxC)
203 */
204
205
206 var _multiplyMatrixMatrix = typed('_multiplyMatrixMatrix', {
207 'DenseMatrix, DenseMatrix': _multiplyDenseMatrixDenseMatrix,
208 'DenseMatrix, SparseMatrix': _multiplyDenseMatrixSparseMatrix,
209 'SparseMatrix, DenseMatrix': _multiplySparseMatrixDenseMatrix,
210 'SparseMatrix, SparseMatrix': _multiplySparseMatrixSparseMatrix
211 });
212 /**
213 * C = A * B
214 *
215 * @param {Matrix} a DenseMatrix (MxN)
216 * @param {Matrix} b Dense Vector (N)
217 *
218 * @return {Matrix} Dense Vector (M)
219 */
220
221
222 function _multiplyDenseMatrixVector(a, b) {
223 // a dense
224 var adata = a._data;
225 var asize = a._size;
226 var adt = a._datatype; // b dense
227
228 var bdata = b._data;
229 var bdt = b._datatype; // rows & columns
230
231 var arows = asize[0];
232 var acolumns = asize[1]; // datatype
233
234 var dt; // addScalar signature to use
235
236 var af = addScalar; // multiplyScalar signature to use
237
238 var mf = multiplyScalar; // process data types
239
240 if (adt && bdt && adt === bdt && typeof adt === 'string') {
241 // datatype
242 dt = adt; // find signatures that matches (dt, dt)
243
244 af = typed.find(addScalar, [dt, dt]);
245 mf = typed.find(multiplyScalar, [dt, dt]);
246 } // result
247
248
249 var c = []; // loop matrix a rows
250
251 for (var i = 0; i < arows; i++) {
252 // current row
253 var row = adata[i]; // sum (do not initialize it with zero)
254
255 var sum = mf(row[0], bdata[0]); // loop matrix a columns
256
257 for (var j = 1; j < acolumns; j++) {
258 // multiply & accumulate
259 sum = af(sum, mf(row[j], bdata[j]));
260 }
261
262 c[i] = sum;
263 } // return matrix
264
265
266 return a.createDenseMatrix({
267 data: c,
268 size: [arows],
269 datatype: dt
270 });
271 }
272 /**
273 * C = A * B
274 *
275 * @param {Matrix} a DenseMatrix (MxN)
276 * @param {Matrix} b DenseMatrix (NxC)
277 *
278 * @return {Matrix} DenseMatrix (MxC)
279 */
280
281
282 function _multiplyDenseMatrixDenseMatrix(a, b) {
283 // a dense
284 var adata = a._data;
285 var asize = a._size;
286 var adt = a._datatype; // b dense
287
288 var bdata = b._data;
289 var bsize = b._size;
290 var bdt = b._datatype; // rows & columns
291
292 var arows = asize[0];
293 var acolumns = asize[1];
294 var bcolumns = bsize[1]; // datatype
295
296 var dt; // addScalar signature to use
297
298 var af = addScalar; // multiplyScalar signature to use
299
300 var mf = multiplyScalar; // process data types
301
302 if (adt && bdt && adt === bdt && typeof adt === 'string') {
303 // datatype
304 dt = adt; // find signatures that matches (dt, dt)
305
306 af = typed.find(addScalar, [dt, dt]);
307 mf = typed.find(multiplyScalar, [dt, dt]);
308 } // result
309
310
311 var c = []; // loop matrix a rows
312
313 for (var i = 0; i < arows; i++) {
314 // current row
315 var row = adata[i]; // initialize row array
316
317 c[i] = []; // loop matrix b columns
318
319 for (var j = 0; j < bcolumns; j++) {
320 // sum (avoid initializing sum to zero)
321 var sum = mf(row[0], bdata[0][j]); // loop matrix a columns
322
323 for (var x = 1; x < acolumns; x++) {
324 // multiply & accumulate
325 sum = af(sum, mf(row[x], bdata[x][j]));
326 }
327
328 c[i][j] = sum;
329 }
330 } // return matrix
331
332
333 return a.createDenseMatrix({
334 data: c,
335 size: [arows, bcolumns],
336 datatype: dt
337 });
338 }
339 /**
340 * C = A * B
341 *
342 * @param {Matrix} a DenseMatrix (MxN)
343 * @param {Matrix} b SparseMatrix (NxC)
344 *
345 * @return {Matrix} SparseMatrix (MxC)
346 */
347
348
349 function _multiplyDenseMatrixSparseMatrix(a, b) {
350 // a dense
351 var adata = a._data;
352 var asize = a._size;
353 var adt = a._datatype; // b sparse
354
355 var bvalues = b._values;
356 var bindex = b._index;
357 var bptr = b._ptr;
358 var bsize = b._size;
359 var bdt = b._datatype; // validate b matrix
360
361 if (!bvalues) {
362 throw new Error('Cannot multiply Dense Matrix times Pattern only Matrix');
363 } // rows & columns
364
365
366 var arows = asize[0];
367 var bcolumns = bsize[1]; // datatype
368
369 var dt; // addScalar signature to use
370
371 var af = addScalar; // multiplyScalar signature to use
372
373 var mf = multiplyScalar; // equalScalar signature to use
374
375 var eq = equalScalar; // zero value
376
377 var zero = 0; // process data types
378
379 if (adt && bdt && adt === bdt && typeof adt === 'string') {
380 // datatype
381 dt = adt; // find signatures that matches (dt, dt)
382
383 af = typed.find(addScalar, [dt, dt]);
384 mf = typed.find(multiplyScalar, [dt, dt]);
385 eq = typed.find(equalScalar, [dt, dt]); // convert 0 to the same datatype
386
387 zero = typed.convert(0, dt);
388 } // result
389
390
391 var cvalues = [];
392 var cindex = [];
393 var cptr = []; // c matrix
394
395 var c = b.createSparseMatrix({
396 values: cvalues,
397 index: cindex,
398 ptr: cptr,
399 size: [arows, bcolumns],
400 datatype: dt
401 }); // loop b columns
402
403 for (var jb = 0; jb < bcolumns; jb++) {
404 // update ptr
405 cptr[jb] = cindex.length; // indeces in column jb
406
407 var kb0 = bptr[jb];
408 var kb1 = bptr[jb + 1]; // do not process column jb if no data exists
409
410 if (kb1 > kb0) {
411 // last row mark processed
412 var last = 0; // loop a rows
413
414 for (var i = 0; i < arows; i++) {
415 // column mark
416 var mark = i + 1; // C[i, jb]
417
418 var cij = void 0; // values in b column j
419
420 for (var kb = kb0; kb < kb1; kb++) {
421 // row
422 var ib = bindex[kb]; // check value has been initialized
423
424 if (last !== mark) {
425 // first value in column jb
426 cij = mf(adata[i][ib], bvalues[kb]); // update mark
427
428 last = mark;
429 } else {
430 // accumulate value
431 cij = af(cij, mf(adata[i][ib], bvalues[kb]));
432 }
433 } // check column has been processed and value != 0
434
435
436 if (last === mark && !eq(cij, zero)) {
437 // push row & value
438 cindex.push(i);
439 cvalues.push(cij);
440 }
441 }
442 }
443 } // update ptr
444
445
446 cptr[bcolumns] = cindex.length; // return sparse matrix
447
448 return c;
449 }
450 /**
451 * C = A * B
452 *
453 * @param {Matrix} a SparseMatrix (MxN)
454 * @param {Matrix} b Dense Vector (N)
455 *
456 * @return {Matrix} SparseMatrix (M, 1)
457 */
458
459
460 function _multiplySparseMatrixVector(a, b) {
461 // a sparse
462 var avalues = a._values;
463 var aindex = a._index;
464 var aptr = a._ptr;
465 var adt = a._datatype; // validate a matrix
466
467 if (!avalues) {
468 throw new Error('Cannot multiply Pattern only Matrix times Dense Matrix');
469 } // b dense
470
471
472 var bdata = b._data;
473 var bdt = b._datatype; // rows & columns
474
475 var arows = a._size[0];
476 var brows = b._size[0]; // result
477
478 var cvalues = [];
479 var cindex = [];
480 var cptr = []; // datatype
481
482 var dt; // addScalar signature to use
483
484 var af = addScalar; // multiplyScalar signature to use
485
486 var mf = multiplyScalar; // equalScalar signature to use
487
488 var eq = equalScalar; // zero value
489
490 var zero = 0; // process data types
491
492 if (adt && bdt && adt === bdt && typeof adt === 'string') {
493 // datatype
494 dt = adt; // find signatures that matches (dt, dt)
495
496 af = typed.find(addScalar, [dt, dt]);
497 mf = typed.find(multiplyScalar, [dt, dt]);
498 eq = typed.find(equalScalar, [dt, dt]); // convert 0 to the same datatype
499
500 zero = typed.convert(0, dt);
501 } // workspace
502
503
504 var x = []; // vector with marks indicating a value x[i] exists in a given column
505
506 var w = []; // update ptr
507
508 cptr[0] = 0; // rows in b
509
510 for (var ib = 0; ib < brows; ib++) {
511 // b[ib]
512 var vbi = bdata[ib]; // check b[ib] != 0, avoid loops
513
514 if (!eq(vbi, zero)) {
515 // A values & index in ib column
516 for (var ka0 = aptr[ib], ka1 = aptr[ib + 1], ka = ka0; ka < ka1; ka++) {
517 // a row
518 var ia = aindex[ka]; // check value exists in current j
519
520 if (!w[ia]) {
521 // ia is new entry in j
522 w[ia] = true; // add i to pattern of C
523
524 cindex.push(ia); // x(ia) = A
525
526 x[ia] = mf(vbi, avalues[ka]);
527 } else {
528 // i exists in C already
529 x[ia] = af(x[ia], mf(vbi, avalues[ka]));
530 }
531 }
532 }
533 } // copy values from x to column jb of c
534
535
536 for (var p1 = cindex.length, p = 0; p < p1; p++) {
537 // row
538 var ic = cindex[p]; // copy value
539
540 cvalues[p] = x[ic];
541 } // update ptr
542
543
544 cptr[1] = cindex.length; // return sparse matrix
545
546 return a.createSparseMatrix({
547 values: cvalues,
548 index: cindex,
549 ptr: cptr,
550 size: [arows, 1],
551 datatype: dt
552 });
553 }
554 /**
555 * C = A * B
556 *
557 * @param {Matrix} a SparseMatrix (MxN)
558 * @param {Matrix} b DenseMatrix (NxC)
559 *
560 * @return {Matrix} SparseMatrix (MxC)
561 */
562
563
564 function _multiplySparseMatrixDenseMatrix(a, b) {
565 // a sparse
566 var avalues = a._values;
567 var aindex = a._index;
568 var aptr = a._ptr;
569 var adt = a._datatype; // validate a matrix
570
571 if (!avalues) {
572 throw new Error('Cannot multiply Pattern only Matrix times Dense Matrix');
573 } // b dense
574
575
576 var bdata = b._data;
577 var bdt = b._datatype; // rows & columns
578
579 var arows = a._size[0];
580 var brows = b._size[0];
581 var bcolumns = b._size[1]; // datatype
582
583 var dt; // addScalar signature to use
584
585 var af = addScalar; // multiplyScalar signature to use
586
587 var mf = multiplyScalar; // equalScalar signature to use
588
589 var eq = equalScalar; // zero value
590
591 var zero = 0; // process data types
592
593 if (adt && bdt && adt === bdt && typeof adt === 'string') {
594 // datatype
595 dt = adt; // find signatures that matches (dt, dt)
596
597 af = typed.find(addScalar, [dt, dt]);
598 mf = typed.find(multiplyScalar, [dt, dt]);
599 eq = typed.find(equalScalar, [dt, dt]); // convert 0 to the same datatype
600
601 zero = typed.convert(0, dt);
602 } // result
603
604
605 var cvalues = [];
606 var cindex = [];
607 var cptr = []; // c matrix
608
609 var c = a.createSparseMatrix({
610 values: cvalues,
611 index: cindex,
612 ptr: cptr,
613 size: [arows, bcolumns],
614 datatype: dt
615 }); // workspace
616
617 var x = []; // vector with marks indicating a value x[i] exists in a given column
618
619 var w = []; // loop b columns
620
621 for (var jb = 0; jb < bcolumns; jb++) {
622 // update ptr
623 cptr[jb] = cindex.length; // mark in workspace for current column
624
625 var mark = jb + 1; // rows in jb
626
627 for (var ib = 0; ib < brows; ib++) {
628 // b[ib, jb]
629 var vbij = bdata[ib][jb]; // check b[ib, jb] != 0, avoid loops
630
631 if (!eq(vbij, zero)) {
632 // A values & index in ib column
633 for (var ka0 = aptr[ib], ka1 = aptr[ib + 1], ka = ka0; ka < ka1; ka++) {
634 // a row
635 var ia = aindex[ka]; // check value exists in current j
636
637 if (w[ia] !== mark) {
638 // ia is new entry in j
639 w[ia] = mark; // add i to pattern of C
640
641 cindex.push(ia); // x(ia) = A
642
643 x[ia] = mf(vbij, avalues[ka]);
644 } else {
645 // i exists in C already
646 x[ia] = af(x[ia], mf(vbij, avalues[ka]));
647 }
648 }
649 }
650 } // copy values from x to column jb of c
651
652
653 for (var p0 = cptr[jb], p1 = cindex.length, p = p0; p < p1; p++) {
654 // row
655 var ic = cindex[p]; // copy value
656
657 cvalues[p] = x[ic];
658 }
659 } // update ptr
660
661
662 cptr[bcolumns] = cindex.length; // return sparse matrix
663
664 return c;
665 }
666 /**
667 * C = A * B
668 *
669 * @param {Matrix} a SparseMatrix (MxN)
670 * @param {Matrix} b SparseMatrix (NxC)
671 *
672 * @return {Matrix} SparseMatrix (MxC)
673 */
674
675
676 function _multiplySparseMatrixSparseMatrix(a, b) {
677 // a sparse
678 var avalues = a._values;
679 var aindex = a._index;
680 var aptr = a._ptr;
681 var adt = a._datatype; // b sparse
682
683 var bvalues = b._values;
684 var bindex = b._index;
685 var bptr = b._ptr;
686 var bdt = b._datatype; // rows & columns
687
688 var arows = a._size[0];
689 var bcolumns = b._size[1]; // flag indicating both matrices (a & b) contain data
690
691 var values = avalues && bvalues; // datatype
692
693 var dt; // addScalar signature to use
694
695 var af = addScalar; // multiplyScalar signature to use
696
697 var mf = multiplyScalar; // process data types
698
699 if (adt && bdt && adt === bdt && typeof adt === 'string') {
700 // datatype
701 dt = adt; // find signatures that matches (dt, dt)
702
703 af = typed.find(addScalar, [dt, dt]);
704 mf = typed.find(multiplyScalar, [dt, dt]);
705 } // result
706
707
708 var cvalues = values ? [] : undefined;
709 var cindex = [];
710 var cptr = []; // c matrix
711
712 var c = a.createSparseMatrix({
713 values: cvalues,
714 index: cindex,
715 ptr: cptr,
716 size: [arows, bcolumns],
717 datatype: dt
718 }); // workspace
719
720 var x = values ? [] : undefined; // vector with marks indicating a value x[i] exists in a given column
721
722 var w = []; // variables
723
724 var ka, ka0, ka1, kb, kb0, kb1, ia, ib; // loop b columns
725
726 for (var jb = 0; jb < bcolumns; jb++) {
727 // update ptr
728 cptr[jb] = cindex.length; // mark in workspace for current column
729
730 var mark = jb + 1; // B values & index in j
731
732 for (kb0 = bptr[jb], kb1 = bptr[jb + 1], kb = kb0; kb < kb1; kb++) {
733 // b row
734 ib = bindex[kb]; // check we need to process values
735
736 if (values) {
737 // loop values in a[:,ib]
738 for (ka0 = aptr[ib], ka1 = aptr[ib + 1], ka = ka0; ka < ka1; ka++) {
739 // row
740 ia = aindex[ka]; // check value exists in current j
741
742 if (w[ia] !== mark) {
743 // ia is new entry in j
744 w[ia] = mark; // add i to pattern of C
745
746 cindex.push(ia); // x(ia) = A
747
748 x[ia] = mf(bvalues[kb], avalues[ka]);
749 } else {
750 // i exists in C already
751 x[ia] = af(x[ia], mf(bvalues[kb], avalues[ka]));
752 }
753 }
754 } else {
755 // loop values in a[:,ib]
756 for (ka0 = aptr[ib], ka1 = aptr[ib + 1], ka = ka0; ka < ka1; ka++) {
757 // row
758 ia = aindex[ka]; // check value exists in current j
759
760 if (w[ia] !== mark) {
761 // ia is new entry in j
762 w[ia] = mark; // add i to pattern of C
763
764 cindex.push(ia);
765 }
766 }
767 }
768 } // check we need to process matrix values (pattern matrix)
769
770
771 if (values) {
772 // copy values from x to column jb of c
773 for (var p0 = cptr[jb], p1 = cindex.length, p = p0; p < p1; p++) {
774 // row
775 var ic = cindex[p]; // copy value
776
777 cvalues[p] = x[ic];
778 }
779 }
780 } // update ptr
781
782
783 cptr[bcolumns] = cindex.length; // return sparse matrix
784
785 return c;
786 }
787 /**
788 * Multiply two or more values, `x * y`.
789 * For matrices, the matrix product is calculated.
790 *
791 * Syntax:
792 *
793 * math.multiply(x, y)
794 * math.multiply(x, y, z, ...)
795 *
796 * Examples:
797 *
798 * math.multiply(4, 5.2) // returns number 20.8
799 * math.multiply(2, 3, 4) // returns number 24
800 *
801 * const a = math.complex(2, 3)
802 * const b = math.complex(4, 1)
803 * math.multiply(a, b) // returns Complex 5 + 14i
804 *
805 * const c = [[1, 2], [4, 3]]
806 * const d = [[1, 2, 3], [3, -4, 7]]
807 * math.multiply(c, d) // returns Array [[7, -6, 17], [13, -4, 33]]
808 *
809 * const e = math.unit('2.1 km')
810 * math.multiply(3, e) // returns Unit 6.3 km
811 *
812 * See also:
813 *
814 * divide, prod, cross, dot
815 *
816 * @param {number | BigNumber | Fraction | Complex | Unit | Array | Matrix} x First value to multiply
817 * @param {number | BigNumber | Fraction | Complex | Unit | Array | Matrix} y Second value to multiply
818 * @return {number | BigNumber | Fraction | Complex | Unit | Array | Matrix} Multiplication of `x` and `y`
819 */
820
821
822 return typed(name, extend({
823 // we extend the signatures of multiplyScalar with signatures dealing with matrices
824 'Array, Array': function ArrayArray(x, y) {
825 // check dimensions
826 _validateMatrixDimensions(arraySize(x), arraySize(y)); // use dense matrix implementation
827
828
829 var m = this(matrix(x), matrix(y)); // return array or scalar
830
831 return isMatrix(m) ? m.valueOf() : m;
832 },
833 'Matrix, Matrix': function MatrixMatrix(x, y) {
834 // dimensions
835 var xsize = x.size();
836 var ysize = y.size(); // check dimensions
837
838 _validateMatrixDimensions(xsize, ysize); // process dimensions
839
840
841 if (xsize.length === 1) {
842 // process y dimensions
843 if (ysize.length === 1) {
844 // Vector * Vector
845 return _multiplyVectorVector(x, y, xsize[0]);
846 } // Vector * Matrix
847
848
849 return _multiplyVectorMatrix(x, y);
850 } // process y dimensions
851
852
853 if (ysize.length === 1) {
854 // Matrix * Vector
855 return _multiplyMatrixVector(x, y);
856 } // Matrix * Matrix
857
858
859 return _multiplyMatrixMatrix(x, y);
860 },
861 'Matrix, Array': function MatrixArray(x, y) {
862 // use Matrix * Matrix implementation
863 return this(x, matrix(y));
864 },
865 'Array, Matrix': function ArrayMatrix(x, y) {
866 // use Matrix * Matrix implementation
867 return this(matrix(x, y.storage()), y);
868 },
869 'SparseMatrix, any': function SparseMatrixAny(x, y) {
870 return algorithm11(x, y, multiplyScalar, false);
871 },
872 'DenseMatrix, any': function DenseMatrixAny(x, y) {
873 return algorithm14(x, y, multiplyScalar, false);
874 },
875 'any, SparseMatrix': function anySparseMatrix(x, y) {
876 return algorithm11(y, x, multiplyScalar, true);
877 },
878 'any, DenseMatrix': function anyDenseMatrix(x, y) {
879 return algorithm14(y, x, multiplyScalar, true);
880 },
881 'Array, any': function ArrayAny(x, y) {
882 // use matrix implementation
883 return algorithm14(matrix(x), y, multiplyScalar, false).valueOf();
884 },
885 'any, Array': function anyArray(x, y) {
886 // use matrix implementation
887 return algorithm14(matrix(y), x, multiplyScalar, true).valueOf();
888 },
889 'any, any': multiplyScalar,
890 'any, any, ...any': function anyAnyAny(x, y, rest) {
891 var result = this(x, y);
892
893 for (var i = 0; i < rest.length; i++) {
894 result = this(result, rest[i]);
895 }
896
897 return result;
898 }
899 }, multiplyScalar.signatures));
900});
\No newline at end of file