2010-06-22 32 views
6

我需要編寫一些代碼來處理生成和操作多元多項式。我將用簡單的例子概述我的任務。用於操作多元多項式的庫

假設我有三個表達式:2x^2,3y + 1和1z。然後我需要把它們放在一起,這會給我6x^2yz + 2x^2z。然後我想找出這個表達式關於x,y和z的偏導數。這會給我12xyz + 4xz,6x^2z和6x^2y + 2x^2。

我的問題涉及在包含數千個變量的表達式上做這樣的簡單操作,我需要一個簡單的方法來系統地完成此操作。我真的很喜歡使用python,因爲我已經使用numpy/scipy/matplotlib完成了許多與項目相關的功能,但是如果在另一種語言中存在強大的工具箱,我也願意使用它。我正在進行大學研究,所以我也願意使用Matlab。

我一直沒能找到任何好的python庫,可以很容易地做到這一點,理想情況下,想要類似於scipy polynomial routines可以在多維多項式上工作的東西。有誰知道一個好的庫,似乎適合這個問題,這將很容易集成到已經存在的Python代碼?

謝謝!

跟進:我花了幾天工作sympy,結果是非常容易使用。然而,對於我正在研究的問題的規模來說,這很慢,所以我現在要去探索matlab。爲了使用小樣本量對速度進行非常粗略的估計,需要大約5秒來計算包含250個變量的2階多項式的每個偏導數。

後續行動#2:當我還在處理這個問題時,我可能應該做到這一點,但我可能會讓每個人都知道matlab符號庫在速度上與sympy極其相似。換句話說,對於大型計算而言,這是非常緩慢的。這兩個庫非常容易使用,所以對於小型計算,我強烈推薦。

爲了解決我的問題,我手工計算了漸變,簡化了它們,然後使用我發現的模式在我的代碼中硬編碼了一些值。這是更多的工作,但使我的代碼指數更快,最終可用。

+0

你的榜樣代表性如何?如果你的起始多邊形只是一個var的函數,那麼問題就更容易了。 – 2010-06-22 22:15:07

+1

+1:真的很好的問題。我正在*要*建議SymPy,它明顯做符號計算(與標記的庫不同),但它似乎只做數值分化! http://docs.sympy.org/modules/mpmath/calculus/differentiation.html – 2010-06-22 22:19:55

+0

@尼克希爾:sympy也做象徵性的分化。看我下面的例子。 – 2010-06-22 22:31:08

回答

9

Sympy是適合這個:http://code.google.com/p/sympy/

文檔:http://docs.sympy.org/

從教程分化的例子:http://docs.sympy.org/tutorial.html#differentiation

import sympy 

x, y, z = sympy.symbols('xyz') 

p1 = 2*x*x 
p2 = 3*y + 1 
p3 = z 

p4 = p1*p2*p3 

print p4 

print p4.diff(x) 
print p4.diff(y) 
print p4.diff(z) 

輸出:

2*z*x**2*(1 + 3*y) 
4*x*z*(1 + 3*y) 
6*z*x**2 
2*x**2*(1 + 3*y) 
+0

+1:重讀文檔,他們確實提到數字參數是可選的,爲什麼......奇怪的是,他們有**沒有**符號區分的例子。 – 2010-06-22 22:34:44

+0

這對我所需要的是完美的。謝謝你的例子! – Spike 2010-06-23 01:17:08

+0

@Nikhil:謝謝你也在爲我着想!我對SO – Spike 2010-06-23 01:19:32

1

您提到的Matlab和其他工具通常會進行數值計算。您應該考慮使用Mathematica或替代Computer Algebra System(CAS)進行符號計算。查看wiki鏈接:http://en.wikipedia.org/wiki/Comparison_of_computer_algebra_systems可以比較各種CAS。

+0

感謝您的意見。我將首先嚐試sympy,因爲我愛Python,它將是迄今爲止最簡單的代碼。如果由於某種原因它太慢了(我發現某些scipy優化方法在大數據集之前會很慢),那麼我肯定會在另一個環境中嘗試它。 – Spike 2010-06-23 01:23:24

2

如果您正在使用MATLAB,象徵性的結核病效果很好,如果你有的話。如果沒有,請使用我的sympoly工具箱。只需從文件交換中下載它。

sympoly x y z 
A = 2*x^2; B = 3*y + 1;C = 1*z; 
gradient(A*B*C) 

ans = 
Sympoly array has size = [1 3] 

Sympoly array element [1 1] 
    4*x*z + 12*x*y*z 
Sympoly array element [1 2] 
    6*x^2*z 
Sympoly array element [1 3] 
    2*x^2 + 6*x^2*y 

請注意,這指出你在你的問題中區分結果與z的區別是錯誤的。

+0

的幫助印象非常深刻感謝您發現我的錯誤。你的sympoly工具箱看起來不錯,如果我最終不得不爲這個問題使用Matlab,我會給它一個旋風。 – Spike 2010-06-23 13:04:09