Skip to content

Commit f8d7d1d

Browse files
committed
feat: Make Range an implementation of Matrix
With this commit, Range is now a full-fledged implementation of Matrix, representing an arbitrary arithmetic sequence (of any type supported by mathjs) in a "lazy" way, i.e. its entries are generated on demand. (Thus, even infinite Ranges are supported.) Note that Range therefore has many new dependencies, and the `matrix()` convertor/constructor function must be able to create Ranges. Therefore, to avoid a circular dependency on `matrix`, many mathjs methods have their dependence on `matrix()` removed. Often this dependence was very superficial, and removing it was essentially trivial; in all other cases, the dependence could be shifted to DenseMatrix rather than matrix, removing the possibility of circularity. In addition, as it seemed very confusing (almost to the point of a bug) that `math.parse('2:5')` produced a representation of 2, 3, 4, 5 while `Range.parse('2:5')` produced a representation of 2, 3, 4. Therefore, this commit changes the interpretation so that both `parse` command include the endpoint. Finally, this commit fixes the remaining doc examples tests in the src/type directory.
1 parent c9c7d4d commit f8d7d1d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

76 files changed

+1169
-606
lines changed

src/core/function/typed.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,10 +132,10 @@ export const createTyped = /* #__PURE__ */ factory('typed', dependencies, functi
132132
{ name: 'string', test: isString },
133133
{ name: 'Chain', test: isChain },
134134
{ name: 'Array', test: isArray },
135-
{ name: 'Matrix', test: isMatrix },
136135
{ name: 'DenseMatrix', test: isDenseMatrix },
137136
{ name: 'SparseMatrix', test: isSparseMatrix },
138137
{ name: 'Range', test: isRange },
138+
{ name: 'Matrix', test: isMatrix },
139139
{ name: 'Index', test: isIndex },
140140
{ name: 'boolean', test: isBoolean },
141141
{ name: 'ResultSet', test: isResultSet },

src/expression/transform/and.transform.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@ import { factory } from '../../utils/factory.js'
33
import { isCollection } from '../../utils/is.js'
44

55
const name = 'and'
6-
const dependencies = ['typed', 'matrix', 'zeros', 'add', 'equalScalar', 'not', 'concat']
6+
const dependencies = ['typed', 'DenseMatrix', 'zeros', 'add', 'equalScalar', 'not']
77

8-
export const createAndTransform = /* #__PURE__ */ factory(name, dependencies, ({ typed, matrix, equalScalar, zeros, not, concat }) => {
9-
const and = createAnd({ typed, matrix, equalScalar, zeros, not, concat })
8+
export const createAndTransform = /* #__PURE__ */ factory(name, dependencies, provided => {
9+
const and = createAnd(provided)
1010

1111
function andTransform (args, math, scope) {
1212
const condition1 = args[0].compile().evaluate(scope)

src/expression/transform/bitAnd.transform.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@ import { factory } from '../../utils/factory.js'
33
import { isCollection } from '../../utils/is.js'
44

55
const name = 'bitAnd'
6-
const dependencies = ['typed', 'matrix', 'zeros', 'add', 'equalScalar', 'not', 'concat']
6+
const dependencies = ['typed', 'DenseMatrix', 'equalScalar']
77

8-
export const createBitAndTransform = /* #__PURE__ */ factory(name, dependencies, ({ typed, matrix, equalScalar, zeros, not, concat }) => {
9-
const bitAnd = createBitAnd({ typed, matrix, equalScalar, zeros, not, concat })
8+
export const createBitAndTransform = /* #__PURE__ */ factory(name, dependencies, provided => {
9+
const bitAnd = createBitAnd(provided)
1010

1111
function bitAndTransform (args, math, scope) {
1212
const condition1 = args[0].compile().evaluate(scope)

src/expression/transform/bitOr.transform.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@ import { factory } from '../../utils/factory.js'
33
import { isCollection } from '../../utils/is.js'
44

55
const name = 'bitOr'
6-
const dependencies = ['typed', 'matrix', 'equalScalar', 'DenseMatrix', 'concat']
6+
const dependencies = ['typed', 'equalScalar', 'DenseMatrix']
77

8-
export const createBitOrTransform = /* #__PURE__ */ factory(name, dependencies, ({ typed, matrix, equalScalar, DenseMatrix, concat }) => {
9-
const bitOr = createBitOr({ typed, matrix, equalScalar, DenseMatrix, concat })
8+
export const createBitOrTransform = /* #__PURE__ */ factory(name, dependencies, provided => {
9+
const bitOr = createBitOr(provided)
1010

1111
function bitOrTransform (args, math, scope) {
1212
const condition1 = args[0].compile().evaluate(scope)

src/expression/transform/index.transform.js

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ import {
44
import { factory } from '../../utils/factory.js'
55

66
const name = 'index'
7-
const dependencies = ['Index', 'getMatrixDataType']
7+
const dependencies = ['Index', 'Range', 'number', 'getMatrixDataType']
88

9-
export const createIndexTransform = /* #__PURE__ */ factory(name, dependencies, ({ Index, getMatrixDataType }) => {
9+
export const createIndexTransform = /* #__PURE__ */ factory(name, dependencies, ({ Index, Range, number, getMatrixDataType }) => {
1010
/**
1111
* Attach a transform function to math.index
1212
* Adds a property transform containing the transform function.
@@ -20,8 +20,11 @@ export const createIndexTransform = /* #__PURE__ */ factory(name, dependencies,
2020

2121
// change from one-based to zero based, convert BigNumber to number and leave Array of Booleans as is
2222
if (isRange(arg)) {
23-
arg.start--
24-
arg.end -= (arg.step > 0 ? 0 : 2)
23+
arg = new Range({
24+
from: number(arg.from) - 1,
25+
for: arg.for,
26+
by: number(arg.by)
27+
})
2528
} else if (arg && arg.isSet === true) {
2629
arg = arg.map(function (v) { return v - 1 })
2730
} else if (isArray(arg) || isMatrix(arg)) {

src/expression/transform/nullish.transform.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@ import { factory } from '../../utils/factory.js'
33
import { isCollection } from '../../utils/is.js'
44

55
const name = 'nullish'
6-
const dependencies = ['typed', 'matrix', 'size', 'flatten', 'deepEqual']
6+
const dependencies = ['typed', 'DenseMatrix', 'size', 'flatten', 'deepEqual']
77

8-
export const createNullishTransform = /* #__PURE__ */ factory(name, dependencies, ({ typed, matrix, size, flatten, deepEqual }) => {
9-
const nullish = createNullish({ typed, matrix, size, flatten, deepEqual })
8+
export const createNullishTransform = /* #__PURE__ */ factory(name, dependencies, provided => {
9+
const nullish = createNullish(provided)
1010

1111
function nullishTransform (args, math, scope) {
1212
const left = args[0].compile().evaluate(scope)

src/expression/transform/range.transform.js

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,18 @@
11
import { factory } from '../../utils/factory.js'
2-
import { createRange } from '../../function/matrix/range.js'
2+
import { createRange, dependencies } from '../../function/matrix/range.js'
33

44
const name = 'range'
5-
const dependencies = ['typed', 'config', '?matrix', '?bignumber', 'equal', 'smaller', 'smallerEq', 'larger', 'largerEq', 'add', 'isZero', 'isPositive']
65

7-
export const createRangeTransform = /* #__PURE__ */ factory(name, dependencies, ({ typed, config, matrix, bignumber, equal, smaller, smallerEq, larger, largerEq, add, isZero, isPositive }) => {
8-
const range = createRange({ typed, config, matrix, bignumber, equal, smaller, smallerEq, larger, largerEq, add, isZero, isPositive })
6+
export const createRangeTransform = /* #__PURE__ */ factory(name, dependencies, provided => {
7+
const range = createRange(provided)
98

109
/**
1110
* Attach a transform function to math.range
1211
* Adds a property transform containing the transform function.
1312
*
1413
* This transform creates a range which includes the end value
1514
*/
16-
return typed('range', {
15+
return provided.typed('range', {
1716
'...any': function (args) {
1817
const lastIndex = args.length - 1
1918
const last = args[lastIndex]

src/factoriesNumber.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ export { createTyped } from './core/function/typed.js'
8383
// classes
8484
export { createResultSet } from './type/resultset/ResultSet.js'
8585
export { createRangeClass } from './type/matrix/Range.js'
86+
export { createMatrixClass } from './type/matrix/Matrix.js'
8687
export { createHelpClass } from './expression/Help.js'
8788
export { createChainClass } from './type/chain/Chain.js'
8889
export { createHelp } from './expression/function/help.js'
@@ -128,6 +129,7 @@ export const createPow = /* #__PURE__ */ createNumberFactory('pow', powNumber)
128129
export { createOneNumber } from './function/arithmetic/one.js'
129130
export const createRound = /* #__PURE__ */
130131
createNumberOptionalSecondArgFactory('round', roundNumber)
132+
export { createScalarDivide } from './function/arithmetic/scalarDivide.js'
131133
export const createLog = /* #__PURE__ */
132134
createNumberOptionalSecondArgFactory('log', logNumber)
133135
export const createLog1p = /* #__PURE__ */ createNumberFactory('log1p', log1pNumber)
@@ -211,6 +213,7 @@ export const createOr = /* #__PURE__ */ createNumberFactory('or', orNumber)
211213
export const createXor = /* #__PURE__ */ createNumberFactory('xor', xorNumber)
212214

213215
// matrix
216+
export { createGetMatrixDataType } from './function/matrix/getMatrixDataType.js'
214217
export { createMapSlices } from './function/matrix/mapSlices.js'
215218
export { createFilter } from './function/matrix/filter.js'
216219
export { createForEach } from './function/matrix/forEach.js'

src/function/arithmetic/add.js

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,20 @@ import { createMatrixAlgorithmSuite } from '../../type/matrix/utils/matrixAlgori
77
const name = 'add'
88
const dependencies = [
99
'typed',
10-
'matrix',
1110
'addScalar',
1211
'equalScalar',
1312
'DenseMatrix',
14-
'SparseMatrix',
15-
'concat'
13+
'SparseMatrix'
1614
]
1715

1816
export const createAdd = /* #__PURE__ */ factory(
1917
name,
2018
dependencies,
21-
({ typed, matrix, addScalar, equalScalar, DenseMatrix, SparseMatrix, concat }) => {
19+
({ typed, addScalar, equalScalar, DenseMatrix, SparseMatrix, math, concat }) => {
2220
const matAlgo01xDSid = createMatAlgo01xDSid({ typed })
2321
const matAlgo04xSidSid = createMatAlgo04xSidSid({ typed, equalScalar })
2422
const matAlgo10xSids = createMatAlgo10xSids({ typed, DenseMatrix })
25-
const matrixAlgorithmSuite = createMatrixAlgorithmSuite({ typed, matrix, concat })
23+
const matrixAlgorithmSuite = createMatrixAlgorithmSuite({ typed, DenseMatrix })
2624
/**
2725
* Add two or more values, `x + y`.
2826
* For matrices, the function is evaluated element wise.
@@ -70,7 +68,29 @@ export const createAdd = /* #__PURE__ */ factory(
7068
}
7169

7270
return result
73-
})
71+
}),
72+
'Range, Range': typed.referToSelf(self => (r, p) => {
73+
if (r.for !== p.for) throw new Error('Range length mismatch')
74+
return r.createRange({
75+
from: self(r.from, p.from),
76+
for: r.for,
77+
by: self(r.by, p.by)
78+
})
79+
}),
80+
'Range, Matrix': typed.referToSelf(
81+
self => (r, m) => self(r.valueOf(), m)),
82+
'Range, any': typed.referToSelf(self => (r, s) => r.createRange({
83+
from: self(r.from, s),
84+
for: r.for,
85+
by: r.by
86+
})),
87+
'Matrix, Range': typed.referToSelf(
88+
self => (m, r) => self(m, r.valueOf())),
89+
'any, Range': typed.referToSelf(self => (s, r) => r.createRange({
90+
from: self(s, r.from),
91+
for: r.for,
92+
by: r.by
93+
}))
7494
},
7595
matrixAlgorithmSuite({
7696
elop: addScalar,

src/function/arithmetic/ceil.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { createMatAlgo12xSfs } from '../../type/matrix/utils/matAlgo12xSfs.js'
88
import { createMatAlgo14xDs } from '../../type/matrix/utils/matAlgo14xDs.js'
99

1010
const name = 'ceil'
11-
const dependencies = ['typed', 'config', 'round', 'matrix', 'equalScalar', 'zeros', 'DenseMatrix']
11+
const dependencies = ['typed', 'config', 'round', 'equalScalar', 'zeros', 'DenseMatrix']
1212

1313
const bigTen = new Decimal(10)
1414

@@ -46,7 +46,7 @@ export const createCeilNumber = /* #__PURE__ */ factory(
4646
}
4747
)
4848

49-
export const createCeil = /* #__PURE__ */ factory(name, dependencies, ({ typed, config, round, matrix, equalScalar, zeros, DenseMatrix }) => {
49+
export const createCeil = /* #__PURE__ */ factory(name, dependencies, ({ typed, config, round, equalScalar, zeros, DenseMatrix }) => {
5050
const matAlgo11xS0s = createMatAlgo11xS0s({ typed, equalScalar })
5151
const matAlgo12xSfs = createMatAlgo12xSfs({ typed, DenseMatrix })
5252
const matAlgo14xDs = createMatAlgo14xDs({ typed })
@@ -181,7 +181,7 @@ export const createCeil = /* #__PURE__ */ factory(name, dependencies, ({ typed,
181181
'number | Complex | Fraction | BigNumber, Array':
182182
typed.referToSelf(self => (x, y) => {
183183
// use matrix implementation
184-
return matAlgo14xDs(matrix(y), x, self, true).valueOf()
184+
return matAlgo14xDs(new DenseMatrix(y), x, self, true).valueOf()
185185
}),
186186

187187
'number | Complex | Fraction | BigNumber, Matrix':

0 commit comments

Comments
 (0)