(一)R 计算微积分
1.1差分
x=1:12
diff(x) #向量差分 后面一个数减去前面一个数
## [1] 1 1 1 1 1 1 1 1 1 1 1
z=matrix(x,3,4)
z
## [,1] [,2] [,3] [,4]
## [1,] 1 4 7 10
## [2,] 2 5 8 11
## [3,] 3 6 9 12
diff(z) #矩阵差分 前行减去后行
## [,1] [,2] [,3] [,4]
## [1,] 1 1 1 1
## [2,] 1 1 1 1
1.2 符号计算–微分
1.2.1求一元函数导数— \(\sin{x}\) 的一阶导数为: \(\cos{x}\)
在R里,声明表达式对象使用 expression() 函数, 计算一阶导数用D()函数,格式:D(表达式,对谁求导)
fun=expression(sin(x))# 声明表达式
D(fun,"x")#---方法1
## cos(x)
deriv(fun,"x")#---方法2 其中.grad[, "x"]为求x的导数表达式
## expression({
## .value <- sin(x)
## .grad <- array(0, c(length(.value), 1L), list(NULL, c("x")))
## .grad[, "x"] <- cos(x)
## attr(.value, "gradient") <- .grad
## .value
## })
deriv3(fun,"x")#---方法3 其中.grad[, "x"]为求x的导数表达式
## expression({
## .expr1 <- sin(x)
## .value <- .expr1
## .grad <- array(0, c(length(.value), 1L), list(NULL, c("x")))
## .hessian <- array(0, c(length(.value), 1L, 1L), list(NULL,
## c("x"), c("x")))
## .grad[, "x"] <- cos(x)
## .hessian[, "x", "x"] <- -.expr1
## attr(.value, "gradient") <- .grad
## attr(.value, "hessian") <- .hessian
## .value
## })
1.2.2 计算n阶导数
计算n阶导数—方法一: 结合一阶导数写递归函数
函数: \(\sin{x}+\cos{2x}+x^2+xy+y^2+2x^3+y^3\) 的3阶导数为:\(12 + 8\sin{2x} -\cos{x}\)
fun=expression(sin(x)+cos(2*x)+x^2+x*y+y^2+2*x^3+y^3)
DD <- function(expr, name, order = 1) {
if (order < 1)
stop("'order' must be >= 1")
if (order == 1){
D(expr, name)
}else{
DD(D(expr, name), name, order - 1)
}
}
DD(fun,"x",3)
## 2 * (3 * 2) - (cos(x) - sin(2 * x) * 2 * 2 * 2)
- 计算n阶导数—方法二: Deriv 包中Simplify()化简表达式
library(Deriv)
DD(fun,"x",3)
## 2 * (3 * 2) - (cos(x) - sin(2 * x) * 2 * 2 * 2)
Simplify(DD(fun, "x", 3))
## 12 + 8 * sin(2 * x) - cos(x)
1.2.3 通过函数计算导数
有时候我们有的就是函数,这怎么计算导数呢?—还是用上面的函数
f=function(x,y)sin(x)+cos(2*x)+x^2+x*y+y^2+2*x^3+y^3 #这里是函数,而不是表达式
body(f)
## sin(x) + cos(2 * x) + x^2 + x * y + y^2 + 2 * x^3 + y^3
Simplify(D(body(f), "x"))# 注意:函数体有花括号{}会出错
## cos(x) + x * (2 + 6 * x) + y - 2 * sin(2 * x)
1.2.4 求二元函数偏导数及梯度
D(expression(x^2+x*y+y^2),"x")# x偏导数
## 2 * x + y
D(expression(x^2+x*y+y^2),"y")# y偏导数
## x + 2 * y
1.2.5 符号计算扩展包 Ryacas
想要做更多的符号计算内容,如解方程,泰勒展开等,可以借助第三方 R 扩展包 Ryacas
解方程: \(\frac{x}{1+x}=a\) 求解\(x=\frac{a}{1-a}\)
library(Ryacas)
ysym("Solve(x/(1+x) == a, x)")
## {x==a/(1-a)}
多项式展开:如\((1+x)^3\) 展开
ysym(expression(Expand((1 + x)^3)))# 把(1+x)^3展开
## y: x^3+3*x^2+3*x+1
求解常微分方程:\(y''=4y\)
ysym("OdeSolve(y''== 4 * y)")
## y: C105*Exp(2*x)+C109*Exp((-2)*x)
泰勒展开:\(\cos{x}=1-\frac{1}{2!}x^2+\frac{1}{4!}x^4+o(x^4)\)
ysym("Taylor(x, a, 3) cos(x)") # cos(x)函数在a点的3阶泰勒展开
## y: cos(a)+(Deriv(a)cos(a))*(x-a)+((x-a)^2*(Deriv(a)Deriv(a)cos(a)))/2+((x-a)^3*(Deriv(a)Deriv(a)Deriv(a)cos(a)))/6
1.3 表达式转为函数值
很多时候我们使用 R 目的是计算,符号计算后希望可以直接代入计算,那么只需要在 deriv 中指定 function.arg 参数为 TRUE。 \[ \sin{x}+\cos{2x}+x^2+xy+y^2对x求偏导为:\cos{x}-2sin{2x}+2x+y \]
fun=expression(sin(x)+cos(2*x)+x^2+x*y+y^2)
dx=D(fun,"x") #用D()函数得到符号运算结果,然后代入数值即可得到最后结果
dx
## cos(x) - sin(2 * x) * 2 + 2 * x + y
x=0;y=pi# 对x、y赋值
eval(dx)#求出数值解
## [1] 4.141593
Dfun=deriv(fun,c("x","y"),function.arg = TRUE)# 同时对x、y求偏导--D()函数不可以同时求偏导
Dfun(x=0,y=pi/2) # 代值计算,其中attr(,"gradient")的值为导数值 ,另一个为原函数在该处的函数值
## [1] 3.467401
## attr(,"gradient")
## x y
## [1,] 2.570796 3.141593
#我们可以作如下简单验证:
fun=function(x,y){sin(x)+cos(2*x)+x^2+x*y+y^2}
fun(x=0,y=pi/2)
## [1] 3.467401
1.3、求积分—暂时只找到数值计算的–没找到符号计算的
积分函数: integrate(fun,a,b)
fun被积函数,不需要表达式,因为这是数值计算, a,b为上下限
f <- function (x) sin(x)
integrate(f,0,pi/2)
## 1 with absolute error < 1.1e-14
有些时候只想要值输入 integrate(f,0,1)$value
integrate(f,0,pi/2)$value
## [1] 1
sessionInfo()
## R version 4.0.2 (2020-06-22)
## Platform: x86_64-apple-darwin17.0 (64-bit)
## Running under: macOS Mojave 10.14.5
##
## Matrix products: default
## BLAS: /Library/Frameworks/R.framework/Versions/4.0/Resources/lib/libRblas.dylib
## LAPACK: /Library/Frameworks/R.framework/Versions/4.0/Resources/lib/libRlapack.dylib
##
## locale:
## [1] zh_CN.UTF-8/zh_CN.UTF-8/zh_CN.UTF-8/C/zh_CN.UTF-8/zh_CN.UTF-8
##
## attached base packages:
## [1] stats graphics grDevices utils datasets methods base
##
## other attached packages:
## [1] Ryacas_1.1.3 Deriv_4.0.1
##
## loaded via a namespace (and not attached):
## [1] Rcpp_1.0.5 bookdown_0.20 rprojroot_1.3-2 crayon_1.3.4
## [5] assertthat_0.2.1 withr_2.2.0 digest_0.6.25 R6_2.4.1
## [9] backports_1.1.8 magrittr_1.5 evaluate_0.14 blogdown_0.20
## [13] rlang_0.4.7 stringi_1.4.6 testthat_2.3.2 rmarkdown_2.3
## [17] desc_1.2.0 tools_4.0.2 stringr_1.4.0 pkgload_1.1.0
## [21] xfun_0.17 yaml_2.2.1 compiler_4.0.2 htmltools_0.5.0
## [25] knitr_1.29