在Sympy中,如何定义类似f(x)的泛型函数,以使sympy.diff(f(x),x)返回f'而不是0。

时间:2019-01-03 17:48:54

标签: python sympy

我正在尝试使用此函数的派生

x, y, z, P, k, q = sp.symbols('x y z P k q')
expr = sp.exp(-sp.I*(P+k/(2*q)*(x**2 + y**2))) 

其中P和q是z的函数。如何定义P和q,以使sp.diff(P,z)返回P'而不是0?

2 个答案:

答案 0 :(得分:3)

根据您所写的内容,sympy不知道Pqz的功能,对吗?因此,它将它们视为常量-就像z以外的所有其他变量一样。您的表达式根本没有提到z,所以它都是常量表达式-常量的派生为0,没有例外。

确保sympy知道Pqz的功能。显然,这些功能是什么很重要-您不能仅将它们留空。平方的区别与平方根的区别不同。如果您不知道,sympy将尽其所能:

x, y, z, k = sp.symbols('x y z k')
P = sp.Function('P')
q = sp.Function('q')
expr = sp.exp(-sp.I*(P(z)+k/(2*q(z))*(x**2 + y**2)))
sp.diff(expr, z)
# => -I*(-k*(x**2 + y**2)*Derivative(q(z), z)/(2*q(z)**2) + Derivative(P(z), z))*
#    exp(-I*(k*(x**2 + y**2)/(2*q(z)) + P(z)))

但是,如果您知道的话,它可以准确计算出它:

x, y, z, k = sp.symbols('x y z k')
P = sp.Lambda(z, z * z)
q = sp.Lambda(z, sp.sqrt(z))
expr = sp.exp(-sp.I*(P(z)+k/(2*q(z))*(x**2 + y**2)))
sp.diff(expr, z)
# => -I*(-k*(x**2 + y**2)/(4*z**(3/2)) + 2*z)*
#    exp(-I*(k*(x**2 + y**2)/(2*sqrt(z)) + z**2))

类似地,我认为您无法区分P,但这有效:

sp.diff(P(z), z)
# => 2*z

答案 1 :(得分:0)

您可以使用idiff来获得带有未评估导数的脆弱结果:dPdz = idiff(expr, (P, q), z)。从某种意义上来说,dPdz.doit()会给出0是脆弱的,因为q对于z没有明确的依赖。

>>> idiff(expr,(P,q),z)
k*(x**2 + y**2)*Derivative(q, z)/(2*q**2)
>>> _.doit()
0