实现基本的数学表达式简化

时间:2014-03-21 13:52:05

标签: javascript math derivative recursive-descent simplification

我正在为我的calc类开发一个侧面项目,它区分Javascript中的y=x^2之类的简单函数。为此,我将表达式解析为抽象语法树,然后硬编码衍生规则,如产品规则和链规则。

唯一可以解决的问题是AP微积分/第一年的微积分问题,所以三角形,日志,指数都在发挥作用

我的程序很好地采用了衍生工具,但我最终得到的是以一种荒谬的简单方式编写的函数。

例如,区分x^2会给出(2*(x^(2-1))),这在技术上是正确的,但可以写成2 * x更容易。到目前为止,我有一个基本的简化器,基本上重复分析树,并应用一些基本规则。

我的一般程序是用递归下降来分析它。

如果当前树没有变量,请对其进行评估并用结果替换当前节点。

否则,应用大量的if语句来简化它。这包括像

这样的东西
  • 如果您乘以零,请将表达式替换为零
  • 如果乘以1,则将表达式替换为另一个操作数
  • 如果您正在升力为零,请将表达式替换为一个。

依此类推。如果我真的希望得到任何真正的简化,比如组合类似术语,这将很快失控。另外,如果我想确定任何两个表达式是否相同,我的最佳解决方案是简单地在函数域中生成随机数,并查看它们是否相等。然而,这似乎不是很有效。

如何更有效地确定两个不同表达式的相等性(一个简单的例子是x+22+x),有没有一种方法可以在没有大量if语句的情况下简化函数? / p>

2 个答案:

答案 0 :(得分:0)

我实际上在开发一个使用二叉树的计算机代数系统。它有一个比较函数,用于确定两个表达式(树)在数学上是否相等,以便对它们进行分解。例如:

  • sin(x + 1)+ sin(1 + x)= 2 * sin(x + 1)
  • sin(x-1)和sin(1-x)无法添加
  • x + x ^ 2 = x *(1 + x)

算法如下:

每个节点都有一个边(左边或右边)。搜索树中的每个操作符,如果它是+或*,则子项的各个方面都不重要。但是如果操作员是/,^或 - 孩子们的身边很重要。在分工中,谁在分子中,谁在分母中。因此,使用此算法,x + 2将等于2 + x。

抱歉我的英语不好:P

答案 1 :(得分:0)

我会在

的一系列步骤中解决这个问题
  1. 将所有多项式节点写入"规范"办法
    • 例如,通过使用词典顺序和度数对其单项式进行排序(以便1 + x始终表示为x + 1等)
  2. 将所有有理节点写入"规范"办法
    • 有理表达式是两个多项式的商,所以你在这里使用1。
  3. 列出每个特定功能的身份列表
    • 例如,ln(xy) = ln(x) + ln(y)
  4. 列出一系列注入能力减少量
    • 例如sin x = sin y当且仅当x = y + 2*k*Pi表示某个整数值为kln(x) = ln(y) iff x = y等等。
  5. 这些只是为了帮助您入门的一些想法。该项目雄心勃勃。