Python 3:优化scipy数组上的求和

Python 3:优化scipy数组上的求和,python,arrays,optimization,numpy,scipy,Python,Arrays,Optimization,Numpy,Scipy,我目前正在解决一个问题,我必须对scipy/numpy数组的特定条目进行求和,我正在寻找一种方法来完全摆脱所有Python for循环。我在Mac OS X上使用Python3.3。下面是我正在做的一个求和示例,为了这个示例,我对填充了随机整数的数组项求和 from scipy import ones, conjugate, sum, random n = 5 M = random.randint(5,size=(4*n**2,4*n**2)) H = sum((M[i+1,:2*n**2]*

我目前正在解决一个问题,我必须对scipy/numpy数组的特定条目进行求和,我正在寻找一种方法来完全摆脱所有Python for循环。我在Mac OS X上使用Python3.3。下面是我正在做的一个求和示例,为了这个示例,我对填充了随机整数的数组项求和

from scipy import ones, conjugate, sum, random

n = 5
M = random.randint(5,size=(4*n**2,4*n**2))
H = sum((M[i+1,:2*n**2]*M[i,:2*n**2].conjugate()).sum() * (-M[i,:2*n**2]*M[i+1,:2*n**2].conjugate()).sum() for i in range(0,2*n**2,2))
我首先计算两个矩阵项的乘积,然后对一半的列求和。我这样做了两次,然后以两步一步的方式对一半以上的行求和

这可能看起来很奇怪,但我使用的是晶格系统的哈密顿量,其中每一行对应于某个晶格点,偶数行和奇数行代表自旋向上或向下。n最终会很大,我需要把这个求和的速度加快一点

现在,我不知道如何摆脱for循环。我尝试在行索引中使用range()-参数,但没有得到相同的结果

谢谢

这个怎么样:

# We need a complex test case to make sure the conjugate works properly
M = (random.randint(5,size=(4*n**2,4*n**2)) +
     random.randint(5,size=(4*n**2,4*n**2))*1j)

H_bis = np.sum(M[1:2*n**2:2, :2*n**2] * M[:2*n**2:2, :2*n**2].conjugate(),
               axis=-1)
H_bis *= np.sum(-M[:2*n**2:2, :2*n**2] * M[1:2*n**2:2, :2*n**2].conjugate(),
                axis=-1)
H_bis = np.sum(H_bis)
>>> np.allclose(H, H_bis)
True

我觉得你能做到

H_bis = np.sum(M[1:2*n**2:2, :2*n**2] * M[:2*n**2:2, :2*n**2].conjugate(), axis=1)
H_bis = H_bis * H_bis.conjugate()
H_bis = -np.sum(H_bis)

是我,还是你只使用了数组的四分之一?是的,我通过对角化矩阵得到数组,M对应于填充了特征向量的矩阵。我已经对求和进行了变换,使得循环是最短的。其他求和将使用数组的不同部分。我想你可能缺少一个共轭。你完全正确,我误读了索引,它只起作用,因为他的数据是真实的……是我还是比原来的慢?对于OP的
n=5
值,我得到了x8.5的加速。但是对于更大的
n
情况,我们的系统在
n=20
时,OP的方法实际上要快一点。可能是因为这种矢量化的方法,特别是没有优化的情况下,占用的内存要多得多。