mirror of
https://github.com/josdejong/mathjs.git
synced 2026-01-18 14:59:29 +00:00
Merge branch 'develop' into feat/migrate-to-webpack-5
This commit is contained in:
commit
211aceecb2
@ -10,6 +10,8 @@
|
||||
errors for larger values, see #2414. Thanks @gwhitney.
|
||||
- Fix #2385: function `rotate` missing in TypeScript definitions.
|
||||
Thanks @DIVYA-19.
|
||||
- Fix #2450: Add BigNumber to parameter type in `math.unit` and add TypeScript
|
||||
types for `Unit.simplify` and `Unit.units` (#2353). Thanks @joshhansen.
|
||||
|
||||
|
||||
# 2022-02-02, version 10.1.1
|
||||
|
||||
@ -76,6 +76,9 @@ export const createHelpClass = /* #__PURE__ */ factory(name, dependencies, ({ pa
|
||||
}
|
||||
desc += '\n'
|
||||
}
|
||||
if (doc.mayThrow && doc.mayThrow.length) {
|
||||
desc += 'Throws: ' + doc.mayThrow.join(', ') + '\n\n'
|
||||
}
|
||||
if (doc.seealso && doc.seealso.length) {
|
||||
desc += 'See also: ' + doc.seealso.join(', ') + '\n'
|
||||
}
|
||||
|
||||
@ -178,6 +178,8 @@ import { sluDocs } from './function/algebra/slu.js'
|
||||
import { leafCountDocs } from './function/algebra/leafCount.js'
|
||||
import { rationalizeDocs } from './function/algebra/rationalize.js'
|
||||
import { simplifyDocs } from './function/algebra/simplify.js'
|
||||
import { simplifyCoreDocs } from './function/algebra/simplifyCore.js'
|
||||
import { resolveDocs } from './function/algebra/resolve.js'
|
||||
import { lupDocs } from './function/algebra/lup.js'
|
||||
import { lsolveDocs } from './function/algebra/lsolve.js'
|
||||
import { lsolveAllDocs } from './function/algebra/lsolveAll.js'
|
||||
@ -329,6 +331,8 @@ export const embeddedDocs = {
|
||||
lusolve: lusolveDocs,
|
||||
leafCount: leafCountDocs,
|
||||
simplify: simplifyDocs,
|
||||
resolve: resolveDocs,
|
||||
simplifyCore: simplifyCoreDocs,
|
||||
rationalize: rationalizeDocs,
|
||||
slu: sluDocs,
|
||||
usolve: usolveDocs,
|
||||
|
||||
20
src/expression/embeddedDocs/function/algebra/resolve.js
Normal file
20
src/expression/embeddedDocs/function/algebra/resolve.js
Normal file
@ -0,0 +1,20 @@
|
||||
export const resolveDocs = {
|
||||
name: 'resolve',
|
||||
category: 'Algebra',
|
||||
syntax: [
|
||||
'resolve(node, scope)'
|
||||
],
|
||||
description: 'Recursively substitute variables in an expression tree.',
|
||||
examples: [
|
||||
'resolve(parse("1 + x"), { x: 7 })',
|
||||
'resolve(parse("size(text)"), { text: "Hello World" })',
|
||||
'resolve(parse("x + y"), { x: parse("3z") })',
|
||||
'resolve(parse("3x"), { x: parse("y+z"), z: parse("w^y") })'
|
||||
],
|
||||
seealso: [
|
||||
'simplify', 'evaluate'
|
||||
],
|
||||
mayThrow: [
|
||||
'ReferenceError'
|
||||
]
|
||||
}
|
||||
@ -14,6 +14,6 @@ export const simplifyDocs = {
|
||||
'simplified.evaluate({x: 2})'
|
||||
],
|
||||
seealso: [
|
||||
'derivative', 'parse', 'evaluate'
|
||||
'simplifyCore', 'derivative', 'evaluate', 'parse', 'rationalize', 'resolve'
|
||||
]
|
||||
}
|
||||
|
||||
15
src/expression/embeddedDocs/function/algebra/simplifyCore.js
Normal file
15
src/expression/embeddedDocs/function/algebra/simplifyCore.js
Normal file
@ -0,0 +1,15 @@
|
||||
export const simplifyCoreDocs = {
|
||||
name: 'simplifyCore',
|
||||
category: 'Algebra',
|
||||
syntax: [
|
||||
'simplifyCore(node)'
|
||||
],
|
||||
description: 'Perform simple one-pass simplifications on an expression tree.',
|
||||
examples: [
|
||||
'simplifyCore(parse("0*x"))',
|
||||
'simplifyCore(parse("(x+0)*2"))'
|
||||
],
|
||||
seealso: [
|
||||
'simplify', 'evaluate'
|
||||
]
|
||||
}
|
||||
@ -243,6 +243,8 @@ export { createCatalan } from './function/combinatorics/catalan.js'
|
||||
export { createComposition } from './function/combinatorics/composition.js'
|
||||
export { createLeafCount } from './function/algebra/leafCount.js'
|
||||
export { createSimplify } from './function/algebra/simplify.js'
|
||||
export { createSimplifyCore } from './function/algebra/simplifyCore.js'
|
||||
export { createResolve } from './function/algebra/resolve.js'
|
||||
export { createDerivative } from './function/algebra/derivative.js'
|
||||
export { createRationalize } from './function/algebra/rationalize.js'
|
||||
export { createReviver } from './json/reviver.js'
|
||||
|
||||
@ -89,7 +89,9 @@ export { createHelp } from './expression/function/help.js'
|
||||
export { createChain } from './type/chain/function/chain.js'
|
||||
|
||||
// algebra
|
||||
export { createResolve } from './function/algebra/resolve.js'
|
||||
export { createSimplify } from './function/algebra/simplify.js'
|
||||
export { createSimplifyCore } from './function/algebra/simplifyCore.js'
|
||||
export { createDerivative } from './function/algebra/derivative.js'
|
||||
export { createRationalize } from './function/algebra/rationalize.js'
|
||||
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
import { isInteger } from '../../utils/number.js'
|
||||
import { factory } from '../../utils/factory.js'
|
||||
import { createSimplifyConstant } from './simplify/simplifyConstant.js'
|
||||
import { createSimplifyCore } from './simplify/simplifyCore.js'
|
||||
|
||||
const name = 'rationalize'
|
||||
const dependencies = [
|
||||
@ -15,6 +14,7 @@ const dependencies = [
|
||||
'divide',
|
||||
'pow',
|
||||
'parse',
|
||||
'simplifyCore',
|
||||
'simplify',
|
||||
'?bignumber',
|
||||
'?fraction',
|
||||
@ -42,6 +42,7 @@ export const createRationalize = /* #__PURE__ */ factory(name, dependencies, ({
|
||||
divide,
|
||||
pow,
|
||||
parse,
|
||||
simplifyCore,
|
||||
simplify,
|
||||
fraction,
|
||||
bignumber,
|
||||
@ -73,24 +74,6 @@ export const createRationalize = /* #__PURE__ */ factory(name, dependencies, ({
|
||||
OperatorNode,
|
||||
SymbolNode
|
||||
})
|
||||
const simplifyCore = createSimplifyCore({
|
||||
equal,
|
||||
isZero,
|
||||
add,
|
||||
subtract,
|
||||
multiply,
|
||||
divide,
|
||||
pow,
|
||||
AccessorNode,
|
||||
ArrayNode,
|
||||
ConstantNode,
|
||||
FunctionNode,
|
||||
IndexNode,
|
||||
ObjectNode,
|
||||
OperatorNode,
|
||||
ParenthesisNode,
|
||||
SymbolNode
|
||||
})
|
||||
|
||||
/**
|
||||
* Transform a rationalizable expression in a rational fraction.
|
||||
|
||||
94
src/function/algebra/resolve.js
Normal file
94
src/function/algebra/resolve.js
Normal file
@ -0,0 +1,94 @@
|
||||
import { createMap, isMap } from '../../utils/map.js'
|
||||
import { isFunctionNode, isNode, isOperatorNode, isParenthesisNode, isSymbolNode } from '../../utils/is.js'
|
||||
import { factory } from '../../utils/factory.js'
|
||||
|
||||
const name = 'resolve'
|
||||
const dependencies = [
|
||||
'parse',
|
||||
'ConstantNode',
|
||||
'FunctionNode',
|
||||
'OperatorNode',
|
||||
'ParenthesisNode'
|
||||
]
|
||||
|
||||
export const createResolve = /* #__PURE__ */ factory(name, dependencies, ({
|
||||
parse,
|
||||
ConstantNode,
|
||||
FunctionNode,
|
||||
OperatorNode,
|
||||
ParenthesisNode
|
||||
}) => {
|
||||
/**
|
||||
* resolve(expr, scope) replaces variable nodes with their scoped values
|
||||
*
|
||||
* Syntax:
|
||||
*
|
||||
* resolve(expr, scope)
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* math.resolve('x + y', {x:1, y:2}) // Node {1 + 2}
|
||||
* math.resolve(math.parse('x+y'), {x:1, y:2}) // Node {1 + 2}
|
||||
* math.simplify('x+y', {x:2, y:'x+x'}).toString() // "6"
|
||||
*
|
||||
* See also:
|
||||
*
|
||||
* simplify, evaluate
|
||||
*
|
||||
* @param {Node} node
|
||||
* The expression tree to be simplified
|
||||
* @param {Object} scope
|
||||
* Scope specifying variables to be resolved
|
||||
* @return {Node} Returns `node` with variables recursively substituted.
|
||||
* @throws {ReferenceError}
|
||||
* If there is a cyclic dependency among the variables in `scope`,
|
||||
* resolution is impossible and a ReferenceError is thrown.
|
||||
*/
|
||||
function resolve (node, scope, within = new Set()) { // note `within`:
|
||||
// `within` is not documented, since it is for internal cycle
|
||||
// detection only
|
||||
if (!scope) {
|
||||
return node
|
||||
}
|
||||
if (!isMap(scope)) {
|
||||
scope = createMap(scope)
|
||||
}
|
||||
if (isSymbolNode(node)) {
|
||||
if (within.has(node.name)) {
|
||||
const variables = Array.from(within).join(', ')
|
||||
throw new ReferenceError(
|
||||
`recursive loop of variable definitions among {${variables}}`
|
||||
)
|
||||
}
|
||||
const value = scope.get(node.name)
|
||||
if (isNode(value)) {
|
||||
const nextWithin = new Set(within)
|
||||
nextWithin.add(node.name)
|
||||
return resolve(value, scope, nextWithin)
|
||||
} else if (typeof value === 'number') {
|
||||
return parse(String(value))
|
||||
} else if (value !== undefined) {
|
||||
return new ConstantNode(value)
|
||||
} else {
|
||||
return node
|
||||
}
|
||||
} else if (isOperatorNode(node)) {
|
||||
const args = node.args.map(function (arg) {
|
||||
return resolve(arg, scope, within)
|
||||
})
|
||||
return new OperatorNode(node.op, node.fn, args, node.implicit)
|
||||
} else if (isParenthesisNode(node)) {
|
||||
return new ParenthesisNode(resolve(node.content, scope, within))
|
||||
} else if (isFunctionNode(node)) {
|
||||
const args = node.args.map(function (arg) {
|
||||
return resolve(arg, scope, within)
|
||||
})
|
||||
return new FunctionNode(node.name, args)
|
||||
}
|
||||
// Otherwise just recursively resolve any children (might also work
|
||||
// for some of the above special cases)
|
||||
return node.map(child => resolve(child, scope, within))
|
||||
}
|
||||
|
||||
return resolve
|
||||
})
|
||||
@ -1,9 +1,7 @@
|
||||
import { isConstantNode, isParenthesisNode } from '../../utils/is.js'
|
||||
import { factory } from '../../utils/factory.js'
|
||||
import { createUtil } from './simplify/util.js'
|
||||
import { createSimplifyCore } from './simplify/simplifyCore.js'
|
||||
import { createSimplifyConstant } from './simplify/simplifyConstant.js'
|
||||
import { createResolve } from './simplify/resolve.js'
|
||||
import { hasOwnProperty } from '../../utils/object.js'
|
||||
import { createEmptyMap, createMap } from '../../utils/map.js'
|
||||
|
||||
@ -19,6 +17,8 @@ const dependencies = [
|
||||
'pow',
|
||||
'isZero',
|
||||
'equal',
|
||||
'resolve',
|
||||
'simplifyCore',
|
||||
'?fraction',
|
||||
'?bignumber',
|
||||
'mathWithTransform',
|
||||
@ -46,6 +46,8 @@ export const createSimplify = /* #__PURE__ */ factory(name, dependencies, (
|
||||
pow,
|
||||
isZero,
|
||||
equal,
|
||||
resolve,
|
||||
simplifyCore,
|
||||
fraction,
|
||||
bignumber,
|
||||
mathWithTransform,
|
||||
@ -77,30 +79,6 @@ export const createSimplify = /* #__PURE__ */ factory(name, dependencies, (
|
||||
OperatorNode,
|
||||
SymbolNode
|
||||
})
|
||||
const simplifyCore = createSimplifyCore({
|
||||
equal,
|
||||
isZero,
|
||||
add,
|
||||
subtract,
|
||||
multiply,
|
||||
divide,
|
||||
pow,
|
||||
AccessorNode,
|
||||
ArrayNode,
|
||||
ConstantNode,
|
||||
FunctionNode,
|
||||
IndexNode,
|
||||
ObjectNode,
|
||||
OperatorNode,
|
||||
ParenthesisNode,
|
||||
SymbolNode
|
||||
})
|
||||
const resolve = createResolve({
|
||||
parse,
|
||||
FunctionNode,
|
||||
OperatorNode,
|
||||
ParenthesisNode
|
||||
})
|
||||
|
||||
const { hasProperty, isCommutative, isAssociative, mergeContext, flatten, unflattenr, unflattenl, createMakeNodeFunction, defaultContext, realContext, positiveContext } =
|
||||
createUtil({ FunctionNode, OperatorNode, SymbolNode })
|
||||
@ -200,7 +178,7 @@ export const createSimplify = /* #__PURE__ */ factory(name, dependencies, (
|
||||
*
|
||||
* See also:
|
||||
*
|
||||
* derivative, parse, evaluate, rationalize
|
||||
* simplifyCore, derivative, evaluate, parse, rationalize, resolve
|
||||
*
|
||||
* @param {Node | string} expr
|
||||
* The expression to be simplified
|
||||
@ -298,8 +276,6 @@ export const createSimplify = /* #__PURE__ */ factory(name, dependencies, (
|
||||
return res
|
||||
}
|
||||
})
|
||||
simplify.simplifyCore = simplifyCore
|
||||
simplify.resolve = resolve
|
||||
simplify.defaultContext = defaultContext
|
||||
simplify.realContext = realContext
|
||||
simplify.positiveContext = positiveContext
|
||||
@ -374,7 +350,7 @@ export const createSimplify = /* #__PURE__ */ factory(name, dependencies, (
|
||||
assuming: { multiply: { commutative: false }, subtract: { total: true } }
|
||||
},
|
||||
{ l: '-(n1/n2)', r: '-n1/n2' },
|
||||
{ l: '-v', r: 'v * (-1)' },
|
||||
{ l: '-v', r: 'v * (-1)' }, // finish making non-constant terms positive
|
||||
{ l: '(n1 + n2)*(-1)', r: 'n1*(-1) + n2*(-1)', repeat: true }, // expand negations to achieve as much sign cancellation as possible
|
||||
{ l: 'n/n1^n2', r: 'n*n1^-n2' }, // temporarily replace 'divide' so we can further flatten the 'multiply' operator
|
||||
{ l: 'n/n1', r: 'n*n1^-1' },
|
||||
@ -387,15 +363,26 @@ export const createSimplify = /* #__PURE__ */ factory(name, dependencies, (
|
||||
assuming: { multiply: { commutative: false } }
|
||||
},
|
||||
|
||||
simplifyConstant,
|
||||
|
||||
// expand nested exponentiation
|
||||
{
|
||||
s: '(n ^ n1) ^ n2 -> n ^ (n1 * n2)',
|
||||
assuming: { divide: { total: true } } // 1/(1/n) = n needs 1/n to exist
|
||||
},
|
||||
|
||||
// collect like factors
|
||||
// collect like factors; into a sum, only do this for nonconstants
|
||||
{ l: ' v * ( v * n1 + n2)', r: 'v^2 * n1 + v * n2' },
|
||||
{
|
||||
s: ' v * (v^n4 * n1 + n2) -> v^(1+n4) * n1 + v * n2',
|
||||
assuming: { divide: { total: true } } // v*1/v = v^(1+-1) needs 1/v
|
||||
},
|
||||
{
|
||||
s: 'v^n3 * ( v * n1 + n2) -> v^(n3+1) * n1 + v^n3 * n2',
|
||||
assuming: { divide: { total: true } }
|
||||
},
|
||||
{
|
||||
s: 'v^n3 * (v^n4 * n1 + n2) -> v^(n3+n4) * n1 + v^n3 * n2',
|
||||
assuming: { divide: { total: true } }
|
||||
},
|
||||
{ l: 'n*n', r: 'n^2' },
|
||||
{
|
||||
s: 'n * n^n1 -> n^(n1+1)',
|
||||
@ -406,6 +393,12 @@ export const createSimplify = /* #__PURE__ */ factory(name, dependencies, (
|
||||
assuming: { divide: { total: true } } // ditto for n^2*1/n^2
|
||||
},
|
||||
|
||||
// Unfortunately, to deal with more complicated cancellations, it
|
||||
// becomes necessary to simplify constants twice per pass. It's not
|
||||
// terribly expensive compared to matching rules, so this should not
|
||||
// pose a performance problem.
|
||||
simplifyConstant, // First: before collecting like terms
|
||||
|
||||
// collect like terms
|
||||
{
|
||||
s: 'n+n -> 2*n',
|
||||
@ -414,6 +407,8 @@ export const createSimplify = /* #__PURE__ */ factory(name, dependencies, (
|
||||
{ l: 'n+-n', r: '0' },
|
||||
{ l: 'v*n + v', r: 'v*(n+1)' }, // NOTE: leftmost position is special:
|
||||
{ l: 'n3*n1 + n3*n2', r: 'n3*(n1+n2)' }, // All sub-monomials tried there.
|
||||
{ l: 'n3^(-n4)*n1 + n3 * n2', r: 'n3^(-n4)*(n1 + n3^(n4+1) *n2)' },
|
||||
{ l: 'n3^(-n4)*n1 + n3^n5 * n2', r: 'n3^(-n4)*(n1 + n3^(n4+n5)*n2)' },
|
||||
{
|
||||
s: 'n*v + v -> (n+1)*v', // noncommutative additional cases
|
||||
assuming: { multiply: { commutative: false } }
|
||||
@ -422,12 +417,22 @@ export const createSimplify = /* #__PURE__ */ factory(name, dependencies, (
|
||||
s: 'n1*n3 + n2*n3 -> (n1+n2)*n3',
|
||||
assuming: { multiply: { commutative: false } }
|
||||
},
|
||||
{
|
||||
s: 'n1*n3^(-n4) + n2 * n3 -> (n1 + n2*n3^(n4 + 1))*n3^(-n4)',
|
||||
assuming: { multiply: { commutative: false } }
|
||||
},
|
||||
{
|
||||
s: 'n1*n3^(-n4) + n2 * n3^n5 -> (n1 + n2*n3^(n4 + n5))*n3^(-n4)',
|
||||
assuming: { multiply: { commutative: false } }
|
||||
},
|
||||
{ l: 'n*c + c', r: '(n+1)*c' },
|
||||
{
|
||||
s: 'c*n + c -> c*(n+1)',
|
||||
assuming: { multiply: { commutative: false } }
|
||||
},
|
||||
|
||||
simplifyConstant, // Second: before returning expressions to "standard form"
|
||||
|
||||
// make factors positive (and undo 'make non-constant terms positive')
|
||||
{
|
||||
s: '(-n)*n1 -> -(n*n1)',
|
||||
@ -462,10 +467,10 @@ export const createSimplify = /* #__PURE__ */ factory(name, dependencies, (
|
||||
assuming: { multiply: { commutative: true } } // o.w. / not conventional
|
||||
},
|
||||
{
|
||||
s: 'n1^-1 -> 1/n1',
|
||||
s: 'n^-1 -> 1/n',
|
||||
assuming: { multiply: { commutative: true } } // o.w. / not conventional
|
||||
},
|
||||
|
||||
{ l: 'n^1', r: 'n' }, // can be produced by power cancellation
|
||||
{
|
||||
s: 'n*(n1/n2) -> (n*n1)/n2', // '*' before '/'
|
||||
assuming: { multiply: { associative: true } }
|
||||
|
||||
@ -1,67 +0,0 @@
|
||||
import { createMap, isMap } from '../../../utils/map.js'
|
||||
import { isFunctionNode, isNode, isOperatorNode, isParenthesisNode, isSymbolNode } from '../../../utils/is.js'
|
||||
import { factory } from '../../../utils/factory.js'
|
||||
|
||||
const name = 'resolve'
|
||||
const dependencies = [
|
||||
'parse',
|
||||
'FunctionNode',
|
||||
'OperatorNode',
|
||||
'ParenthesisNode'
|
||||
]
|
||||
|
||||
export const createResolve = /* #__PURE__ */ factory(name, dependencies, ({
|
||||
parse,
|
||||
FunctionNode,
|
||||
OperatorNode,
|
||||
ParenthesisNode
|
||||
}) => {
|
||||
/**
|
||||
* resolve(expr, scope) replaces variable nodes with their scoped values
|
||||
*
|
||||
* Syntax:
|
||||
*
|
||||
* simplify.resolve(expr, scope)
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* math.simplify.resolve('x + y', {x:1, y:2}) // Node {1 + 2}
|
||||
* math.simplify.resolve(math.parse('x+y'), {x:1, y:2}) // Node {1 + 2}
|
||||
* math.simplify('x+y', {x:2, y:'x+x'}).toString() // "6"
|
||||
*
|
||||
* @param {Node} node
|
||||
* The expression tree to be simplified
|
||||
* @param {Object} scope with variables to be resolved
|
||||
*/
|
||||
function resolve (node, scope) {
|
||||
if (!scope) {
|
||||
return node
|
||||
}
|
||||
if (!isMap(scope)) {
|
||||
scope = createMap(scope)
|
||||
}
|
||||
if (isSymbolNode(node)) {
|
||||
const value = scope.get(node.name)
|
||||
if (isNode(value)) {
|
||||
return resolve(value, scope)
|
||||
} else if (typeof value === 'number') {
|
||||
return parse(String(value))
|
||||
}
|
||||
} else if (isOperatorNode(node)) {
|
||||
const args = node.args.map(function (arg) {
|
||||
return resolve(arg, scope)
|
||||
})
|
||||
return new OperatorNode(node.op, node.fn, args, node.implicit)
|
||||
} else if (isParenthesisNode(node)) {
|
||||
return new ParenthesisNode(resolve(node.content, scope))
|
||||
} else if (isFunctionNode(node)) {
|
||||
const args = node.args.map(function (arg) {
|
||||
return resolve(arg, scope)
|
||||
})
|
||||
return new FunctionNode(node.name, args)
|
||||
}
|
||||
return node
|
||||
}
|
||||
|
||||
return resolve
|
||||
})
|
||||
@ -1,6 +1,6 @@
|
||||
import { isAccessorNode, isArrayNode, isConstantNode, isFunctionNode, isIndexNode, isObjectNode, isOperatorNode } from '../../../utils/is.js'
|
||||
import { createUtil } from './util.js'
|
||||
import { factory } from '../../../utils/factory.js'
|
||||
import { isAccessorNode, isArrayNode, isConstantNode, isFunctionNode, isIndexNode, isObjectNode, isOperatorNode } from '../../utils/is.js'
|
||||
import { createUtil } from './simplify/util.js'
|
||||
import { factory } from '../../utils/factory.js'
|
||||
|
||||
const name = 'simplifyCore'
|
||||
const dependencies = [
|
||||
@ -53,22 +53,23 @@ export const createSimplifyCore = /* #__PURE__ */ factory(name, dependencies, ({
|
||||
*
|
||||
* Syntax:
|
||||
*
|
||||
* simplify.simplifyCore(expr)
|
||||
* simplifyCore(expr)
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* const f = math.parse('2 * 1 * x ^ (2 - 1)')
|
||||
* math.simplify.simpifyCore(f) // Node {2 * x}
|
||||
* math.simplify('2 * 1 * x ^ (2 - 1)', [math.simplify.simpifyCore]) // Node {2 * x}
|
||||
* math.simpifyCore(f) // Node {2 * x}
|
||||
* math.simplify('2 * 1 * x ^ (2 - 1)', [math.simplifyCore]) // Node {2 * x}
|
||||
*
|
||||
* See also:
|
||||
*
|
||||
* derivative
|
||||
* simplify, resolve, derivative
|
||||
*
|
||||
* @param {Node} node
|
||||
* The expression to be simplified
|
||||
* @param {Object} options
|
||||
* Simplification options, as per simplify()
|
||||
* @return {Node} Returns expression with basic simplifications applied
|
||||
*/
|
||||
function simplifyCore (node, options) {
|
||||
const context = options ? options.context : undefined
|
||||
64
test/unit-tests/function/algebra/resolve.test.js
Normal file
64
test/unit-tests/function/algebra/resolve.test.js
Normal file
@ -0,0 +1,64 @@
|
||||
// test resolve
|
||||
import assert from 'assert'
|
||||
|
||||
import math from '../../../../src/defaultInstance.js'
|
||||
|
||||
import { simplifyAndCompare } from './simplify.test.js'
|
||||
|
||||
describe('resolve', function () {
|
||||
it('should substitute scoped constants', function () {
|
||||
const sumxy = math.parse('x+y')
|
||||
const collapsingScope = { x: math.parse('y'), y: math.parse('z') }
|
||||
assert.strictEqual(
|
||||
math.resolve(sumxy, { x: 1 }).toString(),
|
||||
'1 + y'
|
||||
) // direct
|
||||
assert.strictEqual(
|
||||
math.resolve(sumxy, collapsingScope).toString(),
|
||||
'z + z'
|
||||
)
|
||||
assert.strictEqual(
|
||||
math.resolve(
|
||||
math.parse('[x,y,1,w]'), collapsingScope).toString(),
|
||||
'[z, z, 1, w]'
|
||||
)
|
||||
simplifyAndCompare('x+y', 'x+y', {}) // operator
|
||||
simplifyAndCompare('x+y', 'y+1', { x: 1 })
|
||||
simplifyAndCompare('x+y', 'y+1', { x: math.parse('1') })
|
||||
simplifyAndCompare('x+y', '3', { x: 1, y: 2 })
|
||||
simplifyAndCompare('x+x+x', '3*x')
|
||||
simplifyAndCompare('y', 'x+1', { y: math.parse('1+x') })
|
||||
simplifyAndCompare('y', '3', { x: 2, y: math.parse('1+x') })
|
||||
simplifyAndCompare('x+y', '3*x', { y: math.parse('x+x') })
|
||||
simplifyAndCompare('x+y', '6', { x: 2, y: math.parse('x+x') })
|
||||
simplifyAndCompare('x+(y+2-1-1)', '6', { x: 2, y: math.parse('x+x') }) // parentheses
|
||||
simplifyAndCompare('log(x+y)', String(Math.log(6)), { x: 2, y: math.parse('x+x') }) // function
|
||||
simplifyAndCompare('combinations( ceil(abs(sin(x)) * (y+3)), abs(x) )',
|
||||
'combinations(ceil(0.9092974268256817 * (y + 3) ), 2)', { x: -2 })
|
||||
|
||||
simplifyAndCompare('size(text)[1]', '11', { text: 'hello world' })
|
||||
})
|
||||
|
||||
it('should substitute scoped constants from Map like scopes', function () {
|
||||
assert.strictEqual(
|
||||
math.resolve(math.parse('x+y'), new Map([['x', 1]])).toString(), '1 + y'
|
||||
) // direct
|
||||
simplifyAndCompare('x+y', 'x+y', new Map()) // operator
|
||||
simplifyAndCompare('x+y', 'y+1', new Map([['x', 1]]))
|
||||
simplifyAndCompare('x+y', 'y+1', new Map([['x', math.parse('1')]]))
|
||||
})
|
||||
|
||||
it('should throw an error in case of reference loop', function () {
|
||||
const sumxy = math.parse('x+y')
|
||||
assert.throws(
|
||||
() => math.resolve(sumxy, { x: math.parse('x') }),
|
||||
/ReferenceError.*\{x\}/)
|
||||
assert.throws(
|
||||
() => math.resolve(sumxy, {
|
||||
y: math.parse('3z'),
|
||||
z: math.parse('1-x'),
|
||||
x: math.parse('cos(y)')
|
||||
}),
|
||||
/ReferenceError.*\{x, y, z\}/)
|
||||
})
|
||||
})
|
||||
@ -3,44 +3,44 @@ import assert from 'assert'
|
||||
|
||||
import math from '../../../../src/defaultInstance.js'
|
||||
|
||||
describe('simplify', function () {
|
||||
const expLibrary = []
|
||||
function simplifyAndCompare (left, right, rules, scope, opt, stringOpt) {
|
||||
expLibrary.push(left)
|
||||
let simpLeft
|
||||
try {
|
||||
if (Array.isArray(rules)) {
|
||||
if (opt) {
|
||||
simpLeft = math.simplify(left, rules, scope, opt)
|
||||
} else if (scope) {
|
||||
simpLeft = math.simplify(left, rules, scope)
|
||||
} else {
|
||||
simpLeft = math.simplify(left, rules)
|
||||
}
|
||||
const expLibrary = []
|
||||
export function simplifyAndCompare (left, right, rules, scope, opt, stringOpt) {
|
||||
expLibrary.push(left)
|
||||
let simpLeft
|
||||
try {
|
||||
if (Array.isArray(rules)) {
|
||||
if (opt) {
|
||||
simpLeft = math.simplify(left, rules, scope, opt)
|
||||
} else if (scope) {
|
||||
simpLeft = math.simplify(left, rules, scope)
|
||||
} else {
|
||||
if (opt) stringOpt = opt
|
||||
if (scope) opt = scope
|
||||
if (rules) scope = rules
|
||||
if (opt) {
|
||||
simpLeft = math.simplify(left, scope, opt)
|
||||
} else if (scope) {
|
||||
simpLeft = math.simplify(left, scope)
|
||||
} else {
|
||||
simpLeft = math.simplify(left)
|
||||
}
|
||||
simpLeft = math.simplify(left, rules)
|
||||
}
|
||||
} catch (err) {
|
||||
if (err instanceof Error) {
|
||||
console.log(err.stack)
|
||||
} else {
|
||||
if (opt) stringOpt = opt
|
||||
if (scope) opt = scope
|
||||
if (rules) scope = rules
|
||||
if (opt) {
|
||||
simpLeft = math.simplify(left, scope, opt)
|
||||
} else if (scope) {
|
||||
simpLeft = math.simplify(left, scope)
|
||||
} else {
|
||||
console.log(new Error(err))
|
||||
simpLeft = math.simplify(left)
|
||||
}
|
||||
throw err
|
||||
}
|
||||
assert.strictEqual(
|
||||
simpLeft.toString(stringOpt), math.parse(right).toString(stringOpt))
|
||||
} catch (err) {
|
||||
if (err instanceof Error) {
|
||||
console.log(err.stack)
|
||||
} else {
|
||||
console.log(new Error(err))
|
||||
}
|
||||
throw err
|
||||
}
|
||||
assert.strictEqual(
|
||||
simpLeft.toString(stringOpt), math.parse(right).toString(stringOpt))
|
||||
}
|
||||
|
||||
describe('simplify', function () {
|
||||
function simplifyAndCompareEval (left, right, scope) {
|
||||
expLibrary.push(left)
|
||||
scope = scope || {}
|
||||
@ -101,65 +101,13 @@ describe('simplify', function () {
|
||||
const f = new math.FunctionAssignmentNode('sigma', ['x'], math.parse('1 / (1 + exp(-x))'))
|
||||
assert.strictEqual(f.toString(), 'sigma(x) = 1 / (1 + exp(-x))')
|
||||
assert.strictEqual(f.evaluate()(5), 0.9933071490757153)
|
||||
const fsimplified = math.simplify.simplifyCore(f)
|
||||
const fsimplified = math.simplifyCore(f)
|
||||
assert.strictEqual(fsimplified.toString(), 'sigma(x) = 1 / (1 + exp(-x))')
|
||||
assert.strictEqual(fsimplified.evaluate()(5), 0.9933071490757153)
|
||||
})
|
||||
|
||||
const testSimplifyCore = function (expr, expected, opts = {}) {
|
||||
const actual = math.simplify.simplifyCore(math.parse(expr)).toString(opts)
|
||||
assert.strictEqual(actual, expected)
|
||||
}
|
||||
|
||||
it('simplifyCore should handle different node types', function () {
|
||||
testSimplifyCore('5*x*3', '15 * x')
|
||||
testSimplifyCore('5*x*3*x', '15 * x * x')
|
||||
|
||||
testSimplifyCore('x-0', 'x')
|
||||
testSimplifyCore('0-x', '-x')
|
||||
testSimplifyCore('0-3', '-3')
|
||||
testSimplifyCore('x+0', 'x')
|
||||
testSimplifyCore('0+x', 'x')
|
||||
testSimplifyCore('0*x', '0')
|
||||
testSimplifyCore('x*0', '0')
|
||||
testSimplifyCore('x*1', 'x')
|
||||
testSimplifyCore('1*x', 'x')
|
||||
testSimplifyCore('-(x)', '-x')
|
||||
testSimplifyCore('0/x', '0')
|
||||
testSimplifyCore('(1*x + y*0)*1+0', 'x')
|
||||
testSimplifyCore('sin(x+0)*1', 'sin(x)')
|
||||
testSimplifyCore('((x+0)*1)', 'x')
|
||||
testSimplifyCore('sin((x-0)*1+y*0)', 'sin(x)')
|
||||
testSimplifyCore('[x+0,1*y,z*0]', '[x, y, 0]')
|
||||
testSimplifyCore('(a+b+0)[n*0+1,-(n)]', '(a + b)[1, -n]')
|
||||
testSimplifyCore('{a:x*1, b:y-0}', '{"a": x, "b": y}')
|
||||
})
|
||||
|
||||
it('simplifyCore strips ParenthesisNodes (implicit in tree)', function () {
|
||||
testSimplifyCore('((x)*(y))', 'x * y')
|
||||
testSimplifyCore('((x)*(y))^1', 'x * y')
|
||||
testSimplifyCore('x*(y+z)', 'x * (y + z)')
|
||||
testSimplifyCore('x+(y+z)+w', 'x + y + z + w')
|
||||
// But it doesn't actually change the association internally:
|
||||
testSimplifyCore('x+ y+z +w', '((x + y) + z) + w', { parenthesis: 'all' })
|
||||
testSimplifyCore('x+(y+z)+w', '(x + (y + z)) + w', { parenthesis: 'all' })
|
||||
})
|
||||
|
||||
it('simplifyCore folds constants', function () {
|
||||
testSimplifyCore('1+2', '3')
|
||||
testSimplifyCore('2*3', '6')
|
||||
testSimplifyCore('2-3', '-1')
|
||||
testSimplifyCore('3/2', '1.5')
|
||||
testSimplifyCore('3^2', '9')
|
||||
})
|
||||
|
||||
it('should simplifyCore convert +unaryMinus to subtract', function () {
|
||||
simplifyAndCompareEval('--2', '2')
|
||||
const result = math.simplify('x + y + a', [math.simplify.simplifyCore], { a: -1 }).toString()
|
||||
assert.strictEqual(result, 'x + y - 1')
|
||||
})
|
||||
|
||||
it('should simplify convert minus and unary minus', function () {
|
||||
simplifyAndCompareEval('--2', '2')
|
||||
// see https://github.com/josdejong/mathjs/issues/1013
|
||||
assert.strictEqual(math.simplify('0 - -1', {}).toString(), '1')
|
||||
assert.strictEqual(math.simplify('0 - -x', {}).toString(), 'x')
|
||||
@ -171,10 +119,10 @@ describe('simplify', function () {
|
||||
})
|
||||
|
||||
it('should simplify inside arrays and indexing', function () {
|
||||
simplifyAndCompare('[3x+0]', '[3x]') // simplifyCore inside array
|
||||
simplifyAndCompare('[3x+0]', '[3x]')
|
||||
simplifyAndCompare('[3x+5x]', '[8*x]')
|
||||
simplifyAndCompare('[2*3,6+2]', '[6,8]')
|
||||
simplifyAndCompare('[x^0,y*0,z*1,w-0][2+n*1]', '[1,0,z,w][n+2]') // simplifyCore in index
|
||||
simplifyAndCompare('[x^0,y*0,z*1,w-0][2+n*1]', '[1,0,z,w][n+2]')
|
||||
simplifyAndCompare('[x,y-2y,z,w+w][(3-2)*n+2]', '[x,-y,z,2*w][n+2]')
|
||||
})
|
||||
|
||||
@ -212,7 +160,7 @@ describe('simplify', function () {
|
||||
const f = new math.FunctionNode(new math.SymbolNode('doubleIt'), [new math.SymbolNode('value')])
|
||||
assert.strictEqual(f.toString(), 'doubleIt(value)')
|
||||
assert.strictEqual(f.evaluate({ doubleIt: doubleIt, value: 4 }), 8)
|
||||
const fsimplified = math.simplify.simplifyCore(f)
|
||||
const fsimplified = math.simplifyCore(f)
|
||||
assert.strictEqual(fsimplified.toString(), 'doubleIt(value)')
|
||||
assert.strictEqual(fsimplified.evaluate({ doubleIt: doubleIt, value: 4 }), 8)
|
||||
})
|
||||
@ -222,7 +170,7 @@ describe('simplify', function () {
|
||||
const f = new math.FunctionNode(s, [new math.SymbolNode('x')])
|
||||
assert.strictEqual(f.toString(), '(sigma(x) = 1 / (1 + exp(-x)))(x)')
|
||||
assert.strictEqual(f.evaluate({ x: 5 }), 0.9933071490757153)
|
||||
const fsimplified = math.simplify.simplifyCore(f)
|
||||
const fsimplified = math.simplifyCore(f)
|
||||
assert.strictEqual(fsimplified.toString(), '(sigma(x) = 1 / (1 + exp(-x)))(x)')
|
||||
assert.strictEqual(fsimplified.evaluate({ x: 5 }), 0.9933071490757153)
|
||||
})
|
||||
@ -232,11 +180,11 @@ describe('simplify', function () {
|
||||
simplifyAndCompare('2 - 3', '-1')
|
||||
simplifyAndCompare('2 - -3', '5')
|
||||
let e = math.parse('2 - -3')
|
||||
e = math.simplify.simplifyCore(e)
|
||||
e = math.simplifyCore(e)
|
||||
assert.strictEqual(e.toString(), '5') // simplifyCore
|
||||
simplifyAndCompare('x - -x', '2*x')
|
||||
e = math.parse('x - -x')
|
||||
e = math.simplify.simplifyCore(e)
|
||||
e = math.simplifyCore(e)
|
||||
assert.strictEqual(e.toString(), 'x + x') // not a core simplification since + is cheaper than *
|
||||
})
|
||||
|
||||
@ -301,6 +249,13 @@ describe('simplify', function () {
|
||||
simplifyAndCompare('x - (y - (y - x))', '0')
|
||||
simplifyAndCompare('5 + (5 * x) - (3 * x) + 2', '2*x+7')
|
||||
simplifyAndCompare('x^2*y^2 - (x*y)^2', '0')
|
||||
simplifyAndCompare('(x*z^2 + y*z)/z^4', '(y + z*x)/z^3') // #1423
|
||||
simplifyAndCompare('(x^2*y + z*y)/y^4', '(x^2 + z)/y^3')
|
||||
simplifyAndCompare('6x/3x', '2') // Additional cases from PR review
|
||||
simplifyAndCompare('-28y/-4y', '7')
|
||||
simplifyAndCompare('-28*(z/-4z)', '7')
|
||||
simplifyAndCompare('(x^2 + 2x)*x', '2*x^2 + x^3')
|
||||
simplifyAndCompare('x + y/z', 'x + y/z') // avoid overzealous '(x+y*z)/z'
|
||||
})
|
||||
|
||||
it('should collect separated like factors', function () {
|
||||
@ -415,38 +370,6 @@ describe('simplify', function () {
|
||||
simplifyAndCompare('x-(y-y+x)', '0', {}, optsNAANCM)
|
||||
})
|
||||
|
||||
it('resolve() should substitute scoped constants', function () {
|
||||
assert.strictEqual(
|
||||
math.simplify.resolve(math.parse('x+y'), { x: 1 }).toString(),
|
||||
'1 + y'
|
||||
) // direct
|
||||
simplifyAndCompare('x+y', 'x+y', {}) // operator
|
||||
simplifyAndCompare('x+y', 'y+1', { x: 1 })
|
||||
simplifyAndCompare('x+y', 'y+1', { x: math.parse('1') })
|
||||
simplifyAndCompare('x+y', '3', { x: 1, y: 2 })
|
||||
simplifyAndCompare('x+x+x', '3*x')
|
||||
simplifyAndCompare('y', 'x+1', { y: math.parse('1+x') })
|
||||
simplifyAndCompare('y', '3', { x: 2, y: math.parse('1+x') })
|
||||
simplifyAndCompare('x+y', '3*x', { y: math.parse('x+x') })
|
||||
simplifyAndCompare('x+y', '6', { x: 2, y: math.parse('x+x') })
|
||||
simplifyAndCompare('x+(y+2-1-1)', '6', { x: 2, y: math.parse('x+x') }) // parentheses
|
||||
simplifyAndCompare('log(x+y)', String(Math.log(6)), { x: 2, y: math.parse('x+x') }) // function
|
||||
simplifyAndCompare('combinations( ceil(abs(sin(x)) * (y+3)), abs(x) )',
|
||||
'combinations(ceil(0.9092974268256817 * (y + 3) ), 2)', { x: -2 })
|
||||
|
||||
// TODO(deal with accessor nodes) simplifyAndCompare('size(text)[1]', '11', {text: "hello world"})
|
||||
})
|
||||
|
||||
it('resolve() should substitute scoped constants from Map like scopes', function () {
|
||||
assert.strictEqual(
|
||||
math.simplify.resolve(math.parse('x+y'), new Map([['x', 1]])).toString(),
|
||||
'1 + y'
|
||||
) // direct
|
||||
simplifyAndCompare('x+y', 'x+y', new Map()) // operator
|
||||
simplifyAndCompare('x+y', 'y+1', new Map([['x', 1]]))
|
||||
simplifyAndCompare('x+y', 'y+1', new Map([['x', math.parse('1')]]))
|
||||
})
|
||||
|
||||
it('should keep implicit multiplication implicit', function () {
|
||||
const f = math.parse('2x')
|
||||
assert.strictEqual(f.toString({ implicit: 'hide' }), '2 x')
|
||||
|
||||
60
test/unit-tests/function/algebra/simplifyCore.test.js
Normal file
60
test/unit-tests/function/algebra/simplifyCore.test.js
Normal file
@ -0,0 +1,60 @@
|
||||
// test simplifyCore
|
||||
import assert from 'assert'
|
||||
|
||||
import math from '../../../../src/defaultInstance.js'
|
||||
|
||||
describe('simplifyCore', function () {
|
||||
const testSimplifyCore = function (expr, expected, opts = {}) {
|
||||
const actual = math.simplifyCore(math.parse(expr)).toString(opts)
|
||||
assert.strictEqual(actual, expected)
|
||||
}
|
||||
|
||||
it('should handle different node types', function () {
|
||||
testSimplifyCore('5*x*3', '15 * x')
|
||||
testSimplifyCore('5*x*3*x', '15 * x * x')
|
||||
|
||||
testSimplifyCore('x-0', 'x')
|
||||
testSimplifyCore('0-x', '-x')
|
||||
testSimplifyCore('0-3', '-3')
|
||||
testSimplifyCore('x+0', 'x')
|
||||
testSimplifyCore('0+x', 'x')
|
||||
testSimplifyCore('0*x', '0')
|
||||
testSimplifyCore('x*0', '0')
|
||||
testSimplifyCore('x*1', 'x')
|
||||
testSimplifyCore('1*x', 'x')
|
||||
testSimplifyCore('-(x)', '-x')
|
||||
testSimplifyCore('0/x', '0')
|
||||
testSimplifyCore('(1*x + y*0)*1+0', 'x')
|
||||
testSimplifyCore('sin(x+0)*1', 'sin(x)')
|
||||
testSimplifyCore('((x+0)*1)', 'x')
|
||||
testSimplifyCore('sin((x-0)*1+y*0)', 'sin(x)')
|
||||
testSimplifyCore('[x+0,1*y,z*0]', '[x, y, 0]')
|
||||
testSimplifyCore('(a+b+0)[n*0+1,-(n)]', '(a + b)[1, -n]')
|
||||
testSimplifyCore('{a:x*1, b:y-0}', '{"a": x, "b": y}')
|
||||
})
|
||||
|
||||
it('strips ParenthesisNodes (implicit in tree)', function () {
|
||||
testSimplifyCore('((x)*(y))', 'x * y')
|
||||
testSimplifyCore('((x)*(y))^1', 'x * y')
|
||||
testSimplifyCore('x*(y+z)', 'x * (y + z)')
|
||||
testSimplifyCore('x+(y+z)+w', 'x + y + z + w')
|
||||
// But it doesn't actually change the association internally:
|
||||
testSimplifyCore('x+ y+z +w', '((x + y) + z) + w', { parenthesis: 'all' })
|
||||
testSimplifyCore('x+(y+z)+w', '(x + (y + z)) + w', { parenthesis: 'all' })
|
||||
})
|
||||
|
||||
it('folds constants', function () {
|
||||
testSimplifyCore('1+2', '3')
|
||||
testSimplifyCore('2*3', '6')
|
||||
testSimplifyCore('2-3', '-1')
|
||||
testSimplifyCore('3/2', '1.5')
|
||||
testSimplifyCore('3^2', '9')
|
||||
})
|
||||
|
||||
it('should convert +unaryMinus to subtract', function () {
|
||||
const result = math.simplify(
|
||||
'x + y + a', [math.simplifyCore], { a: -1 }
|
||||
).toString()
|
||||
assert.strictEqual(result, 'x + y - 1')
|
||||
})
|
||||
})
|
||||
@ -282,6 +282,34 @@ function generateDoc (name, code) {
|
||||
return count > 0
|
||||
}
|
||||
|
||||
function parseThrows () {
|
||||
let count = 0
|
||||
let match
|
||||
do {
|
||||
match = /\s*@throws\s*\{(.*)}\s*(.*)?$/.exec(line)
|
||||
if (match) {
|
||||
next()
|
||||
|
||||
count++
|
||||
const annotation = {
|
||||
description: (match[2] || '').trim(),
|
||||
type: (match[1] || '').trim()
|
||||
}
|
||||
doc.mayThrow.push(annotation)
|
||||
|
||||
// multi line description (must be non-empty and not start with @param or @return)
|
||||
while (exists() && !empty() && !/^\s*@/.test(line)) {
|
||||
const lineTrim = line.trim()
|
||||
const separator = (lineTrim[0] === '-' ? '</br>' : ' ')
|
||||
annotation.description += separator + lineTrim
|
||||
next()
|
||||
}
|
||||
}
|
||||
} while (match)
|
||||
|
||||
return count > 0
|
||||
}
|
||||
|
||||
function parseReturns () {
|
||||
const match = /\s*@returns?\s*\{(.*)}\s*(.*)?$/.exec(line)
|
||||
if (match) {
|
||||
@ -312,7 +340,8 @@ function generateDoc (name, code) {
|
||||
examples: [],
|
||||
seeAlso: [],
|
||||
parameters: [],
|
||||
returns: null
|
||||
returns: null,
|
||||
mayThrow: []
|
||||
}
|
||||
|
||||
next()
|
||||
@ -327,7 +356,8 @@ function generateDoc (name, code) {
|
||||
parseExamples() ||
|
||||
parseSeeAlso() ||
|
||||
parseParameters() ||
|
||||
parseReturns()
|
||||
parseReturns() ||
|
||||
parseThrows()
|
||||
|
||||
if (!handled) {
|
||||
// skip this line, no one knows what to do with it
|
||||
@ -384,6 +414,15 @@ function validateDoc (doc) {
|
||||
}
|
||||
}
|
||||
|
||||
if (doc.mayThrow && doc.mayThrow.length) {
|
||||
doc.mayThrow.forEach(function (err, index) {
|
||||
if (!err.type) {
|
||||
issues.push(
|
||||
'function "' + doc.name + '": error type missing for throw ' + index)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
if (doc.returns) {
|
||||
if (!doc.returns.description || !doc.returns.description.trim()) {
|
||||
issues.push('function "' + doc.name + '": description missing of returns')
|
||||
@ -453,6 +492,16 @@ function generateMarkdown (doc, functions) {
|
||||
'\n\n\n'
|
||||
}
|
||||
|
||||
if (doc.mayThrow) {
|
||||
text += '### Throws\n\n' +
|
||||
'Type | Description\n' +
|
||||
'---- | -----------\n' +
|
||||
doc.mayThrow.map(function (t) {
|
||||
return (t.type || '') + ' | ' + t.description
|
||||
}).join('\n') +
|
||||
'\n\n'
|
||||
}
|
||||
|
||||
if (doc.examples && doc.examples.length) {
|
||||
text += '## Examples\n\n' +
|
||||
'```js\n' +
|
||||
|
||||
33
types/index.d.ts
vendored
33
types/index.d.ts
vendored
@ -575,7 +575,7 @@ declare namespace math {
|
||||
* @param unit The unit to be created
|
||||
* @returns The created unit
|
||||
*/
|
||||
unit(value: number | MathArray | Matrix, unit: string): Unit;
|
||||
unit(value: number | MathArray | Matrix | BigNumber, unit: string): Unit;
|
||||
|
||||
/*************************************************************************
|
||||
* Expression functions
|
||||
@ -1796,7 +1796,7 @@ declare namespace math {
|
||||
* @param n A real or complex number
|
||||
* @returns The gamma of n
|
||||
*/
|
||||
gamma(n: number | MathArray | Matrix): number | MathArray | Matrix;
|
||||
gamma<T extends number | BigNumber | Complex | MathArray | Matrix>(n: T): NoLiteralType<T>;
|
||||
|
||||
/**
|
||||
* Calculate the Kullback-Leibler (KL) divergence between two
|
||||
@ -3134,6 +3134,28 @@ declare namespace math {
|
||||
fixPrefix?: boolean;
|
||||
}
|
||||
|
||||
interface UnitComponent {
|
||||
power: number;
|
||||
prefix: string;
|
||||
unit: {
|
||||
name: string;
|
||||
base: {
|
||||
dimensions: number[];
|
||||
key: string;
|
||||
};
|
||||
prefixes: Record<string, UnitPrefix>;
|
||||
value: number;
|
||||
offset: number;
|
||||
dimensions: number[];
|
||||
};
|
||||
}
|
||||
|
||||
interface UnitPrefix {
|
||||
name: string;
|
||||
value: number;
|
||||
scientific: boolean;
|
||||
}
|
||||
|
||||
interface Unit {
|
||||
valueOf(): string;
|
||||
clone(): Unit;
|
||||
@ -3152,7 +3174,14 @@ declare namespace math {
|
||||
toJSON(): MathJSON;
|
||||
formatUnits(): string;
|
||||
format(options: FormatOptions): string;
|
||||
simplify(): Unit;
|
||||
splitUnit(parts: ReadonlyArray<string | Unit>): Unit[];
|
||||
|
||||
units: UnitComponent[];
|
||||
dimensions: number[];
|
||||
value: number;
|
||||
fixPrefix: boolean;
|
||||
skipAutomaticSimplification: true;
|
||||
}
|
||||
|
||||
interface CreateUnitOptions {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user