2013-01-03 80 views
0

同樣,我有一個關於大循環的問題。在其他編程語言中的Python循環傳輸

假設我有一個功能

limits

def limits(a,b): 
    *evaluate integral with upper and lower limits a and b* 
    return float result 

A和B是我的存儲值a和b簡單np.arrays。現在我想計算積分300'000^2/2次,因爲A和B的長度都是300'000,積分是對稱的。

在Python中,我嘗試了幾種方法,如itertools.combinations_with_replacement創建A和B的組合,然後將它們放入積分中,但需要大量時間並且內存完全超載。 有沒有什麼辦法,例如用另一種語言傳遞循環,以加快速度?

我想運行循環

for i in range(len(A)): 
    for j in range(len(B)): 
    np.histogram(limits(A[i],B[j])) 

我覺得histrogramming的limits回報是爲了不存儲增長正視其他陣列可取的。

從我讀的python不是真正的這個迭代ansatzes最好的選擇。

因此,如果是的話,在Python中用另一種語言評估這個循環是合理的,如何去做。我知道有些方法可以傳輸代碼,但我從來沒有這樣做過。

感謝您的幫助。

+1

'itertools.combinations'和朋友產生迭代器。通常,你直接循環這些內容,而不是嘗試在內存中擴展它們(例如,通過將它們轉換爲列表)。您不需要隨機訪問的所有中介結果,對嗎? –

+0

300k^2/2 = 450億。只是將它移植到另一種語言不會削減它,你需要強健的硬件和巧妙的優化才能開始。 – delnan

+0

@MartijnPieters,不,我不需要中間結果,只是最後(histrogrammed)之一。 delnan,在C中有一段代碼,總共在4個小時內管理它。我想同樣高效。 – madzone

回答

0

如果你擔心內存佔用,你需要做的就是將結果放入for循環。

num_bins = 100 
bin_upper_limits = np.linspace(-456, 456, num=num_bins-1) 
# (last bin has no upper limit, it goes from 456 to infinity) 
bin_count = np.zeros(num_bins) 
for a in A: 
    for b in B: 
     if b<a: 
      # you said the integral is symmetric, so we can skip these, right? 
      continue 
     new_result = limits(a,b) 
     which_bin = np.digitize([new_result], bin_upper_limits) 
     bin_count[which_bin] += 1 

因此,沒有大的內存被保存在內存中。

至於速度,我想絕大多數時間都花在評估limits(a,b)上。在這種情況下,循環和分箱是非常快速的,即使在python中也是如此。要說服自己,請嘗試用new_result = 234替換new_result = limits(a,b)行。你會發現循環運行速度非常快。 (在我的電腦上幾分鐘,遠遠低於你引用的4小時的數字)。與C相比,Python不會快速循環,但在這種情況下並不重要。

無論您如何加快limits()調用(包括使用其他語言實現),都會加速該程序。

如果改變算法,還有很大的改進空間。我們來看看你在做什麼。假設A和B是0,1,2,3。您正在將函數集成到0 - > 0,0 - > 1,1 - > 1,1 - > 2,0 - > 2等等。您正在重新執行同樣的工作一遍又一遍。如果你已經集成了0 - > 1和1 - > 2,那麼你可以將這兩個結果相加得到積分0 - > 2。您不必使用花哨的整合算法,只需添加兩個您已知的數字即可。

因此,在我看來,你可以計算所有最小範圍內的積分(0 - > 1,1 - > 2,2 - > 3),將結果存儲在數組中,並將結果的子集結果得到你想要的任何範圍的積分。如果你想讓這個程序運行幾分鐘而不是4個小時,我建議你通過一個替代算法來思考這些問題。

(很抱歉,如果我誤解你正在試圖解決這個問題。)

+0

感謝您的回答。我使用'np.histogram'直接對輸出進行直方圖分析,類似於您的建議。不過,我認爲循環會導致他的問題,而不是我工作的簡單功能。 我真的嘗試了一個月來提高這一點,但在Python中失敗。 – madzone

+0

有沒有一種方法可以像MPI那樣爲'C'並行化或者評估其他語言的循環? – madzone