Shixiang Wang

>上士闻道
勤而行之

R应用数值计算

王诗翔 · 2018-05-09

分类: r  
标签: r   math  

这里我们学习下有关数值计算的根查找微积分的内置函数。

根查找

假设我们想要求解以下方程的根:

\[ 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语言编程指南》