R语言:求解函数一阶导数为0的x值,代码无输出问题排查
求解TPC.dev函数一阶导数为0的x值
原问题与代码
你定义的温度依赖型函数TPC.dev如下:
require(plot3D) require(numDeriv) require(rgl) Mass.init<-8.8 k<-8.617333262*10^(-5) r_tref.d<-0.300 e.d<-0.4 eh.d<-3 th.d<-31 tref.d<-20 TPC.dev<-function(x){ r_tref.d*exp((-e.d/k)*(1/(x+273.15)-1/(tref.d+273.15)))/ (1+exp((eh.d/k)*(1/(th.d+273.15)-1/(x+273.15)))) }
你尝试通过遍历离散点寻找导数为0的x值,代码如下:
Mean.vector <- seq(10, 30, 0.01) tolerance <- 1e-6 x_values <- numeric() for (i in 1:length(Mean.vector)) { x <- Mean.vector[i] deriv.dev <- genD(TPC.dev, x) if (all(abs(deriv.dev$D[, 1]) < tolerance)) { x_values <- c(x_values, x) } } print(x_values)
运行后输出numeric(0),但可视化观察到极值点在x≈25附近。
问题分析
原方法失效的核心原因:
- 遍历离散点的方式几乎不可能刚好命中导数精确为0的点,离散间隔(0.01)无法覆盖连续函数的根位置。
genD函数主要用于计算高阶导数和混合导数,对于一阶导数,使用grad函数更直接,也能避免对返回结构的错误索引。
正确解法
方法一:数值导数+求根函数
利用numDeriv包的grad生成一阶导数函数,再用uniroot寻找该函数在区间[10,30]内的根:
require(numDeriv) # 定义一阶导数函数 TPC.dev.deriv <- function(x) { grad(TPC.dev, x) } # 在区间[10,30]内寻找导数为0的点 root_result <- uniroot(TPC.dev.deriv, interval = c(10, 30)) cat("导数为0的x值:", root_result$root, "\n")
方法二:直接寻找函数极值点
由于导数为0的点对应函数的极值点(此处为最大值点),可以直接用optimize函数寻找TPC.dev的最大值位置:
# 寻找函数在[10,30]内的最大值点 max_result <- optimize(TPC.dev, interval = c(10, 30), maximum = TRUE) cat("函数最大值对应的x值:", max_result$maximum, "\n")
两种方法均能得到精确的x值(约25.1左右),远优于离散遍历的方式。
内容的提问来源于stack exchange,提问作者Nate Trf
相关产品推荐
相关产品推荐

