SymPy中非交换导数问题:非交换场平方求导结果异常
问题分析与解决方案
你的问题出在SymPy对同一非交换符号幂次的导数处理逻辑上:当你计算phi*phi时,SymPy会自动将其合并为phi**2,而幂次的导数规则默认沿用了交换代数的n*phi^(n-1)*diff(phi,x),哪怕你指定了commutative=False,合并后的幂运算导数也不会触发非交换的莱布尼茨展开。
解决方法
方法一:用两个独立的同名字段实例计算后替换
定义两个不同的SymPy对象(哪怕名字相同),计算乘积的导数后再将其中一个替换为原字段:
from sympy import symbols, function, diff x = symbols('x') phi = function("\phi", commutative=False)(x) phi2 = function("\phi", commutative=False)(x) # 独立的实例对象 # 计算两个独立字段乘积的导数 deriv = diff(phi * phi2, x) # 将phi2替换为phi,得到非交换的正确结果 final_deriv = deriv.subs(phi2, phi) print(final_deriv)
方法二:用UnevaluatedExpr强制保留乘积形式
通过UnevaluatedExpr避免SymPy将phi*phi合并为幂次,确保触发非交换莱布尼茨法则:
from sympy import symbols, function, diff, UnevaluatedExpr x = symbols('x') phi = function("\phi", commutative=False)(x) # 用UnevaluatedExpr包裹每个因子,阻止合并为幂次 phi_product = UnevaluatedExpr(phi) * UnevaluatedExpr(phi) # 先展开乘积再求导 deriv = diff(phi_product.doit(), x) print(deriv)
上述两种方法都能得到你预期的\phi'(x)\phi(x) + \phi(x)\phi'(x)形式的结果。
内容的提问来源于stack exchange,提问作者Ramon
相关产品推荐
相关产品推荐

