重写几个矩阵运算以避免内存错误?

Rewrite several matrix operations to avoid memory error?

我有一个非常大的矩阵。 buildmatrix 是一个 N × N 矩阵。所以 sumHamiltonian 是 N^2 乘 N^2 矩阵。然后 transform(N) 是 N^2 x N(N-1)/2 矩阵。 (因此得到的 shortHamiltonian(N) 是一个 N(N-1)/2 x N(N-1)/2 矩阵)。矩阵项也是复数。

如果 N=200,我得到一个内存错误。有没有办法重写:

def sumHamiltonian(N):
    return 0.5*(np.kron(buildmatrix(N),np.identity(N))+np.kron(np.identity(N),buildmatrix(N)))

def shortHamiltonian(N):
    return np.matmul(np.transpose(transform(N)),np.matmul(sumHamiltonian(N),transform(N)))

减少内存?

我看到了一些减少矩阵乘法内存的方法 (Python/Numpy MemoryError),这很有用,但我的内存错误出现在 kronecker 产品上。有没有办法重写这个,或者更好的是,所有矩阵运算以避免内存错误?

根据你有多少内存过剩,你可以通过使用类似 .astype(np.float32) 的东西来减小矩阵的大小(例如,如果当前 dtypenp.float64).

buildmatrix(N) 在同一行中被调用两次(与 transform 相同)。如果结果是确定性的(你只是想使用相同的结果)然后尝试将它分配给一个变量,这样它只需要被调用一次。

这些技巧可能会略微减少内存配置文件,但可能不够,也可能不够。我不确定计算是否也可以通过一些身份来简化。

一个建议是使用稀疏矩阵。另外,如果可能的话,让你的 buildmatrix 到 return 成为 dtype np.complex64 而不是 np.complex128 的矩阵。请参阅以下示例:

from scipy import sparse


def buildmatrix(N):
    return (np.random.rand(N, N) + np.random.rand(N, N) * 1j).astype(np.complex64)

N = 100

m = buildmatrix(N)
I = np.identity(N)
sumHamiltonian = 0.5 * (np.kron(m, I) + np.kron(I, m))
print(f'{sumHamiltonian.nbytes * 1e-9} GB')
#1.6 GB

m_s = sparse.csr_matrix(m)
I_s = sparse.identity(N)
sumHamiltonian_s = 0.5 * (sparse.kron(m_s, I_s) + sparse.kron(I_s, m_s))
print(f'{sumHamiltonian_s.data.nbytes * 1e-6} MB')
#31.84 MB

#np.all(sumHamiltonian == sumHamiltonian_s)
#True

同样尝试将您的 shortHamiltonian 转换为 "sparse version"。