2012-11-12 30 views
0

我試圖評估一個函數(另一個的二階導數),但Sympy似乎有困難做到這一點......?Sympy無法區分與變量

from sympy import * 
from sympy import Symbol 

# Symbols 
theta = Symbol('theta') 
phi = Symbol('phi') 
phi0 = Symbol('phi0') 
H0 = Symbol('H0') 
# Constants 
a = 0.05 
t = 100*1e-9 
b = 0.05**2/(8*pi*1e-7) 
c = 0.001/(4*pi*1e-7) 
phi0 = 60*pi/180 
H0 = -0.03/(4*pi*1e-7) 
def m(theta,phi): 
    return Matrix([[sin(theta)*cos(phi), sin(theta)*cos(phi), cos(phi)]]) 
def h(phi0): 
    return Matrix([[cos(phi0), sin(phi0), 0]]) 
def k(theta,phi,phi0): 
    return m(theta,phi).dot(h(phi0)) 
def F(theta,phi,phi0,H0): 
    return -(t*a*H0)*k(theta,phi,phi0)+b*t*(cos(theta)**2)+c*t*(sin(2*theta)**2)+t*sin(theta)**4*sin(2*phi)**2 
def F_theta(theta,phi,phi0,H0): 
    return simplify(diff(F(theta,phi,phi0,H0),theta)) 
def F_thetatheta(theta,phi,phi0,H0): 
    return simplify(diff(F_theta(theta,phi,phi0,H0),theta)) 

print F_thetatheta(theta,phi,phi0,H0), F_thetatheta(pi/2,phi,phi0,H0) 

如下面看到的那樣,一般功能進行評價,但是當我嘗試更換由PI/2或另一個值THETA,這是行不通的。

(4.0e-7*pi*sin(theta)**4*cos(2*phi)**2 - 4.0e-7*pi*sin(theta)**4 + 0.00125*sin(theta)**2 - 0.0001875*sqrt(3)*sin(theta)*cos(phi) - 0.0001875*sin(theta)*cos(phi) + 1.2e-6*pi*cos(2*phi)**2*cos(theta)**4 - 1.2e-6*pi*cos(2*phi)**2*cos(theta)**2 - 1.2e-6*pi*cos(theta)**4 + 1.2e-6*pi*cos(theta)**2 + 0.004*cos(2*theta)**2 - 0.002625)/pi 
Traceback (most recent call last): 
File "Test.py", line 46, in <module> 
print F_thetatheta(theta,phi,phi0,H0), F_thetatheta(pi/2,phi,phi0,H0) 
File "Test.py", line 29, in F_thetatheta 
return simplify(diff(F_theta(theta,phi,phi0,H0),theta)) 
File "Test.py", line 27, in F_theta 
return simplify(diff(F(theta,phi,phi0,H0),theta)) 
File "/usr/lib64/python2.7/site-packages/sympy/core/function.py", line 1418, in diff 
return Derivative(f, *symbols, **kwargs) 
File "/usr/lib64/python2.7/site-packages/sympy/core/function.py", line 852, in __new__ 
Can\'t differentiate wrt the variable: %s, %s''' % (v, count))) 
ValueError: 
Can't differentiate wrt the variable: pi/2, 1 

回答

2

該錯誤表示您無法區分數字pi/2。也就是說,你從一個變量(x,y ...)導出,而不是一個數字。

在具有幾個變量的表達式,則可以通過使用subs通過其值(或另一種表達)代替它們(或多個)中的一個:

F_thetatheta(theta,phi,phi0,H0).subs(theta, pi/2) 

然後,將其評估爲你所需的精度可以使用evalf。比較兩個結果:

F_thetatheta(theta,phi,phi0,H0).evalf(50, subs={theta:pi/2, phi:0}) 
F_thetatheta(theta,phi,phi0,H0).subs({theta: pi/2, phi:0}) 

你或許應該看看在sympy documentation或跟隨tutorial。該文檔非常好,您甚至可以在瀏覽器中嘗試這些示例並評估代碼。

+1

是的,抱歉,我現在明白了錯誤。我應該閱讀關於sympy的教程,我一定會需要它!但是你的建議實際上並不奏效。這相反:'F_thetatheta(theta,phi,phi0,H0).subs(theta,pi/2)' – aymenbh

+0

@ user1816760 Ops,你說的沒錯,我沒有意識到phi還在最後的表達,在這種情況下,你需要像你一樣替換theta。如果你同時評估theta和phi,這將起作用:'F_thetatheta(theta,phi,phi0,H0).evalf(subs = {theta:pi/2,phi:0})'。無論如何,你最終需要'evalf'來獲得一個數值而不是確切的數值(我會修復我的答案)。 – jorgeca