4. The derivative of a function $f(x)$ at $x$ can be approximated by the Newton's quotient
$$\frac{f(x+h) - f(x-h)}{2 * h},$$
where $h$ is a small number. Write a function to calculate the Newton's quotient for the function $f(x) = \exp(x)$. The function should take two scalar arguments, $x$ and $h$. Use a default value of $h = 1e-6$.
f<-function(x,h=1e-6){
f<-(exp(x+h)-exp(x-h))/(2*h)
return(f)
}
f(1)
exp(1)
f(1)-exp(1)
Test your function at the point $x=1$ using the default value of $h$, and compare to the true value of the derivative $f'(1) = e^1$.
5. A very useful feature in R is the ability to pass a function name as an argument.
Here is an example, where 2 is added to the value of a function, for three different functions $\exp(x)$, $\log(x)$, and $\sin(x)$, at selected points $x$.
test <- function(x, f) {
output <- f(x) + 2
return(output)
}
test(0, exp)
test(1, log)
test(0, sin)
test(pi/2,sin)
Modify your function from problem 4 so that you pass in the name of the function for which you want to approximate the derivative. Use the same default value for $h$, and approximate the derivative of $sin(x)$ at $x=\pi/4$, of $\log(x)$ at $x=2$, and of $\exp(x)$ at $x=1$.
基于Monster 组和GPT的调写:
函数 f(x) 在 x处的导数可以近似地表示为牛顿商
其中 h是一个小的数。编写一个函数来计算函数 f(x) = \exp(x) 的牛顿商。该函数应该接受两个标量参数 x 和 h。使用默认值 h=1e-6。
f <- function(x, h=1e-6) {
f <- (exp(x+h) - exp(x-h))/(2*h)
return(f)
}
f(1)
exp(1)
f(1) - exp(1)
用默认值 h 在 x=1 处测试函数,并将其与导数的真实值 f'(1) = e^1 进行比较。
R 中非常有用的一个特性是能够将函数名作为参数传递。以下是一个示例,在选择的点 x 上,对三个不同的函数 \exp(x),$log(x) 和 \sin(x)的值加上了2。
test <- function(x, f) {
output <- f(x) + 2
return(output)
}
test(0, exp)
test(1, log)
test(0, sin)
test(pi/2, sin)
修改问题4中的函数,使其传递要近似导数的函数的名称。使用相同的默认值 $h$,并近似于在 $x=\pi/4 处的 sin(x),在 x=2 处的 \log(x) 和在 x=1处的 exp(x) 的导数。
f_newton <- function(f, x, h=1e-6) {
df <- (f(x+h) - f(x-h))/(2*h)
return(df)
}
f_newton(sin, pi/4)
f_newton(log, 2)
f_newton(exp, 1)
牛顿商是一种用于求解多项式根的方法。假设我们已知一个n次多项式P(x),其中系数为a0,a1,a2,...,an,且P(x)有一个根为x0。我们希望通过逐步逼近来求解出x0的值。
定义牛顿商:
f(x) = (x - x0)P1(x) + b0
f(x) = (x - x0)((x - x1)P2(x) + b1) + b0
f(x) = (x - x0)((x - x1)((x - x2)P3(x) + b2) + b1) + b0
...
f(x) = (x - x0)((x - x1)((x - x2)...((x - xn-1)Pn(x) + bn-1) + bn-2)... + b0)
其中P1(x), P2(x), ..., Pn(x)为P(x)的每一次差商,也就是:
P1(x) = (P(x) - a0) / (x - x0)
P2(x) = (P1(x) - a1) / (x - x1)
P3(x) = (P2(x) - a2) / (x - x2)
...
Pn(x) = (Pn-1(x) - an-1) / (x - xn-1)
每次求解牛顿商时,我们希望得出下一个根的估计值xk+1,即:
xk+1 = xk - f(xk) / f'(xk)
其中f(x)为上述的牛顿商,f'(x)为其一阶导数,即f'(x) = P1(x) + (x - x0)P2(x) + (x - x0)(x - x1)P3(x) + ... + (x - x0)(x - x1)...(x - xn-2)Pn(x)。
接下来我们使用R语言实现这个算法。首先定义一个函数来计算P(x)的每一次差商:
diff_coef <- function(x, y) {
if (length(y) == 1) {
return(y)
} else {
return((diff_coef(tail(x, -1), tail(y, -1)) - diff_coef(head(x, -1), head(y, -1))) / (x[length(x)] - x[1]))
}
}
然后定义一个函数来计算牛顿商:
newton_quot <- function(x, y, epsilon) {
iter <- 1
root <- x[1]
while (iter <= 1000) {
fx <- y[1]
dfx <- 1
for (i in 2:length(x)) {
dfx <- dfx * (root - x[i-1])
fx <- fx * (root - x[i-1]) + y[i]
}
root_new <- root - fx / dfx
if (abs(root_new - root) < epsilon) {
return(root_new)
}
root <- root_new
iter <- iter + 1
}
return(NA)
}
最后,我们可以使用上述函数来求解多项式的根:
x <- c(1, 2, 3, 4, 5)
y <- c(-1, 0, 2, 1, -2)
diff_coef(x, y)
newton_quot(x, y, 1e-8)
这里我们以一个5次多项式为例,使用差商函数求解每一次差商,然后使用牛顿商函数求解多项式的根。其中epsilon是我们设置的精度,表示当根的变化量小于这个值时,停止迭代。
该回答引用ChatGPT GPT-4
运行结果
将函数名作为参数传递。我们将使用相同的默认值 h,并分别计算在 $x = \pi/4$ 处的 $sin(x)$ 导数,$x = 2$ 处的 $\log(x)$ 导数和 $x = 1$ 处的 $\exp(x)$ 导数。
首先定义了一个名为 newtons_quotient 的函数,该函数接受 x, f 和 h 作为参数,并计算牛顿商。接下来,我们定义了三个点 $x = \pi/4$,$x = 2$ 和 $x = 1$,并分别计算了在这些点上的 $sin(x)$, $\log(x)$ 和 $\exp(x)$ 的导数。最后,我们打印了计算结果。
代码如下
newtons_quotient <- function(x, f, h = 1e-6) {
quotient <- (f(x + h) - f(x - h)) / (2 * h)
return(quotient)
}
x1 <- pi / 4
x2 <- 2
x3 <- 1
result_sin <- newtons_quotient(x1, sin)
result_log <- newtons_quotient(x2, log)
result_exp <- newtons_quotient(x3, exp)
print(paste("sin'(pi/4) =", result_sin))
print(paste("log'(2) =", result_log))
print(paste("exp'(1) =", result_exp))