2010-11-05 51 views
1

我開始在python上編程,但我有一個內存問題(抱歉我的英語不好)。 我在我的算法上做了一個while循環,但是在每一個cicle上,程序都會消耗大量的內存。我有3Gb的內存AMD 64 x2處理器和Windows 7 64位。Python內存問題

對於每一個cicle,它消耗大約800 Mb的RAM,這是我想太多了。我的代碼 部分原因是這裏

from sympy import Symbol, diff, flatten 
import numpy as np 
from numpy import linalg 
from math import log, sqrt, cos, pi 
import matplotlib.pyplot as plt 

L = 7 #numero de variables 
X = [Symbol('x%d' % i) for i in range(L*(L+1))] #Las variables simbolicas 
XX = [X[i] for i in xrange(L)] 

LAM = []  

# Parametros 
Pr = 10 
Eps = 0 
Ome = 5 
LL = 0.5 
b = 2 
Gam = 0.2*2*(pi**2) 


ran1 = xrange(L) 
ran2 = xrange(L*L) 
ran3 = xrange(0,L*(L-1)+1,L) 
ran4 = xrange(L,2*L,1) 

dt = 0.01 
TMAX = 60 

def f(x,R,Tau): 
    return [Pr*((1 + Eps*cos(Ome*Tau))*x[2] - LL*x[0] - (1 -LL*x[5])) , \ 
     Pr*((1 + Eps*cos(Ome*Tau))*x[3] - LL*x[1] - (1 - LL)*x[6]),\ 
     R*x[0] - x[2] - x[0]*x[4],R*x[1] - x[3] - x[1]*x[4],(x[0]*x[2] + x[1]*x[3])/2 - b*x[4],\ 
     (1/Gam)*(x[0] - x[5]),(1/Gam)*(x[1] - x[6])] 

def Jacobian(f,x):   #num son los numeros en el que se evalua la matriz jacobiana, x las variables y f la funcion 
    return [[diff(f[i],x[n]) for i in ran1] for n in ran1] 

def Y(x): 
    return[[x[i+j] for j in ran3] for i in ran4] 
    #Ahora la multiplicacion de Y traspuesto por Jacobian traspuesto 
def JY(r,Tau): 
    J = flatten((np.dot(np.array(Jacobian(f(XX,r,Tau),XX)),np.array(Y(X)))).T) 
    return [J[i] for i in ran2] 
def Func(x,r,Tau):   #Expandemos las funciones en un solo arreglo 
    FFF = [] 
    map(lambda g: FFF.append(g),f(XX,r,Tau)) 
    map(lambda g: FFF.append(g),JY(r,Tau)) 
    return map(lambda f: f.evalf(subs={X[j]:x[j] for j in xrange(L*(L+1))}),FFF) 

def RKutta(xi,r): 
    i = 1 
    while i <= int(TMAX/dt): 
     Tau = 0 
     YY = xi 
     k1 = np.array(Func(YY,r,Tau))*dt 
     k2 = (np.array(Func(YY + k1/2,r,Tau/2)))*dt 
     k3 = (np.array(Func(YY + k2/2,r,Tau/2)))*dt 
     k4 = (np.array(Func(YY + k3,r,Tau)))*dt 
     xi = YY + (k1/6) + (k2/3) + (k3/3) + (k4/6) 
     Tau = Tau + dt 
     i = i + 1 
    return [xi[j] for j in xrange(len(xi))] 


def lyap(xxi): 
    u = [i for i in flatten(np.random.rand(1,L))] 
    PhiT = (np.array([[float(xxi[i+j]) for j in ran3] for i in ran4])).T 
    PU = np.dot(PhiT,u) 
    summ = 0 
    jj = 0 
    while jj < len(PU): 
     summ += (float(PU[jj]))**2 
     jj = jj + 1 
    lam = log(sqrt(summ))/TMAX 
    return lam 

R = 46.5 
Rmax = 48.5 
Rstep = 0.5 

