2013-03-04 37 views
6

我使用sympy解決一個多項式:忽略虛根在sympy

x = Symbol('x') 
y = solve(int(row["scaleA"])*x**3 + int(row["scaleB"])*x**2 + int(row["scaleC"])*x + int(row["scaleD"]), x) 

y是可能的解決方案列表。但是,我需要忽略虛構的,只使用真正的解決方案。此外,我希望解決方案作爲價值而不是表達。現在它看起來像:

[-2/3 - 55**(1/3)*(-1/2 - sqrt(3)*I/2)/3, -2/3 - 55**(1/3)*(-1/2 + sqrt(3)*I/2)/3, -55**(1/3)/3 - 2/3] 

我需要最後一個表達式的值(-2.22756)。 sympy中是否有函數來簡化它?

+4

如果您僅對浮點/雙重近似值感興趣,SymPy很可能不是正確的庫。如果你使用numpy/scipy,你可能會獲得更好的性能和更簡單的代碼。如果你在numpy/scipy上選擇sympy,因爲它比較小,你可以使用mpmath在sympy中使用更小的數字(任意精度不受機器限制) – Krastanov 2013-03-04 23:50:31

回答

0

由於Krastonov曾提到mpmath提供更簡單的方法:

y = polyroots([int(row["scaleA"]), int(row["scaleB"]), int(row["scaleC"]), int(row["scaleD"])-value]) 
for root in y: 
    if "j" not in str(root): 
     value = root 
-3

我設法忽略包含字符"I"的解決方案,並使用.evalf()來評估表達式。該代碼現在:

x = Symbol('x') 
    y = solve(int(row["scaleA"])*x**3 + int(row["scaleB"])*x**2 + int(row["scaleC"])*x + int(row["scaleD"]), x) 
    for root in y: 
     if "I" not in str(root): 
      print("This One:" + str(root.evalf())) 
+3

過濾真實根源的更好方法是檢查' root.is_real'。 – asmeurer 2013-03-08 07:43:26

9

如果設置x是真實的,SymPy只會給你真正的解決方案

x = Symbol('x', real=True) 
solve(..., x) 
+0

我試圖用這種方法解決方程,但它仍然返回假想的解決方案 – Alex 2016-08-08 11:22:29

+0

您使用解決方案嗎?請注意,新的'solveset'忽略了在符號上設置的假設(使用'solveset(domain = S.Reals)'在真實域中解決。如果使用solve,這是一個應該[報告]的錯誤(https: //github.com/sympy/sympy/issues/new) – asmeurer 2016-08-08 16:16:31

+0

我嘗試了兩種解決方法:假設,solveset和solveset與domain = S.Reals。 Solve簡單地跳過了要解決的變量的假設(如解決方案)在30秒內到達解決方案,而解決域名問題無法在20分鐘內到達解決方案。它可能是重複的嗎?(https://github.com/sympy/sympy/issues/9973 ) – Alex 2016-08-08 23:18:42

0

solve()對於各種類型的解決方案沒有一致的輸出,請使用solveset(Eq,x,domain=S.Reals)

from sympy import ImageSet, S 
x = Symbol('x') 
y = solveset(int(row["scaleA"])*x**3 + int(row["scaleB"])*x**2+int(row["scaleC"])*x + int(row["scaleD"]), x, domain=S.Reals) 

http://docs.sympy.org/latest/modules/solvers/solveset.html

1

這也正是這種東西real_roots被用於製成,特別適用於你的情況下係數是整數:

x = Symbol('x') 
eq = int(row["scaleA"])*x**3 + int(row["scaleB"])*x**2 + int(row["scaleC"])*x + int(row["scaleD"]) 
y = real_roots(eq, x) # gives [CRootOf(...), ...] 

CRootOf實例的值可以是評估你需要的任何精度,不應該包含任何虛構部分。例如,

>>> [i.n(12) for i in real_roots(3*x**3 - 2*x**2 + 7*x - 9, x)] 
[1.07951904858] 

注:我記得,解決將發回的根,這是不能夠確認滿足的假設(即如果他們沒有發現是假設然後他們將返回錯誤)。此外,如果您想要解決更多的一致性輸出,@PyRick,請設置標誌dict=True