F#表达式求导

简介: 用F#实现一个简单的表达式求导推理: diff(sin(x^3-x)) => cos(x^3-x) * (3*x^2-1)

     Matlab可以对数学公式进行求导操作,这里用F#实现一个简单的表达式求导推理。首先还是定义一个自定义的Expr数据类型:

typeExpr=|CstFoffloat|Varofstring|AddofExpr*Expr// +|SubofExpr*Expr// -|MulofExpr*Expr// *|DivofExpr*Expr// / |PowofExpr*Expr// ^ |SinofExpr|CosofExpr|NegofExpr

  定义一个递归的求导函数diff,由于求导的规则比较多,这里就简单的实现几个场景的求导公式:

letrecdiffe=matchewith|CstFf->CstF0.0|Varx->CstF1.0|Add(CstFa, Varx)   ->CstF1.0|Add(e1, e2)  ->Add(diffe1, diffe2)
|Sub(e1, e2)  ->Sub(diffe1, diffe2)
|Mul(CstFa, Varx) ->CstFa|Mul(e1, e2) ->Mul(diffe1, diffe2)
|Pow(Varx,CstFa) ->Mul(CstFa,Pow(Varx,CstF (a-1.)))
|Pow(e1,e2)  ->Mul(e2,Pow(e1, Sub(e2,CstF1.)))
|Sin(e1)  ->Mul(Cos(e1),diffe1)
|Cos(e1)  ->Mul(Neg(Sin(e1)),diffe1)
|Neg(e1)  ->Neg(diffe1)
|e->e ;;

  为了更到的输出DSL到控制台,定义一个打印表达式的函数:

letrecprintExpr2e=matchewith|CstFf->stringf|Varx->x|Add(e1 , e2) ->"("+ (printExpr2e1) +"+"+ (printExpr2e2) +")"|Sub(e1 , e2) ->"("+ (printExpr2e1) +"-"+ (printExpr2e2) +")"|Mul(e1 , e2) ->"("+ (printExpr2e1) +"*"+ (printExpr2e2) +")"|Div(e1 , e2) ->"("+ (printExpr2e1) +"/"+ (printExpr2e2) +")"|Pow(e1 , e2) ->"("+ (printExpr2e1) +"^"+ (printExpr2e2) +")"|Sin(e1) ->"sin("+ (printExpr2e1) +")"|Cos(e1) ->"cos("+ (printExpr2e1) +")"|Neg(e1) ->"-("+ (printExpr2e1) +")"|_->failwith"unknown operation";;

   严格来讲,每个操作的前后用()进行分组应该更加严谨,但是过多的()嵌套会让数学表达式不容易理解。但,关于括号的嵌套化简问题,还需要一定的工作才能工作,这里先不进行处理。下面定义一个求导示例:

lete1=Sin(Sub(Pow(Var"x", CstF3.0), Var"x")) ;; 
lete2=diffe1;;
printExpr2e2;;

 执行如上代码,则输出如下图所示:

1628574321590046518.jpg

这与网上的求导工具(https://zh.numberempire.com/derivativecalculator.php)求出的一致:

1628574321590046518.jpg

相关文章
|
JSON Java 数据格式
【Java反序列化】@JsonAlias字段别名
 @JsonAlias 是 Jackson 库提供的一个注解,用于在反序列化 JSON 数据时,为字段或方法指定多个可接受的名称或别名。
1594 0
|
存储 Oracle Java
大厂(转转、携程、京东)都用分代ZGC,卡顿降低20倍,吞吐量提升4倍。分代ZGC 这么牛?底层原理是什么?
大厂(转转、携程、京东)都用分代ZGC,卡顿降低20倍,吞吐量提升4倍。分代ZGC 这么牛?底层原理是什么?
|
监控 Java 编译器
Java虚拟机调优指南####
本文深入探讨了Java虚拟机(JVM)调优的精髓,从内存管理、垃圾回收到性能监控等多个维度出发,为开发者提供了一系列实用的调优策略。通过优化配置与参数调整,旨在帮助读者提升Java应用的运行效率和稳定性,确保其在高并发、大数据量场景下依然能够保持高效运作。 ####
384 58
|
存储 缓存 Java
Java性能优化: 如何减少Java程序的内存占用?
Java性能优化: 如何减少Java程序的内存占用?
2169 2
|
Java 程序员 API
Android|集成 slf4j + logback 作为日志框架
做个简单改造,统一 Android APP 和 Java 后端项目打印日志的体验。
910 1
|
存储 算法 安全
JVM从入门到入土之详解G1垃圾回收器
前言 文本已收录至我的GitHub仓库,欢迎Star:https://github.com/bin392328206/six-finger
814 0
|
安全 Java API
Java 8 流库的魔法革命:Filter、Map、FlatMap 和 Optional 如何颠覆编程世界!
【8月更文挑战第29天】Java 8 的 Stream API 通过 Filter、Map、FlatMap 和 Optional 等操作,提供了高效、简洁的数据集合处理方式。Filter 用于筛选符合条件的元素;Map 对元素进行转换;FlatMap 将多个流扁平化合并;Optional 安全处理空值。这些操作结合使用,能够显著提升代码的可读性和简洁性,使数据处理更为高效和便捷。
637 0
|
安全 Java 编译器
JDK8到JDK21版本升级的新特性问题之JDK17重要的新特性有哪些
JDK8到JDK21版本升级的新特性问题之JDK17重要的新特性有哪些
|
存储 Java
软件体系结构 - 垃圾收集器(1)分代ZGC
【4月更文挑战第22天】软件体系结构 - 垃圾收集器(1)分代ZGC
512 2
|
XML 存储 JSON
(十二)探索高性能通信与RPC框架基石:Json、ProtoBuf、Hessian序列化详解
如今这个分布式风靡的时代,网络通信技术,是每位技术人员必须掌握的技能,因为无论是哪种分布式技术,都离不开心跳、选举、节点感知、数据同步……等机制,而究其根本,这些技术的本质都是网络间的数据交互。正因如此,想要构建一个高性能的分布式组件/系统,不得不思考一个问题:怎么才能让数据传输的速度更快?
1063 1