From 6b0ea89632469273a43e95921437768b3cb300e1 Mon Sep 17 00:00:00 2001 From: David Contreras Date: Tue, 9 Dec 2025 22:38:00 +0000 Subject: [PATCH 01/19] feat: implement broadcastSizes and broadcastTo functions for matrix operations --- src/function/matrix/broadcastSizes.js | 36 +++++++++++++++++++++++++++ src/function/matrix/broadcastTo.js | 34 +++++++++++++++++++++++++ 2 files changed, 70 insertions(+) create mode 100644 src/function/matrix/broadcastSizes.js create mode 100644 src/function/matrix/broadcastTo.js diff --git a/src/function/matrix/broadcastSizes.js b/src/function/matrix/broadcastSizes.js new file mode 100644 index 0000000000..d51fa82d8d --- /dev/null +++ b/src/function/matrix/broadcastSizes.js @@ -0,0 +1,36 @@ +import { broadcastSizes } from '../../utils/array.js' +import { factory } from '../../utils/factory.js' +import { isMatrix } from '../../utils/is.js' + +const name = 'broadcastSizes' +const dependencies = ['typed'] + +export const createBroadcastSizes = /* #__PURE__ */ factory(name, dependencies, ({ typed }) => { + /** + * Calculate the broadcasted size of one or more matrices or arrays. + * Always returns an Array containing numbers. + * + * Syntax: + * + * math.broadcastSizes(x, y) + * math.broadcastSizes(x, y, ...) + * + * Examples: + * + * math.broadcastSizes([2, 3]) // returns [2, 3] + * math.broadcastSizes([2, 3], [3]) // returns [2, 3] + * math.broadcastSizes([1, 2, 3], [[1, 2, 3]]) // returns [[1, 2, 3]] + * + * See also: + * + * size, reshape, squeeze, broadcastTo + * + * @param {...(Array|Matrix)} x One or more matrices or arrays + * @return {Array} A vector with the broadcasted size. + */ + return typed(name, { + '...Array': broadcastSizes, + '...Matrix': matrices => broadcastSizes(...matrices.map(m => m.toArray())), + '...Array|Matrix': collections => broadcastSizes(...collections.map(c => isMatrix(c) ? c.toArray() : c)) + }) +}) diff --git a/src/function/matrix/broadcastTo.js b/src/function/matrix/broadcastTo.js new file mode 100644 index 0000000000..8501929d22 --- /dev/null +++ b/src/function/matrix/broadcastTo.js @@ -0,0 +1,34 @@ +import { broadcastTo } from '../../utils/array.js' +import { factory } from '../../utils/factory.js' + +const name = 'broadcastTo' +const dependencies = ['typed'] + +export const createBroadcastTo = /* #__PURE__ */ factory(name, dependencies, ({ typed }) => { + /** + * Broadcast an array to a specified size. + * + * Syntax: + * + * math.broadcastTo(x, size) + * + * Examples: + * + * math.broadcastTo([1, 2, 3], [2, 3]) // returns [[1, 2, 3], [1, 2, 3]] + * math.broadcastTo([2, 3], [2, 2]) // returns [[2, 3], [2, 3]] + * + * See also: + * + * size, reshape, squeeze, broadcastSizes + * + * @param {Array|Matrix} x The array or matrix to broadcast + * @param {Array|Matrix} size The target size + * @return {Array} The broadcasted array + */ + return typed(name, { + 'Array, Array': broadcastTo, + 'Array, Matrix': (arr, size) => broadcastTo(arr, size.toArray()), + 'Matrix, Array': (M, size) => M.create(broadcastTo(M.toArray(), size)), + 'Matrix, Matrix': (M1, size) => M1.create(broadcastTo(M1.toArray(), size.toArray())) + }) +}) From cd83def253021d8003c7e79d5372a3f1d5471e03 Mon Sep 17 00:00:00 2001 From: David Contreras Date: Wed, 10 Dec 2025 14:20:53 +0000 Subject: [PATCH 02/19] Included new functions in factories --- src/factoriesAny.js | 3 ++ src/function/matrix/broadcastMatrices.js | 36 ++++++++++++++++++++++++ 2 files changed, 39 insertions(+) create mode 100644 src/function/matrix/broadcastMatrices.js diff --git a/src/factoriesAny.js b/src/factoriesAny.js index 15ea5de0d0..3b45209d79 100644 --- a/src/factoriesAny.js +++ b/src/factoriesAny.js @@ -88,6 +88,9 @@ export { createOnes } from './function/matrix/ones.js' export { createRange } from './function/matrix/range.js' export { createReshape } from './function/matrix/reshape.js' export { createResize } from './function/matrix/resize.js' +export { createBroadcastMatrices } from './function/matrix/broadcastMatrices.js' +export { createBroadcastSizes } from './function/matrix/broadcastSizes.js' +export { createBroadcastTo } from './function/matrix/broadcastTo.js' export { createRotate } from './function/matrix/rotate.js' export { createRotationMatrix } from './function/matrix/rotationMatrix.js' export { createRow } from './function/matrix/row.js' diff --git a/src/function/matrix/broadcastMatrices.js b/src/function/matrix/broadcastMatrices.js new file mode 100644 index 0000000000..4c16d3a066 --- /dev/null +++ b/src/function/matrix/broadcastMatrices.js @@ -0,0 +1,36 @@ +import { broadcastArrays } from '../../utils/array.js' +import { factory } from '../../utils/factory.js' +import { isMatrix } from '../../utils/is.js' + +const name = 'broadcastMatrices' +const dependencies = ['typed'] + +export const createBroadcastMatrices = /* #__PURE__ */ factory(name, dependencies, ({ typed }) => { + /** + * Broadcast multiple matrices together. + * Return and array of matrices with the broadcasted sizes. + * + * Syntax: + * + * math.broadcastMatrices(x, y) + * math.broadcastMatrices(x, y, ...) + * + * Examples: + * + * math.broadcastMatrices([1, 2], [[3], [4]]) // returns [[[1, 2], [1, 2]], [[3, 3], [4, 4]]] + * math.broadcastMatrices([2, 3]) // returns [[2, 3]] + * math.broadcastMatrices([2, 3], [3, 1]) // returns [[2, 3], [3, 1]] + * + * See also: + * + * size, reshape, broadcastSizes, broadcastTo + * + * @param {...(Array|Matrix)} x One or more matrices or arrays + * @return {Array[Array|Matrix]} An array of matrices with the broadcasted sizes. + */ + return typed(name, { + '...Array': broadcastArrays, + '...Matrix': matrices => broadcastArrays(...matrices.map(m => m.toArray())), + '...Array|Matrix': collections => broadcastArrays(...collections.map(c => isMatrix(c) ? c.toArray() : c)) + }) +}) From f2a294305df84fc58de69375631d52c1abbc1a73 Mon Sep 17 00:00:00 2001 From: David Contreras Date: Fri, 26 Dec 2025 09:14:15 -0600 Subject: [PATCH 03/19] Fixed typed issues --- src/function/matrix/broadcastMatrices.js | 13 ++++++++++--- src/function/matrix/broadcastSizes.js | 14 +++++++++++--- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/src/function/matrix/broadcastMatrices.js b/src/function/matrix/broadcastMatrices.js index 4c16d3a066..84d934437b 100644 --- a/src/function/matrix/broadcastMatrices.js +++ b/src/function/matrix/broadcastMatrices.js @@ -29,8 +29,15 @@ export const createBroadcastMatrices = /* #__PURE__ */ factory(name, dependencie * @return {Array[Array|Matrix]} An array of matrices with the broadcasted sizes. */ return typed(name, { - '...Array': broadcastArrays, - '...Matrix': matrices => broadcastArrays(...matrices.map(m => m.toArray())), - '...Array|Matrix': collections => broadcastArrays(...collections.map(c => isMatrix(c) ? c.toArray() : c)) + '...Array|Matrix': collections => { + const areMatrices = collections.map(isMatrix) + if(areMatrices.includes(true)) { + const arrays = collections.map((c,i) => areMatrices[i] ? c.valueOf() : c) + const broadcastedArrays = broadcastArrays(...arrays) + const broadcastedCollections = broadcastedArrays.map((arr, i) => areMatrices[i] ? collections[i].create(arr) : arr) + return broadcastedCollections + } + return broadcastArrays(...collections) + } }) }) diff --git a/src/function/matrix/broadcastSizes.js b/src/function/matrix/broadcastSizes.js index d51fa82d8d..aff941ef66 100644 --- a/src/function/matrix/broadcastSizes.js +++ b/src/function/matrix/broadcastSizes.js @@ -29,8 +29,16 @@ export const createBroadcastSizes = /* #__PURE__ */ factory(name, dependencies, * @return {Array} A vector with the broadcasted size. */ return typed(name, { - '...Array': broadcastSizes, - '...Matrix': matrices => broadcastSizes(...matrices.map(m => m.toArray())), - '...Array|Matrix': collections => broadcastSizes(...collections.map(c => isMatrix(c) ? c.toArray() : c)) + '...Array|Matrix': collections => { + const areMatrices = collections.map(isMatrix) + if(areMatrices.includes(true)) { + const arrays = collections.map((c,i) => areMatrices[i] ? c.valueOf() : c) + const broadcastedArrays = broadcastSizes(...arrays) + const broadcastedCollections = broadcastedArrays.map((arr, i) => areMatrices[i] ? collections[i].create(arr) : arr) + return broadcastedCollections + } + return broadcastSizes(...collections) + } + }) }) From 756aa83149a73b14256ddaf3e0b6aa36b2492e65 Mon Sep 17 00:00:00 2001 From: David Contreras Date: Fri, 26 Dec 2025 09:18:26 -0600 Subject: [PATCH 04/19] format --- src/function/matrix/broadcastMatrices.js | 4 ++-- src/function/matrix/broadcastSizes.js | 4 ++-- src/function/matrix/broadcastTo.js | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/function/matrix/broadcastMatrices.js b/src/function/matrix/broadcastMatrices.js index 84d934437b..4f0fbc62da 100644 --- a/src/function/matrix/broadcastMatrices.js +++ b/src/function/matrix/broadcastMatrices.js @@ -31,8 +31,8 @@ export const createBroadcastMatrices = /* #__PURE__ */ factory(name, dependencie return typed(name, { '...Array|Matrix': collections => { const areMatrices = collections.map(isMatrix) - if(areMatrices.includes(true)) { - const arrays = collections.map((c,i) => areMatrices[i] ? c.valueOf() : c) + if (areMatrices.includes(true)) { + const arrays = collections.map((c, i) => areMatrices[i] ? c.valueOf() : c) const broadcastedArrays = broadcastArrays(...arrays) const broadcastedCollections = broadcastedArrays.map((arr, i) => areMatrices[i] ? collections[i].create(arr) : arr) return broadcastedCollections diff --git a/src/function/matrix/broadcastSizes.js b/src/function/matrix/broadcastSizes.js index aff941ef66..a0f692e644 100644 --- a/src/function/matrix/broadcastSizes.js +++ b/src/function/matrix/broadcastSizes.js @@ -31,8 +31,8 @@ export const createBroadcastSizes = /* #__PURE__ */ factory(name, dependencies, return typed(name, { '...Array|Matrix': collections => { const areMatrices = collections.map(isMatrix) - if(areMatrices.includes(true)) { - const arrays = collections.map((c,i) => areMatrices[i] ? c.valueOf() : c) + if (areMatrices.includes(true)) { + const arrays = collections.map((c, i) => areMatrices[i] ? c.valueOf() : c) const broadcastedArrays = broadcastSizes(...arrays) const broadcastedCollections = broadcastedArrays.map((arr, i) => areMatrices[i] ? collections[i].create(arr) : arr) return broadcastedCollections diff --git a/src/function/matrix/broadcastTo.js b/src/function/matrix/broadcastTo.js index 8501929d22..a92ac86a34 100644 --- a/src/function/matrix/broadcastTo.js +++ b/src/function/matrix/broadcastTo.js @@ -5,7 +5,7 @@ const name = 'broadcastTo' const dependencies = ['typed'] export const createBroadcastTo = /* #__PURE__ */ factory(name, dependencies, ({ typed }) => { - /** + /** * Broadcast an array to a specified size. * * Syntax: From a804f9d943d4f0b83758527a0465859edd0d6817 Mon Sep 17 00:00:00 2001 From: David Contreras Date: Fri, 26 Dec 2025 10:05:17 -0600 Subject: [PATCH 05/19] Added embedded docs --- src/expression/embeddedDocs/embeddedDocs.js | 6 ++++++ .../embeddedDocs/function/matrix/bradcastTo.js | 15 +++++++++++++++ .../function/matrix/broadcastMatrices.js | 15 +++++++++++++++ .../function/matrix/broadcastSizes.js | 15 +++++++++++++++ src/function/matrix/broadcastSizes.js | 5 +---- 5 files changed, 52 insertions(+), 4 deletions(-) create mode 100644 src/expression/embeddedDocs/function/matrix/bradcastTo.js create mode 100644 src/expression/embeddedDocs/function/matrix/broadcastMatrices.js create mode 100644 src/expression/embeddedDocs/function/matrix/broadcastSizes.js diff --git a/src/expression/embeddedDocs/embeddedDocs.js b/src/expression/embeddedDocs/embeddedDocs.js index 2e4383beb4..f1087386e3 100644 --- a/src/expression/embeddedDocs/embeddedDocs.js +++ b/src/expression/embeddedDocs/embeddedDocs.js @@ -143,6 +143,9 @@ import { partitionSelectDocs } from './function/matrix/partitionSelect.js' import { rangeDocs } from './function/matrix/range.js' import { reshapeDocs } from './function/matrix/reshape.js' import { resizeDocs } from './function/matrix/resize.js' +import { broadcastMatricesDocs } from './function/matrix/broadcastMatrices.js' +import { broadcastToDocs } from './function/matrix/bradcastTo.js' +import { broadcastSizesDocs } from './function/matrix/broadcastSizes.js' import { rotateDocs } from './function/matrix/rotate.js' import { rotationMatrixDocs } from './function/matrix/rotationMatrix.js' import { rowDocs } from './function/matrix/row.js' @@ -481,6 +484,9 @@ export const embeddedDocs = { partitionSelect: partitionSelectDocs, range: rangeDocs, resize: resizeDocs, + broadcastMatrices: broadcastMatricesDocs, + broadcastTo: broadcastToDocs, + broadcastSizes: broadcastSizesDocs, reshape: reshapeDocs, rotate: rotateDocs, rotationMatrix: rotationMatrixDocs, diff --git a/src/expression/embeddedDocs/function/matrix/bradcastTo.js b/src/expression/embeddedDocs/function/matrix/bradcastTo.js new file mode 100644 index 0000000000..f0376515cc --- /dev/null +++ b/src/expression/embeddedDocs/function/matrix/bradcastTo.js @@ -0,0 +1,15 @@ +export const broadcastToDocs = { + name: 'broadcastTo', + category: 'Matrix', + syntax: [ + 'broadcastTo(A, size)' + ], + description: 'Broadcast a matrix to a compatible size', + examples: [ + 'broadcastTo([1, 2, 3], [3, 3])', + 'broadcastTo([1, 2; 3, 4], [2, 2])' + ], + seealso: [ + 'size', 'reshape', 'broadcastSizes', 'broadcastMatrices' + ] +} diff --git a/src/expression/embeddedDocs/function/matrix/broadcastMatrices.js b/src/expression/embeddedDocs/function/matrix/broadcastMatrices.js new file mode 100644 index 0000000000..943bcaa058 --- /dev/null +++ b/src/expression/embeddedDocs/function/matrix/broadcastMatrices.js @@ -0,0 +1,15 @@ +export const broadcastMatricesDocs = { + name: 'broadcastMatrices', + category: 'Matrix', + syntax: [ + 'broadcastMatrices(A, B)' + ], + description: 'Broadcast two matrices to compatible sizes', + examples: [ + 'broadcastMatrices([1, 2, 3], [[1], [2], [3]])', + 'broadcastMatrices([1, 2; 3, 4], [5, 6; 7, 8])' + ], + seealso: [ + 'size', 'reshape', 'broadcastSizes', 'broadcastTo' + ] +} diff --git a/src/expression/embeddedDocs/function/matrix/broadcastSizes.js b/src/expression/embeddedDocs/function/matrix/broadcastSizes.js new file mode 100644 index 0000000000..ca0823b6b5 --- /dev/null +++ b/src/expression/embeddedDocs/function/matrix/broadcastSizes.js @@ -0,0 +1,15 @@ +export const broadcastSizesDocs = { + name: 'broadcastSizes', + category: 'Matrix', + syntax: [ + 'broadcastSizes(sizeA, sizeB)' + ], + description: 'Broadcast the sizes of matrices to a compatible size', + examples: [ + 'broadcastSizes([3, 1, 3], [3, 3])', + 'broadcastSizes([2, 1], [2, 2])' + ], + seealso: [ + 'size', 'reshape', 'broadcastTo', 'broadcastMatrices' + ] +} diff --git a/src/function/matrix/broadcastSizes.js b/src/function/matrix/broadcastSizes.js index a0f692e644..24d15ee5bc 100644 --- a/src/function/matrix/broadcastSizes.js +++ b/src/function/matrix/broadcastSizes.js @@ -33,12 +33,9 @@ export const createBroadcastSizes = /* #__PURE__ */ factory(name, dependencies, const areMatrices = collections.map(isMatrix) if (areMatrices.includes(true)) { const arrays = collections.map((c, i) => areMatrices[i] ? c.valueOf() : c) - const broadcastedArrays = broadcastSizes(...arrays) - const broadcastedCollections = broadcastedArrays.map((arr, i) => areMatrices[i] ? collections[i].create(arr) : arr) - return broadcastedCollections + return broadcastSizes(...arrays) } return broadcastSizes(...collections) } - }) }) From cfe64908df1c29863a0571abde2456f6be638f5a Mon Sep 17 00:00:00 2001 From: David Contreras Date: Sat, 27 Dec 2025 22:39:30 -0600 Subject: [PATCH 06/19] Added tests for broadcastSizes --- .../function/matrix/broadcastSizes.test.js | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 test/unit-tests/function/matrix/broadcastSizes.test.js diff --git a/test/unit-tests/function/matrix/broadcastSizes.test.js b/test/unit-tests/function/matrix/broadcastSizes.test.js new file mode 100644 index 0000000000..34b8597a0f --- /dev/null +++ b/test/unit-tests/function/matrix/broadcastSizes.test.js @@ -0,0 +1,24 @@ +import assert from 'assert' +import math from '../../../../src/defaultInstance.js' + +describe('broadcastSizes', function () { + it('should broadcast sizes', function () { + assert.deepStrictEqual(math.broadcastSizes([2, 3]), [2, 3]) + assert.deepStrictEqual(math.broadcastSizes([3, 3], [3, 1]), [3, 3]) + assert.deepStrictEqual(math.broadcastSizes([2, 1], [1, 3]), [2, 3]) + assert.deepStrictEqual(math.broadcastSizes([5, 4, 3], [1, 4, 1]), [5, 4, 3]) + assert.deepStrictEqual(math.broadcastSizes([3], [2, 3]), [2, 3]) + assert.deepStrictEqual(math.broadcastSizes([1, 3], [2, 1]), [2, 3]) + }) + + it('should throw an error if sizes are not compatible', function () { + assert.throws(function () { math.broadcastSizes([2, 3], [3, 2]) }, /Error: shape mismatch: /) + assert.throws(function () { math.broadcastSizes([2, 3], [2, 3, 4]) }, /Error: shape mismatch: /) + }) + + it('should broadcast sizes of mixed arrays and matrices', function () { + assert.deepStrictEqual(math.broadcastSizes([3, 3], math.matrix([3, 1])), [3, 3]) + assert.deepStrictEqual(math.broadcastSizes(math.matrix([2, 1]), [1, 3]), [2, 3]) + assert.deepStrictEqual(math.broadcastSizes(math.matrix([5, 4, 3]), math.matrix([1, 4, 1])), [5, 4, 3]) + }) +}) From 5224a45c154b31492713f1c48fe613115d98e131 Mon Sep 17 00:00:00 2001 From: David Contreras Date: Sun, 28 Dec 2025 00:22:25 -0600 Subject: [PATCH 07/19] Added tests for broadcastMatrices and fixed an issue with broadcastArrays --- src/utils/array.js | 2 +- .../function/matrix/broadcastMatrices.test.js | 35 +++++++++++++++++++ test/unit-tests/utils/array.test.js | 6 ++-- 3 files changed, 39 insertions(+), 4 deletions(-) create mode 100644 test/unit-tests/function/matrix/broadcastMatrices.test.js diff --git a/src/utils/array.js b/src/utils/array.js index 3c8b8813fa..4097372fa3 100644 --- a/src/utils/array.js +++ b/src/utils/array.js @@ -810,7 +810,7 @@ export function broadcastArrays (...arrays) { throw new Error('Insufficient number of arguments in function broadcastArrays') } if (arrays.length === 1) { - return arrays[0] + return arrays } const sizes = arrays.map(function (array) { return arraySize(array) }) const broadcastedSize = broadcastSizes(...sizes) diff --git a/test/unit-tests/function/matrix/broadcastMatrices.test.js b/test/unit-tests/function/matrix/broadcastMatrices.test.js new file mode 100644 index 0000000000..c870c9d531 --- /dev/null +++ b/test/unit-tests/function/matrix/broadcastMatrices.test.js @@ -0,0 +1,35 @@ +import assert from 'assert' +import math from '../../../../src/defaultInstance.js' + +describe('broadcastMatrices', function () { + const matrix = math.matrix + const broadcastMatrices = math.broadcastMatrices + const A = [[1], [2], [3]] + const B = [[10, 20, 30]] + const C = [100] + const broadcastedA = [[1, 1, 1], [2, 2, 2], [3, 3, 3]] + const broadcastedB = [[10, 20, 30], [10, 20, 30], [10, 20, 30]] + const broadcastedC = [[100, 100, 100], [100, 100, 100], [100, 100, 100]] + + it('should broadcast matrices', function () { + assert.deepStrictEqual(broadcastMatrices(matrix(A), matrix(B)), [matrix(broadcastedA), matrix(broadcastedB)]) + assert.deepStrictEqual(broadcastMatrices(matrix(A), matrix(C)), [matrix(A), matrix([[100], [100], [100]])]) + assert.deepStrictEqual(broadcastMatrices(matrix(B), matrix(A)), [matrix(broadcastedB), matrix(broadcastedA)]) + assert.deepStrictEqual(broadcastMatrices(matrix(A), matrix(B), matrix(C)), [matrix(broadcastedA), matrix(broadcastedB), matrix(broadcastedC)]) + }) + + it('should broadcast arrays', function () { + assert.deepStrictEqual(broadcastMatrices(A, B), [broadcastedA, broadcastedB]) + assert.deepStrictEqual(broadcastMatrices(B, A), [broadcastedB, broadcastedA]) + assert.deepStrictEqual(broadcastMatrices(A, B, C), [broadcastedA, broadcastedB, broadcastedC]) + assert.deepStrictEqual(broadcastMatrices(A), [A]) + assert.deepStrictEqual(broadcastMatrices(B, C, A), [broadcastedB, broadcastedC, broadcastedA]) + }) + + it('should throw an error if sizes are not compatible', function () { + assert.throws(function () { broadcastMatrices(matrix([[1, 2], [3, 4]]), matrix([[1, 2, 3]])) }, /Error: shape mismatch: /) + assert.throws(function () { broadcastMatrices([[1, 2], [3, 4]], matrix([[1, 2, 3]])) }, /Error: shape mismatch: /) + assert.throws(function () { broadcastMatrices(matrix([[1, 2], [3, 4]]), [[1, 2, 3]]) }, /Error: shape mismatch: /) + assert.throws(function () { broadcastMatrices([[1, 2], [3, 4]], [[1, 2, 3]]) }, /Error: shape mismatch: /) + }) +}) diff --git a/test/unit-tests/utils/array.test.js b/test/unit-tests/utils/array.test.js index f779379356..02ca7d85fe 100644 --- a/test/unit-tests/utils/array.test.js +++ b/test/unit-tests/utils/array.test.js @@ -702,9 +702,9 @@ describe('util.array', function () { }) it('should broadcast leave arrays as such when only one is supplied', function () { - assert.deepStrictEqual(broadcastArrays([1, 2]), [1, 2], [3, 4]) - assert.deepStrictEqual(broadcastArrays([[3], [4]]), [[3], [4]]) - assert.deepStrictEqual(broadcastArrays([[5, 6]]), [[5, 6]]) + assert.deepStrictEqual(broadcastArrays([1, 2])[0], [1, 2]) + assert.deepStrictEqual(broadcastArrays([[3], [4]])[0], [[3], [4]]) + assert.deepStrictEqual(broadcastArrays([[5, 6]])[0], [[5, 6]]) }) it('should throw an arryor when the broadcasting rules don\'t apply', function () { From 43156517dc47ccb795153e4f21dedb1da5f155c3 Mon Sep 17 00:00:00 2001 From: David Contreras Date: Sun, 28 Dec 2025 13:40:25 -0600 Subject: [PATCH 08/19] Added test for broadcastTo --- .../function/matrix/broadcastSizes.test.js | 25 +++++++++++-------- .../function/matrix/broadcastTo.test.js | 22 ++++++++++++++++ 2 files changed, 36 insertions(+), 11 deletions(-) create mode 100644 test/unit-tests/function/matrix/broadcastTo.test.js diff --git a/test/unit-tests/function/matrix/broadcastSizes.test.js b/test/unit-tests/function/matrix/broadcastSizes.test.js index 34b8597a0f..1978417daf 100644 --- a/test/unit-tests/function/matrix/broadcastSizes.test.js +++ b/test/unit-tests/function/matrix/broadcastSizes.test.js @@ -2,23 +2,26 @@ import assert from 'assert' import math from '../../../../src/defaultInstance.js' describe('broadcastSizes', function () { + const broadcastSizes = math.broadcastSizes + const matrix = math.matrix + it('should broadcast sizes', function () { - assert.deepStrictEqual(math.broadcastSizes([2, 3]), [2, 3]) - assert.deepStrictEqual(math.broadcastSizes([3, 3], [3, 1]), [3, 3]) - assert.deepStrictEqual(math.broadcastSizes([2, 1], [1, 3]), [2, 3]) - assert.deepStrictEqual(math.broadcastSizes([5, 4, 3], [1, 4, 1]), [5, 4, 3]) - assert.deepStrictEqual(math.broadcastSizes([3], [2, 3]), [2, 3]) - assert.deepStrictEqual(math.broadcastSizes([1, 3], [2, 1]), [2, 3]) + assert.deepStrictEqual(broadcastSizes([2, 3]), [2, 3]) + assert.deepStrictEqual(broadcastSizes([3, 3], [3, 1]), [3, 3]) + assert.deepStrictEqual(broadcastSizes([2, 1], [1, 3]), [2, 3]) + assert.deepStrictEqual(broadcastSizes([5, 4, 3], [1, 4, 1]), [5, 4, 3]) + assert.deepStrictEqual(broadcastSizes([3], [2, 3]), [2, 3]) + assert.deepStrictEqual(broadcastSizes([1, 3], [2, 1]), [2, 3]) }) it('should throw an error if sizes are not compatible', function () { - assert.throws(function () { math.broadcastSizes([2, 3], [3, 2]) }, /Error: shape mismatch: /) - assert.throws(function () { math.broadcastSizes([2, 3], [2, 3, 4]) }, /Error: shape mismatch: /) + assert.throws(function () { broadcastSizes([2, 3], [3, 2]) }, /Error: shape mismatch: /) + assert.throws(function () { broadcastSizes([2, 3], [2, 3, 4]) }, /Error: shape mismatch: /) }) it('should broadcast sizes of mixed arrays and matrices', function () { - assert.deepStrictEqual(math.broadcastSizes([3, 3], math.matrix([3, 1])), [3, 3]) - assert.deepStrictEqual(math.broadcastSizes(math.matrix([2, 1]), [1, 3]), [2, 3]) - assert.deepStrictEqual(math.broadcastSizes(math.matrix([5, 4, 3]), math.matrix([1, 4, 1])), [5, 4, 3]) + assert.deepStrictEqual(broadcastSizes([3, 3], matrix([3, 1])), [3, 3]) + assert.deepStrictEqual(broadcastSizes(matrix([2, 1]), [1, 3]), [2, 3]) + assert.deepStrictEqual(broadcastSizes(matrix([5, 4, 3]), matrix([1, 4, 1])), [5, 4, 3]) }) }) diff --git a/test/unit-tests/function/matrix/broadcastTo.test.js b/test/unit-tests/function/matrix/broadcastTo.test.js new file mode 100644 index 0000000000..c15d551c39 --- /dev/null +++ b/test/unit-tests/function/matrix/broadcastTo.test.js @@ -0,0 +1,22 @@ +import assert from 'assert' +import math from '../../../../src/defaultInstance.js' + +describe('broadcastTo', function () { + const broadcastTo = math.broadcastTo + const matrix = math.matrix + + it('should broadcast arrays to a given size', function () { + assert.deepStrictEqual(broadcastTo([1, 2, 3], [2, 3]), [[1, 2, 3], [1, 2, 3]]) + assert.deepStrictEqual(broadcastTo([2, 3], [2, 2]), [[2, 3], [2, 3]]) + }) + + it('should broadcast matrices to a given size', function () { + assert.deepStrictEqual(broadcastTo(matrix([1, 2, 3]), [2, 3]), matrix([[1, 2, 3], [1, 2, 3]])) + assert.deepStrictEqual(broadcastTo(matrix([2, 3]), [2, 2]), matrix([[2, 3], [2, 3]])) + }) + + it('should throw an error if sizes are not compatible', function () { + assert.throws(function () { broadcastTo([1, 2], [2, 3]) }, /Error: shape mismatch: /) + assert.throws(function () { broadcastTo(matrix([1, 2]), [2, 3]) }, /Error: shape mismatch: /) + }) +}) From c99c48a8fd35f0895cdb61d3a891148428c86a0b Mon Sep 17 00:00:00 2001 From: David Contreras Date: Sun, 28 Dec 2025 14:00:50 -0600 Subject: [PATCH 09/19] Added more tests to broadcastTo --- test/unit-tests/function/matrix/broadcastTo.test.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/test/unit-tests/function/matrix/broadcastTo.test.js b/test/unit-tests/function/matrix/broadcastTo.test.js index c15d551c39..3498f7e915 100644 --- a/test/unit-tests/function/matrix/broadcastTo.test.js +++ b/test/unit-tests/function/matrix/broadcastTo.test.js @@ -15,6 +15,13 @@ describe('broadcastTo', function () { assert.deepStrictEqual(broadcastTo(matrix([2, 3]), [2, 2]), matrix([[2, 3], [2, 3]])) }) + it('should broadcast mixed arrays and matrices to a given size', function () { + assert.deepStrictEqual(broadcastTo([1, 2, 3], matrix([2, 3])), [[1, 2, 3], [1, 2, 3]]) + assert.deepStrictEqual(broadcastTo(matrix([2, 3]), [2, 2]), matrix([[2, 3], [2, 3]])) + assert.deepStrictEqual(broadcastTo(matrix([1, 2, 3]), matrix([2, 3])), matrix([[1, 2, 3], [1, 2, 3]])) + assert.deepStrictEqual(broadcastTo([2, 3], matrix([2, 2])), [[2, 3], [2, 3]]) + }) + it('should throw an error if sizes are not compatible', function () { assert.throws(function () { broadcastTo([1, 2], [2, 3]) }, /Error: shape mismatch: /) assert.throws(function () { broadcastTo(matrix([1, 2]), [2, 3]) }, /Error: shape mismatch: /) From d7494058ac308c5e6d97ce97af04f0e11b57c826 Mon Sep 17 00:00:00 2001 From: David Contreras Date: Sun, 28 Dec 2025 14:25:02 -0600 Subject: [PATCH 10/19] Add types --- types/index.d.ts | 73 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/types/index.d.ts b/types/index.d.ts index 05b2711423..86661fe4ef 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -2222,6 +2222,79 @@ export interface MathJsInstance extends MathJsFactory { > ): T + /** + * Broadcast a matrix or array to a specified size. + * + * The input collection is conceptually expanded to match the given dimensions, + * following broadcasting rules. The returned object is a new matrix or array + * with the requested size; the original input is not modified. + * + * @param x The matrix or array to broadcast. + * @param size The target size for each dimension of the broadcasted result. + * @returns A matrix or array with the specified size, containing broadcasted values. + * @param x The matrix or array to broadcast. + * @param size The target size of the broadcasted output, specified as an array of dimension lengths. + * @returns A new matrix or array with the requested size, containing the broadcasted values of `x`. + */ + broadcastTo( + x: Matrix, + size: number[] | BigNumber[] | Matrix | Matrix + ): Matrix + broadcastTo( + x: MathArray, + size: number[] | BigNumber[] | Matrix | Matrix + ): MathArray + + /** + * Calculate the broadcasted size of one or more matrices or arrays. + * Always returns an Array containing numbers. + * + * Syntax: + * + * math.broadcastSizes(x, y) + * math.broadcastSizes(x, y, ...) + * + * Examples: + * + * math.broadcastSizes([2, 3]) // returns [2, 3] + * math.broadcastSizes([2, 3], [3]) // returns [2, 3] + * math.broadcastSizes([1, 2, 3], [[1, 2, 3]]) // returns [1, 2, 3] + * + * See also: + * + * size, reshape, squeeze, broadcastTo + * + * @param {...(Array|Matrix)} x One or more matrices or arrays + * @return {number[]} A vector with the broadcasted size. + */ + broadcastSizes(...args: Array): number[] + + /** + * Broadcast multiple matrices together. + * Return an array of matrices with the broadcasted sizes. + * + * Syntax: + * + * math.broadcastMatrices(x, y) + * math.broadcastMatrices(x, y, ...) + * + * Examples: + * + * math.broadcastMatrices([1, 2], [[3], [4]]) // returns [[[1, 2], [1, 2]], [[3, 3], [4, 4]]] + * math.broadcastMatrices([2, 3]) // returns [[2, 3]] + * math.broadcastMatrices([2, 3], [3, 1]) // returns [[2, 3], [3, 1]] + * + * See also: + * + * size, reshape, broadcastSizes, broadcastTo + * + * @param {...(Array|Matrix)} args One or more matrices or arrays + * @returns {(Array|Matrix)[]} An array of matrices with the broadcasted sizes. + */ + broadcastMatrices( + ...args: Array + ): Array + /** * Create a matrix filled with ones. The created matrix can have one or * multiple dimensions. From c267a8c83471830147a5ea0bb4bf9459f6f495f6 Mon Sep 17 00:00:00 2001 From: David Contreras Date: Sun, 28 Dec 2025 15:23:13 -0600 Subject: [PATCH 11/19] Fixed wrong example in jsdocs --- src/function/matrix/broadcastSizes.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/function/matrix/broadcastSizes.js b/src/function/matrix/broadcastSizes.js index 24d15ee5bc..c845fb3644 100644 --- a/src/function/matrix/broadcastSizes.js +++ b/src/function/matrix/broadcastSizes.js @@ -19,7 +19,7 @@ export const createBroadcastSizes = /* #__PURE__ */ factory(name, dependencies, * * math.broadcastSizes([2, 3]) // returns [2, 3] * math.broadcastSizes([2, 3], [3]) // returns [2, 3] - * math.broadcastSizes([1, 2, 3], [[1, 2, 3]]) // returns [[1, 2, 3]] + * math.broadcastSizes([1, 2, 3], [1, 2, 1]) // returns [[1, 2, 3]] * * See also: * From 23bc58351771623e7c322e3a6bfe7fa806901e64 Mon Sep 17 00:00:00 2001 From: David Contreras Date: Sun, 28 Dec 2025 22:39:55 -0600 Subject: [PATCH 12/19] Added hisotry --- src/function/matrix/broadcastMatrices.js | 13 ++++++++----- src/function/matrix/broadcastSizes.js | 5 ++++- src/function/matrix/broadcastTo.js | 4 ++++ 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/function/matrix/broadcastMatrices.js b/src/function/matrix/broadcastMatrices.js index 4f0fbc62da..0566668770 100644 --- a/src/function/matrix/broadcastMatrices.js +++ b/src/function/matrix/broadcastMatrices.js @@ -12,19 +12,22 @@ export const createBroadcastMatrices = /* #__PURE__ */ factory(name, dependencie * * Syntax: * - * math.broadcastMatrices(x, y) - * math.broadcastMatrices(x, y, ...) + * math.broadcastMatrices(x, y) + * math.broadcastMatrices(x, y, ...) * * Examples: * - * math.broadcastMatrices([1, 2], [[3], [4]]) // returns [[[1, 2], [1, 2]], [[3, 3], [4, 4]]] - * math.broadcastMatrices([2, 3]) // returns [[2, 3]] - * math.broadcastMatrices([2, 3], [3, 1]) // returns [[2, 3], [3, 1]] + * math.broadcastMatrices([1, 2], [[3], [4]]) // returns [[[1, 2], [1, 2]], [[3, 3], [4, 4]]] + * math.broadcastMatrices([2, 3]) // returns [[2, 3]] + * math.broadcastMatrices([2, 3], [3, 1]) // returns [[2, 3], [3, 1]] * * See also: * * size, reshape, broadcastSizes, broadcastTo * + * History: + * + * v15.1.1 created * @param {...(Array|Matrix)} x One or more matrices or arrays * @return {Array[Array|Matrix]} An array of matrices with the broadcasted sizes. */ diff --git a/src/function/matrix/broadcastSizes.js b/src/function/matrix/broadcastSizes.js index c845fb3644..a5921ef034 100644 --- a/src/function/matrix/broadcastSizes.js +++ b/src/function/matrix/broadcastSizes.js @@ -19,12 +19,15 @@ export const createBroadcastSizes = /* #__PURE__ */ factory(name, dependencies, * * math.broadcastSizes([2, 3]) // returns [2, 3] * math.broadcastSizes([2, 3], [3]) // returns [2, 3] - * math.broadcastSizes([1, 2, 3], [1, 2, 1]) // returns [[1, 2, 3]] + * math.broadcastSizes([1, 2, 3], [1, 2, 1]) // returns [1, 2, 3] * * See also: * * size, reshape, squeeze, broadcastTo * + * History: + * + * v15.1.1 created * @param {...(Array|Matrix)} x One or more matrices or arrays * @return {Array} A vector with the broadcasted size. */ diff --git a/src/function/matrix/broadcastTo.js b/src/function/matrix/broadcastTo.js index a92ac86a34..ef4d259b6c 100644 --- a/src/function/matrix/broadcastTo.js +++ b/src/function/matrix/broadcastTo.js @@ -21,6 +21,10 @@ export const createBroadcastTo = /* #__PURE__ */ factory(name, dependencies, ({ * * size, reshape, squeeze, broadcastSizes * + * History: + * + * v15.1.1 created + * * @param {Array|Matrix} x The array or matrix to broadcast * @param {Array|Matrix} size The target size * @return {Array} The broadcasted array From 26367b5154b11da23d84ad0cfc276394aa3fda49 Mon Sep 17 00:00:00 2001 From: David Contreras Date: Sun, 28 Dec 2025 22:41:44 -0600 Subject: [PATCH 13/19] Format --- src/function/matrix/broadcastMatrices.js | 2 +- src/function/matrix/broadcastSizes.js | 2 +- src/function/matrix/broadcastTo.js | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/function/matrix/broadcastMatrices.js b/src/function/matrix/broadcastMatrices.js index 0566668770..7012eec589 100644 --- a/src/function/matrix/broadcastMatrices.js +++ b/src/function/matrix/broadcastMatrices.js @@ -26,7 +26,7 @@ export const createBroadcastMatrices = /* #__PURE__ */ factory(name, dependencie * size, reshape, broadcastSizes, broadcastTo * * History: - * + * * v15.1.1 created * @param {...(Array|Matrix)} x One or more matrices or arrays * @return {Array[Array|Matrix]} An array of matrices with the broadcasted sizes. diff --git a/src/function/matrix/broadcastSizes.js b/src/function/matrix/broadcastSizes.js index a5921ef034..4924288746 100644 --- a/src/function/matrix/broadcastSizes.js +++ b/src/function/matrix/broadcastSizes.js @@ -26,7 +26,7 @@ export const createBroadcastSizes = /* #__PURE__ */ factory(name, dependencies, * size, reshape, squeeze, broadcastTo * * History: - * + * * v15.1.1 created * @param {...(Array|Matrix)} x One or more matrices or arrays * @return {Array} A vector with the broadcasted size. diff --git a/src/function/matrix/broadcastTo.js b/src/function/matrix/broadcastTo.js index ef4d259b6c..cda1724eb0 100644 --- a/src/function/matrix/broadcastTo.js +++ b/src/function/matrix/broadcastTo.js @@ -22,9 +22,9 @@ export const createBroadcastTo = /* #__PURE__ */ factory(name, dependencies, ({ * size, reshape, squeeze, broadcastSizes * * History: - * + * * v15.1.1 created - * + * * @param {Array|Matrix} x The array or matrix to broadcast * @param {Array|Matrix} size The target size * @return {Array} The broadcasted array From 54338f552231c50d34b1227484ae27fce9f3aa38 Mon Sep 17 00:00:00 2001 From: David Contreras Date: Thu, 8 Jan 2026 21:28:12 -0600 Subject: [PATCH 14/19] Fix typos and grammar errors --- src/expression/embeddedDocs/embeddedDocs.js | 2 +- .../embeddedDocs/function/matrix/broadcastMatrices.js | 5 +++-- .../embeddedDocs/function/matrix/broadcastSizes.js | 3 ++- .../function/matrix/{bradcastTo.js => broadcastTo.js} | 0 src/function/matrix/broadcastMatrices.js | 3 +-- src/function/matrix/broadcastSizes.js | 10 +--------- src/function/matrix/broadcastTo.js | 11 ++++++++--- test/unit-tests/utils/array.test.js | 6 +++--- 8 files changed, 19 insertions(+), 21 deletions(-) rename src/expression/embeddedDocs/function/matrix/{bradcastTo.js => broadcastTo.js} (100%) diff --git a/src/expression/embeddedDocs/embeddedDocs.js b/src/expression/embeddedDocs/embeddedDocs.js index f1087386e3..82f9c23b4e 100644 --- a/src/expression/embeddedDocs/embeddedDocs.js +++ b/src/expression/embeddedDocs/embeddedDocs.js @@ -144,7 +144,7 @@ import { rangeDocs } from './function/matrix/range.js' import { reshapeDocs } from './function/matrix/reshape.js' import { resizeDocs } from './function/matrix/resize.js' import { broadcastMatricesDocs } from './function/matrix/broadcastMatrices.js' -import { broadcastToDocs } from './function/matrix/bradcastTo.js' +import { broadcastToDocs } from './function/matrix/broadcastTo.js' import { broadcastSizesDocs } from './function/matrix/broadcastSizes.js' import { rotateDocs } from './function/matrix/rotate.js' import { rotationMatrixDocs } from './function/matrix/rotationMatrix.js' diff --git a/src/expression/embeddedDocs/function/matrix/broadcastMatrices.js b/src/expression/embeddedDocs/function/matrix/broadcastMatrices.js index 943bcaa058..5074c05910 100644 --- a/src/expression/embeddedDocs/function/matrix/broadcastMatrices.js +++ b/src/expression/embeddedDocs/function/matrix/broadcastMatrices.js @@ -4,10 +4,11 @@ export const broadcastMatricesDocs = { syntax: [ 'broadcastMatrices(A, B)' ], - description: 'Broadcast two matrices to compatible sizes', + description: 'Broadcast any number of arrays or matrices against each other.', examples: [ 'broadcastMatrices([1, 2, 3], [[1], [2], [3]])', - 'broadcastMatrices([1, 2; 3, 4], [5, 6; 7, 8])' + 'broadcastMatrices([1, 2; 3, 4], [5, 6; 7, 8])', + 'broadcastMatrices([1, 2, 3], [5], [[10], [20], [30]])' ], seealso: [ 'size', 'reshape', 'broadcastSizes', 'broadcastTo' diff --git a/src/expression/embeddedDocs/function/matrix/broadcastSizes.js b/src/expression/embeddedDocs/function/matrix/broadcastSizes.js index ca0823b6b5..df0be7b4ca 100644 --- a/src/expression/embeddedDocs/function/matrix/broadcastSizes.js +++ b/src/expression/embeddedDocs/function/matrix/broadcastSizes.js @@ -7,7 +7,8 @@ export const broadcastSizesDocs = { description: 'Broadcast the sizes of matrices to a compatible size', examples: [ 'broadcastSizes([3, 1, 3], [3, 3])', - 'broadcastSizes([2, 1], [2, 2])' + 'broadcastSizes([2, 1], [2, 2])', + 'broadcastSizes([1, 3], [2, 3], [4, 2, 3])' ], seealso: [ 'size', 'reshape', 'broadcastTo', 'broadcastMatrices' diff --git a/src/expression/embeddedDocs/function/matrix/bradcastTo.js b/src/expression/embeddedDocs/function/matrix/broadcastTo.js similarity index 100% rename from src/expression/embeddedDocs/function/matrix/bradcastTo.js rename to src/expression/embeddedDocs/function/matrix/broadcastTo.js diff --git a/src/function/matrix/broadcastMatrices.js b/src/function/matrix/broadcastMatrices.js index 7012eec589..4cc100c4b5 100644 --- a/src/function/matrix/broadcastMatrices.js +++ b/src/function/matrix/broadcastMatrices.js @@ -7,8 +7,7 @@ const dependencies = ['typed'] export const createBroadcastMatrices = /* #__PURE__ */ factory(name, dependencies, ({ typed }) => { /** - * Broadcast multiple matrices together. - * Return and array of matrices with the broadcasted sizes. + * Broadcast any number of arrays or matrices against each other. * * Syntax: * diff --git a/src/function/matrix/broadcastSizes.js b/src/function/matrix/broadcastSizes.js index 4924288746..3801fa0b87 100644 --- a/src/function/matrix/broadcastSizes.js +++ b/src/function/matrix/broadcastSizes.js @@ -1,6 +1,5 @@ import { broadcastSizes } from '../../utils/array.js' import { factory } from '../../utils/factory.js' -import { isMatrix } from '../../utils/is.js' const name = 'broadcastSizes' const dependencies = ['typed'] @@ -32,13 +31,6 @@ export const createBroadcastSizes = /* #__PURE__ */ factory(name, dependencies, * @return {Array} A vector with the broadcasted size. */ return typed(name, { - '...Array|Matrix': collections => { - const areMatrices = collections.map(isMatrix) - if (areMatrices.includes(true)) { - const arrays = collections.map((c, i) => areMatrices[i] ? c.valueOf() : c) - return broadcastSizes(...arrays) - } - return broadcastSizes(...collections) - } + '...Array|Matrix': collections => broadcastSizes(...collections.map(collection => collection.valueOf())) }) }) diff --git a/src/function/matrix/broadcastTo.js b/src/function/matrix/broadcastTo.js index cda1724eb0..c90a253d52 100644 --- a/src/function/matrix/broadcastTo.js +++ b/src/function/matrix/broadcastTo.js @@ -31,8 +31,13 @@ export const createBroadcastTo = /* #__PURE__ */ factory(name, dependencies, ({ */ return typed(name, { 'Array, Array': broadcastTo, - 'Array, Matrix': (arr, size) => broadcastTo(arr, size.toArray()), - 'Matrix, Array': (M, size) => M.create(broadcastTo(M.toArray(), size)), - 'Matrix, Matrix': (M1, size) => M1.create(broadcastTo(M1.toArray(), size.toArray())) + 'Array, Matrix': (arr, size) => broadcastTo(arr, size.valueOf()), + 'Matrix, Array|Matrix': (M, size) => { + const result = M.create() + result._size = size.valueOf() + result._data = broadcastTo(M.valueOf(), size.valueOf()) + result._datatype = M.datatype() + return result + } }) }) diff --git a/test/unit-tests/utils/array.test.js b/test/unit-tests/utils/array.test.js index 02ca7d85fe..af3e3f8e71 100644 --- a/test/unit-tests/utils/array.test.js +++ b/test/unit-tests/utils/array.test.js @@ -701,19 +701,19 @@ describe('util.array', function () { assert.deepStrictEqual(broadcastArrays([1, 2], [[3], [4]], [5, 6]), [[[1, 2], [1, 2]], [[3, 3], [4, 4]], [[5, 6], [5, 6]]]) }) - it('should broadcast leave arrays as such when only one is supplied', function () { + it('should broadcast a single array, returning the array itself in an array', function () { assert.deepStrictEqual(broadcastArrays([1, 2])[0], [1, 2]) assert.deepStrictEqual(broadcastArrays([[3], [4]])[0], [[3], [4]]) assert.deepStrictEqual(broadcastArrays([[5, 6]])[0], [[5, 6]]) }) - it('should throw an arryor when the broadcasting rules don\'t apply', function () { + it('should throw an error when the broadcasting rules don\'t apply', function () { assert.throws(function () { broadcastArrays([1, 2], [1, 2, 3]) }) assert.throws(function () { broadcastArrays([1, 2], [1, 2, 3], [4, 5]) }) assert.throws(function () { broadcastArrays([[1, 2], [1, 2]], [[1, 2, 3]]) }) }) - it('should throw an arryor when not enough arguments are supplied', function () { + it('should throw an error when not enough arguments are supplied', function () { assert.throws(function () { broadcastArrays() }) }) }) From bb50f2b299324c4b818e33d5f60a452ec1c9a789 Mon Sep 17 00:00:00 2001 From: David Contreras Date: Sun, 5 Apr 2026 09:28:55 -0600 Subject: [PATCH 15/19] Improved syntax --- .../embeddedDocs/function/matrix/broadcastMatrices.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/expression/embeddedDocs/function/matrix/broadcastMatrices.js b/src/expression/embeddedDocs/function/matrix/broadcastMatrices.js index 5074c05910..e3071c4e08 100644 --- a/src/expression/embeddedDocs/function/matrix/broadcastMatrices.js +++ b/src/expression/embeddedDocs/function/matrix/broadcastMatrices.js @@ -2,7 +2,8 @@ export const broadcastMatricesDocs = { name: 'broadcastMatrices', category: 'Matrix', syntax: [ - 'broadcastMatrices(A, B)' + 'broadcastMatrices(A, B)', + 'broadcastMatrices(A, B, ...)' ], description: 'Broadcast any number of arrays or matrices against each other.', examples: [ From 826d36e3e55dbce14a780a6629252af6b7ed4b44 Mon Sep 17 00:00:00 2001 From: David Contreras Date: Sun, 5 Apr 2026 09:34:07 -0600 Subject: [PATCH 16/19] Extended description of broadcastSizes --- .../embeddedDocs/function/matrix/broadcastSizes.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/expression/embeddedDocs/function/matrix/broadcastSizes.js b/src/expression/embeddedDocs/function/matrix/broadcastSizes.js index df0be7b4ca..191c2ddacd 100644 --- a/src/expression/embeddedDocs/function/matrix/broadcastSizes.js +++ b/src/expression/embeddedDocs/function/matrix/broadcastSizes.js @@ -2,9 +2,10 @@ export const broadcastSizesDocs = { name: 'broadcastSizes', category: 'Matrix', syntax: [ - 'broadcastSizes(sizeA, sizeB)' + 'broadcastSizes(sizeA, sizeB)', + 'broadcastSizes(sizeA, sizeB, ...)' ], - description: 'Broadcast the sizes of matrices to a compatible size', + description: 'Broadcast the sizes of matrices to a compatible size. Computes the size of the resulting matrix when broadcasting the input sizes against each other.', examples: [ 'broadcastSizes([3, 1, 3], [3, 3])', 'broadcastSizes([2, 1], [2, 2])', From 9f761fc55ff10deb580a6534dd647a1575acda90 Mon Sep 17 00:00:00 2001 From: David Contreras Date: Sun, 5 Apr 2026 10:35:11 -0600 Subject: [PATCH 17/19] Avoid matrix create shortcut. --- src/function/matrix/broadcastTo.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/function/matrix/broadcastTo.js b/src/function/matrix/broadcastTo.js index c90a253d52..dcbac36089 100644 --- a/src/function/matrix/broadcastTo.js +++ b/src/function/matrix/broadcastTo.js @@ -32,12 +32,12 @@ export const createBroadcastTo = /* #__PURE__ */ factory(name, dependencies, ({ return typed(name, { 'Array, Array': broadcastTo, 'Array, Matrix': (arr, size) => broadcastTo(arr, size.valueOf()), - 'Matrix, Array|Matrix': (M, size) => { - const result = M.create() - result._size = size.valueOf() - result._data = broadcastTo(M.valueOf(), size.valueOf()) - result._datatype = M.datatype() - return result + 'Matrix, Array|Matrix': function (M, size) { + return M.create({ + data: broadcastTo(M.valueOf(), size.valueOf()), + size: size.valueOf() + }, + M.datatype()) } }) }) From 1b4afd9d805d0a456f9ff5df6378eed38ef2cf22 Mon Sep 17 00:00:00 2001 From: David Contreras Date: Sun, 5 Apr 2026 12:29:07 -0600 Subject: [PATCH 18/19] Added references to broadcasting rules --- src/function/matrix/broadcastMatrices.js | 1 + src/function/matrix/broadcastSizes.js | 2 +- src/function/matrix/broadcastTo.js | 3 ++- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/function/matrix/broadcastMatrices.js b/src/function/matrix/broadcastMatrices.js index 4cc100c4b5..9d914dda89 100644 --- a/src/function/matrix/broadcastMatrices.js +++ b/src/function/matrix/broadcastMatrices.js @@ -8,6 +8,7 @@ const dependencies = ['typed'] export const createBroadcastMatrices = /* #__PURE__ */ factory(name, dependencies, ({ typed }) => { /** * Broadcast any number of arrays or matrices against each other. + * The broadcasting rules can be found in [Matrices#Broadcasting](./datatype/matrices#Broadcasting). * * Syntax: * diff --git a/src/function/matrix/broadcastSizes.js b/src/function/matrix/broadcastSizes.js index 3801fa0b87..3d9534da4c 100644 --- a/src/function/matrix/broadcastSizes.js +++ b/src/function/matrix/broadcastSizes.js @@ -8,7 +8,7 @@ export const createBroadcastSizes = /* #__PURE__ */ factory(name, dependencies, /** * Calculate the broadcasted size of one or more matrices or arrays. * Always returns an Array containing numbers. - * + * The broadcasting rules can be found in [Matrices#Broadcasting](./datatype/matrices#Broadcasting).* * Syntax: * * math.broadcastSizes(x, y) diff --git a/src/function/matrix/broadcastTo.js b/src/function/matrix/broadcastTo.js index dcbac36089..f65f6849ae 100644 --- a/src/function/matrix/broadcastTo.js +++ b/src/function/matrix/broadcastTo.js @@ -7,7 +7,8 @@ const dependencies = ['typed'] export const createBroadcastTo = /* #__PURE__ */ factory(name, dependencies, ({ typed }) => { /** * Broadcast an array to a specified size. - * + * The broadcasting rules can be found in [Matrices#Broadcasting](./datatype/matrices#Broadcasting). + * * Syntax: * * math.broadcastTo(x, size) From 3a19f481b22741534ed74c147f462621bdf92742 Mon Sep 17 00:00:00 2001 From: David Contreras Date: Sun, 5 Apr 2026 12:34:09 -0600 Subject: [PATCH 19/19] Format --- src/function/matrix/broadcastTo.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/function/matrix/broadcastTo.js b/src/function/matrix/broadcastTo.js index f65f6849ae..ba5ffa7ad9 100644 --- a/src/function/matrix/broadcastTo.js +++ b/src/function/matrix/broadcastTo.js @@ -7,7 +7,7 @@ const dependencies = ['typed'] export const createBroadcastTo = /* #__PURE__ */ factory(name, dependencies, ({ typed }) => { /** * Broadcast an array to a specified size. - * The broadcasting rules can be found in [Matrices#Broadcasting](./datatype/matrices#Broadcasting). + * The broadcasting rules can be found in [Matrices#Broadcasting](./datatype/matrices#Broadcasting). * * Syntax: *