我对构建衍生计算器很感兴趣。我已经绞尽脑汁解决问题,但我还没有找到合适的解决方案。你可以提示如何开始吗?感谢
对不起!我显然想要进行象征性的区分。
假设你有函数f(x)= x ^ 3 + 2x ^ 2 + x
我想显示导数,在这种情况下f'(x)= 3x ^ 2 + 4x + 1
我想在iPhone的objective-c中实现它。
答案 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已经描述了符号区分的程序。我只想补充几点:
2 * x
将产生2 + 0*x
。这也可以通过树处理来完成(例如,通过将0 * [...]
转换为0
和[...] + 0
转换为[...]
等等)答案 4 :(得分:1)
您想要计算衍生品的操作类型?如果你允许三角函数,如正弦,余弦和正切,这些可能最好存储在一个表中,而其他像多项式可能更容易做到。您是否允许函数具有多个输入,例如。 f(x,y)而不仅仅是f(x)?
单个变量中的多项式将是我的建议,然后考虑添加三角函数,对数函数,指数函数和其他高级函数来计算可能更难做的衍生函数。
答案 5 :(得分:1)
对常见函数(+, - ,*,/,^,sin,cos等)的符号区分,忽略函数或其派生未定义的区域很容易。很难,也许是违反直觉的,后来简化了结果。
要进行区分,请将操作存储在树中(或者甚至只用波兰表示法),并制作每个基本操作的派生表。然后重复应用链规则和基本导数,并将常数的导数设置为0.这很容易实现。