2010-11-05 76 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