You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

非恒定间隔下如何用有限差分计算向量的二阶导数?

非均匀网格下二阶导数的有限差分计算方案

你的判断没错——原代码的误差根源在于一阶导数dydx对应的是相邻x的中点,而后续计算时用了错位的x序列,导致二阶导数的计算逻辑完全不匹配非均匀网格的特性。针对非均匀间隔的x,必须使用基于拉格朗日插值推导的三点公式来计算二阶导数,才能保证精度。

解决方案:三点公式直接计算二阶导数

对于非均匀网格中的每个内部点x[i](2 ≤ i ≤ n-1),二阶导数的计算公式由三点拉格朗日插值多项式求导推导而来:

d2ydx2[i] = 2 * [ y[i+1]/(h2*(h1+h2)) - y[i]/(h1*h2) + y[i-1]/(h1*(h1+h2)) ]

其中h1 = x[i] - x[i-1],h2 = x[i+1] - x[i]。

向量化实现(高效适合大样本)

用向量化操作替代循环,避免性能损耗:

set.seed(123) # 固定随机种子方便复现
x <- rnorm(2000)
y <- x^2

# 排序x和对应y(保持x递增)
ord <- order(x)
x <- x[ord]
y <- y[ord]

n <- length(x)
d2ydx2 <- rep(NA, n)

# 向量化计算各部分项
h1 <- diff(x)[-length(diff(x))]  # x[i]-x[i-1],对应i=2到n-1
h2 <- diff(x)[-1]                # x[i+1]-x[i],对应i=2到n-1
term1 <- y[-c(1, 2)] / (h2 * (h1 + h2))
term2 <- -y[-c(1, n)] / (h1 * h2)
term3 <- y[-c(n-1, n)] / (h1 * (h1 + h2))

# 填充内部点的二阶导数
d2ydx2[2:(n-1)] <- 2 * (term1 + term2 + term3)

# 绘图验证(理论二阶导数为2)
plot(x, d2ydx2, main = "非均匀网格下的二阶导数", ylab = "d2y/dx²")
abline(h = 2, col = "red", lwd = 2)

循环实现(逻辑更直观)

如果需要更清晰的逻辑展示,循环版本也能满足需求:

set.seed(123)
x <- rnorm(2000)
y <- x^2

ord <- order(x)
x <- x[ord]
y <- y[ord]

n <- length(x)
d2ydx2 <- rep(NA, n)

for (i in 2:(n-1)) {
  h1 <- x[i] - x[i-1]
  h2 <- x[i+1] - x[i]
  d2ydx2[i] <- 2 * (y[i+1]/(h2*(h1+h2)) - y[i]/(h1*h2) + y[i-1]/(h1*(h1+h2)))
}

plot(x, d2ydx2, main = "非均匀网格下的二阶导数", ylab = "d2y/dx²")
abline(h = 2, col = "red", lwd = 2)

为什么原代码会出错?

原代码中dydx的每个值对应x[i]和x[i+1]的中点,而diff(x[-1])对应的是x[2]到x[n]的间隔,这两个序列的位置完全错位。当x间隔变化较大时,这种错位计算会产生极大的误差,完全不符合二阶导数的数学定义。

内容的提问来源于stack exchange,提问作者Anthony Tan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 21:01:55