重写几个矩阵运算以避免内存错误?
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)
的东西来减小矩阵的大小(例如,如果当前 dtype
是 np.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"。
我有一个非常大的矩阵。 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)
的东西来减小矩阵的大小(例如,如果当前 dtype
是 np.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"。