Sympy自定义变换坐标系中梯度化简返回零向量问题
Sympy Vector模块自定义坐标系梯度化简异常问题
问题重现
使用带自定义变换(哪怕是恒等变换)的CoordSys3D创建坐标系后,计算标量函数的梯度并调用simplify(),会错误返回零向量:
from sympy import Function from sympy.vector import CoordSys3D, gradient S = CoordSys3D('S', transformation=lambda x,y,z : (x, y, z), variable_names=('x','y','z')) f = Function('f') grad_f = gradient(f(S.x,S.y,S.z)).simplify() print(grad_f)
输出:
0
现象对比
默认坐标系下运行正常
import sympy as sp from sympy.vector import CoordSys3D, gradient R = CoordSys3D('R') f = sp.Function('f') grad_f = gradient(f(R.x,R.y,R.z)) print(grad_f) print(grad_f.simplify())
输出:
(Derivative(f(R.x, R.y, R.z), R.x))*R.i + (Derivative(f(R.x, R.y, R.z), R.y))*R.j + (Derivative(f(R.x, R.y, R.z), R.z))*R.k (Derivative(f(R.x, R.y, R.z), R.x))*R.i + (Derivative(f(R.x, R.y, R.z), R.y))*R.j + (Derivative(f(R.x, R.y, R.z), R.z))*R.k
自定义坐标系下的异常
梯度计算结果本身正确,但调用simplify()后错误归零:
S = CoordSys3D('S', transformation=lambda x,y,z : (x, y, z), variable_names=('x','y','z')) grad_f = gradient(f(S.x,S.y,S.z)) print(grad_f) print(grad_f.simplify())
输出:
(Derivative(f(S.x, S.y, S.z), S.x))*S.i + (Derivative(f(S.x, S.y, S.z), S.y))*S.j + (Derivative(f(S.x, S.y, S.z), S.z))*S.k 0
若使用非平凡变换(如自定义球坐标系),化简步骤耗时极久后仍返回错误的零向量。
临时解决方案
将坐标系变量替换为普通符号后再执行化简,可得到预期结果:
x,y,z = sp.symbols('x,y,z') grad_f = grad_f.subs({S.x : x, S.y : y, S.z : z}) print(grad_f) print(grad_f.simplify())
输出:
(Derivative(f(x, y, z), x))*S.i + (Derivative(f(x, y, z), y))*S.j + (Derivative(f(x, y, z), z))*S.k (Derivative(f(x, y, z), x))*S.i + (Derivative(f(x, y, z), y))*S.j + (Derivative(f(x, y, z), z))*S.k
结论
这是Sympy Vector模块处理带自定义变换坐标系时的bug,并非对自定义变换的理解有误。问题出在simplify()方法对关联自定义坐标系变量的导数处理逻辑上,导致错误地将非零梯度判定为零。
内容的提问来源于stack exchange,提问作者Donna
相关产品推荐
相关产品推荐

