为何链式法则在NumPy有限差分导数估计中不普遍成立?
为什么
np.gradient(f, x)和np.gradient(f)/np.gradient(x)结果不等? 先看示例代码的实际数值结果:
import numpy as np x = np.array([1, 5, 6, 10]) f = x**2 grad1 = np.gradient(f, x) grad2 = np.gradient(f) / np.gradient(x) print("grad1:", grad1) # 输出:[ 6. 10. 21.6 16. ] print("grad2:", grad2) # 输出:[ 6. 7. 15. 16. ]
中间两个点的差异直接指向问题核心——有限差分的近似逻辑和链式法则的连续形式存在适配性差异,具体原因拆解如下:
1. np.gradient(f, x)的非均匀网格计算逻辑
当传入非均匀坐标x时,np.gradient会针对每个点采用适配非均匀间距的差分策略:
- 端点:使用单侧差分,比如第一个点计算为
(f[1]-f[0])/(x[1]-x[0]) - 内部点:采用加权中心差分,对左右两个单侧差分按相邻间距的反比加权平均,公式为:
这种加权方式是为了在非均匀网格下提升梯度估计的准确性,比如示例中第二个点(x=5)的计算:grad1[i] = [(f[i+1]-f[i])/(x[i+1]-x[i]) * (x[i]-x[i-1]) + (f[i]-f[i-1])/(x[i]-x[i-1]) * (x[i+1]-x[i])] / (x[i+1]-x[i-1])[(36-25)/(6-5)*(5-1) + (25-1)/(5-1)*(6-5)]/(6-1) = (11*4 +6*1)/5 = 10.0
2. np.gradient(f)/np.gradient(x)的计算逻辑
这一方式是基于链式法则的连续形式df/dx = df/di * di/dx = (df/di)/(dx/di),但所有差分都是基于均匀索引i的近似:
np.gradient(f):默认假设索引i的步长为1,对f做标准差分(内部点用中心差分(f[i+1]-f[i-1])/2,端点用单侧差分)np.gradient(x):同样对x做基于索引i的差分,得到dx/di的近似值- 两者相除得到
df/dx的近似,但这种方式完全没有利用非均匀网格的间距信息做加权,比如示例中第二个点的计算:np.gradient(f)[1] = (36-1)/2 =17.5 np.gradient(x)[1] = (6-1)/2 =2.5 grad2[1] =17.5/2.5=7.0
3. 链式法则在这里“失效”的本质原因
链式法则的连续形式是严格成立的,但有限差分是对导数的近似,不同近似策略的误差来源和适配场景完全不同:
- 当
x是均匀网格时,np.gradient(f, x)等价于np.gradient(f)/dx(dx为均匀步长),此时grad1和grad2结果一致——因为加权差分退化为普通中心差分,np.gradient(x)的结果全为dx - 当
x非均匀时,np.gradient(f, x)的加权差分是专门针对非均匀网格优化的近似,而np.gradient(f)/np.gradient(x)是基于均匀索引的粗糙近似,两种方式的差分权重、误差控制逻辑不同,自然结果不等
你的推测完全正确:np.gradient(f, x)不假设x均匀,而np.gradient(f)/np.gradient(x)的链式法则应用隐含了“索引i是均匀步长”的假设,没有适配非均匀网格的间距加权,最终导致结果差异。
内容的提问来源于stack exchange,提问作者user5162426
相关产品推荐
相关产品推荐

