代数 (符号计算) #
math.js 内置支持符号计算 (CAS)。它可以将表达式解析为表达式树,并对树执行简化和求导等代数运算。
值得一提的是 math.js 的一个优秀扩展:mathsteps,这是一个专注于教学(如何更好地教学)的循序渐进的数学解算器库。它侧重的数学问题是预代数和代数问题,涉及简化表达式。
简化 #
函数 math.simplify 简化表达式树
// simplify an expression
console.log(math.simplify('3 + 2 / 4').toString()) // '7 / 2'
console.log(math.simplify('2x + 3x').toString()) // '5 * x'
console.log(math.simplify('x^2 + x + 3 + x^2').toString()) // '2 * x ^ 2 + x + 3'
console.log(math.simplify('x * y * -x / (x ^ 2)').toString()) // '-y'
该函数接受字符串或表达式树(Node)作为输入,并输出一个简化的表达式树(Node)。此节点树可以按照 表达式树 页面的详细说明进行转换和求值。
// work with an expression tree, evaluate results
const f = math.parse('2x + x')
const simplified = math.simplify(f)
console.log(simplified.toString()) // '3 * x'
console.log(simplified.evaluate({x: 4})) // 12
在其执行的其他操作中,在表达式上调用 simplify() 会将任何具有运算符等效项的函数转换为其运算符形式。
console.log(math.simplify('multiply(x,3)').toString) // '3 * x'
请注意,simplify 有一个可选参数 scope,它允许指定表达式中变量的定义(作为数值或进一步的表达式)并在简化中使用。例如,继续之前的示例,
console.log(math.simplify(f, {x: 4}).toString()) // 12
console.log(math.simplify(f, {x: math.parse('y+z')}).toString()) // '3*(y+z)'
总的来说,简化是一个固有困难的问题;事实上,对于某些类别的表达式和代数等价性,无法判断给定表达式是否等价于零。此外,简化通常取决于所涉及运算的性质;由于乘法(例如)根据考虑的域可能具有不同的性质(例如,它可能可以交换,也可能不可以交换),因此可能适用不同的简化。
因此,simplify() 有一个额外的可选参数 options,它控制其行为。此参数是一个对象,用于指定关于简化过程的各种属性。有关完整列表,请参阅 详细文档,但目前最重要的两个属性如下。请注意,只有当 scope 也存在时,才能指定 options 参数。
exactFractions- 一个布尔值,指定非整数数值常数在可能时是否应简化为有理数(true),或者始终转换为十进制表示法(false)。context- 一个对象,其键是运算的名称(“add”、“multiply”等),其值指定相应运算的代数属性(目前可以是“total”、“trivial”、“commutative”和“associative”)。只有当所依赖的属性在给定上下文中为 true 时,才会执行简化。例如,const expr = math.parse('x*y-y*x') console.log(math.simplify(expr).toString()) // 0; * is commutative by default console.log(math.simplify(expr, {}, {context: {multiply: {commutative: false}}})) // 'x*y-y*x'; the order of the right multiplication can't be reversed.
请注意,默认上下文非常宽松(允许许多简化),但也存在 math.simplify.realContext,它只允许保证在所有实数上保留表达式值的简化。
const rational = math.parse('(x-1)*x/(x-1)')
console.log(math.simplify(expr, {}, {context: math.simplify.realContext})
// '(x-1)*x/(x-1)'; canceling the 'x-1' makes the expression defined at 1
有关表达式简化理论的更多详细信息,请参阅
求导 #
函数 math.derivative 查找表达式的符号导数
// calculate a derivative
console.log(math.derivative('2x^2 + 3x + 4', 'x').toString()) // '4 * x + 3'
console.log(math.derivative('sin(2x)', 'x').toString()) // '2 * cos(2 * x)'
与函数 math.simplify 类似,math.derivative 接受字符串或表达式树(Node)作为输入,并输出一个简化的表达式树(Node)。
// work with an expression tree, evaluate results
const h = math.parse('x^2 + x')
const x = math.parse('x')
const dh = math.derivative(h, x)
console.log(dh.toString()) // '2 * x + 1'
console.log(dh.evaluate({x: 3})) // '7'
由 math.derivative 使用的规则可以在 Wikipedia 上找到。
有理化 #
函数 math.rationalize 将可有理化表达式转换为有理分数。如果分数是一个单变量多项式,则将其分子和分母转换为标准形式,指数递减,并返回分子系数。
math.rationalize('2x/y - y/(x+1)')
// (2*x^2-y^2+2*x)/(x*y+y)
math.rationalize('(2x+1)^6')
// 64*x^6+192*x^5+240*x^4+160*x^3+60*x^2+12*x+1
math.rationalize('2x/( (2x-1) / (3x+2) ) - 5x/ ( (3x+4) / (2x^2-5) ) + 3')
// -20*x^4+28*x^3+104*x^2+6*x-12)/(6*x^2+5*x-4)
math.rationalize('x+x+x+y',{y:1}) // 3*x+1
math.rationalize('x+x+x+y',{}) // 3*x+y
const ret = math.rationalize('x+x+x+y',{},true)
// ret.expression=3*x+y, ret.variables = ["x","y"]
const ret = math.rationalize('-2+5x^2',{},true)
// ret.expression=5*x^2-2, ret.variables = ["x"], ret.coefficients=[-2,0,5]