反向自动微分求解
这是**科学技术大学2020年秋季学期编译原理和技术课程郑启龙班的编译原理上机实验2,要求编写一个 YACC 描述文件,实现反向自动微分求解。详细要求见本仓库中的实验要求。本实现支持x0~x9共10个自变量,可以很方便地扩充至更多自变量。
示例:
输入:
f(x1=2,x2=5):ln(x1)+x1*x2-sin(x2)
输出:
val = 11.6521
f-PDF@x1 = 5.5
f-PDF@x2 = 1.71634
开始
需要安装Flex和Bison,在Ubuntu下可以使用命令
git clone git@git.lug.ustc.edu.cn:axy/RevAutoDiff.git
cd RevAutoDiff/
sudo apt-get install flex bison
执行run.sh
脚本查看作者编写的三个样例
./run.sh
在myinput.txt
中写输入函数后求解
make
./autodiff < myinput.txt
验证
执行脚本run.sh
,得到如下输出:
样例1:f(x1=2,x2=5):ln(x1)+x1*x2-sin(x2)
val = 11.6521
f-PDF@x1 = 5.5
f-PDF@x2 = 1.71634
样例2:f(x1=2,x2=3):exp(sin(x1))+x2^x2+x1*x2^2
val = 47.4826
f-PDF@x1 = 7.96688
f-PDF@x2 = 68.6625
样例3:f(x1=2,x2=3,x3=4,x4=5,x5=6):exp(sin(x1))+x2^x2+x3^2+4^x4+ln(x3*x4)+(cos(ln(2.5*x5)))^2
val = 1073.3
f-PDF@x1 = -1.03312
f-PDF@x2 = 56.6625
f-PDF@x3 = 8.25
f-PDF@x4 = 1419.77
f-PDF@x5 = 0.127074
样例4:f(x1=2,x2=5):x1^2+x1*x2
val = 14
f-PDF@x1 = 9
f-PDF@x2 = 2
在check.c
中手动计算写出微分式,代入数值求解作为验证,手动计算的结果如下:
aa@DESKTOP-AXY:~/cplab2/autodiff$ make
gcc -o check check.c -lm
aa@DESKTOP-AXY:~/cplab2/autodiff$ ./check
样例1:f(x1=2,x2=5):ln(x1)+x1*x2-sin(x2)
手动计算结果:
val = 11.6521
f-PDF@x1 = 5.5
f-PDF@x2 = 1.71634
样例2:f(x1=2,x2=3):exp(sin(x1))+x2^x2+x1*x2^2
手动计算结果:
val = 47.4826
f-PDF@x1 = 7.96688
f-PDF@x2 = 68.6625
样例3:f(x1=2,x2=3,x3=4,x4=5,x5=6):exp(sin(x1))+x2^x2+x3^2+4^x4+ln(x3*x4)+(cos(ln(2.5*x5)))^2
手动计算结果:
val = 1073.3
f-PDF@x1 = -1.03312
f-PDF@x2 = 56.6625
f-PDF@x3 = 8.25
f-PDF@x4 = 1419.77
f-PDF@x5 = 0.127074
样例4:f(x1=2,x2=5):x1^2+x1*x2
手动计算结果:
val = 14
f-PDF@x1 = 9
f-PDF@x2 = 2
参考
- [1] 编译原理-如何使用flex和yacc工具构造一个高级计算器
- [2] Flex and Bison Tutorial
- [3] 自动微分