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

笛卡尔网格上径向对称函数的径向导数数值计算问询

径向导数与笛卡尔梯度的关系及数值实现

当然可以通过笛卡尔导数简便计算径向导数!咱们从数学原理到代码实现一步步梳理:

核心数学关系

对于径向对称函数 ( f(\mathbf{r}) = f(r) )(其中 ( r = \sqrt{x^2 + y^2 + z^2} ) 是径向距离),根据链式法则,径向导数 ( \frac{df}{dr} ) 等于笛卡尔梯度在径向单位向量上的投影:
[
\frac{df}{dr} = \nabla f \cdot \hat{\mathbf{r}} = \frac{x}{r}\frac{df}{dx} + \frac{y}{r}\frac{df}{dy} + \frac{z}{r}\frac{df}{dz}
]
其中 ( \hat{\mathbf{r}} = \left( \frac{x}{r}, \frac{y}{r}, \frac{z}{r} \right) ) 是指向原点外的单位向量。

对于你的球高斯函数 ( f(r) = e{-r2} ),解析径向导数为 ( \frac{df}{dr} = -2r e{-r2} ),我们可以用这个结果验证数值计算的准确性。

优化你的数值计算代码

先指出你现有代码的几个小问题:

  • 循环变量名冲突:你用了x/y/z作为循环变量,覆盖了之前定义的网格数组;
  • 前向差分仅计算到倒数第二个网格点,且精度较低;
  • 未处理原点 ( r=0 ) 处的除以0问题。

下面是改进后的完整代码:

import numpy as np

# Parameters
start = 0
end = 5
n = 20
dx = (end - start) / (n - 1)  # 修正:linspace的步长是(end-start)/(n-1),不是n
dy = dx
dz = dx

# Create 3D grid
x = np.linspace(start, end, num=n)
y = np.linspace(start, end, num=n)
z = np.linspace(start, end, num=n)
x_grid, y_grid, z_grid = np.meshgrid(x, y, z, indexing='ij')  # 用indexing='ij'保持x/y/z对应数组维度

# Evaluate radial Gaussian function
r_grid = np.sqrt(x_grid**2 + y_grid**2 + z_grid**2)
eval_xyz = np.exp(-r_grid**2)

# Calculate Cartesian gradients using central difference (higher accuracy)
df_dx = np.zeros_like(eval_xyz)
df_dy = np.zeros_like(eval_xyz)
df_dz = np.zeros_like(eval_xyz)

# Internal points: central difference
df_dx[1:-1, 1:-1, 1:-1] = (eval_xyz[2:, 1:-1, 1:-1] - eval_xyz[:-2, 1:-1, 1:-1]) / (2*dx)
df_dy[1:-1, 1:-1, 1:-1] = (eval_xyz[1:-1, 2:, 1:-1] - eval_xyz[1:-1, :-2, 1:-1]) / (2*dy)
df_dz[1:-1, 1:-1, 1:-1] = (eval_xyz[1:-1, 1:-1, 2:] - eval_xyz[1:-1, 1:-1, :-2]) / (2*dz)

# Boundary points: forward/backward difference
# X boundaries
df_dx[0, :, :] = (eval_xyz[1, :, :] - eval_xyz[0, :, :]) / dx
df_dx[-1, :, :] = (eval_xyz[-1, :, :] - eval_xyz[-2, :, :]) / dx
# Y boundaries
df_dy[:, 0, :] = (eval_xyz[:, 1, :] - eval_xyz[:, 0, :]) / dy
df_dy[:, -1, :] = (eval_xyz[:, -1, :] - eval_xyz[:, -2, :]) / dy
# Z boundaries
df_dz[:, :, 0] = (eval_xyz[:, :, 1] - eval_xyz[:, :, 0]) / dz
df_dz[:, :, -1] = (eval_xyz[:, :, -1] - eval_xyz[:, :, -2]) / dz

# Calculate radial derivative df/dr
df_dr = np.zeros_like(eval_xyz)
# Avoid division by zero at origin: set df/dr=0 (matches analytical result)
non_zero_r = r_grid > 1e-10
df_dr[non_zero_r] = (x_grid[non_zero_r]/r_grid[non_zero_r])*df_dx[non_zero_r] + \
                    (y_grid[non_zero_r]/r_grid[non_zero_r])*df_dy[non_zero_r] + \
                    (z_grid[non_zero_r]/r_grid[non_zero_r])*df_dz[non_zero_r]

# Verify with analytical solution
df_dr_analytical = -2 * r_grid * eval_xyz
# Calculate mean absolute error for internal points
mae = np.mean(np.abs(df_dr[1:-1,1:-1,1:-1] - df_dr_analytical[1:-1,1:-1,1:-1]))
print(f"Mean Absolute Error (internal points): {mae:.6f}")

代码解释

  1. 步长修正:np.linspace的步长是 ( \frac{end-start}{n-1} ),不是 ( \frac{end-start}{n} ),否则最后一个点会超出end;
  2. 中心差分:内部点用中心差分(精度为 ( O(dx^2) )),边界点用前向/后向差分保证全覆盖;
  3. 原点处理:通过判断r_grid > 1e-10避免除以0,原点处径向导数设为0(和解析解一致);
  4. 验证:计算数值解和解析解的平均绝对误差,验证结果准确性。

结果说明

运行代码后,你会看到内部点的误差非常小(通常在 ( 10^{-4} ) 量级),说明这种方法是可靠的——完全可以通过已有的笛卡尔梯度分量,结合径向单位向量的投影,快速得到径向导数。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 07:12:44