Skip to content

Commit

Permalink
Merge branch 'develop' into symbolicEqual-types
Browse files Browse the repository at this point in the history
  • Loading branch information
josdejong authored Oct 25, 2023
2 parents 9250789 + 0222ff7 commit 9f83877
Show file tree
Hide file tree
Showing 29 changed files with 386 additions and 188 deletions.
2 changes: 2 additions & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -233,5 +233,7 @@ BuildTools <[email protected]>
Anik Patel <[email protected]>
Vrushaket Chaudhari <[email protected]>
Praise Nnamonu <[email protected]>
Vincent Tam <[email protected]>
vrushaket <[email protected]>

# Generated by tools/update-authors.js
2 changes: 1 addition & 1 deletion examples/advanced/custom_evaluate_using_import.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const divide = (a, b) => a / b

// create a mathjs instance with hardly any functions
// there are some functions created which are used internally by evaluate though,
// for example by the Unit class which has dependencies on addScalar, subtract,
// for example by the Unit class which has dependencies on addScalar, subtractScalar,
// multiplyScalar, etc.
const math = create(evaluateDependencies)

Expand Down
125 changes: 49 additions & 76 deletions src/expression/parse.js
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,19 @@ export const createParse = /* #__PURE__ */ factory(name, dependencies, ({
'Infinity'
]

const ESCAPE_CHARACTERS = {
'"': '"',
"'": "'",
'\\': '\\',
'/': '/',
b: '\b',
f: '\f',
n: '\n',
r: '\r',
t: '\t'
// note that \u is handled separately in parseStringToken()
}

function initialState () {
return {
extraNodes: {}, // current extra nodes, must be careful not to mutate
Expand Down Expand Up @@ -1339,7 +1352,7 @@ export const createParse = /* #__PURE__ */ factory(name, dependencies, ({
return node
}

return parseDoubleQuotesString(state)
return parseString(state)
}

/**
Expand Down Expand Up @@ -1436,15 +1449,15 @@ export const createParse = /* #__PURE__ */ factory(name, dependencies, ({
}

/**
* Parse a double quotes string.
* Parse a single or double quoted string.
* @return {Node} node
* @private
*/
function parseDoubleQuotesString (state) {
function parseString (state) {
let node, str

if (state.token === '"') {
str = parseDoubleQuotesStringToken(state)
if (state.token === '"' || state.token === "'") {
str = parseStringToken(state, state.token)

// create constant
node = new ConstantNode(str)
Expand All @@ -1455,92 +1468,54 @@ export const createParse = /* #__PURE__ */ factory(name, dependencies, ({
return node
}

return parseSingleQuotesString(state)
return parseMatrix(state)
}

/**
* Parse a string surrounded by double quotes "..."
* Parse a string surrounded by single or double quotes
* @param {Object} state
* @param {"'" | "\""} quote
* @return {string}
*/
function parseDoubleQuotesStringToken (state) {
function parseStringToken (state, quote) {
let str = ''

while (currentCharacter(state) !== '' && currentCharacter(state) !== '"') {
while (currentCharacter(state) !== '' && currentCharacter(state) !== quote) {
if (currentCharacter(state) === '\\') {
// escape character, immediately process the next
// character to prevent stopping at a next '\"'
const cNext = nextCharacter(state)
if (cNext !== "'") {
str += currentCharacter(state)
}
next(state)
}

str += currentCharacter(state)
next(state)
}

getToken(state)
if (state.token !== '"') {
throw createSyntaxError(state, 'End of string " expected')
}
getToken(state)

return JSON.parse('"' + str + '"') // unescape escaped characters
}

/**
* Parse a single quotes string.
* @return {Node} node
* @private
*/
function parseSingleQuotesString (state) {
let node, str

if (state.token === '\'') {
str = parseSingleQuotesStringToken(state)

// create constant
node = new ConstantNode(str)

// parse index parameters
node = parseAccessors(state, node)

return node
}

return parseMatrix(state)
}

/**
* Parse a string surrounded by single quotes '...'
* @return {string}
*/
function parseSingleQuotesStringToken (state) {
let str = ''

while (currentCharacter(state) !== '' && currentCharacter(state) !== '\'') {
if (currentCharacter(state) === '\\') {
// escape character, immediately process the next
// character to prevent stopping at a next '\''
const cNext = nextCharacter(state)
if (cNext !== "'" && cNext !== '"') {
str += currentCharacter(state)
const char = currentCharacter(state)
const escapeChar = ESCAPE_CHARACTERS[char]
if (escapeChar !== undefined) {
// an escaped control character like \" or \n
str += escapeChar
state.index += 1
} else if (char === 'u') {
// escaped unicode character
const unicode = state.expression.slice(state.index + 1, state.index + 5)
if (/^[0-9A-Fa-f]{4}$/.test(unicode)) { // test whether the string holds four hexadecimal values
str += String.fromCharCode(parseInt(unicode, 16))
state.index += 5
} else {
throw createSyntaxError(state, `Invalid unicode character \\u${unicode}`)
}
} else {
throw createSyntaxError(state, `Bad escape character \\${char}`)
}
} else {
// any regular character
str += currentCharacter(state)
next(state)
}

str += currentCharacter(state)
next(state)
}

getToken(state)
if (state.token !== '\'') {
throw createSyntaxError(state, 'End of string \' expected')
if (state.token !== quote) {
throw createSyntaxError(state, `End of string ${quote} expected`)
}
getToken(state)

return JSON.parse('"' + str.replace(/"/g, '\\"') + '"') // unescape escaped characters
return str
}

/**
Expand Down Expand Up @@ -1647,10 +1622,8 @@ export const createParse = /* #__PURE__ */ factory(name, dependencies, ({

if (state.token !== '}') {
// parse key
if (state.token === '"') {
key = parseDoubleQuotesStringToken(state)
} else if (state.token === '\'') {
key = parseSingleQuotesStringToken(state)
if (state.token === '"' || state.token === "'") {
key = parseStringToken(state, state.token)
} else if (state.tokenType === TOKENTYPE.SYMBOL || (state.tokenType === TOKENTYPE.DELIMITER && state.token in NAMED_DELIMITERS)) {
key = state.token
getToken(state)
Expand Down
1 change: 1 addition & 0 deletions src/factoriesAny.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export { createUnaryPlus } from './function/arithmetic/unaryPlus.js'
export { createAbs } from './function/arithmetic/abs.js'
export { createApply } from './function/matrix/apply.js'
export { createAddScalar } from './function/arithmetic/addScalar.js'
export { createSubtractScalar } from './function/arithmetic/subtractScalar.js'
export { createCbrt } from './function/arithmetic/cbrt.js'
export { createCeil } from './function/arithmetic/ceil.js'
export { createCube } from './function/arithmetic/cube.js'
Expand Down
1 change: 1 addition & 0 deletions src/factoriesNumber.js
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ export const createUnaryMinus = /* #__PURE__ */ createNumberFactory('unaryMinus'
export const createUnaryPlus = /* #__PURE__ */ createNumberFactory('unaryPlus', unaryPlusNumber)
export const createAbs = /* #__PURE__ */ createNumberFactory('abs', absNumber)
export const createAddScalar = /* #__PURE__ */ createNumberFactory('addScalar', addNumber)
export const createSubtractScalar = /* #__PURE__ */ createNumberFactory('subtractScalar', subtractNumber)
export const createCbrt = /* #__PURE__ */ createNumberFactory('cbrt', cbrtNumber)
export { createCeilNumber as createCeil } from './function/arithmetic/ceil.js'
export const createCube = /* #__PURE__ */ createNumberFactory('cube', cubeNumber)
Expand Down
6 changes: 3 additions & 3 deletions src/function/algebra/decomposition/lup.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const dependencies = [
'addScalar',
'divideScalar',
'multiplyScalar',
'subtract',
'subtractScalar',
'larger',
'equalScalar',
'unaryMinus',
Expand All @@ -26,7 +26,7 @@ export const createLup = /* #__PURE__ */ factory(name, dependencies, (
addScalar,
divideScalar,
multiplyScalar,
subtract,
subtractScalar,
larger,
equalScalar,
unaryMinus,
Expand Down Expand Up @@ -119,7 +119,7 @@ export const createLup = /* #__PURE__ */ factory(name, dependencies, (
// s = l[i, k] - data[k, j]
s = addScalar(s, multiplyScalar(data[i][k], data[k][j]))
}
data[i][j] = subtract(data[i][j], s)
data[i][j] = subtractScalar(data[i][j], s)
}
}
// row with larger value in cvector, row >= j
Expand Down
10 changes: 5 additions & 5 deletions src/function/algebra/decomposition/qr.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const dependencies = [
'addScalar',
'divideScalar',
'multiplyScalar',
'subtract',
'subtractScalar',
'complex'
]

Expand All @@ -34,7 +34,7 @@ export const createQr = /* #__PURE__ */ factory(name, dependencies, (
addScalar,
divideScalar,
multiplyScalar,
subtract,
subtractScalar,
complex
}
) => {
Expand Down Expand Up @@ -159,7 +159,7 @@ export const createQr = /* #__PURE__ */ factory(name, dependencies, (

if (!isZero(alpha)) {
// first element in vector u
const u1 = subtract(pivot, alpha)
const u1 = subtractScalar(pivot, alpha)

// w = v * u1 / |u| (only elements k to (rows-1) are used)
w[k] = 1
Expand Down Expand Up @@ -198,7 +198,7 @@ export const createQr = /* #__PURE__ */ factory(name, dependencies, (

for (i = k; i < rows; i++) {
Rdata[i][j] = multiplyScalar(
subtract(Rdata[i][j], multiplyScalar(w[i], s)),
subtractScalar(Rdata[i][j], multiplyScalar(w[i], s)),
conjSgn
)
}
Expand All @@ -223,7 +223,7 @@ export const createQr = /* #__PURE__ */ factory(name, dependencies, (

for (j = k; j < rows; ++j) {
Qdata[i][j] = divideScalar(
subtract(Qdata[i][j], multiplyScalar(s, conj(w[j]))),
subtractScalar(Qdata[i][j], multiplyScalar(s, conj(w[j]))),
conjSgn
)
}
Expand Down
8 changes: 4 additions & 4 deletions src/function/algebra/solver/lsolve.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ const dependencies = [
'matrix',
'divideScalar',
'multiplyScalar',
'subtract',
'subtractScalar',
'equalScalar',
'DenseMatrix'
]

export const createLsolve = /* #__PURE__ */ factory(name, dependencies, ({ typed, matrix, divideScalar, multiplyScalar, subtract, equalScalar, DenseMatrix }) => {
export const createLsolve = /* #__PURE__ */ factory(name, dependencies, ({ typed, matrix, divideScalar, multiplyScalar, subtractScalar, equalScalar, DenseMatrix }) => {
const solveValidation = createSolveValidation({ DenseMatrix })

/**
Expand Down Expand Up @@ -87,7 +87,7 @@ export const createLsolve = /* #__PURE__ */ factory(name, dependencies, ({ typed

// loop rows
for (let i = j + 1; i < rows; i++) {
bdata[i] = [subtract(bdata[i][0] || 0, multiplyScalar(xj, mdata[i][j]))]
bdata[i] = [subtractScalar(bdata[i][0] || 0, multiplyScalar(xj, mdata[i][j]))]
}
} else {
// degenerate row, we can choose any value
Expand Down Expand Up @@ -158,7 +158,7 @@ export const createLsolve = /* #__PURE__ */ factory(name, dependencies, ({ typed

for (let k = 0, l = jIndices.length; k < l; k++) {
const i = jIndices[k]
bdata[i] = [subtract(bdata[i][0] || 0, multiplyScalar(xj, jValues[k]))]
bdata[i] = [subtractScalar(bdata[i][0] || 0, multiplyScalar(xj, jValues[k]))]
}

x[j] = [xj]
Expand Down
12 changes: 6 additions & 6 deletions src/function/algebra/solver/lsolveAll.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ const dependencies = [
'matrix',
'divideScalar',
'multiplyScalar',
'subtract',
'subtractScalar',
'equalScalar',
'DenseMatrix'
]

export const createLsolveAll = /* #__PURE__ */ factory(name, dependencies, ({ typed, matrix, divideScalar, multiplyScalar, subtract, equalScalar, DenseMatrix }) => {
export const createLsolveAll = /* #__PURE__ */ factory(name, dependencies, ({ typed, matrix, divideScalar, multiplyScalar, subtractScalar, equalScalar, DenseMatrix }) => {
const solveValidation = createSolveValidation({ DenseMatrix })

/**
Expand Down Expand Up @@ -82,7 +82,7 @@ export const createLsolveAll = /* #__PURE__ */ factory(name, dependencies, ({ ty

for (let j = i + 1; j < columns; j++) {
// b[j] -= b[i] * M[j,i]
b[j] = subtract(b[j], multiplyScalar(b[i], M[j][i]))
b[j] = subtractScalar(b[j], multiplyScalar(b[i], M[j][i]))
}
} else if (!equalScalar(b[i], 0)) {
// singular row, nonzero RHS
Expand All @@ -103,7 +103,7 @@ export const createLsolveAll = /* #__PURE__ */ factory(name, dependencies, ({ ty
bNew[i] = 1

for (let j = i + 1; j < columns; j++) {
bNew[j] = subtract(bNew[j], M[j][i])
bNew[j] = subtractScalar(bNew[j], M[j][i])
}

B.push(bNew)
Expand Down Expand Up @@ -162,7 +162,7 @@ export const createLsolveAll = /* #__PURE__ */ factory(name, dependencies, ({ ty

for (let j = 0, lastIndex = iIndices.length; j < lastIndex; j++) {
const J = iIndices[j]
b[J] = subtract(b[J], multiplyScalar(b[i], iValues[j]))
b[J] = subtractScalar(b[J], multiplyScalar(b[i], iValues[j]))
}
} else if (!equalScalar(b[i], 0)) {
// singular row, nonzero RHS
Expand All @@ -184,7 +184,7 @@ export const createLsolveAll = /* #__PURE__ */ factory(name, dependencies, ({ ty

for (let j = 0, lastIndex = iIndices.length; j < lastIndex; j++) {
const J = iIndices[j]
bNew[J] = subtract(bNew[J], iValues[j])
bNew[J] = subtractScalar(bNew[J], iValues[j])
}

B.push(bNew)
Expand Down
Loading

0 comments on commit 9f83877

Please sign in to comment.