衍生计算器

时间:2010-05-25 14:20:33

标签: math calculator derivative differentiation

我对构建衍生计算器很感兴趣。我已经绞尽脑汁解决问题,但我还没有找到合适的解决方案。你可以提示如何开始吗?感谢

对不起!我显然想要进行象征性的区分。

假设你有函数f(x)= x ^ 3 + 2x ^ 2 + x

我想显示导数,在这种情况下f'(x)= 3x ^ 2 + 4x + 1

我想在iPhone的objective-c中实现它。

6 个答案:

答案 0 :(得分:6)

我假设您正试图找到函数的确切导数。 (符号分化)

您需要解析数学表达式并将函数中的各个操作存储在树结构中。

例如,x + sin²(x)将存储为+操作,应用于x的表达式^以及sin(x)的{​​{1}}(取幂)操作2

然后,您可以通过将差异规则应用于每个节点来递归地区分树。例如,+节点将成为u' + v'*节点将成为uv' + vu'

答案 1 :(得分:4)

你需要记住你的微积分。基本上你需要两件事:基本函数的导数表和如何推导复合表达式的规则(如d(f + g)/dx = df/dx + dg/dx)。然后取表达式解析器并递归地转到其他树。 (http://www.sosmath.com/tables/derivative/derivative.html

答案 2 :(得分:4)

将你的字符串解析成S-expression(即使这通常是在Lisp上下文中,你可以用几乎任何语言做同样的事情),最简单的lex / yacc或等价,然后写一个递归“推导出“功能。在OCaml-ish方言中,有类似的东西:

let rec derive var = function
    | Const(_) -> Const(0)
    | Var(x) -> if x = var then Const(1) else Deriv(Var(x), Var(var))
    | Add(x, y) -> Add(derive var x, derive var y)
    | Mul(a, b) -> Add(Mul(a, derive var b), Mul(derive var a, b))
    ...

(如果您不知道OCaml语法 - derive是双参数递归函数,第一个参数是变量名,第二个参数是连续行;例如,如果此参数是结构表单Add(x, y)的形式,返回从两个字段构建的结构Add,其值为派生x和派生y;类似于derive的其他情况可能会收到参数;第一种模式中的_表示“匹配任何内容”)

在此之后你可能有一些清理功能来整理结果表达式(减少分数等)但这变得复杂,并且对于派生本身不是必需的(即没有它你得到的仍然是正确的答案)

当你完成对s-exp的转换时,将结果s-exp重新转换为字符串形式,再次使用递归函数

答案 3 :(得分:2)

SLaks已经描述了符号区分的程序。我只想补充几点:

  • 符号数学主要是解析和树转换。 ANTLR对两者都是一个很好的工具。我建议从这本伟大的书Language implementation patterns
  • 开始
  • 有开源程序可以满足您的需求(例如Maxima)。解剖这样的程序也可能很有意思(但是如果你自己先尝试自己编写,可能更容易理解发生了什么)。
  • 可能您还需要对输出进行某种简化。例如,仅将基本衍生规则应用于表达式2 * x将产生2 + 0*x。这也可以通过树处理来完成(例如,通过将0 * [...]转换为0[...] + 0转换为[...]等等)

答案 4 :(得分:1)

您想要计算衍生品的操作类型?如果你允许三角函数,如正弦,余弦和正切,这些可能最好存储在一个表中,而其他像多项式可能更容易做到。您是否允许函数具有多个输入,例如。 f(x,y)而不仅仅是f(x)?

单个变量中的多项式将是我的建议,然后考虑添加三角函数,对数函数,指数函数和其他高级函数来计算可能更难做的衍生函数。

答案 5 :(得分:1)

对常见函数(+, - ,*,/,^,sin,cos等)的符号区分,忽略函数或其派生未定义的区域很容易。很难,也许是违反直觉的,后来简化了结果。

要进行区分,请将操作存储在树中(或者甚至只用波兰表示法),并制作每个基本操作的派生表。然后重复应用链规则和基本导数,并将常数的导数设置为0.这很容易实现。