123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879 |
- import { factory } from '../../utils/factory.js';
- import { isMatrix } from '../../utils/is.js';
- import { arraySize } from '../../utils/array.js';
- import { createMatAlgo11xS0s } from '../../type/matrix/utils/matAlgo11xS0s.js';
- import { createMatAlgo14xDs } from '../../type/matrix/utils/matAlgo14xDs.js';
- var name = 'multiply';
- var dependencies = ['typed', 'matrix', 'addScalar', 'multiplyScalar', 'equalScalar', 'dot'];
- export var createMultiply = /* #__PURE__ */factory(name, dependencies, _ref => {
- var {
- typed,
- matrix,
- addScalar,
- multiplyScalar,
- equalScalar,
- dot
- } = _ref;
- var matAlgo11xS0s = createMatAlgo11xS0s({
- typed,
- equalScalar
- });
- var matAlgo14xDs = createMatAlgo14xDs({
- typed
- });
- function _validateMatrixDimensions(size1, size2) {
- // check left operand dimensions
- switch (size1.length) {
- case 1:
- // check size2
- switch (size2.length) {
- case 1:
- // Vector x Vector
- if (size1[0] !== size2[0]) {
- // throw error
- throw new RangeError('Dimension mismatch in multiplication. Vectors must have the same length');
- }
- break;
- case 2:
- // Vector x Matrix
- if (size1[0] !== size2[0]) {
- // throw error
- throw new RangeError('Dimension mismatch in multiplication. Vector length (' + size1[0] + ') must match Matrix rows (' + size2[0] + ')');
- }
- break;
- default:
- throw new Error('Can only multiply a 1 or 2 dimensional matrix (Matrix B has ' + size2.length + ' dimensions)');
- }
- break;
- case 2:
- // check size2
- switch (size2.length) {
- case 1:
- // Matrix x Vector
- if (size1[1] !== size2[0]) {
- // throw error
- throw new RangeError('Dimension mismatch in multiplication. Matrix columns (' + size1[1] + ') must match Vector length (' + size2[0] + ')');
- }
- break;
- case 2:
- // Matrix x Matrix
- if (size1[1] !== size2[0]) {
- // throw error
- throw new RangeError('Dimension mismatch in multiplication. Matrix A columns (' + size1[1] + ') must match Matrix B rows (' + size2[0] + ')');
- }
- break;
- default:
- throw new Error('Can only multiply a 1 or 2 dimensional matrix (Matrix B has ' + size2.length + ' dimensions)');
- }
- break;
- default:
- throw new Error('Can only multiply a 1 or 2 dimensional matrix (Matrix A has ' + size1.length + ' dimensions)');
- }
- }
- /**
- * C = A * B
- *
- * @param {Matrix} a Dense Vector (N)
- * @param {Matrix} b Dense Vector (N)
- *
- * @return {number} Scalar value
- */
- function _multiplyVectorVector(a, b, n) {
- // check empty vector
- if (n === 0) {
- throw new Error('Cannot multiply two empty vectors');
- }
- return dot(a, b);
- }
- /**
- * C = A * B
- *
- * @param {Matrix} a Dense Vector (M)
- * @param {Matrix} b Matrix (MxN)
- *
- * @return {Matrix} Dense Vector (N)
- */
- function _multiplyVectorMatrix(a, b) {
- // process storage
- if (b.storage() !== 'dense') {
- throw new Error('Support for SparseMatrix not implemented');
- }
- return _multiplyVectorDenseMatrix(a, b);
- }
- /**
- * C = A * B
- *
- * @param {Matrix} a Dense Vector (M)
- * @param {Matrix} b Dense Matrix (MxN)
- *
- * @return {Matrix} Dense Vector (N)
- */
- function _multiplyVectorDenseMatrix(a, b) {
- // a dense
- var adata = a._data;
- var asize = a._size;
- var adt = a._datatype;
- // b dense
- var bdata = b._data;
- var bsize = b._size;
- var bdt = b._datatype;
- // rows & columns
- var alength = asize[0];
- var bcolumns = bsize[1];
- // datatype
- var dt;
- // addScalar signature to use
- var af = addScalar;
- // multiplyScalar signature to use
- var mf = multiplyScalar;
- // process data types
- if (adt && bdt && adt === bdt && typeof adt === 'string') {
- // datatype
- dt = adt;
- // find signatures that matches (dt, dt)
- af = typed.find(addScalar, [dt, dt]);
- mf = typed.find(multiplyScalar, [dt, dt]);
- }
- // result
- var c = [];
- // loop matrix columns
- for (var j = 0; j < bcolumns; j++) {
- // sum (do not initialize it with zero)
- var sum = mf(adata[0], bdata[0][j]);
- // loop vector
- for (var i = 1; i < alength; i++) {
- // multiply & accumulate
- sum = af(sum, mf(adata[i], bdata[i][j]));
- }
- c[j] = sum;
- }
- // return matrix
- return a.createDenseMatrix({
- data: c,
- size: [bcolumns],
- datatype: dt
- });
- }
- /**
- * C = A * B
- *
- * @param {Matrix} a Matrix (MxN)
- * @param {Matrix} b Dense Vector (N)
- *
- * @return {Matrix} Dense Vector (M)
- */
- var _multiplyMatrixVector = typed('_multiplyMatrixVector', {
- 'DenseMatrix, any': _multiplyDenseMatrixVector,
- 'SparseMatrix, any': _multiplySparseMatrixVector
- });
- /**
- * C = A * B
- *
- * @param {Matrix} a Matrix (MxN)
- * @param {Matrix} b Matrix (NxC)
- *
- * @return {Matrix} Matrix (MxC)
- */
- var _multiplyMatrixMatrix = typed('_multiplyMatrixMatrix', {
- 'DenseMatrix, DenseMatrix': _multiplyDenseMatrixDenseMatrix,
- 'DenseMatrix, SparseMatrix': _multiplyDenseMatrixSparseMatrix,
- 'SparseMatrix, DenseMatrix': _multiplySparseMatrixDenseMatrix,
- 'SparseMatrix, SparseMatrix': _multiplySparseMatrixSparseMatrix
- });
- /**
- * C = A * B
- *
- * @param {Matrix} a DenseMatrix (MxN)
- * @param {Matrix} b Dense Vector (N)
- *
- * @return {Matrix} Dense Vector (M)
- */
- function _multiplyDenseMatrixVector(a, b) {
- // a dense
- var adata = a._data;
- var asize = a._size;
- var adt = a._datatype;
- // b dense
- var bdata = b._data;
- var bdt = b._datatype;
- // rows & columns
- var arows = asize[0];
- var acolumns = asize[1];
- // datatype
- var dt;
- // addScalar signature to use
- var af = addScalar;
- // multiplyScalar signature to use
- var mf = multiplyScalar;
- // process data types
- if (adt && bdt && adt === bdt && typeof adt === 'string') {
- // datatype
- dt = adt;
- // find signatures that matches (dt, dt)
- af = typed.find(addScalar, [dt, dt]);
- mf = typed.find(multiplyScalar, [dt, dt]);
- }
- // result
- var c = [];
- // loop matrix a rows
- for (var i = 0; i < arows; i++) {
- // current row
- var row = adata[i];
- // sum (do not initialize it with zero)
- var sum = mf(row[0], bdata[0]);
- // loop matrix a columns
- for (var j = 1; j < acolumns; j++) {
- // multiply & accumulate
- sum = af(sum, mf(row[j], bdata[j]));
- }
- c[i] = sum;
- }
- // return matrix
- return a.createDenseMatrix({
- data: c,
- size: [arows],
- datatype: dt
- });
- }
- /**
- * C = A * B
- *
- * @param {Matrix} a DenseMatrix (MxN)
- * @param {Matrix} b DenseMatrix (NxC)
- *
- * @return {Matrix} DenseMatrix (MxC)
- */
- function _multiplyDenseMatrixDenseMatrix(a, b) {
- // a dense
- var adata = a._data;
- var asize = a._size;
- var adt = a._datatype;
- // b dense
- var bdata = b._data;
- var bsize = b._size;
- var bdt = b._datatype;
- // rows & columns
- var arows = asize[0];
- var acolumns = asize[1];
- var bcolumns = bsize[1];
- // datatype
- var dt;
- // addScalar signature to use
- var af = addScalar;
- // multiplyScalar signature to use
- var mf = multiplyScalar;
- // process data types
- if (adt && bdt && adt === bdt && typeof adt === 'string') {
- // datatype
- dt = adt;
- // find signatures that matches (dt, dt)
- af = typed.find(addScalar, [dt, dt]);
- mf = typed.find(multiplyScalar, [dt, dt]);
- }
- // result
- var c = [];
- // loop matrix a rows
- for (var i = 0; i < arows; i++) {
- // current row
- var row = adata[i];
- // initialize row array
- c[i] = [];
- // loop matrix b columns
- for (var j = 0; j < bcolumns; j++) {
- // sum (avoid initializing sum to zero)
- var sum = mf(row[0], bdata[0][j]);
- // loop matrix a columns
- for (var x = 1; x < acolumns; x++) {
- // multiply & accumulate
- sum = af(sum, mf(row[x], bdata[x][j]));
- }
- c[i][j] = sum;
- }
- }
- // return matrix
- return a.createDenseMatrix({
- data: c,
- size: [arows, bcolumns],
- datatype: dt
- });
- }
- /**
- * C = A * B
- *
- * @param {Matrix} a DenseMatrix (MxN)
- * @param {Matrix} b SparseMatrix (NxC)
- *
- * @return {Matrix} SparseMatrix (MxC)
- */
- function _multiplyDenseMatrixSparseMatrix(a, b) {
- // a dense
- var adata = a._data;
- var asize = a._size;
- var adt = a._datatype;
- // b sparse
- var bvalues = b._values;
- var bindex = b._index;
- var bptr = b._ptr;
- var bsize = b._size;
- var bdt = b._datatype;
- // validate b matrix
- if (!bvalues) {
- throw new Error('Cannot multiply Dense Matrix times Pattern only Matrix');
- }
- // rows & columns
- var arows = asize[0];
- var bcolumns = bsize[1];
- // datatype
- var dt;
- // addScalar signature to use
- var af = addScalar;
- // multiplyScalar signature to use
- var mf = multiplyScalar;
- // equalScalar signature to use
- var eq = equalScalar;
- // zero value
- var zero = 0;
- // process data types
- if (adt && bdt && adt === bdt && typeof adt === 'string') {
- // datatype
- dt = adt;
- // find signatures that matches (dt, dt)
- af = typed.find(addScalar, [dt, dt]);
- mf = typed.find(multiplyScalar, [dt, dt]);
- eq = typed.find(equalScalar, [dt, dt]);
- // convert 0 to the same datatype
- zero = typed.convert(0, dt);
- }
- // result
- var cvalues = [];
- var cindex = [];
- var cptr = [];
- // c matrix
- var c = b.createSparseMatrix({
- values: cvalues,
- index: cindex,
- ptr: cptr,
- size: [arows, bcolumns],
- datatype: dt
- });
- // loop b columns
- for (var jb = 0; jb < bcolumns; jb++) {
- // update ptr
- cptr[jb] = cindex.length;
- // indeces in column jb
- var kb0 = bptr[jb];
- var kb1 = bptr[jb + 1];
- // do not process column jb if no data exists
- if (kb1 > kb0) {
- // last row mark processed
- var last = 0;
- // loop a rows
- for (var i = 0; i < arows; i++) {
- // column mark
- var mark = i + 1;
- // C[i, jb]
- var cij = void 0;
- // values in b column j
- for (var kb = kb0; kb < kb1; kb++) {
- // row
- var ib = bindex[kb];
- // check value has been initialized
- if (last !== mark) {
- // first value in column jb
- cij = mf(adata[i][ib], bvalues[kb]);
- // update mark
- last = mark;
- } else {
- // accumulate value
- cij = af(cij, mf(adata[i][ib], bvalues[kb]));
- }
- }
- // check column has been processed and value != 0
- if (last === mark && !eq(cij, zero)) {
- // push row & value
- cindex.push(i);
- cvalues.push(cij);
- }
- }
- }
- }
- // update ptr
- cptr[bcolumns] = cindex.length;
- // return sparse matrix
- return c;
- }
- /**
- * C = A * B
- *
- * @param {Matrix} a SparseMatrix (MxN)
- * @param {Matrix} b Dense Vector (N)
- *
- * @return {Matrix} SparseMatrix (M, 1)
- */
- function _multiplySparseMatrixVector(a, b) {
- // a sparse
- var avalues = a._values;
- var aindex = a._index;
- var aptr = a._ptr;
- var adt = a._datatype;
- // validate a matrix
- if (!avalues) {
- throw new Error('Cannot multiply Pattern only Matrix times Dense Matrix');
- }
- // b dense
- var bdata = b._data;
- var bdt = b._datatype;
- // rows & columns
- var arows = a._size[0];
- var brows = b._size[0];
- // result
- var cvalues = [];
- var cindex = [];
- var cptr = [];
- // datatype
- var dt;
- // addScalar signature to use
- var af = addScalar;
- // multiplyScalar signature to use
- var mf = multiplyScalar;
- // equalScalar signature to use
- var eq = equalScalar;
- // zero value
- var zero = 0;
- // process data types
- if (adt && bdt && adt === bdt && typeof adt === 'string') {
- // datatype
- dt = adt;
- // find signatures that matches (dt, dt)
- af = typed.find(addScalar, [dt, dt]);
- mf = typed.find(multiplyScalar, [dt, dt]);
- eq = typed.find(equalScalar, [dt, dt]);
- // convert 0 to the same datatype
- zero = typed.convert(0, dt);
- }
- // workspace
- var x = [];
- // vector with marks indicating a value x[i] exists in a given column
- var w = [];
- // update ptr
- cptr[0] = 0;
- // rows in b
- for (var ib = 0; ib < brows; ib++) {
- // b[ib]
- var vbi = bdata[ib];
- // check b[ib] != 0, avoid loops
- if (!eq(vbi, zero)) {
- // A values & index in ib column
- for (var ka0 = aptr[ib], ka1 = aptr[ib + 1], ka = ka0; ka < ka1; ka++) {
- // a row
- var ia = aindex[ka];
- // check value exists in current j
- if (!w[ia]) {
- // ia is new entry in j
- w[ia] = true;
- // add i to pattern of C
- cindex.push(ia);
- // x(ia) = A
- x[ia] = mf(vbi, avalues[ka]);
- } else {
- // i exists in C already
- x[ia] = af(x[ia], mf(vbi, avalues[ka]));
- }
- }
- }
- }
- // copy values from x to column jb of c
- for (var p1 = cindex.length, p = 0; p < p1; p++) {
- // row
- var ic = cindex[p];
- // copy value
- cvalues[p] = x[ic];
- }
- // update ptr
- cptr[1] = cindex.length;
- // return sparse matrix
- return a.createSparseMatrix({
- values: cvalues,
- index: cindex,
- ptr: cptr,
- size: [arows, 1],
- datatype: dt
- });
- }
- /**
- * C = A * B
- *
- * @param {Matrix} a SparseMatrix (MxN)
- * @param {Matrix} b DenseMatrix (NxC)
- *
- * @return {Matrix} SparseMatrix (MxC)
- */
- function _multiplySparseMatrixDenseMatrix(a, b) {
- // a sparse
- var avalues = a._values;
- var aindex = a._index;
- var aptr = a._ptr;
- var adt = a._datatype;
- // validate a matrix
- if (!avalues) {
- throw new Error('Cannot multiply Pattern only Matrix times Dense Matrix');
- }
- // b dense
- var bdata = b._data;
- var bdt = b._datatype;
- // rows & columns
- var arows = a._size[0];
- var brows = b._size[0];
- var bcolumns = b._size[1];
- // datatype
- var dt;
- // addScalar signature to use
- var af = addScalar;
- // multiplyScalar signature to use
- var mf = multiplyScalar;
- // equalScalar signature to use
- var eq = equalScalar;
- // zero value
- var zero = 0;
- // process data types
- if (adt && bdt && adt === bdt && typeof adt === 'string') {
- // datatype
- dt = adt;
- // find signatures that matches (dt, dt)
- af = typed.find(addScalar, [dt, dt]);
- mf = typed.find(multiplyScalar, [dt, dt]);
- eq = typed.find(equalScalar, [dt, dt]);
- // convert 0 to the same datatype
- zero = typed.convert(0, dt);
- }
- // result
- var cvalues = [];
- var cindex = [];
- var cptr = [];
- // c matrix
- var c = a.createSparseMatrix({
- values: cvalues,
- index: cindex,
- ptr: cptr,
- size: [arows, bcolumns],
- datatype: dt
- });
- // workspace
- var x = [];
- // vector with marks indicating a value x[i] exists in a given column
- var w = [];
- // loop b columns
- for (var jb = 0; jb < bcolumns; jb++) {
- // update ptr
- cptr[jb] = cindex.length;
- // mark in workspace for current column
- var mark = jb + 1;
- // rows in jb
- for (var ib = 0; ib < brows; ib++) {
- // b[ib, jb]
- var vbij = bdata[ib][jb];
- // check b[ib, jb] != 0, avoid loops
- if (!eq(vbij, zero)) {
- // A values & index in ib column
- for (var ka0 = aptr[ib], ka1 = aptr[ib + 1], ka = ka0; ka < ka1; ka++) {
- // a row
- var ia = aindex[ka];
- // check value exists in current j
- if (w[ia] !== mark) {
- // ia is new entry in j
- w[ia] = mark;
- // add i to pattern of C
- cindex.push(ia);
- // x(ia) = A
- x[ia] = mf(vbij, avalues[ka]);
- } else {
- // i exists in C already
- x[ia] = af(x[ia], mf(vbij, avalues[ka]));
- }
- }
- }
- }
- // copy values from x to column jb of c
- for (var p0 = cptr[jb], p1 = cindex.length, p = p0; p < p1; p++) {
- // row
- var ic = cindex[p];
- // copy value
- cvalues[p] = x[ic];
- }
- }
- // update ptr
- cptr[bcolumns] = cindex.length;
- // return sparse matrix
- return c;
- }
- /**
- * C = A * B
- *
- * @param {Matrix} a SparseMatrix (MxN)
- * @param {Matrix} b SparseMatrix (NxC)
- *
- * @return {Matrix} SparseMatrix (MxC)
- */
- function _multiplySparseMatrixSparseMatrix(a, b) {
- // a sparse
- var avalues = a._values;
- var aindex = a._index;
- var aptr = a._ptr;
- var adt = a._datatype;
- // b sparse
- var bvalues = b._values;
- var bindex = b._index;
- var bptr = b._ptr;
- var bdt = b._datatype;
- // rows & columns
- var arows = a._size[0];
- var bcolumns = b._size[1];
- // flag indicating both matrices (a & b) contain data
- var values = avalues && bvalues;
- // datatype
- var dt;
- // addScalar signature to use
- var af = addScalar;
- // multiplyScalar signature to use
- var mf = multiplyScalar;
- // process data types
- if (adt && bdt && adt === bdt && typeof adt === 'string') {
- // datatype
- dt = adt;
- // find signatures that matches (dt, dt)
- af = typed.find(addScalar, [dt, dt]);
- mf = typed.find(multiplyScalar, [dt, dt]);
- }
- // result
- var cvalues = values ? [] : undefined;
- var cindex = [];
- var cptr = [];
- // c matrix
- var c = a.createSparseMatrix({
- values: cvalues,
- index: cindex,
- ptr: cptr,
- size: [arows, bcolumns],
- datatype: dt
- });
- // workspace
- var x = values ? [] : undefined;
- // vector with marks indicating a value x[i] exists in a given column
- var w = [];
- // variables
- var ka, ka0, ka1, kb, kb0, kb1, ia, ib;
- // loop b columns
- for (var jb = 0; jb < bcolumns; jb++) {
- // update ptr
- cptr[jb] = cindex.length;
- // mark in workspace for current column
- var mark = jb + 1;
- // B values & index in j
- for (kb0 = bptr[jb], kb1 = bptr[jb + 1], kb = kb0; kb < kb1; kb++) {
- // b row
- ib = bindex[kb];
- // check we need to process values
- if (values) {
- // loop values in a[:,ib]
- for (ka0 = aptr[ib], ka1 = aptr[ib + 1], ka = ka0; ka < ka1; ka++) {
- // row
- ia = aindex[ka];
- // check value exists in current j
- if (w[ia] !== mark) {
- // ia is new entry in j
- w[ia] = mark;
- // add i to pattern of C
- cindex.push(ia);
- // x(ia) = A
- x[ia] = mf(bvalues[kb], avalues[ka]);
- } else {
- // i exists in C already
- x[ia] = af(x[ia], mf(bvalues[kb], avalues[ka]));
- }
- }
- } else {
- // loop values in a[:,ib]
- for (ka0 = aptr[ib], ka1 = aptr[ib + 1], ka = ka0; ka < ka1; ka++) {
- // row
- ia = aindex[ka];
- // check value exists in current j
- if (w[ia] !== mark) {
- // ia is new entry in j
- w[ia] = mark;
- // add i to pattern of C
- cindex.push(ia);
- }
- }
- }
- }
- // check we need to process matrix values (pattern matrix)
- if (values) {
- // copy values from x to column jb of c
- for (var p0 = cptr[jb], p1 = cindex.length, p = p0; p < p1; p++) {
- // row
- var ic = cindex[p];
- // copy value
- cvalues[p] = x[ic];
- }
- }
- }
- // update ptr
- cptr[bcolumns] = cindex.length;
- // return sparse matrix
- return c;
- }
- /**
- * Multiply two or more values, `x * y`.
- * For matrices, the matrix product is calculated.
- *
- * Syntax:
- *
- * math.multiply(x, y)
- * math.multiply(x, y, z, ...)
- *
- * Examples:
- *
- * math.multiply(4, 5.2) // returns number 20.8
- * math.multiply(2, 3, 4) // returns number 24
- *
- * const a = math.complex(2, 3)
- * const b = math.complex(4, 1)
- * math.multiply(a, b) // returns Complex 5 + 14i
- *
- * const c = [[1, 2], [4, 3]]
- * const d = [[1, 2, 3], [3, -4, 7]]
- * math.multiply(c, d) // returns Array [[7, -6, 17], [13, -4, 33]]
- *
- * const e = math.unit('2.1 km')
- * math.multiply(3, e) // returns Unit 6.3 km
- *
- * See also:
- *
- * divide, prod, cross, dot
- *
- * @param {number | BigNumber | Fraction | Complex | Unit | Array | Matrix} x First value to multiply
- * @param {number | BigNumber | Fraction | Complex | Unit | Array | Matrix} y Second value to multiply
- * @return {number | BigNumber | Fraction | Complex | Unit | Array | Matrix} Multiplication of `x` and `y`
- */
- return typed(name, multiplyScalar, {
- // we extend the signatures of multiplyScalar with signatures dealing with matrices
- 'Array, Array': typed.referTo('Matrix, Matrix', selfMM => (x, y) => {
- // check dimensions
- _validateMatrixDimensions(arraySize(x), arraySize(y));
- // use dense matrix implementation
- var m = selfMM(matrix(x), matrix(y));
- // return array or scalar
- return isMatrix(m) ? m.valueOf() : m;
- }),
- 'Matrix, Matrix': function MatrixMatrix(x, y) {
- // dimensions
- var xsize = x.size();
- var ysize = y.size();
- // check dimensions
- _validateMatrixDimensions(xsize, ysize);
- // process dimensions
- if (xsize.length === 1) {
- // process y dimensions
- if (ysize.length === 1) {
- // Vector * Vector
- return _multiplyVectorVector(x, y, xsize[0]);
- }
- // Vector * Matrix
- return _multiplyVectorMatrix(x, y);
- }
- // process y dimensions
- if (ysize.length === 1) {
- // Matrix * Vector
- return _multiplyMatrixVector(x, y);
- }
- // Matrix * Matrix
- return _multiplyMatrixMatrix(x, y);
- },
- 'Matrix, Array': typed.referTo('Matrix,Matrix', selfMM => (x, y) => selfMM(x, matrix(y))),
- 'Array, Matrix': typed.referToSelf(self => (x, y) => {
- // use Matrix * Matrix implementation
- return self(matrix(x, y.storage()), y);
- }),
- 'SparseMatrix, any': function SparseMatrixAny(x, y) {
- return matAlgo11xS0s(x, y, multiplyScalar, false);
- },
- 'DenseMatrix, any': function DenseMatrixAny(x, y) {
- return matAlgo14xDs(x, y, multiplyScalar, false);
- },
- 'any, SparseMatrix': function anySparseMatrix(x, y) {
- return matAlgo11xS0s(y, x, multiplyScalar, true);
- },
- 'any, DenseMatrix': function anyDenseMatrix(x, y) {
- return matAlgo14xDs(y, x, multiplyScalar, true);
- },
- 'Array, any': function ArrayAny(x, y) {
- // use matrix implementation
- return matAlgo14xDs(matrix(x), y, multiplyScalar, false).valueOf();
- },
- 'any, Array': function anyArray(x, y) {
- // use matrix implementation
- return matAlgo14xDs(matrix(y), x, multiplyScalar, true).valueOf();
- },
- 'any, any': multiplyScalar,
- 'any, any, ...any': typed.referToSelf(self => (x, y, rest) => {
- var result = self(x, y);
- for (var i = 0; i < rest.length; i++) {
- result = self(result, rest[i]);
- }
- return result;
- })
- });
- });
|