diff --git a/HISTORY.md b/HISTORY.md index e5c58212a1..dfb1eee0f4 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -7,7 +7,9 @@ Breaking changes: - Improvements in calculation of the `dot` product of complex values. The first argument is now conjugated. See #1761. Thanks @m93a. - +- Change function `size` to always return an `Array` as output instead + of returning a `Matrix` when the input is a matrix or + `config.matrix == 'Array'`. See #1771. # 2020-03-29, version 6.6.2 diff --git a/docs/datatypes/matrices.md b/docs/datatypes/matrices.md index 8c90122e7c..b5383078ba 100644 --- a/docs/datatypes/matrices.md +++ b/docs/datatypes/matrices.md @@ -155,8 +155,8 @@ Math.js uses geometric dimensions: - A vector is one-dimensional. - A matrix is two or multi-dimensional. -The size of a matrix can be calculated with the function `size`. Function `size` -returns a `Matrix` or `Array`, depending on the configuration option `matrix`. +The size of a matrix can be calculated with the function `size`. +Function `size` always returns an `Array`. Furthermore, matrices have a function `size` as well, which always returns an Array. diff --git a/docs/expressions/syntax.md b/docs/expressions/syntax.md index 4cc2121bb4..f3b1c5096c 100644 --- a/docs/expressions/syntax.md +++ b/docs/expressions/syntax.md @@ -408,7 +408,7 @@ parser.evaluate('"hello"') // String, "hello" // string manipulation parser.evaluate('a = concat("hello", " world")') // String, "hello world" -parser.evaluate('size(a)') // Matrix [11] +parser.evaluate('size(a)') // Array [11] parser.evaluate('a[1:5]') // String, "hello" parser.evaluate('a[1] = "H"') // String, "H" parser.evaluate('a[7:12] = "there!"') // String, "there!" diff --git a/src/function/matrix/size.js b/src/function/matrix/size.js index e3d6fd4ff8..009b1ca524 100644 --- a/src/function/matrix/size.js +++ b/src/function/matrix/size.js @@ -1,14 +1,15 @@ import { arraySize } from '../../utils/array' import { factory } from '../../utils/factory' -import { noMatrix } from '../../utils/noop' const name = 'size' -const dependencies = ['typed', 'config', '?matrix'] +const dependencies = ['typed'] -export const createSize = /* #__PURE__ */ factory(name, dependencies, ({ typed, config, matrix }) => { +export const createSize = /* #__PURE__ */ factory(name, dependencies, ({ typed }) => { /** * Calculate the size of a matrix or scalar. * + * The function always returns an Array, also for Matrix input. + * * Syntax: * * math.size(x) @@ -27,24 +28,22 @@ export const createSize = /* #__PURE__ */ factory(name, dependencies, ({ typed, * resize, squeeze, subset * * @param {boolean | number | Complex | Unit | string | Array | Matrix} x A matrix - * @return {Array | Matrix} A vector with size of `x`. + * @return {Array} A vector with size of `x`. */ return typed(name, { Matrix: function (x) { - return x.create(x.size()) + return x.size() }, Array: arraySize, string: function (x) { - return (config.matrix === 'Array') ? [x.length] : matrix([x.length]) + return [x.length] }, 'number | Complex | BigNumber | Unit | boolean | null': function (x) { // scalar - return (config.matrix === 'Array') - ? [] - : matrix ? matrix([]) : noMatrix() + return [] } }) }) diff --git a/test/unit-tests/expression/parse.test.js b/test/unit-tests/expression/parse.test.js index 4ce0c46d8d..e0f464e85d 100644 --- a/test/unit-tests/expression/parse.test.js +++ b/test/unit-tests/expression/parse.test.js @@ -592,7 +592,7 @@ describe('parse', function () { it('should get/set the matrix correctly for 3d matrices', function () { const scope = {} assert.deepStrictEqual(parseAndEval('f=[1,2;3,4]', scope), math.matrix([[1, 2], [3, 4]])) - assert.deepStrictEqual(parseAndEval('size(f)', scope), math.matrix([2, 2])) + assert.deepStrictEqual(parseAndEval('size(f)', scope), [2, 2]) parseAndEval('f[:,:,2]=[5,6;7,8]', scope) assert.deepStrictEqual(scope.f, math.matrix([ @@ -606,7 +606,7 @@ describe('parse', function () { ] ])) - assert.deepStrictEqual(parseAndEval('size(f)', scope), math.matrix([2, 2, 2])) + assert.deepStrictEqual(parseAndEval('size(f)', scope), [2, 2, 2]) assert.deepStrictEqual(parseAndEval('f[:,:,1]', scope), math.matrix([[[1], [2]], [[3], [4]]])) assert.deepStrictEqual(parseAndEval('f[:,:,2]', scope), math.matrix([[[5], [6]], [[7], [8]]])) assert.deepStrictEqual(parseAndEval('f[:,2,:]', scope), math.matrix([[[2, 6]], [[4, 8]]])) @@ -642,11 +642,11 @@ describe('parse', function () { assert.deepStrictEqual(parseAndEval('d=1:3', scope), math.matrix([1, 2, 3])) assert.deepStrictEqual(parseAndEval('concat(d,d)', scope), math.matrix([1, 2, 3, 1, 2, 3])) assert.deepStrictEqual(parseAndEval('e=1+d', scope), math.matrix([2, 3, 4])) - assert.deepStrictEqual(parseAndEval('size(e)', scope), math.matrix([3])) + assert.deepStrictEqual(parseAndEval('size(e)', scope), [3]) assert.deepStrictEqual(parseAndEval('concat(e,e)', scope), math.matrix([2, 3, 4, 2, 3, 4])) assert.deepStrictEqual(parseAndEval('[[],[]]', scope), math.matrix([[], []])) assert.deepStrictEqual(parseAndEval('[[],[]]', scope).size(), [2, 0]) - assert.deepStrictEqual(parseAndEval('size([[],[]])', scope), math.matrix([2, 0])) + assert.deepStrictEqual(parseAndEval('size([[],[]])', scope), [2, 0]) }) it('should disable arrays as range in a matrix index', function () { @@ -1545,7 +1545,7 @@ describe('parse', function () { assert.ok(parseAndEval('[1,2,3;4,5,6]\'') instanceof Matrix) assert.deepStrictEqual(parseAndEval('[1:5]'), math.matrix([[1, 2, 3, 4, 5]])) assert.deepStrictEqual(parseAndEval('[1:5]\''), math.matrix([[1], [2], [3], [4], [5]])) - assert.deepStrictEqual(parseAndEval('size([1:5])'), math.matrix([1, 5])) + assert.deepStrictEqual(parseAndEval('size([1:5])'), [1, 5]) assert.deepStrictEqual(parseAndEval('[1,2;3,4]\''), math.matrix([[1, 3], [2, 4]])) }) diff --git a/test/unit-tests/function/matrix/ones.test.js b/test/unit-tests/function/matrix/ones.test.js index 6ff60c992e..b9327188e3 100644 --- a/test/unit-tests/function/matrix/ones.test.js +++ b/test/unit-tests/function/matrix/ones.test.js @@ -65,7 +65,7 @@ describe('ones', function () { it('should create a matrix with ones with the same size as original matrix', function () { const a = matrix([[1, 2, 3], [4, 5, 6]]) - assert.deepStrictEqual(ones(math.size(a)).size(), a.size()) + assert.deepStrictEqual(math.size(ones(math.matrix(math.size(a)))), a.size()) }) // TODO: test with invalid input diff --git a/test/unit-tests/function/matrix/size.test.js b/test/unit-tests/function/matrix/size.test.js index 8e7672d78b..03402a03f8 100644 --- a/test/unit-tests/function/matrix/size.test.js +++ b/test/unit-tests/function/matrix/size.test.js @@ -21,21 +21,21 @@ describe('size', function () { }) it('should calculate the size of a matrix', function () { - assert.deepStrictEqual(size(matrix()), matrix([0])) - assert.deepStrictEqual(size(matrix([[1, 2, 3], [4, 5, 6]])), matrix([2, 3])) - assert.deepStrictEqual(size(matrix([[], []])), matrix([2, 0])) + assert.deepStrictEqual(size(matrix()), [0]) + assert.deepStrictEqual(size(matrix([[1, 2, 3], [4, 5, 6]])), [2, 3]) + assert.deepStrictEqual(size(matrix([[], []])), [2, 0]) }) it('should calculate the size of a range', function () { - assert.deepStrictEqual(size(math.range(2, 6)), matrix([4])) + assert.deepStrictEqual(size(math.range(2, 6)), [4]) }) it('should calculate the size of a scalar', function () { - assert.deepStrictEqual(size(2), matrix([])) - assert.deepStrictEqual(size(math.bignumber(2)), matrix([])) - assert.deepStrictEqual(size(math.complex(2, 3)), matrix([])) - assert.deepStrictEqual(size(true), matrix([])) - assert.deepStrictEqual(size(null), matrix([])) + assert.deepStrictEqual(size(2), []) + assert.deepStrictEqual(size(math.bignumber(2)), []) + assert.deepStrictEqual(size(math.complex(2, 3)), []) + assert.deepStrictEqual(size(true), []) + assert.deepStrictEqual(size(null), []) }) it('should calculate the size of a scalar with setting matrix=="array"', function () { @@ -47,8 +47,8 @@ describe('size', function () { }) it('should calculate the size of a string', function () { - assert.deepStrictEqual(size('hello'), matrix([5])) - assert.deepStrictEqual(size(''), matrix([0])) + assert.deepStrictEqual(size('hello'), [5]) + assert.deepStrictEqual(size(''), [0]) }) it('should throw an error if called with an invalid number of arguments', function () { diff --git a/test/unit-tests/function/matrix/squeeze.test.js b/test/unit-tests/function/matrix/squeeze.test.js index deb76d773c..6016a1b66c 100644 --- a/test/unit-tests/function/matrix/squeeze.test.js +++ b/test/unit-tests/function/matrix/squeeze.test.js @@ -9,14 +9,14 @@ const matrix = math.matrix describe('squeeze', function () { it('should squeeze an matrix', function () { let m = math.ones(matrix([1, 3, 2])) - assert.deepStrictEqual(size(m), matrix([1, 3, 2])) + assert.deepStrictEqual(size(m), [1, 3, 2]) assert.deepStrictEqual(size(m.valueOf()), [1, 3, 2]) - assert.deepStrictEqual(size(squeeze(m)), matrix([3, 2])) + assert.deepStrictEqual(size(squeeze(m)), [3, 2]) m = math.ones(matrix([1, 1, 3])) - assert.deepStrictEqual(size(m), matrix([1, 1, 3])) - assert.deepStrictEqual(size(squeeze(m)), matrix([3])) - assert.deepStrictEqual(size(squeeze(math.range(1, 6))), matrix([5])) + assert.deepStrictEqual(size(m), [1, 1, 3]) + assert.deepStrictEqual(size(squeeze(m)), [3]) + assert.deepStrictEqual(size(squeeze(math.range(1, 6))), [5]) assert.deepStrictEqual(squeeze(2.3), 2.3) assert.deepStrictEqual(squeeze(matrix([[5]])), 5) diff --git a/test/unit-tests/function/matrix/zeros.test.js b/test/unit-tests/function/matrix/zeros.test.js index b27407dea5..91ec061365 100644 --- a/test/unit-tests/function/matrix/zeros.test.js +++ b/test/unit-tests/function/matrix/zeros.test.js @@ -66,7 +66,7 @@ describe('zeros', function () { it('should create a matrix with zeros with the same size as original matrix', function () { const a = matrix([[1, 2, 3], [4, 5, 6]]) - assert.deepStrictEqual(zeros(math.size(a)).size(), a.size()) + assert.deepStrictEqual(math.size(zeros(math.size(a))), a.size()) }) // TODO: test with invalid input diff --git a/test/unit-tests/type/chain/Chain.test.js b/test/unit-tests/type/chain/Chain.test.js index f5497f082b..ca0bdd5718 100644 --- a/test/unit-tests/type/chain/Chain.test.js +++ b/test/unit-tests/type/chain/Chain.test.js @@ -76,7 +76,7 @@ describe('Chain', function () { }) it('should not break with null or true as value', function () { - assert.deepStrictEqual(new Chain(null).size().done(), math.matrix([])) + assert.deepStrictEqual(new Chain(null).size().done(), []) assert.strictEqual(new Chain(true).add(1).done(), 2) }) diff --git a/test/unit-tests/type/matrix/function/matrix.test.js b/test/unit-tests/type/matrix/function/matrix.test.js index 63c8a7922d..d455d82498 100644 --- a/test/unit-tests/type/matrix/function/matrix.test.js +++ b/test/unit-tests/type/matrix/function/matrix.test.js @@ -8,19 +8,19 @@ describe('matrix', function () { it('should create an empty matrix with one dimension if called without argument', function () { const a = matrix() assert.ok(a instanceof math.Matrix) - assert.deepStrictEqual(math.size(a), matrix([0])) // TODO: wouldn't it be nicer if an empty matrix has zero dimensions? + assert.deepStrictEqual(math.size(a), [0]) // TODO: wouldn't it be nicer if an empty matrix has zero dimensions? }) it('should create empty matrix, dense format', function () { const a = matrix('dense') assert.ok(a instanceof math.Matrix) - assert.deepStrictEqual(math.size(a), matrix([0])) + assert.deepStrictEqual(math.size(a), [0]) }) it('should create empty matrix, dense format, number datatype', function () { const a = matrix('dense', 'number') assert.ok(a instanceof math.Matrix) - assert.deepStrictEqual(math.size(a), matrix([0])) + assert.deepStrictEqual(math.size(a), [0]) assert(a.datatype(), 'number') }) @@ -33,7 +33,7 @@ describe('matrix', function () { const b = matrix([[1, 2], [3, 4]]) assert.ok(b instanceof math.Matrix) assert.deepStrictEqual(b, matrix([[1, 2], [3, 4]])) - assert.deepStrictEqual(math.size(b), matrix([2, 2])) + assert.deepStrictEqual(math.size(b), [2, 2]) }) it('should be the identity if called with a matrix, dense format', function () { @@ -41,7 +41,7 @@ describe('matrix', function () { const c = matrix(b, 'dense') assert.ok(c._data !== b._data) // data should be cloned assert.deepStrictEqual(c, matrix([[1, 2], [3, 4]], 'dense')) - assert.deepStrictEqual(math.size(c), matrix([2, 2], 'dense')) + assert.deepStrictEqual(math.size(c), [2, 2]) }) it('should be the identity if called with a matrix, dense format, number datatype', function () { @@ -73,7 +73,7 @@ describe('matrix', function () { const d = matrix(math.range(1, 6)) assert.ok(d instanceof math.Matrix) assert.deepStrictEqual(d, matrix([1, 2, 3, 4, 5])) - assert.deepStrictEqual(math.size(d), matrix([5])) + assert.deepStrictEqual(math.size(d), [5]) }) it('should throw an error if called with an invalid argument', function () {