【F#从入门到实战】10. F#表达式积分
【摘要】 如何用F#对数学公式进行不定积分(x^3)-x => (0.25*x^4)-(0.5*x^2)
欢迎大家来到【F#从入门到实战】,在这里我将分享关于F#编程语言的系列文章,带大家一起去学习和成长,并探索函数编程语言F#这个有趣的世界。所有文章都会结合示例代码和笔者的经验进行讲解,真心想把十余年的IT经验分享给大家,希望对您有所帮助,文章中也定有不足之处,请海涵!本系统文章将从F#基本语法入手,逐步通过自定义类型来实现数学表达式的各种常见解析操作,如对表达式进行求值、化简、展开、求导和求积分等。此系统博文也是了解和实现一个简易的计算机代数系统的基础。
下面给出【F#从入门到实战】系统专题文章的目录:
【F#从入门到实战】01. F#语言快速入门
【F#从入门到实战】02. F#数组常见用法
【F#从入门到实战】03. F#自定义操作符
【F#从入门到实战】04. F#5.0新特征总结
【F#从入门到实战】05. F#表达式求值
【F#从入门到实战】06. F#表达式化简
【F#从入门到实战】07. F#表达式展开
【F#从入门到实战】08. F#大整数阶乘
【F#从入门到实战】09. F#表达式求导
【F#从入门到实战】10. F#表达式积分
【F#从入门到实战】11. F#库FParsec入门
【F#从入门到实战】12. F#库FParsec解析表达式
【F#从入门到实战】13. F#库FParsec实现求导符号计算
【F#从入门到实战】14. F#实现分部积分法
下面将正式开始本文的介绍:
前面一篇博文,介绍了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) ;;
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
作者其他文章
评论(0)