UNPKG

mathjs

Version:

Math.js is an extensive math library for JavaScript and Node.js. It features a flexible expression parser with support for symbolic computation, comes with a large set of built-in functions and constants, and offers an integrated solution to work with dif

69 lines (64 loc) 2.47 kB
import { checkBroadcastingRules } from '../../../utils/array.js'; import { factory } from '../../../utils/factory.js'; var name = 'broadcast'; var dependancies = ['concat']; export var createBroadcast = /* #__PURE__ */factory(name, dependancies, _ref => { var { concat } = _ref; /** * Broadcasts two matrices, and return both in an array * It checks if it's possible with broadcasting rules * * @param {Matrix} A First Matrix * @param {Matrix} B Second Matrix * * @return {Matrix[]} [ broadcastedA, broadcastedB ] */ return function (A, B) { var N = Math.max(A._size.length, B._size.length); // max number of dims if (A._size.length === B._size.length) { if (A._size.every((dim, i) => dim === B._size[i])) { // If matrices have the same size return them return [A, B]; } } var sizeA = _padLeft(A._size, N, 0); // pad to the left to align dimensions to the right var sizeB = _padLeft(B._size, N, 0); // pad to the left to align dimensions to the right // calculate the max dimensions var sizeMax = []; for (var dim = 0; dim < N; dim++) { sizeMax[dim] = Math.max(sizeA[dim], sizeB[dim]); } // check if the broadcasting rules applyes for both matrices checkBroadcastingRules(sizeA, sizeMax); checkBroadcastingRules(sizeB, sizeMax); // reshape A or B if needed to make them ready for concat var AA = A.clone(); var BB = B.clone(); if (AA._size.length < N) { AA.reshape(_padLeft(AA._size, N, 1)); } else if (BB._size.length < N) { BB.reshape(_padLeft(BB._size, N, 1)); } // stretches the matrices on each dimension to make them the same size for (var _dim = 0; _dim < N; _dim++) { if (AA._size[_dim] < sizeMax[_dim]) { AA = _stretch(AA, sizeMax[_dim], _dim); } if (BB._size[_dim] < sizeMax[_dim]) { BB = _stretch(BB, sizeMax[_dim], _dim); } } // return the array with the two broadcasted matrices return [AA, BB]; }; function _padLeft(shape, N, filler) { // pads an array of dimensions with numbers to the left, unitl the number of dimensions is N return [...Array(N - shape.length).fill(filler), ...shape]; } function _stretch(arrayToStretch, sizeToStretch, dimToStretch) { // stretches a matrix up to a certain size in a certain dimension return concat(...Array(sizeToStretch).fill(arrayToStretch), dimToStretch); } });