From 065b3ae4e8459413f71650aae20cf60f95540b87 Mon Sep 17 00:00:00 2001 From: David Contreras Date: Thu, 15 Feb 2024 06:35:19 -0600 Subject: [PATCH 01/13] feat: trailing commas in matrices (#3154) --- src/expression/parse.js | 12 +++++--- test/unit-tests/expression/parse.test.js | 39 +++++++++++++++++++++++- 2 files changed, 46 insertions(+), 5 deletions(-) diff --git a/src/expression/parse.js b/src/expression/parse.js index 45df38c985..ef7a8e00b0 100644 --- a/src/expression/parse.js +++ b/src/expression/parse.js @@ -1544,8 +1544,10 @@ export const createParse = /* #__PURE__ */ factory(name, dependencies, ({ while (state.token === ';') { // eslint-disable-line no-unmodified-loop-condition getToken(state) - params[rows] = parseRow(state) - rows++ + if (state.token !== ']') { + params[rows] = parseRow(state) + rows++ + } } if (state.token !== ']') { @@ -1599,8 +1601,10 @@ export const createParse = /* #__PURE__ */ factory(name, dependencies, ({ getToken(state) // parse expression - params[len] = parseAssignment(state) - len++ + if (state.token !== ']' && state.token !== ';') { + params[len] = parseAssignment(state) + len++ + } } return new ArrayNode(params) diff --git a/test/unit-tests/expression/parse.test.js b/test/unit-tests/expression/parse.test.js index fe3190ea5c..2bd7641926 100644 --- a/test/unit-tests/expression/parse.test.js +++ b/test/unit-tests/expression/parse.test.js @@ -621,6 +621,43 @@ describe('parse', function () { assert.deepStrictEqual(parseAndEval('[[[1],[2]],[[3],[4]]]'), math.matrix([[[1], [2]], [[3], [4]]])) }) + it('should parse a matrix with trailing commas', function () { + assert.ok(parseAndEval('[1,2;3,4;]') instanceof Matrix) + + const m = parseAndEval('[1,2,3;4,5,6;]') + assert.deepStrictEqual(m.size(), [2, 3]) + assert.deepStrictEqual(m, math.matrix([[1, 2, 3], [4, 5, 6]])) + + const b = parseAndEval('[5, 6; 1, 1;]') + assert.deepStrictEqual(b.size(), [2, 2]) + assert.deepStrictEqual(b, math.matrix([[5, 6], [1, 1]])) + + // from 1 to n dimensions + assert.deepStrictEqual(parseAndEval('[ ]'), math.matrix([])) + assert.deepStrictEqual(parseAndEval('[1,2,3,]'), math.matrix([1, 2, 3])) + assert.deepStrictEqual(parseAndEval('[1;2;3;]'), math.matrix([[1], [2], [3]])) + assert.deepStrictEqual(parseAndEval('[[1,2],[3,4],]'), math.matrix([[1, 2], [3, 4]])) + assert.deepStrictEqual(parseAndEval('[[[1],[2]],[[3],[4]],]'), math.matrix([[[1], [2]], [[3], [4]]])) + }) + + it('should throw an error when multiple trailing commas/semicolons are in a matrix', function () { + assert.throws(function () { + parseAndEval('[1,2,3,,] ') + }, /SyntaxError: Value expected/) + + assert.throws(function () { + parseAndEval('[1,2;3,4;,] ') + }, /SyntaxError: Value expected/) + + assert.throws(function () { + parseAndEval('[1;2;3;;]') + }, /SyntaxError: Value expected/) + + assert.throws(function () { + parseAndEval('[[[1],[2]],[[3],[4]],,]') + }, /SyntaxError: Value expected/) + }) + it('should parse an empty matrix', function () { assert.deepStrictEqual(parseAndEval('[]'), math.matrix([])) }) @@ -2365,7 +2402,7 @@ describe('parse', function () { try { mathClone.evaluate('f(x)=1;config({clone:f})') - } catch (err) {} + } catch (err) { } assert.strictEqual(mathClone.evaluate('2'), 2) }) From 8454d4baeea6aab850b3324882b47b17e54de23e Mon Sep 17 00:00:00 2001 From: Jos de Jong Date: Thu, 15 Feb 2024 13:36:09 +0100 Subject: [PATCH 02/13] chore: update history --- HISTORY.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/HISTORY.md b/HISTORY.md index e7586a1388..80fbc09247 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -3,6 +3,8 @@ # Unpublished changes since 12.3.2 +- Feat: implement support for trailing commas in matrices (#3154, #2968). + Thanks @dvd101x. - Docs: describe method `getAllAsMap` in the Parser docs (#3158, #3157). Thanks @dvd101x. From 085b85532cf6a0abd469c48c73959e4f1aa2d7df Mon Sep 17 00:00:00 2001 From: Jos de Jong Date: Fri, 16 Feb 2024 15:48:12 +0100 Subject: [PATCH 03/13] docs: fix broken example in the documentation about matrices (see #3159) --- docs/datatypes/matrices.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/datatypes/matrices.md b/docs/datatypes/matrices.md index ab02879bd7..57cc80608b 100644 --- a/docs/datatypes/matrices.md +++ b/docs/datatypes/matrices.md @@ -30,8 +30,8 @@ const array = [[2, 0], [-1, 3]] // Array const matrix = math.matrix([[7, 1], [-2, 3]]) // Matrix // perform a calculation on an array and matrix -math.square(array) // Array, [[4, 0], [1, 9]] -math.square(matrix) // Matrix, [[49, 1], [4, 9]] +math.map(array, math.square) // Array, [[4, 0], [1, 9]] +math.map(matrix, math.square) // Matrix, [[49, 1], [4, 9]] // perform calculations with mixed array and matrix input math.add(array, matrix) // Matrix, [[9, 1], [-3, 6]] From a7f84abe51a72b6037c7fdf72c9295c9b18830a8 Mon Sep 17 00:00:00 2001 From: Jos de Jong Date: Wed, 21 Feb 2024 12:17:30 +0100 Subject: [PATCH 04/13] fix: `PartitionedMap` and `ObjectWrappingMap` missing a property `Symbol.iterator` --- HISTORY.md | 3 +++ src/utils/map.js | 4 ++++ test/unit-tests/utils/map.test.js | 14 ++++++++++++++ 3 files changed, 21 insertions(+) diff --git a/HISTORY.md b/HISTORY.md index 80fbc09247..2da4d93b04 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -5,6 +5,9 @@ - Feat: implement support for trailing commas in matrices (#3154, #2968). Thanks @dvd101x. +- Fix: `PartitionedMap` and `ObjectWrappingMap` missing a property + `Symbol.iterator`, causing problems when trying `new Map(scope)`. See + https://github.com/josdejong/mathjs/discussions/3156#discussioncomment-8516994 - Docs: describe method `getAllAsMap` in the Parser docs (#3158, #3157). Thanks @dvd101x. diff --git a/src/utils/map.js b/src/utils/map.js index 7228bbb055..baa898d5ba 100644 --- a/src/utils/map.js +++ b/src/utils/map.js @@ -12,6 +12,8 @@ import { isObject } from './is.js' export class ObjectWrappingMap { constructor (object) { this.wrappedObject = object + + this[Symbol.iterator] = this.entries } keys () { @@ -80,6 +82,8 @@ export class PartitionedMap { this.a = a this.b = b this.bKeys = bKeys + + this[Symbol.iterator] = this.entries } get (key) { diff --git a/test/unit-tests/utils/map.test.js b/test/unit-tests/utils/map.test.js index 743fc66a71..5163e04867 100644 --- a/test/unit-tests/utils/map.test.js +++ b/test/unit-tests/utils/map.test.js @@ -110,6 +110,10 @@ describe('maps', function () { const innerObject = toObject(map) assert.strictEqual(innerObject, obj) + // Create a new Map + const copy = new Map(map) + assert.deepStrictEqual([...copy.keys()], [...map.keys()]) + // clear map.clear() assert.deepStrictEqual([...map.keys()], []) @@ -214,6 +218,16 @@ describe('maps', function () { assert.deepStrictEqual(it.next(), { done: true, value: undefined }) }) + it('copy', function () { + const { a, b, p } = createPartitionedMap(['b']) + p + .set('a', 2) + .set('b', 3) + + const copy = new Map(p) + assert.deepStrictEqual([...copy.keys()], [...p.keys()]) + }) + it('size', function () { const { p } = createPartitionedMap(['b']) p.set('a', 2) From 663bbea40d1ccc80273457ce4a87652fc6add21f Mon Sep 17 00:00:00 2001 From: Jos de Jong Date: Wed, 21 Feb 2024 12:23:05 +0100 Subject: [PATCH 05/13] fix: linting issue --- test/unit-tests/utils/map.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/unit-tests/utils/map.test.js b/test/unit-tests/utils/map.test.js index 5163e04867..aeba77615d 100644 --- a/test/unit-tests/utils/map.test.js +++ b/test/unit-tests/utils/map.test.js @@ -219,7 +219,7 @@ describe('maps', function () { }) it('copy', function () { - const { a, b, p } = createPartitionedMap(['b']) + const { p } = createPartitionedMap(['b']) p .set('a', 2) .set('b', 3) From b78ac811a4fc4a69d6f99f5ac523e6fee544819e Mon Sep 17 00:00:00 2001 From: Rich Martinez <6185506+rich-martinez@users.noreply.github.com> Date: Wed, 21 Feb 2024 06:36:40 -0500 Subject: [PATCH 06/13] fix: mode signature return types (#3153) * fix: mode type signatures * Add ts tests for mode * Add assertions mode type tests * Update author Rich in AUTHORS file --------- Co-authored-by: Rich Martinez Co-authored-by: Jos de Jong --- AUTHORS | 1 + test/typescript-tests/testTypes.ts | 31 ++++++++++++++++++++++++++++++ types/index.d.ts | 10 +++++----- 3 files changed, 37 insertions(+), 5 deletions(-) diff --git a/AUTHORS b/AUTHORS index cd302b33ec..8df842e40a 100644 --- a/AUTHORS +++ b/AUTHORS @@ -239,5 +239,6 @@ Brooks Smith Alex Edgcomb S.Y. Lee Hudsxn <143907857+Hudsxn@users.noreply.github.com> +Rich Martinez # Generated by tools/update-authors.js diff --git a/test/typescript-tests/testTypes.ts b/test/typescript-tests/testTypes.ts index 982d4374d5..634476345e 100644 --- a/test/typescript-tests/testTypes.ts +++ b/test/typescript-tests/testTypes.ts @@ -2542,3 +2542,34 @@ Match types of exact positional arguments. expectTypeOf(node3.items[0]).toMatchTypeOf() expectTypeOf(node3.items[1]).toMatchTypeOf() } + +/** + * mode Return Types + */ +{ + const math = create(all, {}) + const a = math.mode([1, 2, 3]) + expectTypeOf(a).toMatchTypeOf() + assert.deepStrictEqual(a, [1, 2, 3]) + + const b = math.mode([ + [1, 2], + [2, 2], + [3, 5] + ]) + expectTypeOf(b).toMatchTypeOf() + assert.deepStrictEqual(b, [2]) + + const c = math.mode(1, 2, 2, 2, 3, 5) + expectTypeOf(c).toMatchTypeOf() + assert.deepStrictEqual(c, [2]) + + const d = math.mode(1, 2, 2, 2, 3, 5) + expectTypeOf(d).toMatchTypeOf() + assert.deepStrictEqual(d, [2]) + + const mathCollection = math.concat([1, 2, 3], [1], [4, 5]) + const e = math.mode(mathCollection) + expectTypeOf(e).toMatchTypeOf() + assert.deepStrictEqual(e, [1]) +} diff --git a/types/index.d.ts b/types/index.d.ts index b015c4e68e..3c46acb9e8 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -2760,22 +2760,22 @@ export interface MathJsInstance extends MathJsFactory { * @param args Multiple scalar values * @returns The mode of all values */ - mode(...args: T[]): T + mode(...args: T[]): T[] /** * @param args Multiple scalar values * @returns The mode of all values */ - mode(...args: MathScalarType[]): MathScalarType + mode(...args: MathScalarType[]): MathScalarType[] /** * @param A A single matrix - * @returns The median value + * @returns The mode value */ - mode(A: T[] | T[][]): T + mode(A: T[] | T[][]): T[] /** * @param A A single matrix * @returns The mode of all values */ - mode(A: MathCollection): MathScalarType + mode(A: MathCollection): MathScalarType[] /** * Compute the product of a matrix or a list with values. In case of a From 9842ad93bf9db9fb6339353c37fbfa747799302b Mon Sep 17 00:00:00 2001 From: Jos de Jong Date: Wed, 21 Feb 2024 13:28:51 +0100 Subject: [PATCH 07/13] chore: update history --- HISTORY.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 2da4d93b04..3f35e9aafa 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -6,8 +6,8 @@ - Feat: implement support for trailing commas in matrices (#3154, #2968). Thanks @dvd101x. - Fix: `PartitionedMap` and `ObjectWrappingMap` missing a property - `Symbol.iterator`, causing problems when trying `new Map(scope)`. See - https://github.com/josdejong/mathjs/discussions/3156#discussioncomment-8516994 + `Symbol.iterator`, causing problems when trying `new Map(scope)` (#3156). +- Fix: type definitions of function `mode` (#3153). Thanks @rich-martinez. - Docs: describe method `getAllAsMap` in the Parser docs (#3158, #3157). Thanks @dvd101x. From 207623c931cd326b6eb4160e307e9f2563e50125 Mon Sep 17 00:00:00 2001 From: RandomGamingDev <83996185+RandomGamingDev@users.noreply.github.com> Date: Thu, 22 Feb 2024 05:10:26 -0500 Subject: [PATCH 08/13] feat: improve the performance f `multiply` by adding matrix type inferencing (#3149) * added type inference * added back accidentally removed return statement and made it so that the explicitly defined type is returned at the end * made sure that mixed types are ignored in the process data types check * fixed issue with undefined _data for SparseMatrix and linting issues * simplified syntax and added type inferencing to src/type/matrix/utils and src/function/matrix/dot.js * shortened the final part of the type inferencing and moved it to matrix creation in multiply --------- Co-authored-by: Jos de Jong --- AUTHORS | 1 + src/function/arithmetic/multiply.js | 60 +++++++++++------------ src/function/matrix/dot.js | 6 +-- src/type/matrix/utils/matAlgo01xDSid.js | 8 +-- src/type/matrix/utils/matAlgo02xDS0.js | 8 +-- src/type/matrix/utils/matAlgo03xDSf.js | 8 +-- src/type/matrix/utils/matAlgo04xSidSid.js | 8 +-- src/type/matrix/utils/matAlgo05xSfSf.js | 8 +-- src/type/matrix/utils/matAlgo06xS0S0.js | 8 +-- src/type/matrix/utils/matAlgo07xSSf.js | 8 +-- src/type/matrix/utils/matAlgo08xS0Sid.js | 8 +-- src/type/matrix/utils/matAlgo09xS0Sf.js | 8 +-- 12 files changed, 70 insertions(+), 69 deletions(-) diff --git a/AUTHORS b/AUTHORS index 8df842e40a..0fbe5b0230 100644 --- a/AUTHORS +++ b/AUTHORS @@ -239,6 +239,7 @@ Brooks Smith Alex Edgcomb S.Y. Lee Hudsxn <143907857+Hudsxn@users.noreply.github.com> +RandomGamingDev Rich Martinez # Generated by tools/update-authors.js diff --git a/src/function/arithmetic/multiply.js b/src/function/arithmetic/multiply.js index daf14bc46d..19bd3b7eef 100644 --- a/src/function/arithmetic/multiply.js +++ b/src/function/arithmetic/multiply.js @@ -110,11 +110,11 @@ export const createMultiply = /* #__PURE__ */ factory(name, dependencies, ({ typ // a dense const adata = a._data const asize = a._size - const adt = a._datatype + const adt = a._datatype || a.getDataType() // b dense const bdata = b._data const bsize = b._size - const bdt = b._datatype + const bdt = b._datatype || b.getDataType() // rows & columns const alength = asize[0] const bcolumns = bsize[1] @@ -127,7 +127,7 @@ export const createMultiply = /* #__PURE__ */ factory(name, dependencies, ({ typ let mf = multiplyScalar // process data types - if (adt && bdt && adt === bdt && typeof adt === 'string') { + if (adt && bdt && adt === bdt && typeof adt === 'string' && adt !== 'mixed') { // datatype dt = adt // find signatures that matches (dt, dt) @@ -154,7 +154,7 @@ export const createMultiply = /* #__PURE__ */ factory(name, dependencies, ({ typ return a.createDenseMatrix({ data: c, size: [bcolumns], - datatype: dt + datatype: adt === a._datatype && bdt === b._datatype ? dt : undefined }) } @@ -198,10 +198,10 @@ export const createMultiply = /* #__PURE__ */ factory(name, dependencies, ({ typ // a dense const adata = a._data const asize = a._size - const adt = a._datatype + const adt = a._datatype || a.getDataType() // b dense const bdata = b._data - const bdt = b._datatype + const bdt = b._datatype || b.getDataType() // rows & columns const arows = asize[0] const acolumns = asize[1] @@ -214,7 +214,7 @@ export const createMultiply = /* #__PURE__ */ factory(name, dependencies, ({ typ let mf = multiplyScalar // process data types - if (adt && bdt && adt === bdt && typeof adt === 'string') { + if (adt && bdt && adt === bdt && typeof adt === 'string' && adt !== 'mixed') { // datatype dt = adt // find signatures that matches (dt, dt) @@ -243,7 +243,7 @@ export const createMultiply = /* #__PURE__ */ factory(name, dependencies, ({ typ return a.createDenseMatrix({ data: c, size: [arows], - datatype: dt + datatype: adt === a._datatype && bdt === b._datatype ? dt : undefined }) } @@ -255,15 +255,15 @@ export const createMultiply = /* #__PURE__ */ factory(name, dependencies, ({ typ * * @return {Matrix} DenseMatrix (MxC) */ - function _multiplyDenseMatrixDenseMatrix (a, b) { + function _multiplyDenseMatrixDenseMatrix (a, b) { // getDataType() // a dense const adata = a._data const asize = a._size - const adt = a._datatype + const adt = a._datatype || a.getDataType() // b dense const bdata = b._data const bsize = b._size - const bdt = b._datatype + const bdt = b._datatype || b.getDataType() // rows & columns const arows = asize[0] const acolumns = asize[1] @@ -277,7 +277,7 @@ export const createMultiply = /* #__PURE__ */ factory(name, dependencies, ({ typ let mf = multiplyScalar // process data types - if (adt && bdt && adt === bdt && typeof adt === 'string') { + if (adt && bdt && adt === bdt && typeof adt === 'string' && adt !== 'mixed' && adt !== 'mixed') { // datatype dt = adt // find signatures that matches (dt, dt) @@ -311,7 +311,7 @@ export const createMultiply = /* #__PURE__ */ factory(name, dependencies, ({ typ return a.createDenseMatrix({ data: c, size: [arows, bcolumns], - datatype: dt + datatype: adt === a._datatype && bdt === b._datatype ? dt : undefined }) } @@ -327,13 +327,13 @@ export const createMultiply = /* #__PURE__ */ factory(name, dependencies, ({ typ // a dense const adata = a._data const asize = a._size - const adt = a._datatype + const adt = a._datatype || a.getDataType() // b sparse const bvalues = b._values const bindex = b._index const bptr = b._ptr const bsize = b._size - const bdt = b._datatype + const bdt = b._datatype || b._data === undefined ? b._datatype : b.getDataType() // validate b matrix if (!bvalues) { throw new Error('Cannot multiply Dense Matrix times Pattern only Matrix') } // rows & columns @@ -352,7 +352,7 @@ export const createMultiply = /* #__PURE__ */ factory(name, dependencies, ({ typ let zero = 0 // process data types - if (adt && bdt && adt === bdt && typeof adt === 'string') { + if (adt && bdt && adt === bdt && typeof adt === 'string' && adt !== 'mixed') { // datatype dt = adt // find signatures that matches (dt, dt) @@ -373,7 +373,7 @@ export const createMultiply = /* #__PURE__ */ factory(name, dependencies, ({ typ index: cindex, ptr: cptr, size: [arows, bcolumns], - datatype: dt + datatype: adt === a._datatype && bdt === b._datatype ? dt : undefined }) // loop b columns @@ -437,12 +437,12 @@ export const createMultiply = /* #__PURE__ */ factory(name, dependencies, ({ typ const avalues = a._values const aindex = a._index const aptr = a._ptr - const adt = a._datatype + const adt = a._datatype || a._data === undefined ? a._datatype : a.getDataType() // validate a matrix if (!avalues) { throw new Error('Cannot multiply Pattern only Matrix times Dense Matrix') } // b dense const bdata = b._data - const bdt = b._datatype + const bdt = b._datatype || b.getDataType() // rows & columns const arows = a._size[0] const brows = b._size[0] @@ -463,7 +463,7 @@ export const createMultiply = /* #__PURE__ */ factory(name, dependencies, ({ typ let zero = 0 // process data types - if (adt && bdt && adt === bdt && typeof adt === 'string') { + if (adt && bdt && adt === bdt && typeof adt === 'string' && adt !== 'mixed') { // datatype dt = adt // find signatures that matches (dt, dt) @@ -516,13 +516,13 @@ export const createMultiply = /* #__PURE__ */ factory(name, dependencies, ({ typ // update ptr cptr[1] = cindex.length - // return sparse matrix + // matrix to return return a.createSparseMatrix({ values: cvalues, index: cindex, ptr: cptr, size: [arows, 1], - datatype: dt + datatype: adt === a._datatype && bdt === b._datatype ? dt : undefined }) } @@ -539,12 +539,12 @@ export const createMultiply = /* #__PURE__ */ factory(name, dependencies, ({ typ const avalues = a._values const aindex = a._index const aptr = a._ptr - const adt = a._datatype + const adt = a._datatype || a._data === undefined ? a._datatype : a.getDataType() // validate a matrix if (!avalues) { throw new Error('Cannot multiply Pattern only Matrix times Dense Matrix') } // b dense const bdata = b._data - const bdt = b._datatype + const bdt = b._datatype || b.getDataType() // rows & columns const arows = a._size[0] const brows = b._size[0] @@ -562,7 +562,7 @@ export const createMultiply = /* #__PURE__ */ factory(name, dependencies, ({ typ let zero = 0 // process data types - if (adt && bdt && adt === bdt && typeof adt === 'string') { + if (adt && bdt && adt === bdt && typeof adt === 'string' && adt !== 'mixed') { // datatype dt = adt // find signatures that matches (dt, dt) @@ -583,7 +583,7 @@ export const createMultiply = /* #__PURE__ */ factory(name, dependencies, ({ typ index: cindex, ptr: cptr, size: [arows, bcolumns], - datatype: dt + datatype: adt === a._datatype && bdt === b._datatype ? dt : undefined }) // workspace @@ -650,12 +650,12 @@ export const createMultiply = /* #__PURE__ */ factory(name, dependencies, ({ typ const avalues = a._values const aindex = a._index const aptr = a._ptr - const adt = a._datatype + const adt = a._datatype || a._data === undefined ? a._datatype : a.getDataType() // b sparse const bvalues = b._values const bindex = b._index const bptr = b._ptr - const bdt = b._datatype + const bdt = b._datatype || b._data === undefined ? b._datatype : b.getDataType() // rows & columns const arows = a._size[0] @@ -671,7 +671,7 @@ export const createMultiply = /* #__PURE__ */ factory(name, dependencies, ({ typ let mf = multiplyScalar // process data types - if (adt && bdt && adt === bdt && typeof adt === 'string') { + if (adt && bdt && adt === bdt && typeof adt === 'string' && adt !== 'mixed') { // datatype dt = adt // find signatures that matches (dt, dt) @@ -689,7 +689,7 @@ export const createMultiply = /* #__PURE__ */ factory(name, dependencies, ({ typ index: cindex, ptr: cptr, size: [arows, bcolumns], - datatype: dt + datatype: adt === a._datatype && bdt === b._datatype ? dt : undefined }) // workspace diff --git a/src/function/matrix/dot.js b/src/function/matrix/dot.js index bf47bb8b76..3f69ca575a 100644 --- a/src/function/matrix/dot.js +++ b/src/function/matrix/dot.js @@ -64,10 +64,10 @@ export const createDot = /* #__PURE__ */ factory(name, dependencies, ({ typed, a const N = _validateDim(a, b) const adata = isMatrix(a) ? a._data : a - const adt = isMatrix(a) ? a._datatype : undefined + const adt = isMatrix(a) ? a._datatype || a.getDataType() : undefined const bdata = isMatrix(b) ? b._data : b - const bdt = isMatrix(b) ? b._datatype : undefined + const bdt = isMatrix(b) ? b._datatype || b.getDataType() : undefined // are these 2-dimensional column vectors? (as opposed to 1-dimensional vectors) const aIsColumn = _size(a).length === 2 @@ -77,7 +77,7 @@ export const createDot = /* #__PURE__ */ factory(name, dependencies, ({ typed, a let mul = multiplyScalar // process data types - if (adt && bdt && adt === bdt && typeof adt === 'string') { + if (adt && bdt && adt === bdt && typeof adt === 'string' && adt !== 'mixed') { const dt = adt // find signatures that matches (dt, dt) add = typed.find(addScalar, [dt, dt]) diff --git a/src/type/matrix/utils/matAlgo01xDSid.js b/src/type/matrix/utils/matAlgo01xDSid.js index ba413a2b7e..7efb6b72de 100644 --- a/src/type/matrix/utils/matAlgo01xDSid.js +++ b/src/type/matrix/utils/matAlgo01xDSid.js @@ -28,13 +28,13 @@ export const createMatAlgo01xDSid = /* #__PURE__ */ factory(name, dependencies, // dense matrix arrays const adata = denseMatrix._data const asize = denseMatrix._size - const adt = denseMatrix._datatype + const adt = denseMatrix._datatype || denseMatrix.getDataType() // sparse matrix arrays const bvalues = sparseMatrix._values const bindex = sparseMatrix._index const bptr = sparseMatrix._ptr const bsize = sparseMatrix._size - const bdt = sparseMatrix._datatype + const bdt = sparseMatrix._datatype || sparseMatrix._data === undefined ? sparseMatrix._datatype : sparseMatrix.getDataType() // validate dimensions if (asize.length !== bsize.length) { throw new DimensionError(asize.length, bsize.length) } @@ -50,7 +50,7 @@ export const createMatAlgo01xDSid = /* #__PURE__ */ factory(name, dependencies, const columns = asize[1] // process data types - const dt = typeof adt === 'string' && adt === bdt ? adt : undefined + const dt = typeof adt === 'string' && adt !== 'mixed' && adt === bdt ? adt : undefined // callback function const cf = dt ? typed.find(callback, [dt, dt]) : callback @@ -97,7 +97,7 @@ export const createMatAlgo01xDSid = /* #__PURE__ */ factory(name, dependencies, return denseMatrix.createDenseMatrix({ data: cdata, size: [rows, columns], - datatype: dt + datatype: adt === denseMatrix._datatype && bdt === sparseMatrix._datatype ? dt : undefined }) } }) diff --git a/src/type/matrix/utils/matAlgo02xDS0.js b/src/type/matrix/utils/matAlgo02xDS0.js index f11dad48a7..0c3d5b8f6a 100644 --- a/src/type/matrix/utils/matAlgo02xDS0.js +++ b/src/type/matrix/utils/matAlgo02xDS0.js @@ -28,13 +28,13 @@ export const createMatAlgo02xDS0 = /* #__PURE__ */ factory(name, dependencies, ( // dense matrix arrays const adata = denseMatrix._data const asize = denseMatrix._size - const adt = denseMatrix._datatype + const adt = denseMatrix._datatype || denseMatrix.getDataType() // sparse matrix arrays const bvalues = sparseMatrix._values const bindex = sparseMatrix._index const bptr = sparseMatrix._ptr const bsize = sparseMatrix._size - const bdt = sparseMatrix._datatype + const bdt = sparseMatrix._datatype || sparseMatrix._data === undefined ? sparseMatrix._datatype : sparseMatrix.getDataType() // validate dimensions if (asize.length !== bsize.length) { throw new DimensionError(asize.length, bsize.length) } @@ -59,7 +59,7 @@ export const createMatAlgo02xDS0 = /* #__PURE__ */ factory(name, dependencies, ( let cf = callback // process data types - if (typeof adt === 'string' && adt === bdt) { + if (typeof adt === 'string' && adt === bdt && adt !== 'mixed') { // datatype dt = adt // find signature that matches (dt, dt) @@ -102,7 +102,7 @@ export const createMatAlgo02xDS0 = /* #__PURE__ */ factory(name, dependencies, ( index: cindex, ptr: cptr, size: [rows, columns], - datatype: dt + datatype: adt === denseMatrix._datatype && bdt === sparseMatrix._datatype ? dt : undefined }) } }) diff --git a/src/type/matrix/utils/matAlgo03xDSf.js b/src/type/matrix/utils/matAlgo03xDSf.js index c3d4965270..bed698bf59 100644 --- a/src/type/matrix/utils/matAlgo03xDSf.js +++ b/src/type/matrix/utils/matAlgo03xDSf.js @@ -28,13 +28,13 @@ export const createMatAlgo03xDSf = /* #__PURE__ */ factory(name, dependencies, ( // dense matrix arrays const adata = denseMatrix._data const asize = denseMatrix._size - const adt = denseMatrix._datatype + const adt = denseMatrix._datatype || denseMatrix.getDataType() // sparse matrix arrays const bvalues = sparseMatrix._values const bindex = sparseMatrix._index const bptr = sparseMatrix._ptr const bsize = sparseMatrix._size - const bdt = sparseMatrix._datatype + const bdt = sparseMatrix._datatype || sparseMatrix._data === undefined ? sparseMatrix._datatype : sparseMatrix.getDataType() // validate dimensions if (asize.length !== bsize.length) { throw new DimensionError(asize.length, bsize.length) } @@ -57,7 +57,7 @@ export const createMatAlgo03xDSf = /* #__PURE__ */ factory(name, dependencies, ( let cf = callback // process data types - if (typeof adt === 'string' && adt === bdt) { + if (typeof adt === 'string' && adt === bdt && adt !== 'mixed') { // datatype dt = adt // convert 0 to the same datatype @@ -109,7 +109,7 @@ export const createMatAlgo03xDSf = /* #__PURE__ */ factory(name, dependencies, ( return denseMatrix.createDenseMatrix({ data: cdata, size: [rows, columns], - datatype: dt + datatype: adt === denseMatrix._datatype && bdt === sparseMatrix._datatype ? dt : undefined }) } }) diff --git a/src/type/matrix/utils/matAlgo04xSidSid.js b/src/type/matrix/utils/matAlgo04xSidSid.js index a98e4ba91a..2d377f2e88 100644 --- a/src/type/matrix/utils/matAlgo04xSidSid.js +++ b/src/type/matrix/utils/matAlgo04xSidSid.js @@ -29,13 +29,13 @@ export const createMatAlgo04xSidSid = /* #__PURE__ */ factory(name, dependencies const aindex = a._index const aptr = a._ptr const asize = a._size - const adt = a._datatype + const adt = a._datatype || a._data === undefined ? a._datatype : a.getDataType() // sparse matrix arrays const bvalues = b._values const bindex = b._index const bptr = b._ptr const bsize = b._size - const bdt = b._datatype + const bdt = b._datatype || b._data === undefined ? b._datatype : b.getDataType() // validate dimensions if (asize.length !== bsize.length) { throw new DimensionError(asize.length, bsize.length) } @@ -57,7 +57,7 @@ export const createMatAlgo04xSidSid = /* #__PURE__ */ factory(name, dependencies let cf = callback // process data types - if (typeof adt === 'string' && adt === bdt) { + if (typeof adt === 'string' && adt === bdt && adt !== 'mixed') { // datatype dt = adt // find signature that matches (dt, dt) @@ -163,7 +163,7 @@ export const createMatAlgo04xSidSid = /* #__PURE__ */ factory(name, dependencies index: cindex, ptr: cptr, size: [rows, columns], - datatype: dt + datatype: adt === a._datatype && bdt === b._datatype ? dt : undefined }) } }) diff --git a/src/type/matrix/utils/matAlgo05xSfSf.js b/src/type/matrix/utils/matAlgo05xSfSf.js index 26af3300fc..f504de9de1 100644 --- a/src/type/matrix/utils/matAlgo05xSfSf.js +++ b/src/type/matrix/utils/matAlgo05xSfSf.js @@ -29,13 +29,13 @@ export const createMatAlgo05xSfSf = /* #__PURE__ */ factory(name, dependencies, const aindex = a._index const aptr = a._ptr const asize = a._size - const adt = a._datatype + const adt = a._datatype || a._data === undefined ? a._datatype : a.getDataType() // sparse matrix arrays const bvalues = b._values const bindex = b._index const bptr = b._ptr const bsize = b._size - const bdt = b._datatype + const bdt = b._datatype || b._data === undefined ? b._datatype : b.getDataType() // validate dimensions if (asize.length !== bsize.length) { throw new DimensionError(asize.length, bsize.length) } @@ -57,7 +57,7 @@ export const createMatAlgo05xSfSf = /* #__PURE__ */ factory(name, dependencies, let cf = callback // process data types - if (typeof adt === 'string' && adt === bdt) { + if (typeof adt === 'string' && adt === bdt && adt !== 'mixed') { // datatype dt = adt // find signature that matches (dt, dt) @@ -155,7 +155,7 @@ export const createMatAlgo05xSfSf = /* #__PURE__ */ factory(name, dependencies, index: cindex, ptr: cptr, size: [rows, columns], - datatype: dt + datatype: adt === a._datatype && bdt === b._datatype ? dt : undefined }) } }) diff --git a/src/type/matrix/utils/matAlgo06xS0S0.js b/src/type/matrix/utils/matAlgo06xS0S0.js index c07613e9fc..c2497e4ed0 100644 --- a/src/type/matrix/utils/matAlgo06xS0S0.js +++ b/src/type/matrix/utils/matAlgo06xS0S0.js @@ -28,11 +28,11 @@ export const createMatAlgo06xS0S0 = /* #__PURE__ */ factory(name, dependencies, // sparse matrix arrays const avalues = a._values const asize = a._size - const adt = a._datatype + const adt = a._datatype || a._data === undefined ? a._datatype : a.getDataType() // sparse matrix arrays const bvalues = b._values const bsize = b._size - const bdt = b._datatype + const bdt = b._datatype || b._data === undefined ? b._datatype : b.getDataType() // validate dimensions if (asize.length !== bsize.length) { throw new DimensionError(asize.length, bsize.length) } @@ -54,7 +54,7 @@ export const createMatAlgo06xS0S0 = /* #__PURE__ */ factory(name, dependencies, let cf = callback // process data types - if (typeof adt === 'string' && adt === bdt) { + if (typeof adt === 'string' && adt === bdt && adt !== 'mixed') { // datatype dt = adt // find signature that matches (dt, dt) @@ -141,7 +141,7 @@ export const createMatAlgo06xS0S0 = /* #__PURE__ */ factory(name, dependencies, index: cindex, ptr: cptr, size: [rows, columns], - datatype: dt + datatype: adt === a._datatype && bdt === b._datatype ? dt : undefined }) } }) diff --git a/src/type/matrix/utils/matAlgo07xSSf.js b/src/type/matrix/utils/matAlgo07xSSf.js index a2e588f6eb..2e42cb0c03 100644 --- a/src/type/matrix/utils/matAlgo07xSSf.js +++ b/src/type/matrix/utils/matAlgo07xSSf.js @@ -22,10 +22,10 @@ export const createMatAlgo07xSSf = /* #__PURE__ */ factory(name, dependencies, ( return function matAlgo07xSSf (a, b, callback) { // sparse matrix arrays const asize = a._size - const adt = a._datatype + const adt = a._datatype || a._data === undefined ? a._datatype : a.getDataType() // sparse matrix arrays const bsize = b._size - const bdt = b._datatype + const bdt = b._datatype || b._data === undefined ? b._datatype : b.getDataType() // validate dimensions if (asize.length !== bsize.length) { throw new DimensionError(asize.length, bsize.length) } @@ -45,7 +45,7 @@ export const createMatAlgo07xSSf = /* #__PURE__ */ factory(name, dependencies, ( let cf = callback // process data types - if (typeof adt === 'string' && adt === bdt) { + if (typeof adt === 'string' && adt === bdt && adt !== 'mixed') { // datatype dt = adt // convert 0 to the same datatype @@ -91,7 +91,7 @@ export const createMatAlgo07xSSf = /* #__PURE__ */ factory(name, dependencies, ( return new DenseMatrix({ data: cdata, size: [rows, columns], - datatype: dt + datatype: adt === a._datatype && bdt === b._datatype ? dt : undefined }) } diff --git a/src/type/matrix/utils/matAlgo08xS0Sid.js b/src/type/matrix/utils/matAlgo08xS0Sid.js index b42f9bd185..210752e8c5 100644 --- a/src/type/matrix/utils/matAlgo08xS0Sid.js +++ b/src/type/matrix/utils/matAlgo08xS0Sid.js @@ -29,13 +29,13 @@ export const createMatAlgo08xS0Sid = /* #__PURE__ */ factory(name, dependencies, const aindex = a._index const aptr = a._ptr const asize = a._size - const adt = a._datatype + const adt = a._datatype || a._data === undefined ? a._datatype : a.getDataType() // sparse matrix arrays const bvalues = b._values const bindex = b._index const bptr = b._ptr const bsize = b._size - const bdt = b._datatype + const bdt = b._datatype || b._data === undefined ? b._datatype : b.getDataType() // validate dimensions if (asize.length !== bsize.length) { throw new DimensionError(asize.length, bsize.length) } @@ -60,7 +60,7 @@ export const createMatAlgo08xS0Sid = /* #__PURE__ */ factory(name, dependencies, let cf = callback // process data types - if (typeof adt === 'string' && adt === bdt) { + if (typeof adt === 'string' && adt === bdt && adt !== 'mixed') { // datatype dt = adt // find signature that matches (dt, dt) @@ -140,7 +140,7 @@ export const createMatAlgo08xS0Sid = /* #__PURE__ */ factory(name, dependencies, index: cindex, ptr: cptr, size: [rows, columns], - datatype: dt + datatype: adt === a._datatype && bdt === b._datatype ? dt : undefined }) } }) diff --git a/src/type/matrix/utils/matAlgo09xS0Sf.js b/src/type/matrix/utils/matAlgo09xS0Sf.js index 1cee1af7ed..643bc32de0 100644 --- a/src/type/matrix/utils/matAlgo09xS0Sf.js +++ b/src/type/matrix/utils/matAlgo09xS0Sf.js @@ -29,13 +29,13 @@ export const createMatAlgo09xS0Sf = /* #__PURE__ */ factory(name, dependencies, const aindex = a._index const aptr = a._ptr const asize = a._size - const adt = a._datatype + const adt = a._datatype || a._data === undefined ? a._datatype : a.getDataType() // sparse matrix arrays const bvalues = b._values const bindex = b._index const bptr = b._ptr const bsize = b._size - const bdt = b._datatype + const bdt = b._datatype || b._data === undefined ? b._datatype : b.getDataType() // validate dimensions if (asize.length !== bsize.length) { throw new DimensionError(asize.length, bsize.length) } @@ -57,7 +57,7 @@ export const createMatAlgo09xS0Sf = /* #__PURE__ */ factory(name, dependencies, let cf = callback // process data types - if (typeof adt === 'string' && adt === bdt) { + if (typeof adt === 'string' && adt === bdt && adt !== 'mixed') { // datatype dt = adt // find signature that matches (dt, dt) @@ -130,7 +130,7 @@ export const createMatAlgo09xS0Sf = /* #__PURE__ */ factory(name, dependencies, index: cindex, ptr: cptr, size: [rows, columns], - datatype: dt + datatype: adt === a._datatype && bdt === b._datatype ? dt : undefined }) } }) From 9baf478f708755d82ea0c313c7264436ed2f3190 Mon Sep 17 00:00:00 2001 From: Jos de Jong Date: Thu, 22 Feb 2024 11:13:23 +0100 Subject: [PATCH 09/13] chore: update history --- HISTORY.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/HISTORY.md b/HISTORY.md index 3f35e9aafa..7783d17529 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -5,6 +5,8 @@ - Feat: implement support for trailing commas in matrices (#3154, #2968). Thanks @dvd101x. +- Feat: improve the performance of `multiply` a lot by adding matrix type + inferencing (#3149). Thanks @RandomGamingDev. - Fix: `PartitionedMap` and `ObjectWrappingMap` missing a property `Symbol.iterator`, causing problems when trying `new Map(scope)` (#3156). - Fix: type definitions of function `mode` (#3153). Thanks @rich-martinez. From 85b65da6cb56fe2d62ce68bd189377dde05e9919 Mon Sep 17 00:00:00 2001 From: Brian Fugate Date: Thu, 22 Feb 2024 09:17:05 -0600 Subject: [PATCH 10/13] Fix: #3100 function `round` not handling round-off errors (#3136) * Fixing rounding bug from issue 3100 * Corrected syntax and converted if...else to logic using ternary operator * Removing nearlyEqual comparison because a false return value was mathematically impossible by user input. Adding dynamic epsilon logic to cover cases when a user requests to round a number to a higher precision than epsilon in the config file. Also adding tests to cover dynamic epsilon cases. * Removing dynamic epsilon and adding test for changing config.epsilon during runtime * Reintroducing nearly equal verification for round function. Adding test case for changing epsilon at runtime. Both tests for changing epsilon at runtime also verify the false nearlyEqual scenario. --------- Co-authored-by: Jos de Jong --- src/function/arithmetic/round.js | 39 ++++++++++++++++--- .../function/arithmetic/round.test.js | 27 +++++++++++++ 2 files changed, 61 insertions(+), 5 deletions(-) diff --git a/src/function/arithmetic/round.js b/src/function/arithmetic/round.js index 5065dafcc9..6bd4da261e 100644 --- a/src/function/arithmetic/round.js +++ b/src/function/arithmetic/round.js @@ -1,5 +1,7 @@ import { factory } from '../../utils/factory.js' import { deepMap } from '../../utils/collection.js' +import { nearlyEqual, splitNumber } from '../../utils/number.js' +import { nearlyEqual as bigNearlyEqual } from '../../utils/bignumber/nearlyEqual.js' import { createMatAlgo11xS0s } from '../../type/matrix/utils/matAlgo11xS0s.js' import { createMatAlgo12xSfs } from '../../type/matrix/utils/matAlgo12xSfs.js' import { createMatAlgo14xDs } from '../../type/matrix/utils/matAlgo14xDs.js' @@ -10,6 +12,7 @@ const NO_INT = 'Number of decimals in function round must be an integer' const name = 'round' const dependencies = [ 'typed', + 'config', 'matrix', 'equalScalar', 'zeros', @@ -17,11 +20,15 @@ const dependencies = [ 'DenseMatrix' ] -export const createRound = /* #__PURE__ */ factory(name, dependencies, ({ typed, matrix, equalScalar, zeros, BigNumber, DenseMatrix }) => { +export const createRound = /* #__PURE__ */ factory(name, dependencies, ({ typed, config, matrix, equalScalar, zeros, BigNumber, DenseMatrix }) => { const matAlgo11xS0s = createMatAlgo11xS0s({ typed, equalScalar }) const matAlgo12xSfs = createMatAlgo12xSfs({ typed, DenseMatrix }) const matAlgo14xDs = createMatAlgo14xDs({ typed }) + function toExponent (epsilon) { + return Math.abs(splitNumber(epsilon).exponent) + } + /** * Round a value towards the nearest rounded value. * For matrices, the function is evaluated element wise. @@ -67,9 +74,22 @@ export const createRound = /* #__PURE__ */ factory(name, dependencies, ({ typed, * @return {number | BigNumber | Fraction | Complex | Array | Matrix} Rounded value */ return typed(name, { - number: roundNumber, + number: function (x) { + // Handle round off errors by first rounding to epsilon precision + const xEpsilon = roundNumber(x, toExponent(config.epsilon)) + const xSelected = nearlyEqual(x, xEpsilon, config.epsilon) ? xEpsilon : x + return roundNumber(xSelected) + }, - 'number, number': roundNumber, + 'number, number': function (x, n) { + // Same as number: unless user specifies more decimals than epsilon + const epsilonExponent = toExponent(config.epsilon) + if (n >= epsilonExponent) { return roundNumber(x, n) } + + const xEpsilon = roundNumber(x, epsilonExponent) + const xSelected = nearlyEqual(x, xEpsilon, config.epsilon) ? xEpsilon : x + return roundNumber(xSelected, n) + }, 'number, BigNumber': function (x, n) { if (!n.isInteger()) { throw new TypeError(NO_INT) } @@ -95,13 +115,22 @@ export const createRound = /* #__PURE__ */ factory(name, dependencies, ({ typed, }, BigNumber: function (x) { - return x.toDecimalPlaces(0) + // Handle round off errors by first rounding to epsilon precision + const xEpsilon = new BigNumber(x).toDecimalPlaces(toExponent(config.epsilon)) + const xSelected = bigNearlyEqual(x, xEpsilon, config.epsilon) ? xEpsilon : x + return xSelected.toDecimalPlaces(0) }, 'BigNumber, BigNumber': function (x, n) { if (!n.isInteger()) { throw new TypeError(NO_INT) } - return x.toDecimalPlaces(n.toNumber()) + // Same as BigNumber: unless user specifies more decimals than epsilon + const epsilonExponent = toExponent(config.epsilon) + if (n >= epsilonExponent) { return x.toDecimalPlaces(n.toNumber()) } + + const xEpsilon = x.toDecimalPlaces(epsilonExponent) + const xSelected = bigNearlyEqual(x, xEpsilon, config.epsilon) ? xEpsilon : x + return xSelected.toDecimalPlaces(n.toNumber()) }, Fraction: function (x) { diff --git a/test/unit-tests/function/arithmetic/round.test.js b/test/unit-tests/function/arithmetic/round.test.js index 624110cb80..04b841e401 100644 --- a/test/unit-tests/function/arithmetic/round.test.js +++ b/test/unit-tests/function/arithmetic/round.test.js @@ -10,6 +10,11 @@ const matrix = math.matrix const sparse = math.sparse const round = math.round const unit = math.unit +const math2 = math.create() + +// 1 2 3 4 5 6 +// xx.1234567890123456789012345678901234567890123456789012345678901234 +const testBigNum = bignumber('10.9999999999999999999999999999999999999999999999999999999999999998') describe('round', function () { it('should round a number to te given number of decimals', function () { @@ -26,6 +31,9 @@ describe('round', function () { assert.strictEqual(round(-2.5), -3) assert.strictEqual(round(-2.7), -3) assert.strictEqual(round(-2.5, 0), -3) + assert.strictEqual(round(6.999999999999998, 15), 6.999999999999998) + assert.strictEqual(round(6.999999999999998, 14), 7) + assert.strictEqual(round(2.555555555555555, 13), 2.5555555555556) }) it('should round booleans (yeah, not really useful but it should be supported)', function () { @@ -65,6 +73,10 @@ describe('round', function () { }) it('should round bignumbers', function () { + assert.deepStrictEqual(round(bignumber(0.145 * 100)), bignumber(15)) + assert.deepStrictEqual(round(bignumber(0.145 * 100), bignumber(0)), bignumber(15)) + assert.deepStrictEqual(round(testBigNum, bignumber(63)), bignumber(11)) + assert.deepStrictEqual(round(testBigNum, bignumber(64)), testBigNum) assert.deepStrictEqual(round(bignumber(2.7)), bignumber(3)) assert.deepStrictEqual(round(bignumber(2.5)), bignumber(3)) assert.deepStrictEqual(round(bignumber(-2.5)), bignumber(-3)) @@ -92,6 +104,8 @@ describe('round', function () { }) it('should gracefully handle round-off errors', function () { + assert.strictEqual(round(0.145 * 100), 15) + assert.strictEqual(round((0.145 * 100), 0), 15) assert.strictEqual(round(3.0000000000000004), 3) assert.strictEqual(round(7.999999999999999), 8) assert.strictEqual(round(-3.0000000000000004), -3) @@ -159,6 +173,19 @@ describe('round', function () { assert.deepStrictEqual(round(math.matrix([1.7, 2.3])).valueOf(), [2, 2]) }) + describe('changing config.epsilon during runtime', function () { + it('uses default config.epsilon of 1e-12', function () { + assert.strictEqual(math2.round((0.000000000001459), 12), 1e-12) + assert.deepStrictEqual(math2.round(bignumber(1.49e-12), bignumber(12)), bignumber(1e-12)) + }) + + it('uses updated config.epsilon value', function () { + math2.config({ epsilon: 1e-13 }) + assert.strictEqual(math2.round((0.000000000001459), 12), 1e-12) + assert.deepStrictEqual(math2.round(bignumber(1.49e-12), bignumber(12)), bignumber(1e-12)) + }) + }) + describe('Array', function () { it('should round array', function () { assert.deepStrictEqual(round([1.7, 2.3]), [2, 2]) From db24bbe5036126a25fbcd00727b412901ed71a29 Mon Sep 17 00:00:00 2001 From: Jos de Jong Date: Thu, 22 Feb 2024 16:17:46 +0100 Subject: [PATCH 11/13] chore: update history --- HISTORY.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/HISTORY.md b/HISTORY.md index 7783d17529..894eed8d22 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -7,6 +7,8 @@ Thanks @dvd101x. - Feat: improve the performance of `multiply` a lot by adding matrix type inferencing (#3149). Thanks @RandomGamingDev. +- Fix: #3100 function `round` not handling round-off errors (#3136). + Thanks @BrianFugate. - Fix: `PartitionedMap` and `ObjectWrappingMap` missing a property `Symbol.iterator`, causing problems when trying `new Map(scope)` (#3156). - Fix: type definitions of function `mode` (#3153). Thanks @rich-martinez. From f504ffe1d30ca5cbc7eb1f3cfc1454fcc63ac304 Mon Sep 17 00:00:00 2001 From: Jos de Jong Date: Thu, 22 Feb 2024 16:27:24 +0100 Subject: [PATCH 12/13] chore: update devDependencies (most notably eslint) --- package-lock.json | 385 +++++++----------- package.json | 12 +- test/node-tests/commonjs.test.js | 1 + test/node-tests/doc.test.js | 1 + .../algebra/decomposition/schur.test.js | 1 + test/unit-tests/function/algebra/lyap.test.js | 1 + .../function/algebra/polynomialRoot.test.js | 5 + .../function/algebra/sylvester.test.js | 1 + .../function/arithmetic/nthRoots.test.js | 1 + .../function/arithmetic/sign.test.js | 2 + test/unit-tests/function/complex/conj.test.js | 1 + test/unit-tests/function/matrix/apply.test.js | 1 + test/unit-tests/function/matrix/pinv.test.js | 1 + .../function/statistics/corr.test.js | 1 + .../unit-tests/function/string/format.test.js | 32 ++ .../type/matrix/utils/broadcast.test.js | 8 + .../matrix/utils/getMatrixDataType.test.js | 20 + test/unit-tests/utils/array.test.js | 13 + 18 files changed, 238 insertions(+), 249 deletions(-) diff --git a/package-lock.json b/package-lock.json index 547309c34f..3159093ee3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "mathjs", - "version": "12.3.1", + "version": "12.3.2", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "mathjs", - "version": "12.3.1", + "version": "12.3.2", "license": "Apache-2.0", "dependencies": { "@babel/runtime": "^7.23.9", @@ -30,21 +30,21 @@ "@babel/register": "7.23.7", "@types/assert": "1.5.10", "@types/mocha": "10.0.6", - "@typescript-eslint/eslint-plugin": "6.21.0", - "@typescript-eslint/parser": "6.21.0", + "@typescript-eslint/eslint-plugin": "7.0.2", + "@typescript-eslint/parser": "7.0.2", "assert": "2.1.0", "babel-loader": "9.1.3", "benchmark": "2.1.4", "c8": "9.1.0", "codecov": "3.8.3", - "core-js": "3.35.1", + "core-js": "3.36.0", "del": "6.1.1", "dtslint": "4.2.1", "eslint": "8.56.0", "eslint-config-prettier": "9.1.0", "eslint-config-standard": "17.1.0", "eslint-plugin-import": "2.29.1", - "eslint-plugin-mocha": "10.2.0", + "eslint-plugin-mocha": "10.3.0", "eslint-plugin-n": "16.6.2", "eslint-plugin-prettier": "5.1.3", "eslint-plugin-promise": "6.1.1", @@ -63,7 +63,7 @@ "karma-mocha-reporter": "2.2.5", "karma-webpack": "5.0.1", "mkdirp": "3.0.1", - "mocha": "10.2.0", + "mocha": "10.3.0", "mocha-junit-reporter": "2.2.1", "ndarray": "1.0.19", "ndarray-determinant": "1.0.0", @@ -77,7 +77,7 @@ "sylvester": "0.0.21", "ts-node": "10.9.2", "typescript": "5.3.3", - "webpack": "5.90.1", + "webpack": "5.90.3", "zeros": "1.0.0" }, "engines": { @@ -1989,9 +1989,9 @@ "dev": true }, "node_modules/@definitelytyped/utils": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@definitelytyped/utils/-/utils-0.1.1.tgz", - "integrity": "sha512-VCamUy7vNS4x4ZkSTMs/YpyvwDOoPSfJ6OzoHM2PrArGRpvP34z7Au5yauiGGlAOpW3S6JjLQKZaF91sHVUTEg==", + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/@definitelytyped/utils/-/utils-0.1.4.tgz", + "integrity": "sha512-vDmkePbFRJuDw0mlmiGdqiIj1SbN8LqBud5GX6wne2ErKO4RQm+Foc8ufKJ8AAotxaIS7b46km6KUbL0ZbDpUA==", "dev": true, "dependencies": { "@definitelytyped/typescript-packages": "0.1.0", @@ -2511,22 +2511,22 @@ "dev": true }, "node_modules/@types/semver": { - "version": "7.5.6", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.6.tgz", - "integrity": "sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A==", + "version": "7.5.7", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.7.tgz", + "integrity": "sha512-/wdoPq1QqkSj9/QOeKkFquEuPzQbHTWAMPH/PaUMB+JuR31lXhlWXRZ52IpfDYVlDOUBvX09uBrPwxGT1hjNBg==", "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.21.0.tgz", - "integrity": "sha512-oy9+hTPCUFpngkEZUSzbf9MxI65wbKFoQYsgPdILTfbUldp5ovUuphZVe4i30emU9M/kP+T64Di0mxl7dSw3MA==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.0.2.tgz", + "integrity": "sha512-/XtVZJtbaphtdrWjr+CJclaCVGPtOdBpFEnvtNf/jRV0IiEemRrL0qABex/nEt8isYcnFacm3nPHYQwL+Wb7qg==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.21.0", - "@typescript-eslint/type-utils": "6.21.0", - "@typescript-eslint/utils": "6.21.0", - "@typescript-eslint/visitor-keys": "6.21.0", + "@typescript-eslint/scope-manager": "7.0.2", + "@typescript-eslint/type-utils": "7.0.2", + "@typescript-eslint/utils": "7.0.2", + "@typescript-eslint/visitor-keys": "7.0.2", "debug": "^4.3.4", "graphemer": "^1.4.0", "ignore": "^5.2.4", @@ -2542,8 +2542,8 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^6.0.0 || ^6.0.0-alpha", - "eslint": "^7.0.0 || ^8.0.0" + "@typescript-eslint/parser": "^7.0.0", + "eslint": "^8.56.0" }, "peerDependenciesMeta": { "typescript": { @@ -2567,15 +2567,15 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.21.0.tgz", - "integrity": "sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.0.2.tgz", + "integrity": "sha512-GdwfDglCxSmU+QTS9vhz2Sop46ebNCXpPPvsByK7hu0rFGRHL+AusKQJ7SoN+LbLh6APFpQwHKmDSwN35Z700Q==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "6.21.0", - "@typescript-eslint/types": "6.21.0", - "@typescript-eslint/typescript-estree": "6.21.0", - "@typescript-eslint/visitor-keys": "6.21.0", + "@typescript-eslint/scope-manager": "7.0.2", + "@typescript-eslint/types": "7.0.2", + "@typescript-eslint/typescript-estree": "7.0.2", + "@typescript-eslint/visitor-keys": "7.0.2", "debug": "^4.3.4" }, "engines": { @@ -2586,7 +2586,7 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" + "eslint": "^8.56.0" }, "peerDependenciesMeta": { "typescript": { @@ -2595,13 +2595,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz", - "integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.0.2.tgz", + "integrity": "sha512-l6sa2jF3h+qgN2qUMjVR3uCNGjWw4ahGfzIYsCtFrQJCjhbrDPdiihYT8FnnqFwsWX+20hK592yX9I2rxKTP4g==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.21.0", - "@typescript-eslint/visitor-keys": "6.21.0" + "@typescript-eslint/types": "7.0.2", + "@typescript-eslint/visitor-keys": "7.0.2" }, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -2612,13 +2612,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.21.0.tgz", - "integrity": "sha512-rZQI7wHfao8qMX3Rd3xqeYSMCL3SoiSQLBATSiVKARdFGCYSRvmViieZjqc58jKgs8Y8i9YvVVhRbHSTA4VBag==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.0.2.tgz", + "integrity": "sha512-IKKDcFsKAYlk8Rs4wiFfEwJTQlHcdn8CLwLaxwd6zb8HNiMcQIFX9sWax2k4Cjj7l7mGS5N1zl7RCHOVwHq2VQ==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "6.21.0", - "@typescript-eslint/utils": "6.21.0", + "@typescript-eslint/typescript-estree": "7.0.2", + "@typescript-eslint/utils": "7.0.2", "debug": "^4.3.4", "ts-api-utils": "^1.0.1" }, @@ -2630,7 +2630,7 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" + "eslint": "^8.56.0" }, "peerDependenciesMeta": { "typescript": { @@ -2639,9 +2639,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz", - "integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.0.2.tgz", + "integrity": "sha512-ZzcCQHj4JaXFjdOql6adYV4B/oFOFjPOC9XYwCaZFRvqN8Llfvv4gSxrkQkd2u4Ci62i2c6W6gkDwQJDaRc4nA==", "dev": true, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -2652,13 +2652,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz", - "integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.0.2.tgz", + "integrity": "sha512-3AMc8khTcELFWcKcPc0xiLviEvvfzATpdPj/DXuOGIdQIIFybf4DMT1vKRbuAEOFMwhWt7NFLXRkbjsvKZQyvw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.21.0", - "@typescript-eslint/visitor-keys": "6.21.0", + "@typescript-eslint/types": "7.0.2", + "@typescript-eslint/visitor-keys": "7.0.2", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -2719,17 +2719,17 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.21.0.tgz", - "integrity": "sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.0.2.tgz", + "integrity": "sha512-PZPIONBIB/X684bhT1XlrkjNZJIEevwkKDsdwfiu1WeqBxYEEdIgVDgm8/bbKHVu+6YOpeRqcfImTdImx/4Bsw==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.21.0", - "@typescript-eslint/types": "6.21.0", - "@typescript-eslint/typescript-estree": "6.21.0", + "@typescript-eslint/scope-manager": "7.0.2", + "@typescript-eslint/types": "7.0.2", + "@typescript-eslint/typescript-estree": "7.0.2", "semver": "^7.5.4" }, "engines": { @@ -2740,7 +2740,7 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" + "eslint": "^8.56.0" } }, "node_modules/@typescript-eslint/utils/node_modules/semver": { @@ -2759,12 +2759,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz", - "integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.0.2.tgz", + "integrity": "sha512-8Y+YiBmqPighbm5xA2k4wKTxRzx9EkBu7Rlw+WHqMvRJ3RPz/BMBO9b2ru0LUNmXg120PHUXD5+SWFy2R8DqlQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/types": "7.0.2", "eslint-visitor-keys": "^3.4.1" }, "engines": { @@ -5213,9 +5213,9 @@ } }, "node_modules/core-js": { - "version": "3.35.1", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.35.1.tgz", - "integrity": "sha512-IgdsbxNyMskrTFxa9lWHyMwAJU5gXOPP+1yO+K59d50VLVAIDAbs7gIv705KzALModfK3ZrSZTPNpC0PQgIZuw==", + "version": "3.36.0", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.36.0.tgz", + "integrity": "sha512-mt7+TUBbTFg5+GngsAxeKBTl5/VS0guFeJacYge9OmHb+m058UwwIm41SE9T4Den7ClatV57B6TYTuJ0CX1MAw==", "dev": true, "hasInstallScript": true, "funding": { @@ -6684,9 +6684,9 @@ } }, "node_modules/eslint-plugin-mocha": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-mocha/-/eslint-plugin-mocha-10.2.0.tgz", - "integrity": "sha512-ZhdxzSZnd1P9LqDPF0DBcFLpRIGdh1zkF2JHnQklKQOvrQtT73kdP5K9V2mzvbLR+cCAO9OI48NXK/Ax9/ciCQ==", + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-mocha/-/eslint-plugin-mocha-10.3.0.tgz", + "integrity": "sha512-IWzbg2K6B1Q7h37Ih4zMyW+nhmw1JvUlHlbCUUUu6PfOOAUGCB0gxmvv7/U+TQQ6e8yHUv+q7KMdIIum4bx+PA==", "dev": true, "dependencies": { "eslint-utils": "^3.0.0", @@ -10855,9 +10855,9 @@ } }, "node_modules/mocha": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.2.0.tgz", - "integrity": "sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg==", + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.3.0.tgz", + "integrity": "sha512-uF2XJs+7xSLsrmIvn37i/wnc91nw7XjOQB8ccyx5aEgdnohr7n+rEiZP23WkCYHjilR6+EboEnbq/ZQDz4LSbg==", "dev": true, "dependencies": { "ansi-colors": "4.1.1", @@ -10867,13 +10867,12 @@ "diff": "5.0.0", "escape-string-regexp": "4.0.0", "find-up": "5.0.0", - "glob": "7.2.0", + "glob": "8.1.0", "he": "1.2.0", "js-yaml": "4.1.0", "log-symbols": "4.1.0", "minimatch": "5.0.1", "ms": "2.1.3", - "nanoid": "3.3.3", "serialize-javascript": "6.0.0", "strip-json-comments": "3.1.1", "supports-color": "8.1.1", @@ -10888,10 +10887,6 @@ }, "engines": { "node": ">= 14.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mochajs" } }, "node_modules/mocha-junit-reporter": { @@ -11145,48 +11140,6 @@ "node": "6.* || 8.* || >= 10.*" } }, - "node_modules/mocha/node_modules/glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/mocha/node_modules/glob/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/mocha/node_modules/glob/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, "node_modules/mocha/node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -11445,18 +11398,6 @@ "dev": true, "optional": true }, - "node_modules/nanoid": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz", - "integrity": "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==", - "dev": true, - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, "node_modules/nanomatch": { "version": "1.2.13", "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", @@ -14472,12 +14413,12 @@ "dev": true }, "node_modules/ts-api-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.1.tgz", - "integrity": "sha512-lC/RGlPmwdrIBFTX59wwNzqh7aR2otPNPR/5brHZm/XKFYKsfqxihXUe9pU3JI+3vGkl+vyCoNNnPhJn3aLK1A==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.2.1.tgz", + "integrity": "sha512-RIYA36cJn2WiH9Hy77hdF9r7oEwxAtB/TS9/S4Qd90Ap4z5FSiin5zEiTL44OII1Y3IIlEvxwxFUVgrHSZ/UpA==", "dev": true, "engines": { - "node": ">=16.13.0" + "node": ">=16" }, "peerDependencies": { "typescript": ">=4.2.0" @@ -15474,9 +15415,9 @@ "dev": true }, "node_modules/webpack": { - "version": "5.90.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.90.1.tgz", - "integrity": "sha512-SstPdlAC5IvgFnhiRok8hqJo/+ArAbNv7rhU4fnWGHNVfN59HSQFaxZDSAL3IFG2YmqxuRs+IU33milSxbPlog==", + "version": "5.90.3", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.90.3.tgz", + "integrity": "sha512-h6uDYlWCctQRuXBs1oYpVe6sFcWedl0dpcVaTf/YF67J9bKvwJajFulMVSYKHrksMB3I/pIagRzDxwxkebuzKA==", "dev": true, "dependencies": { "@types/eslint-scope": "^3.7.3", @@ -17157,9 +17098,9 @@ "dev": true }, "@definitelytyped/utils": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@definitelytyped/utils/-/utils-0.1.1.tgz", - "integrity": "sha512-VCamUy7vNS4x4ZkSTMs/YpyvwDOoPSfJ6OzoHM2PrArGRpvP34z7Au5yauiGGlAOpW3S6JjLQKZaF91sHVUTEg==", + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/@definitelytyped/utils/-/utils-0.1.4.tgz", + "integrity": "sha512-vDmkePbFRJuDw0mlmiGdqiIj1SbN8LqBud5GX6wne2ErKO4RQm+Foc8ufKJ8AAotxaIS7b46km6KUbL0ZbDpUA==", "dev": true, "requires": { "@definitelytyped/typescript-packages": "0.1.0", @@ -17572,22 +17513,22 @@ "dev": true }, "@types/semver": { - "version": "7.5.6", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.6.tgz", - "integrity": "sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A==", + "version": "7.5.7", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.7.tgz", + "integrity": "sha512-/wdoPq1QqkSj9/QOeKkFquEuPzQbHTWAMPH/PaUMB+JuR31lXhlWXRZ52IpfDYVlDOUBvX09uBrPwxGT1hjNBg==", "dev": true }, "@typescript-eslint/eslint-plugin": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.21.0.tgz", - "integrity": "sha512-oy9+hTPCUFpngkEZUSzbf9MxI65wbKFoQYsgPdILTfbUldp5ovUuphZVe4i30emU9M/kP+T64Di0mxl7dSw3MA==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.0.2.tgz", + "integrity": "sha512-/XtVZJtbaphtdrWjr+CJclaCVGPtOdBpFEnvtNf/jRV0IiEemRrL0qABex/nEt8isYcnFacm3nPHYQwL+Wb7qg==", "dev": true, "requires": { "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.21.0", - "@typescript-eslint/type-utils": "6.21.0", - "@typescript-eslint/utils": "6.21.0", - "@typescript-eslint/visitor-keys": "6.21.0", + "@typescript-eslint/scope-manager": "7.0.2", + "@typescript-eslint/type-utils": "7.0.2", + "@typescript-eslint/utils": "7.0.2", + "@typescript-eslint/visitor-keys": "7.0.2", "debug": "^4.3.4", "graphemer": "^1.4.0", "ignore": "^5.2.4", @@ -17608,54 +17549,54 @@ } }, "@typescript-eslint/parser": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.21.0.tgz", - "integrity": "sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.0.2.tgz", + "integrity": "sha512-GdwfDglCxSmU+QTS9vhz2Sop46ebNCXpPPvsByK7hu0rFGRHL+AusKQJ7SoN+LbLh6APFpQwHKmDSwN35Z700Q==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "6.21.0", - "@typescript-eslint/types": "6.21.0", - "@typescript-eslint/typescript-estree": "6.21.0", - "@typescript-eslint/visitor-keys": "6.21.0", + "@typescript-eslint/scope-manager": "7.0.2", + "@typescript-eslint/types": "7.0.2", + "@typescript-eslint/typescript-estree": "7.0.2", + "@typescript-eslint/visitor-keys": "7.0.2", "debug": "^4.3.4" } }, "@typescript-eslint/scope-manager": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz", - "integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.0.2.tgz", + "integrity": "sha512-l6sa2jF3h+qgN2qUMjVR3uCNGjWw4ahGfzIYsCtFrQJCjhbrDPdiihYT8FnnqFwsWX+20hK592yX9I2rxKTP4g==", "dev": true, "requires": { - "@typescript-eslint/types": "6.21.0", - "@typescript-eslint/visitor-keys": "6.21.0" + "@typescript-eslint/types": "7.0.2", + "@typescript-eslint/visitor-keys": "7.0.2" } }, "@typescript-eslint/type-utils": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.21.0.tgz", - "integrity": "sha512-rZQI7wHfao8qMX3Rd3xqeYSMCL3SoiSQLBATSiVKARdFGCYSRvmViieZjqc58jKgs8Y8i9YvVVhRbHSTA4VBag==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.0.2.tgz", + "integrity": "sha512-IKKDcFsKAYlk8Rs4wiFfEwJTQlHcdn8CLwLaxwd6zb8HNiMcQIFX9sWax2k4Cjj7l7mGS5N1zl7RCHOVwHq2VQ==", "dev": true, "requires": { - "@typescript-eslint/typescript-estree": "6.21.0", - "@typescript-eslint/utils": "6.21.0", + "@typescript-eslint/typescript-estree": "7.0.2", + "@typescript-eslint/utils": "7.0.2", "debug": "^4.3.4", "ts-api-utils": "^1.0.1" } }, "@typescript-eslint/types": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz", - "integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.0.2.tgz", + "integrity": "sha512-ZzcCQHj4JaXFjdOql6adYV4B/oFOFjPOC9XYwCaZFRvqN8Llfvv4gSxrkQkd2u4Ci62i2c6W6gkDwQJDaRc4nA==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz", - "integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.0.2.tgz", + "integrity": "sha512-3AMc8khTcELFWcKcPc0xiLviEvvfzATpdPj/DXuOGIdQIIFybf4DMT1vKRbuAEOFMwhWt7NFLXRkbjsvKZQyvw==", "dev": true, "requires": { - "@typescript-eslint/types": "6.21.0", - "@typescript-eslint/visitor-keys": "6.21.0", + "@typescript-eslint/types": "7.0.2", + "@typescript-eslint/visitor-keys": "7.0.2", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -17694,17 +17635,17 @@ } }, "@typescript-eslint/utils": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.21.0.tgz", - "integrity": "sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.0.2.tgz", + "integrity": "sha512-PZPIONBIB/X684bhT1XlrkjNZJIEevwkKDsdwfiu1WeqBxYEEdIgVDgm8/bbKHVu+6YOpeRqcfImTdImx/4Bsw==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.21.0", - "@typescript-eslint/types": "6.21.0", - "@typescript-eslint/typescript-estree": "6.21.0", + "@typescript-eslint/scope-manager": "7.0.2", + "@typescript-eslint/types": "7.0.2", + "@typescript-eslint/typescript-estree": "7.0.2", "semver": "^7.5.4" }, "dependencies": { @@ -17720,12 +17661,12 @@ } }, "@typescript-eslint/visitor-keys": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz", - "integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.0.2.tgz", + "integrity": "sha512-8Y+YiBmqPighbm5xA2k4wKTxRzx9EkBu7Rlw+WHqMvRJ3RPz/BMBO9b2ru0LUNmXg120PHUXD5+SWFy2R8DqlQ==", "dev": true, "requires": { - "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/types": "7.0.2", "eslint-visitor-keys": "^3.4.1" } }, @@ -19657,9 +19598,9 @@ } }, "core-js": { - "version": "3.35.1", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.35.1.tgz", - "integrity": "sha512-IgdsbxNyMskrTFxa9lWHyMwAJU5gXOPP+1yO+K59d50VLVAIDAbs7gIv705KzALModfK3ZrSZTPNpC0PQgIZuw==", + "version": "3.36.0", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.36.0.tgz", + "integrity": "sha512-mt7+TUBbTFg5+GngsAxeKBTl5/VS0guFeJacYge9OmHb+m058UwwIm41SE9T4Den7ClatV57B6TYTuJ0CX1MAw==", "dev": true }, "core-js-compat": { @@ -20980,9 +20921,9 @@ } }, "eslint-plugin-mocha": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-mocha/-/eslint-plugin-mocha-10.2.0.tgz", - "integrity": "sha512-ZhdxzSZnd1P9LqDPF0DBcFLpRIGdh1zkF2JHnQklKQOvrQtT73kdP5K9V2mzvbLR+cCAO9OI48NXK/Ax9/ciCQ==", + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-mocha/-/eslint-plugin-mocha-10.3.0.tgz", + "integrity": "sha512-IWzbg2K6B1Q7h37Ih4zMyW+nhmw1JvUlHlbCUUUu6PfOOAUGCB0gxmvv7/U+TQQ6e8yHUv+q7KMdIIum4bx+PA==", "dev": true, "requires": { "eslint-utils": "^3.0.0", @@ -23985,9 +23926,9 @@ "dev": true }, "mocha": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.2.0.tgz", - "integrity": "sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg==", + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.3.0.tgz", + "integrity": "sha512-uF2XJs+7xSLsrmIvn37i/wnc91nw7XjOQB8ccyx5aEgdnohr7n+rEiZP23WkCYHjilR6+EboEnbq/ZQDz4LSbg==", "dev": true, "requires": { "ansi-colors": "4.1.1", @@ -23997,13 +23938,12 @@ "diff": "5.0.0", "escape-string-regexp": "4.0.0", "find-up": "5.0.0", - "glob": "7.2.0", + "glob": "8.1.0", "he": "1.2.0", "js-yaml": "4.1.0", "log-symbols": "4.1.0", "minimatch": "5.0.1", "ms": "2.1.3", - "nanoid": "3.3.3", "serialize-javascript": "6.0.0", "strip-json-comments": "3.1.1", "supports-color": "8.1.1", @@ -24163,41 +24103,6 @@ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true }, - "glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "dependencies": { - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - } - } - }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -24413,12 +24318,6 @@ "dev": true, "optional": true }, - "nanoid": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz", - "integrity": "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==", - "dev": true - }, "nanomatch": { "version": "1.2.13", "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", @@ -26790,9 +26689,9 @@ "dev": true }, "ts-api-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.1.tgz", - "integrity": "sha512-lC/RGlPmwdrIBFTX59wwNzqh7aR2otPNPR/5brHZm/XKFYKsfqxihXUe9pU3JI+3vGkl+vyCoNNnPhJn3aLK1A==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.2.1.tgz", + "integrity": "sha512-RIYA36cJn2WiH9Hy77hdF9r7oEwxAtB/TS9/S4Qd90Ap4z5FSiin5zEiTL44OII1Y3IIlEvxwxFUVgrHSZ/UpA==", "dev": true, "requires": {} }, @@ -27500,9 +27399,9 @@ "dev": true }, "webpack": { - "version": "5.90.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.90.1.tgz", - "integrity": "sha512-SstPdlAC5IvgFnhiRok8hqJo/+ArAbNv7rhU4fnWGHNVfN59HSQFaxZDSAL3IFG2YmqxuRs+IU33milSxbPlog==", + "version": "5.90.3", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.90.3.tgz", + "integrity": "sha512-h6uDYlWCctQRuXBs1oYpVe6sFcWedl0dpcVaTf/YF67J9bKvwJajFulMVSYKHrksMB3I/pIagRzDxwxkebuzKA==", "dev": true, "requires": { "@types/eslint-scope": "^3.7.3", diff --git a/package.json b/package.json index e48fdb7405..99706c7f6a 100644 --- a/package.json +++ b/package.json @@ -43,21 +43,21 @@ "@babel/register": "7.23.7", "@types/assert": "1.5.10", "@types/mocha": "10.0.6", - "@typescript-eslint/eslint-plugin": "6.21.0", - "@typescript-eslint/parser": "6.21.0", + "@typescript-eslint/eslint-plugin": "7.0.2", + "@typescript-eslint/parser": "7.0.2", "assert": "2.1.0", "babel-loader": "9.1.3", "benchmark": "2.1.4", "c8": "9.1.0", "codecov": "3.8.3", - "core-js": "3.35.1", + "core-js": "3.36.0", "del": "6.1.1", "dtslint": "4.2.1", "eslint": "8.56.0", "eslint-config-prettier": "9.1.0", "eslint-config-standard": "17.1.0", "eslint-plugin-import": "2.29.1", - "eslint-plugin-mocha": "10.2.0", + "eslint-plugin-mocha": "10.3.0", "eslint-plugin-n": "16.6.2", "eslint-plugin-prettier": "5.1.3", "eslint-plugin-promise": "6.1.1", @@ -76,7 +76,7 @@ "karma-mocha-reporter": "2.2.5", "karma-webpack": "5.0.1", "mkdirp": "3.0.1", - "mocha": "10.2.0", + "mocha": "10.3.0", "mocha-junit-reporter": "2.2.1", "ndarray": "1.0.19", "ndarray-determinant": "1.0.0", @@ -90,7 +90,7 @@ "sylvester": "0.0.21", "ts-node": "10.9.2", "typescript": "5.3.3", - "webpack": "5.90.1", + "webpack": "5.90.3", "zeros": "1.0.0" }, "type": "module", diff --git a/test/node-tests/commonjs.test.js b/test/node-tests/commonjs.test.js index eac81052c7..48cdb61a3d 100644 --- a/test/node-tests/commonjs.test.js +++ b/test/node-tests/commonjs.test.js @@ -12,6 +12,7 @@ describe('lib/cjs', function () { done() }) }) + it('should load numbers only via commonjs', function (done) { const filename = path.join(__dirname, 'commonjsAppNumberOnly.cjs') cp.exec('node ' + filename, function (error, result) { diff --git a/test/node-tests/doc.test.js b/test/node-tests/doc.test.js index 97f7f0b80d..e64a8b9872 100644 --- a/test/node-tests/doc.test.js +++ b/test/node-tests/doc.test.js @@ -329,6 +329,7 @@ describe('Testing examples from (jsdoc) comments', function () { const allNames = Object.keys(math) const srcPath = path.resolve(__dirname, '../../src') + '/' const allDocs = docgenerator.collectDocs(allNames, srcPath) + it("should cover all names (but doesn't yet)", function () { const documented = new Set(Object.keys(allDocs)) const badUndocumented = allNames.filter(name => { diff --git a/test/unit-tests/function/algebra/decomposition/schur.test.js b/test/unit-tests/function/algebra/decomposition/schur.test.js index 790a5fb82b..7af3c8b426 100644 --- a/test/unit-tests/function/algebra/decomposition/schur.test.js +++ b/test/unit-tests/function/algebra/decomposition/schur.test.js @@ -32,6 +32,7 @@ describe('schur', function () { [-0.6745633977804205, 0.24977632323107185, 0.6575567219332444, -0.22147775183161147, 0.03380493473031572] ])) < 1e-3) }) + it('should calculate schur decomposition of order 5 Matrix with numbers', function () { assert.ok(math.norm(math.subtract(math.schur(math.matrix([ [-5.3, -1.4, -0.2, 0.7, 1.0], diff --git a/test/unit-tests/function/algebra/lyap.test.js b/test/unit-tests/function/algebra/lyap.test.js index 4ac64937e6..5fd73fd023 100644 --- a/test/unit-tests/function/algebra/lyap.test.js +++ b/test/unit-tests/function/algebra/lyap.test.js @@ -25,6 +25,7 @@ describe('lyap', function () { [-0.33204819381292294, 0.5331793776065724, -0.10706505975853345, -0.6187026623519725, -0.4199482902478158] ])), 'fro') < 1e-3) }) + it('should solve lyapunov equation of order 5 with Arrays', function () { assert.ok(math.norm(math.subtract(math.lyap([ [-5.3, -1.4, -0.2, 0.7, 1.0], diff --git a/test/unit-tests/function/algebra/polynomialRoot.test.js b/test/unit-tests/function/algebra/polynomialRoot.test.js index c96dab96ce..d4476427eb 100644 --- a/test/unit-tests/function/algebra/polynomialRoot.test.js +++ b/test/unit-tests/function/algebra/polynomialRoot.test.js @@ -11,10 +11,12 @@ describe('polynomialRoot', function () { approx.deepEqual(pRoot(complex(-3, 2), 2), [complex(1.5, -1)]) approx.deepEqual(pRoot(complex(3, 1), complex(-1, -1)), [complex(2, -1)]) }) + it('should solve a quadratic equation with a double root', function () { approx.deepEqual(pRoot(4, 4, 1), [-2]) approx.deepEqual(pRoot(complex(0, 2), complex(2, 2), 1), [complex(-1, -1)]) }) + it('should solve a quadratic with two distinct roots', function () { approx.deepEqual(pRoot(-3, 2, 1), [1, -3]) approx.deepEqual(pRoot(-2, 0, 1), [math.sqrt(2), -math.sqrt(2)]) @@ -23,12 +25,14 @@ describe('polynomialRoot', function () { approx.deepEqual( pRoot(complex(3, 1), -3, 1), [complex(2, -1), complex(1, 1)]) }) + it('should solve a cubic with a triple root', function () { approx.deepEqual(pRoot(8, 12, 6, 1), [-2]) approx.deepEqual( pRoot(complex(-2, 11), complex(9, -12), complex(-6, 3), 1), [complex(2, -1)]) }) + it('should solve a cubic with one simple and one double root', function () { approx.deepEqual(pRoot(4, 0, -3, 1), [-1, 2]) approx.deepEqual( @@ -41,6 +45,7 @@ describe('polynomialRoot', function () { pRoot(complex(2, 6), complex(8, 6), complex(5, 1), 1), [complex(-3, 1), complex(-1, -1)]) }) + it('should solve a cubic with three distinct roots', function () { approx.deepEqual(pRoot(6, 11, 6, 1), [-3, -1, -2]) approx.deepEqual( diff --git a/test/unit-tests/function/algebra/sylvester.test.js b/test/unit-tests/function/algebra/sylvester.test.js index aac909f63e..3af2472f9d 100644 --- a/test/unit-tests/function/algebra/sylvester.test.js +++ b/test/unit-tests/function/algebra/sylvester.test.js @@ -28,6 +28,7 @@ describe('sylvester', function () { [-1.0935231387905004, 4.113817086842746, 5.747671819196675, -0.9408309030864932, 2.967655969930743] ]), 'fro') < 1e-3) }) + it('should solve sylvester equation of order 5 with Matrices', function () { assert.ok(math.norm(math.subtract(math.sylvester(math.matrix([ [-5.3, -1.4, -0.2, 0.7], diff --git a/test/unit-tests/function/arithmetic/nthRoots.test.js b/test/unit-tests/function/arithmetic/nthRoots.test.js index 0c7c08e7b9..a26e5156b3 100644 --- a/test/unit-tests/function/arithmetic/nthRoots.test.js +++ b/test/unit-tests/function/arithmetic/nthRoots.test.js @@ -39,6 +39,7 @@ describe('nthRoots', function () { complex(-2, 0), complex(0, -2) ] + it('should return pure roots without artifacts', function () { const roots = nthRoots(complex('16'), 4) diff --git a/test/unit-tests/function/arithmetic/sign.test.js b/test/unit-tests/function/arithmetic/sign.test.js index bf0531b506..d61a211a10 100644 --- a/test/unit-tests/function/arithmetic/sign.test.js +++ b/test/unit-tests/function/arithmetic/sign.test.js @@ -90,9 +90,11 @@ describe('sign', function () { it('number', function () { assert.strictEqual(math.sign(0), 0) }) + it('bignumber', function () { assert.deepStrictEqual(math.sign(math.bignumber(0)), math.bignumber(0)) }) + it('complex', function () { assert.deepStrictEqual(math.sign(math.complex(0)), math.complex(0)) }) diff --git a/test/unit-tests/function/complex/conj.test.js b/test/unit-tests/function/complex/conj.test.js index ccc6c8235d..f7daba8882 100644 --- a/test/unit-tests/function/complex/conj.test.js +++ b/test/unit-tests/function/complex/conj.test.js @@ -14,6 +14,7 @@ describe('conj', function () { assert.strictEqual(conj(0), 0) assert.strictEqual(conj(-2), -2) }) + it('should compute the conjugate of a bignumber', function () { assert.deepStrictEqual(conj(math.bignumber(2)), math.bignumber(2)) }) diff --git a/test/unit-tests/function/matrix/apply.test.js b/test/unit-tests/function/matrix/apply.test.js index c661bfc19c..fcca85930d 100644 --- a/test/unit-tests/function/matrix/apply.test.js +++ b/test/unit-tests/function/matrix/apply.test.js @@ -18,6 +18,7 @@ describe('apply', function () { [[13, 14], [15, 16], [17, 18]], [[19, 20], [21, 22], [23, 24]] ] + it('should apply to the rows of a tensor', function () { assert.deepStrictEqual(math.apply(inputMatrix, 2, sum), [[3, 7, 11], [15, 19, 23], [27, 31, 35], [39, 43, 47]]) }) diff --git a/test/unit-tests/function/matrix/pinv.test.js b/test/unit-tests/function/matrix/pinv.test.js index 305bd7363f..20663ead19 100644 --- a/test/unit-tests/function/matrix/pinv.test.js +++ b/test/unit-tests/function/matrix/pinv.test.js @@ -53,6 +53,7 @@ describe('pinv', function () { break } } + it('should return the inverse of a number', function () { check(4, 1 / 4, true) check(math.bignumber(4), math.bignumber(1 / 4), true) diff --git a/test/unit-tests/function/statistics/corr.test.js b/test/unit-tests/function/statistics/corr.test.js index 0ca02691db..d32bd2b548 100644 --- a/test/unit-tests/function/statistics/corr.test.js +++ b/test/unit-tests/function/statistics/corr.test.js @@ -39,6 +39,7 @@ describe('correlation', function () { it('should throw an error if called with number of arguments do not have same size', function () { assert.throws(function () { corr([[1, 2, 3, 4, 5], [4, 5, 6, 7]], [[1, 2, 3, 4, 5], []]) }) }) + it('should throw an error if called with number of arguments do not have same size', function () { assert.throws(function () { corr([1, 2, 3, 4, 5], [1, 2, 3, 4]) }) }) diff --git a/test/unit-tests/function/string/format.test.js b/test/unit-tests/function/string/format.test.js index c646935ad2..04c851c7e1 100644 --- a/test/unit-tests/function/string/format.test.js +++ b/test/unit-tests/function/string/format.test.js @@ -67,53 +67,68 @@ describe('format', function () { it('should format positive single digit to engineering notation', function () { assert.strictEqual(math.format(3, { notation: 'engineering' }), '3e+0') }) + it('should format positive two digits to engineering notation', function () { assert.strictEqual(math.format(30, { notation: 'engineering' }), '30e+0') }) + it('should format positive three digits to engineering notation', function () { assert.strictEqual(math.format(300, { notation: 'engineering' }), '300e+0') assert.strictEqual(math.format(320, { notation: 'engineering' }), '320e+0') }) + it('should format positive four digits to engineering notation', function () { assert.strictEqual(math.format(3000, { notation: 'engineering' }), '3e+3') }) + it('should format positive uneven four digits to engineering notation', function () { assert.strictEqual(math.format(3001, { notation: 'engineering' }), '3.001e+3') }) + it('should format a number without trailing zeros to engineering notation', function () { assert.strictEqual(math.format(3010, { notation: 'engineering' }), '3.01e+3') assert.strictEqual(math.format(452550000, { notation: 'engineering' }), '452.55e+6') }) + it('should format positive uneven ten digits to engineering notation', function () { assert.strictEqual(math.format(3741293481, { notation: 'engineering' }), '3.741293481e+9') }) + it('should format negative uneven ten digits to engineering notation', function () { assert.strictEqual(math.format(-3741293481, { notation: 'engineering' }), '-3.741293481e+9') }) + it('should format positive single digit floating point numbers to engineering notation', function () { assert.strictEqual(math.format(0.1, { notation: 'engineering' }), '100e-3') }) + it('should format positive two digit floating point numbers to engineering notation', function () { assert.strictEqual(math.format(0.01, { notation: 'engineering' }), '10e-3') assert.strictEqual(math.format(0.011, { notation: 'engineering' }), '11e-3') assert.strictEqual(math.format(0.0111, { notation: 'engineering' }), '11.1e-3') }) + it('should format positive three digit floating point numbers to engineering notation', function () { assert.strictEqual(math.format(0.003, { notation: 'engineering' }), '3e-3') }) + it('should format positive repeating three digit floating point numbers to engineering notation with precision', function () { assert.strictEqual(math.format(1 / 3, { precision: 3, notation: 'engineering' }), '333e-3') }) + it('should format positive seven digit floating point numbers to engineering notation', function () { assert.strictEqual(math.format(0.1234567, { notation: 'engineering' }), '123.4567e-3') }) + it('should format negative single digit floating point numbers to engineering notation', function () { assert.strictEqual(math.format(-0.1, { notation: 'engineering' }), '-100e-3') assert.strictEqual(math.format(-0.11, { notation: 'engineering' }), '-110e-3') }) + it('should format positive floating point number to engineering notation', function () { assert.strictEqual(math.format(13308.0333333333, { precision: 11, notation: 'engineering' }), '13.308033333e+3') }) + it('should add or remove zeroes if necessary to output precision sig figs', function () { assert.strictEqual(math.format(12400, { notation: 'engineering', precision: 2 }), '12e+3') assert.strictEqual(math.format(12400, { notation: 'engineering', precision: 3 }), '12.4e+3') @@ -254,53 +269,68 @@ describe('format', function () { it('should format positive single digit to engineering notation', function () { assert.strictEqual(math.format(bignumber(3), { notation: 'engineering' }), '3e+0') }) + it('should format positive two digits to engineering notation', function () { assert.strictEqual(math.format(bignumber(30), { notation: 'engineering' }), '30e+0') }) + it('should format positive three digits to engineering notation', function () { assert.strictEqual(math.format(bignumber(300), { notation: 'engineering' }), '300e+0') assert.strictEqual(math.format(bignumber(320), { notation: 'engineering' }), '320e+0') }) + it('should format positive four digits to engineering notation', function () { assert.strictEqual(math.format(bignumber(3000), { notation: 'engineering' }), '3e+3') }) + it('should format positive uneven four digits to engineering notation', function () { assert.strictEqual(math.format(bignumber(3001), { notation: 'engineering' }), '3.001e+3') }) + it('should format a number without trailing zeros to engineering notation', function () { assert.strictEqual(math.format(bignumber(3010), { notation: 'engineering' }), '3.01e+3') assert.strictEqual(math.format(bignumber(452550000), { notation: 'engineering' }), '452.55e+6') }) + it('should format positive uneven ten digits to engineering notation', function () { assert.strictEqual(math.format(bignumber(3741293481), { notation: 'engineering' }), '3.741293481e+9') }) + it('should format negative uneven ten digits to engineering notation', function () { assert.strictEqual(math.format(bignumber(-3741293481), { notation: 'engineering' }), '-3.741293481e+9') }) + it('should format positive single digit floating point numbers to engineering notation', function () { assert.strictEqual(math.format(bignumber(0.1), { notation: 'engineering' }), '100e-3') assert.strictEqual(math.format(bignumber(0.11), { notation: 'engineering' }), '110e-3') }) + it('should format positive two digit floating point numbers to engineering notation', function () { assert.strictEqual(math.format(bignumber(0.01), { notation: 'engineering' }), '10e-3') assert.strictEqual(math.format(bignumber(0.011), { notation: 'engineering' }), '11e-3') assert.strictEqual(math.format(bignumber(0.0111), { notation: 'engineering' }), '11.1e-3') }) + it('should format positive three digit floating point numbers to engineering notation', function () { assert.strictEqual(math.format(bignumber(0.003), { notation: 'engineering' }), '3e-3') }) + it('should format positive repeating three digit floating point numbers to engineering notation with precision', function () { assert.strictEqual(math.format(bignumber(1).div(3), { precision: 3, notation: 'engineering' }), '333e-3') }) + it('should format positive seven digit floating point numbers to engineering notation', function () { assert.strictEqual(math.format(bignumber(0.1234567), { notation: 'engineering' }), '123.4567e-3') }) + it('should format negative single digit floating point numbers to engineering notation', function () { assert.strictEqual(math.format(bignumber(-0.1), { notation: 'engineering' }), '-100e-3') }) + it('should format positive floating point number to engineering notation', function () { assert.strictEqual(math.format(bignumber('13308.0333333333'), { precision: 11, notation: 'engineering' }), '13.308033333e+3') }) + it('should add or remove zeroes if necessary to output precision sig figs', function () { assert.strictEqual(math.format(bignumber(12400), { notation: 'engineering', precision: 2 }), '12e+3') assert.strictEqual(math.format(bignumber(12400), { notation: 'engineering', precision: 3 }), '12.4e+3') @@ -366,6 +396,7 @@ describe('format', function () { assert.strictEqual(math.format(bignumber('0.0000000000001234567890123456789'), { notation: 'engineering', precision: 3 }), '123e-15') assert.strictEqual(math.format(bignumber('0.0000000000001234567890123456789'), { notation: 'engineering', precision: 16 }), '123.4567890123457e-15') }) + it('should format numbers starting with more than 3 sig figs that target 1 or 2 sig figs', function () { assert.strictEqual(math.format(bignumber(0.333333333333333), { notation: 'engineering', precision: 1 }), '300e-3') assert.strictEqual(math.format(bignumber(0.333333333333333), { notation: 'engineering', precision: 2 }), '330e-3') @@ -404,6 +435,7 @@ describe('format', function () { assert.strictEqual(math.format(math.bignumber(1.25), { notation: 'oct' }), '0o1.2') assert.strictEqual(math.format(math.bignumber(1.25), { notation: 'hex' }), '0x1.4') }) + it('should throw an error for invalid values', function () { assert.throws(function () { math.format(math.bignumber(1.25), { notation: 'hex', wordSize: 8 }) }, 'Error: Value must be an integer') assert.throws(function () { math.format(math.bignumber(1), { notation: 'hex', wordSize: -8 }) }, 'Error: size must be greater than 0') diff --git a/test/unit-tests/type/matrix/utils/broadcast.test.js b/test/unit-tests/type/matrix/utils/broadcast.test.js index 19a799e459..7b7ef74be8 100644 --- a/test/unit-tests/type/matrix/utils/broadcast.test.js +++ b/test/unit-tests/type/matrix/utils/broadcast.test.js @@ -13,11 +13,13 @@ describe('broadcast', function () { assert.deepStrictEqual(r[0].valueOf(), A.valueOf()) assert.deepStrictEqual(r[1].valueOf(), B.valueOf()) }) + it('should throw an error if they are not broadcastable', function () { const A = matrix([1, 2]) const B = matrix([3, 4, 5]) assert.throws(function () { broadcast(A, B) }) }) + it('should not mutate the original matrices', function () { const A = matrix([1, 2]) const B = matrix([[3], [4]]) @@ -25,6 +27,7 @@ describe('broadcast', function () { assert.deepStrictEqual(A.valueOf(), [1, 2]) assert.deepStrictEqual(B.valueOf(), [[3], [4]]) }) + it('should broadcast the first matrix', function () { const A = matrix([1, 2]) const B = matrix([[3, 3], [4, 4]]) @@ -32,6 +35,7 @@ describe('broadcast', function () { assert.deepStrictEqual(r[0].valueOf(), [[1, 2], [1, 2]]) assert.deepStrictEqual(r[1].valueOf(), B.valueOf()) }) + it('should broadcast the second matrix', function () { const A = matrix([[1, 2], [1, 2]]) const B = matrix([[3], [4]]) @@ -39,6 +43,7 @@ describe('broadcast', function () { assert.deepStrictEqual(r[0].valueOf(), A.valueOf()) assert.deepStrictEqual(r[1].valueOf(), [[3, 3], [4, 4]]) }) + it('should broadcast both matrices', function () { const A = matrix([1, 2]) const B = matrix([[3], [4]]) @@ -46,6 +51,7 @@ describe('broadcast', function () { assert.deepStrictEqual(r[0].valueOf(), [[1, 2], [1, 2]]) assert.deepStrictEqual(r[1].valueOf(), [[3, 3], [4, 4]]) }) + it('should broadcast a scalar and a column vector', function () { const A = matrix([1]) const B = matrix([[3], [4]]) @@ -53,6 +59,7 @@ describe('broadcast', function () { assert.deepStrictEqual(r[0].valueOf(), [[1], [1]]) assert.deepStrictEqual(r[1].valueOf(), B.valueOf()) }) + it('should broadcast a row vector and a scalar', function () { const A = matrix([1, 2]) const B = matrix([3]) @@ -60,6 +67,7 @@ describe('broadcast', function () { assert.deepStrictEqual(r[0].valueOf(), A.valueOf()) assert.deepStrictEqual(r[1].valueOf(), [3, 3]) }) + it('should broadcast higher dimensions', function () { const A = matrix([[[1, 2]]]) const B = matrix([[[3]], [[4]]]) diff --git a/test/unit-tests/type/matrix/utils/getMatrixDataType.test.js b/test/unit-tests/type/matrix/utils/getMatrixDataType.test.js index caf2b3aa4c..f76890bf38 100644 --- a/test/unit-tests/type/matrix/utils/getMatrixDataType.test.js +++ b/test/unit-tests/type/matrix/utils/getMatrixDataType.test.js @@ -10,34 +10,42 @@ describe('getMatrixDataType', function () { const result = getMatrixDataType([[1, 2, 3], [4, 5, 6], [1, 8, 9]]) assert.strictEqual('number', result) }) + it('should return number for pure numbers with NaN', function () { const result = getMatrixDataType([[1, 2, NaN], [4, 5, 6], [1, 8, 9]]) assert.strictEqual('number', result) }) + it('should return string', function () { const result = getMatrixDataType([['string'], ['test']]) assert.strictEqual('string', result) }) + it('should return boolean', function () { const result = getMatrixDataType([[true], [false]]) assert.strictEqual('boolean', result) }) + it('should return undefined', function () { const result = getMatrixDataType([[undefined], [undefined]]) assert.strictEqual('undefined', result) }) + it('should return null', function () { const result = getMatrixDataType([[null], [null]]) assert.strictEqual('null', result) }) + it('should return mixed when number and null are given', function () { const result = getMatrixDataType([[1], [null]]) assert.strictEqual('mixed', result) }) + it('should return mixed when number and string are given', function () { const result = getMatrixDataType([[1], ['string']]) assert.strictEqual('mixed', result) }) + it('should return undefined if the input is not a matrix', function () { // Not equal in size and one is an empty array const result1 = getMatrixDataType([[1], []]) @@ -58,11 +66,13 @@ describe('getMatrixDataType', function () { const bignumberMatrix = getMatrixDataType([[zero], [zero]]) assert.strictEqual(bignumberMatrix, 'BigNumber') }) + it('should return mixed', function () { const zero = math.bignumber(0) const bignumberMatrix = getMatrixDataType([[zero], [2]]) assert.strictEqual(bignumberMatrix, 'mixed') }) + it('should return undefined', function () { const zero = math.bignumber(0) const bignumberMatrix = getMatrixDataType([[zero], []]) @@ -76,11 +86,13 @@ describe('getMatrixDataType', function () { const unitMatrix = getMatrixDataType([[x], [x]]) assert.strictEqual(unitMatrix, 'Unit') }) + it('should return mixed', function () { const x = math.unit('5cm') const unitMatrix = getMatrixDataType([[x], [2]]) assert.strictEqual(unitMatrix, 'mixed') }) + it('should return undefined', function () { const x = math.unit('5cm') const unitMatrix = getMatrixDataType([[x], []]) @@ -94,11 +106,13 @@ describe('getMatrixDataType', function () { const fractionMatrix = getMatrixDataType([[x], [x]]) assert.strictEqual(fractionMatrix, 'Fraction') }) + it('should return mixed', function () { const x = math.fraction(1, 3) const fractionMatrix = getMatrixDataType([[x], [2]]) assert.strictEqual(fractionMatrix, 'mixed') }) + it('should return undefined', function () { const x = math.fraction(1, 3) const fractionMatrix = getMatrixDataType([[x], []]) @@ -140,6 +154,7 @@ describe('getMatrixDataType', function () { assert.strictEqual('number', result1) assert.strictEqual('number', result2) }) + it('should return string', function () { const matrix = new DenseMatrix([['string'], ['test']]) const result1 = getMatrixDataType(matrix) @@ -147,6 +162,7 @@ describe('getMatrixDataType', function () { assert.strictEqual('string', result1) assert.strictEqual('string', result2) }) + it('should return boolean', function () { const matrix = new DenseMatrix([[true], [false]]) const result1 = getMatrixDataType(matrix) @@ -154,6 +170,7 @@ describe('getMatrixDataType', function () { assert.strictEqual('boolean', result1) assert.strictEqual('boolean', result2) }) + it('should return undefined', function () { const matrix = new DenseMatrix([[undefined], [undefined]]) const result1 = getMatrixDataType(matrix) @@ -161,6 +178,7 @@ describe('getMatrixDataType', function () { assert.strictEqual('undefined', result1) assert.strictEqual('undefined', result2) }) + it('should return null', function () { const matrix = new DenseMatrix([[null], [null]]) const result1 = getMatrixDataType(matrix) @@ -168,6 +186,7 @@ describe('getMatrixDataType', function () { assert.strictEqual('null', result1) assert.strictEqual('null', result2) }) + it('should return mixed when number and null are given', function () { const matrix = new DenseMatrix([[1], [null]]) const result1 = getMatrixDataType(matrix) @@ -175,6 +194,7 @@ describe('getMatrixDataType', function () { assert.strictEqual('mixed', result1) assert.strictEqual('mixed', result2) }) + it('should return mixed when number and string are given', function () { const matrix = new DenseMatrix([[1], ['string']]) const result1 = getMatrixDataType(matrix) diff --git a/test/unit-tests/utils/array.test.js b/test/unit-tests/utils/array.test.js index 219ca89d30..9fb4928252 100644 --- a/test/unit-tests/utils/array.test.js +++ b/test/unit-tests/utils/array.test.js @@ -63,6 +63,7 @@ describe('util.array', function () { const a = 0 assert.deepStrictEqual(resize(a, [3]), [0, 0, 0]) }) + it('should resize a 1 dimensional array', function () { let a = [] @@ -600,6 +601,7 @@ describe('util.array', function () { assert.deepStrictEqual(broadcastSizes([1, 2], [2, 2]), [2, 2]) assert.deepStrictEqual(broadcastSizes([3, 2], [1, 2], [3, 1]), [3, 2]) }) + it('should throw an error when the broadcasting rules are not followed', function () { assert.throws(function () { broadcastSizes([2, 2], [3, 2]) }, /Error: shape missmatch: missmatch is found in arg with shape.*/) }) @@ -612,11 +614,13 @@ describe('util.array', function () { assert.deepStrictEqual(broadcastTo(a, [2]), a) assert.deepStrictEqual(broadcastTo(b, [1, 2]), b) }) + it('should broadcast an array to a certain size', function () { assert.deepStrictEqual(broadcastTo([10, 20], [2, 2]), [[10, 20], [10, 20]]) assert.deepStrictEqual(broadcastTo([[10, 20]], [3, 2]), [[10, 20], [10, 20], [10, 20]]) assert.deepStrictEqual(broadcastTo([1, 2, 3], [1, 2, 3]), [[[1, 2, 3], [1, 2, 3]]]) }) + it('should throw an error when not possible to broadcast to', function () { assert.throws(function () { broadcastTo([10, 20], [1]) }) }) @@ -627,10 +631,12 @@ describe('util.array', function () { assert.deepStrictEqual(concat([[1, 2]], [[1, 2]], 0), [[1, 2], [1, 2]]) assert.deepStrictEqual(concat([[1, 2]], [[1, 2]], 1), [[1, 2, 1, 2]]) }) + it('should return arrays as such if only one is supplied', function () { assert.deepStrictEqual(concat([[1, 2], [3, 4]], 0), [[1, 2], [3, 4]]) assert.deepStrictEqual(concat([1, 2], 0), [1, 2]) }) + it('should throw an error when the wrong number of arguments is supplied', function () { assert.throws(function () { concat([[1, 2], [3, 4]]) }) assert.throws(function () { concat(1) }) @@ -651,6 +657,7 @@ describe('util.array', function () { assert.doesNotThrow(function () { checkBroadcastingRules([1, 2], [2, 2]) }) assert.doesNotThrow(function () { checkBroadcastingRules([2, 1], [2, 2]) }) }) + it('should throw an error if the broadcasting rules are not ok', function () { assert.throws(function () { checkBroadcastingRules([2, 2], [3, 2]) }) assert.throws(function () { checkBroadcastingRules([2, 2], [2, 3]) }) @@ -664,20 +671,24 @@ describe('util.array', function () { assert.deepStrictEqual(broadcastArrays([1, 2], [[3], [4]]), [[[1, 2], [1, 2]], [[3, 3], [4, 4]]]) 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 () { assert.deepStrictEqual(broadcastArrays([1, 2]), [1, 2], [3, 4]) assert.deepStrictEqual(broadcastArrays([[3], [4]]), [[3], [4]]) assert.deepStrictEqual(broadcastArrays([[5, 6]]), [[5, 6]]) }) + it('should throw an arryor 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 () { assert.throws(function () { broadcastArrays() }) }) }) + describe('isEmptyIndex', function () { it('should detect an empty index in arrays', function () { assert.deepStrictEqual(isEmptyIndex(math.index([])), true) @@ -685,12 +696,14 @@ describe('util.array', function () { assert.deepStrictEqual(isEmptyIndex(math.index([], 1)), true) assert.deepStrictEqual(isEmptyIndex(math.index(0, 1)), false) }) + it('should detect an empty index in ranges', function () { assert.deepStrictEqual(isEmptyIndex(math.index(new math.Range(0, 0))), true) assert.deepStrictEqual(isEmptyIndex(math.index(new math.Range(0, 1))), false) assert.deepStrictEqual(isEmptyIndex(math.index(new math.Range(0, 0), 1)), true) assert.deepStrictEqual(isEmptyIndex(math.index(0, new math.Range(0, 1))), false) }) + it('should detect an empty index in text', function () { assert.deepStrictEqual(isEmptyIndex(math.index('')), true) assert.deepStrictEqual(isEmptyIndex(math.index('someText')), false) From 4c42a14c8154a408f6fddbfdda9dcefde0818a9e Mon Sep 17 00:00:00 2001 From: Jos de Jong Date: Thu, 22 Feb 2024 16:32:22 +0100 Subject: [PATCH 13/13] chore: publish v12.4.0 --- AUTHORS | 6 ++++-- HISTORY.md | 2 +- package-lock.json | 4 ++-- package.json | 2 +- src/version.js | 2 +- 5 files changed, 9 insertions(+), 7 deletions(-) diff --git a/AUTHORS b/AUTHORS index 0fbe5b0230..ff6b0e4c3e 100644 --- a/AUTHORS +++ b/AUTHORS @@ -239,7 +239,9 @@ Brooks Smith Alex Edgcomb S.Y. Lee Hudsxn <143907857+Hudsxn@users.noreply.github.com> -RandomGamingDev -Rich Martinez +Rich Martinez <6185506+rich-martinez@users.noreply.github.com> +Rich Martinez +RandomGamingDev <83996185+RandomGamingDev@users.noreply.github.com> +Brian Fugate # Generated by tools/update-authors.js diff --git a/HISTORY.md b/HISTORY.md index 894eed8d22..bc042a1a17 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,7 +1,7 @@ # History -# Unpublished changes since 12.3.2 +# 2024-02-22, 12.4.0 - Feat: implement support for trailing commas in matrices (#3154, #2968). Thanks @dvd101x. diff --git a/package-lock.json b/package-lock.json index 3159093ee3..1f77629812 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "mathjs", - "version": "12.3.2", + "version": "12.4.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "mathjs", - "version": "12.3.2", + "version": "12.4.0", "license": "Apache-2.0", "dependencies": { "@babel/runtime": "^7.23.9", diff --git a/package.json b/package.json index 99706c7f6a..23c0a1d4e8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "mathjs", - "version": "12.3.2", + "version": "12.4.0", "description": "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 different data types like numbers, big numbers, complex numbers, fractions, units, and matrices.", "author": "Jos de Jong (https://github.com/josdejong)", "homepage": "https://mathjs.org", diff --git a/src/version.js b/src/version.js index c586d9b811..c2e1712845 100644 --- a/src/version.js +++ b/src/version.js @@ -1,3 +1,3 @@ -export const version = '12.3.2' +export const version = '12.4.0' // Note: This file is automatically generated when building math.js. // Changes made in this file will be overwritten.