2016-04-17 35 views
2

我有一個sympy結果,像這樣捲起:如何強制sympy提取特定的子表達式?

from sympy import * 
Vin,Vc,C1,Cs,R1,Rs,t=symbols(r'V_{in},V_{C},C_1,C_S,R_1,R_S,t') 
k1=Symbol('k_1') 
eqVc=Eq(Vc(t),(Rs*(exp(t*(R1+Rs)/(R1*Rs*(C1+Cs))) - 1)*Heaviside(t) + 
        k1*(R1+Rs))*exp(-t*(R1+Rs)/(R1*Rs*(C1+Cs)))/(R1+Rs)) 

表達eqVc出來是這樣的:

我知道這個函數的形式爲:

我的目標是獲得V cinit,Vcfinal和tau,但特別是tau。

有沒有辦法讓Sympy提取這些值? cse()並不完全符合我的要求 - 我可以通過使用cse([C1 + Cs,eqVc])來取代C1 + Cs,並且它確實知道e的指數是一個常見的子表達式,但它傾向於在子表達式中包含t。

回答

3

一個簡單的方法是解決會導致表達式在多個時間點相等的參數。鑑於形式其實都是一樣的,這將很好地工作:

V_Ci, tau, V_Cf = symbols('V_Ci, tau, V_Cf') 

target = V_Ci*exp(-t/tau) + Heaviside(t)*V_Cf*(1 - exp(-t/tau)) 

solve([(eqVc.rhs - target).subs(t, ti) for ti in [0, 1, 2]], 
     [V_Ci, tau, V_Cf], dict=True) 

我得到的答案是

[{V_Cf: R_S/(R_1 + R_S), 
    tau: 1/log(exp((1/R_S + 1/R_1)/(C_1 + C_S))), 
    V_Ci: k_1}] 

log(exp())不是簡單的,因爲變量定義的方式離開。定義一切,真正的(V_Ci, tau, V_Cf = symbols('V_Ci, tau, V_Cf', real=True)並在代碼中類似的修改)簡化了soluion到

[{V_Ci: k_1, 
    V_Cf: R_S/(R_1 + R_S), 
    tau: R_1*R_S*(C_1 + C_S)/(R_1 + R_S)}] 
+0

不同的路線比我期待的,但是它幹得不錯!值得指出的是,除了需要至少3個(爲了解決3個未知數)以及由於某種原因需要包括t = 0之外,我們設置相等的時間是相對任意的。出於某種原因,在[1,2,3]解決不起作用(或者至少需要比我願意等待更長的時間)。 – Omegaman

+0

我認爲至少有一次需要在heaviside的零點上計算初始電壓。 – chthonicdaemon