我必须评估以下表达式,给出两个非常大的矩阵A,B和一个非常复杂的函数F: The mathematical expression
我在想是否有一种有效的方法可以首先找到那些在矩阵相乘后给出非零元素的索引i,j,这样我就可以避免使用非常缓慢的'for循环'。 / p>
当前工作代码
# Starting with 4 random matrices
A = np.random.randint(0,2,size=(50,50))
B = np.random.randint(0,2,size=(50,50))
C = np.random.randint(0,2,size=(50,50))
D = np.random.randint(0,2,size=(50,50))
indices []
for i in range(A.shape[0]):
for j in range(A.shape[0]):
if A[i,j] != 0:
for k in range(B.shape[1]):
if B[j,k] != 0:
for l in range(C.shape[1]):
if A[i,j]*B[j,k]*C[k,l]*D[l,i]!=0:
indices.append((i,j,k,l))
print indices
正如您所看到的,为了获得我需要的索引,我必须使用嵌套循环(=巨大的计算时间)。
答案 0 :(得分:0)
我的猜测是否定的:你无法避免for循环。为了找到所有索引ij
,您需要遍历所有违反此检查目的的元素。因此,您应该继续使用numpy
中的简单数组元素乘法和点积 - 对于由numpy
处理的循环,它应该非常快。
但是,如果您计划使用Python循环,那么答案是肯定的,您可以使用numpy
使用以下伪代码(=挥手)来避免它们:
i, j = np.indices((N, M)) # CAREFUL: you may need to swap i<->j or N<->M
fs = F(i, j, z) # array of values of function F
# for a given z over the index grid
R = np.dot(A*fs, B) # summation over j
# return R # if necessary do a summation over i: np.sum(R, axis=...)
如果问题是计算fs = F(i, j, z)
是一个非常慢的操作,那么你必须使用内置于A
的两个循环来识别numpy
的零个元素(所以他们很快):
good = np.nonzero(A) # hidden double loop (for 2D data)
fs = np.zeros_like(A)
fs[good] = F(i[good], j[good], z) # compute F only where A != 0