【摘要】 如何用F#对数学公式进行不定积分(x^3)-x => (0.25*x^4)-(0.5*x^2)
前面一篇博文,介绍了F#对数学表达式进行求导运算,这里再介绍一下如何用F#对数学表达式求积分。求符号积分比求导要复杂一点,其复杂不在于原理,而在于求导的规则少,而求积分的规则非常多,要想相对全面的涵盖是比较难的。
这里只是探索一个求积分的思路,而不会实现一个功能完备的积分引擎。首先还是定义一个数据类型:
type Expr =
| CstF of float
| Var of string
| Add of Expr * Expr // +
| Sub of Expr * Expr // -
| Mul of Expr * Expr // *
| Div of Expr * Expr // /
| Pow of Expr * Expr // ^
| Sin of Expr
| Cos of Expr
| Neg of Expr
再次,给出一个包含少数积分规则的求积分函数:
let rec intf e =
match e with
|CstF f -> Mul(CstF f, Var "x")
|Var x -> Mul(CstF 0.5, Pow(Var x,CstF 2.))
|Add(e1, e2) -> Add(intf e1, intf e2)
|Sub(e1, e2) -> Sub(intf e1, intf e2)
|Pow(Var x,CstF a) -> Mul(CstF (1./(a+1.)),Pow(Var x,CstF (a + 1.)))
|e -> e
这里主要就是最后一条,即 x ^ a 求积分为 x^(a+1)/(a+1) 。同样的,给出DSL字符串输出的函数:
let rec printExpr2 e =
match e with
| CstF f -> string f
| Var x -> x
| Add(e1 , e2) -> "(" + (printExpr2 e1) + "+" + (printExpr2 e2) + ")"
| Sub(e1 , e2) -> "(" + (printExpr2 e1) + "-" + (printExpr2 e2) + ")"
| Mul(e1 , e2) -> "(" + (printExpr2 e1) + "*" + (printExpr2 e2) + ")"
| Div(e1 , e2) -> "(" + (printExpr2 e1) + "/" + (printExpr2 e2) + ")"
| Pow(e1 , e2) -> "(" + (printExpr2 e1) + "^" + (printExpr2 e2) + ")"
| Sin(e1) -> "sin(" + (printExpr2 e1) + ")"
| Cos(e1) -> "cos(" + (printExpr2 e1) + ")"
| Neg(e1) -> "-(" + (printExpr2 e1) + ")"
| _ -> failwith "unknown operation";;
最后,计算一下数学公式(x^3)-x的积分值:
let e1 = Sub(Pow(Var "x", CstF 3.0), Var "x");;
printExpr2 e1 + " => " + printExpr2 (intf e1) ;;
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END