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

相关文章
|
机器学习/深度学习
表达式求解
#include#include#include #define EOFILE '&' typedef char SElemType; #include "stack.h"Status visit(SElemType * e){  printf("%c", *e);} char OP[10]...
816 0
F#表达式化简
如果使用过Matlab或者Maple等软件,应该知道这类数学软件的符号计算引擎非常强大,可以进行数学公式的推导,比如可以对数学公式进行化简。当然,实现一个功能完备的化简引擎还是不容易的。这里用F# 实现一个简单的化简函数: ( a + x )+( a - x ) => 2 * a
927 0
F#表达式化简
|
8月前
|
机器学习/深度学习
函数求导
本文概述了高等数学中函数求导的基本规则,包括常数、幂函数、求和、乘积、商、复合函数、指数函数及三角函数的导数。这些规则是微积分的基础,用于求解各种函数的导数。例如,常数的导数是0,$(x^n)' = n \cdot x^{n-1}$,$(e^x)' = e^x$,$\frac{d}{dx}\sin(x) = \cos(x)$。更复杂的函数可能需要使用隐函数或参数方程求导等高级技术。
250 1
|
9月前
|
存储 Serverless C语言
『C/C++』Eg3:多项式求值
『C/C++』Eg3:多项式求值
|
9月前
|
测试技术
【动态规划】【字符串】【表达式】2019. 解出数学表达式的学生分数
【动态规划】【字符串】【表达式】2019. 解出数学表达式的学生分数
|
算法
数据结构实践——用二叉树求解代数表达式
本文是针对数据结构基础系列(6):树和二叉树的配套实践。 【项目 - 用二叉树求解代数表达式】   用二叉树来表示代数表达式,树的每一个分支节点代表一个运算符,每一个叶子节点代表一个运算数(为简化,只支持二目运算的+、-、*、/,不加括号,运算数也只是一位的数字字符。本项目只考虑输入合乎以上规则的情况)。请设计算法,(1)根据形如“1+2∗3−4/5 1+2*3-4/5”
1992 0
|
JavaScript 关系型数据库 Linux
三元表达式,列表解析和生成器表达式
三元表达式 在以前,在诸如比较两个数大小的时候,通常的写法都是下面的样子 if x > y: print("the max is x") else: print("the max is y") 三元表达式的语法为: True if expression else False 现在可以...
1223 0
|
存储 机器学习/深度学习 人工智能
最佳加法表达式
最佳加法表达式 总时间限制: 1000ms 内存限制: 65536kB 描述 给定n个1到9的数字,要求在数字之间摆放m个加号(加号两边必须有数字),使得所得到的加法表达式的值最小,并输出该值。例如,在1234中摆放1个加号,最好的摆法就是12+34,和为36 输入 有不超过15组数据每组数据两行。
1202 0

热门文章

最新文章