我正在尝试在 sympy 中创建一个自定义符号,其行为类似于 r = √(x2 + y2 + z2) - 具体来说,∂r/∂x = x/r:
from sympy import Symbol, symbols
x, y, z = symbols("x y z")
class _r(Symbol):
def __new__(self):
r = super().__new__(self, "r")
return r
def diff(self, var):
assert var in [x, y, z]
return 1 / self * var
r = _r()
一阶导数按预期工作:
>>> r.diff(x)
x/r
二阶导数应返回 -x2/r3 + 1/r,但 sympy 不会再次区分
r
符号:
>>> r.diff(x).diff(x)
1/r
我检查了中间结果,发现以下内容:
>>> d = r.diff(x)
>>> type(d)
sympy.core.mul.Mul
>>> d.free_symbols
{r, x}
>>> for s in d.free_symbols:
>>> print(s, type(s))
r <class '__main__._r'>
x <class 'sympy.core.symbol.Symbol'>
所以它确实仍然将
r
识别为我的自定义对象,但在调用结果.diff
对象的Mul
时不知何故会丢失。
如何让它发挥作用?通过子类化,我是否走在正确的轨道上?
Symbol
在它们之间进行切换来更轻松地完成此操作
.subs()
R = symbols("R") # your special symbol
r = sqrt(x**2 + y**2 + z**2) # logical equivalence