R应用数值计算
王诗翔 · 2018-05-09
这里我们学习下有关数值计算的根查找与微积分的内置函数。
根查找
假设我们想要求解以下方程的根:
\[ x^2 + x - 2 = 0 \]
若是要手动求解,我们需要先将方程转换为乘积项:
\[ (x+2)(x-1) = 0 \]
因此,方程的根是\(x_1=-2\)和\(x_2=1\)。
在R里面,ployroot()
可以求解像\(p(x)=z_1+z_2x+...+z_nx^{n-1}\)的多项式方程。
我们需要按顺序依次输入零阶到最高阶的系数,这上面这个问题中,我们可以这么写:
polyroot(c(-2, 1, 1))
#> [1] 1-0i -2+0i
该函数总是会返回复数向量,我们可以使用Re()
从复数根中提取实数部分:
Re(polyroot(c(-2, 1, 1)))
#> [1] 1 -2
至于方程\(f(x)=0\)的一般数值求解方法,我们可以利用uniroot()
实现,指定求解函数和查找区间。该函数返回一个列表,其中包含了近似根、近似根处的函数值、计算的迭代次数以及根的估计精度。
uniroot(function(x) x ^ 2 - exp(x), c(-2, 1))
#> $root
#> [1] -0.703
#>
#> $f.root
#> [1] -1.74e-05
#>
#> $iter
#> [1] 6
#>
#> $init.it
#> [1] NA
#>
#> $estim.prec
#> [1] 6.1e-05
需要注意,函数uniroot()
一次只能查找一个根。
微积分
求导
D()
可以用于计算一个函数给定变量的导数,并仍以表达式的形式返回。
例如我们计算\(\frac{dx^2}{dx}\):
D(quote(x ^ 2), "x")
#> 2 * x
求解\(\frac{dsin(x)cos(xy)}{dx}\):
D(quote(sin(x) * cos(x * y)), "x")
#> cos(x) * cos(x * y) - sin(x) * (sin(x * y) * y)
多亏了quote()
函数,它能够使表达式保留输入形式,而不被执行。
我们可以调用eval()
函数执行并执行的表达式:
z <- D(quote(sin(x) * cos(x * y)), "x")
z
#> cos(x) * cos(x * y) - sin(x) * (sin(x * y) * y)
eval(z, list(x = 1, y = 2))
#> [1] -1.76
积分
同样,我们来计算一个定积分问题——求解0~\(\pi/2\)区间正弦曲线下的面积,使用内置函数integrate()
可以轻松解决。
\[ \int_{0}^{\pi/2}sin(x)dx\]
result <- integrate(function(x) sin(x), 0, pi/2)
result
#> 1 with absolute error < 1.1e-14
看起来像一个数值解,但实际返回了一个列表:
str(result)
#> List of 5
#> $ value : num 1
#> $ abs.error : num 1.11e-14
#> $ subdivisions: int 1
#> $ message : chr "OK"
#> $ call : language integrate(f = function(x) sin(x), lower = 0, upper = pi/2)
#> - attr(*, "class")= chr "integrate"
来源: 《R语言编程指南》