while R <= Rmax: 
    xi = [5,5,5,5,5,5,5] #Condiciones Iniciales 
    for i in ran2: 
     xi.append(None) 

    for i in ran4:      
     for j in ran3:   
      if (i+j+1)%(L+1) == 0: 
       xi[i+j] = 1 
      else: 
       xi[i+j] = 0 

    #Ahora el Runge Kutta para integrar todo el sistema 


     #Y.append([r for r in xx]) 
    # savetxt('butterfly.txt', Y, fmt="%12.6G") 
    #print Y 
    XI = RKutta(xi,R) 
    lamb = lyap(XI) 
    LAM.append([R,lamb]) 
    print [R,lamb] 
    R = R + Rstep 
#print LAM 
#x = [LAM[i][0] for i in xrange(len(LAM))] 
#y = [LAM[i][1] for i in xrange(len(LAM))] 
np.savetxt('lyap3.txt', LAM, fmt="%12.6G") 
#plt.axis([10,30,-3,3]); 
#plt.scatter(x,y) 
#plt.show() 

我不知道哪裏出了問題可能是。也許在龍格庫塔步驟或架構問題。內存似乎沒有在每一步清理,我不存儲任何東西,只是在代碼末尾的一對數字。 我希望我表達得很好。

OK,我編輯這並張貼整個代碼,我希望有人能幫助:)。我改變了很多東西,但我仍然有記憶問題。每個cicle使用大約600 Mb的RAM。

在此先感謝

+0

您的代碼在語法上不是正確的Python,因爲縮進是混亂的。那個while循環裏面應該是什麼?另外,L,R,LL的值是多少? – 2010-11-05 22:03:47

+3

您每縮排只有1個空格?你是一個邪惡的邪惡的人。 – delnan 2010-11-05 22:06:18

+0

L只是變量的數量,在這個例子中是7.我有另一個變量有3個變量,但它仍然消耗大量的內存。 – 2010-11-05 22:07:35

回答

0

什麼是L·大部分代碼使用O(L^2)存儲,所以如果L很大,那就是它。

+0

L只是7,變數的數量 – 2010-11-05 22:16:15

0

好像你正在實例化非常大的列表。看看你是否不能用迭代器替換一些列表推導。

+0

那是怎麼回事?我用'whiles'取代了'for'cicles,如果這是你的意思:0 – 2010-11-05 22:12:25

+0

@David Winchester:不,請查看python itertools以獲取迭代器的示例實現。查看您的計算是否無法「隨時隨地」進行,而不是「稍後累積大量清單和處理」。 – 2010-11-05 22:19:33

+0

我試圖在cicle之前做出很多功能,所以我沒有使用大型列表,內存使用量少得多,但問題是計算速度太慢,所以我把所有內容都放在了大型的cicle中。 – 2010-11-05 22:31:38

1

在沒有上下文的情況下遵循代碼有點棘手,因爲您已經明顯在多個位置使用numpy(既可以是np也可以不帶前綴),並且evalf可能來自sympy ..但是我們看不到您的進口。

在一個非常含糊的猜測中,一些列表推導構建了臨時列表,這些列表的周圍時間比預期的要長。你也許可以把它們轉換成發電機。另一種技術是儘可能使用map()或類似的方法。

我也注意到一些不需要的unpythonic索引迭代。 Func首先建立一個名爲FFF的列表,一次一個項目(相當昂貴),然後通過索引遍歷它,沒有真正的原因。使用[f(item) for item in seq]而不是[f(seq[i]) for i in xrange(len(seq))],或更好的是map(f, seq),在這種情況下,請嘗試不要構建臨時列表。

+0

我認爲這是一個好主意,但我不知道如何使用地圖evalf,因爲它是像FFF.evalf()而不是evalf() – 2010-11-06 17:31:34

+0

我只是做了它,我不得不使用lambda函數。感謝您的回答 :) – 2010-11-06 17:43:46