衍生产品计算器
我对构建衍生产品计算器感兴趣。我绞尽脑汁解决问题,但我还没有找到一个合适的解决方案。可能你有一个提示如何开始?谢谢衍生产品计算器
对不起!我显然想要做出象征性的区分。
比方说,你有函数f(x)= X^3 + 2X^2 + X
我想要显示的衍生,在这种情况下,F'(x)= 3倍^ 2 + 4X + 1
我想在Objective-C中为iPhone实现它。
我假设你试图找到函数的确切导数。 (符号区分)
您需要解析数学表达式并将各个操作存储在树结构中的函数中。
例如,x + sin²(x)
将被存储为+
操作中,施加到表达x
和sin(x)
和2
一个^
(幂)操作。
然后,您可以通过对每个节点应用区分规则来递归地区分树。例如,+
节点将变为u' + v'
,并且*
节点将变为uv' + vu'
。
你需要记住你的微积分。基本上你需要两件事:基本函数的派生表和如何派生复合表达式的规则(如d(f + g)/dx = df/dx + dg/dx
)。然后取表达式解析器并递归地转到其他树上。 (http://www.sosmath.com/tables/derivative/derivative.html)
对于您想要计算导数的操作有哪些?如果允许正弦,余弦和正切等三角函数,这些函数最好存储在一个表中,而其他类似多项式的函数可能更容易完成。你是否允许函数有多个输入,例如: f(x,y)而不仅仅是f(x)?
单变量中的多项式是我的建议,然后考虑添加三角函数,对数函数,指数函数和其他高级函数来计算可能难以实现的导数。
只需一个变量f(x)。 – burki 2010-05-26 11:06:42
解析你的字符串转换为S-expression(即使这通常采取在Lisp的背景下,你可以做一个等价的事情在几乎任何语言),最简单的使用lex/yacc的或等效的,然后写一个递归“导出”功能。在OCaml的上下的话,这样的事情:
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
有两个参数递归函数,与第一个参数变量名,并在连续行第二被mathched ;在第一_
;例如,如果该参数为形式Add(x, y)
的结构,返回由两场内置结构Add
,与衍生x
的价值和衍生y
;同样地,对于什么derive
可能会收到作为参数其他案件图案意味着“匹配任何东西”)
Afte这可能会有一些清理功能来清理结果表达式(减少分数等)。),但这会变得复杂,而且对于派生本身并不是必需的(即,如果没有它,它仍然是一个正确的答案)。
当您的S-EXP改造完成后,用递归函数
F#太美了 – erikkallen 2010-06-01 19:00:11
SLaks已经描述的程序符号微分重新转换所得的S-EXP成字符串的形式,再次。我只想添加几件事情:
- 符号数学主要是解析和树转换。 ANTLR是一个很好的工具。我建议从这本好书开始Language implementation patterns
- 有一些开源软件可以做你想做的事(例如Maxima)。解剖这样一个程序也许很有趣(但是如果你试图自己写这个程序,可能会更容易理解)
- 也许你也需要对输出进行某种简化。例如,仅将基本派生规则应用于表达式
2 * x
将产生2 + 0*x
。 (例如,通过转化0 * [...]
到0
和[...] + 0
到[...]
等),这也可以通过树处理完成
了常用功能(+,符号微分 - ,*,/,^,正弦,余弦等)忽略函数或其派生未定义的区域很容易。可能违反直觉的是,后来简化结果很困难。
为了进行区分,将操作存储在树中(甚至只是用波兰语表示),并制作每个基本操作的派生表。然后重复应用链式法则和基本导数,并将常数的导数设置为0.这很快且容易实现。
你究竟想要做什么?符号分化? – SLaks 2010-05-25 14:23:58
金融或数学? – 2010-05-25 14:25:49
数值微分是微不足道的。符号绝对是棘手的,但如果你不需要简化输出,那么它很容易实现。 – 2010-05-25 14:44:28