我有一个大矩阵M(M是正定),维度(10000,10000),我想做以下操作:
r = transpose(e_i - e_j) * M * (e_i - e_j)
where e_i is zeros vector(10000 x 1) with all zero entries except at ith entry
我想对(e_1,e_2)......执行此操作....(e_1,e_10000)...即所有i,j对都属于{1,10000}。
我试过
-do the calculation directly
-Cholesky factorization
然而,这两种方法都需要很长时间。他们花了≥0.5秒来完成一次计算,因此在时间上是不可行的。
有没有方法/库可以尝试加快这个过程?
答案 0 :(得分:1)
你应该研究Strassen Algorithm.它是为O(n ^ 2.8)中的大矩阵乘法而设计的。示例实施here.
答案 1 :(得分:0)
您的表达是transpose(e_i - e_j) * M * (e_i - e_j)
。让我们取最后一部分M * (e_i - e_j)
并将其乘以得到M * e_i - M * e_j
。
现在e_i
为零,除了i
元素M * e_i
之外只选择i
M
列,我们可以做计算为M[:,i]
。再次将点积与e_i
一起使用,即可得到M[i,i]
。
将你的表达完全相乘并将这个想法应用于所有4个术语,给出了@dmuir在上述评论中给出的答案:
r = M[i,i] - M[j,i] - M[i,j] + M[j,j]
这个表达式应该非常快,并且(原则上)根本不依赖于矩阵的大小。因此,您实际上根本不需要任何矩阵运算来计算您的要求。
由于你说你想要为所有i,j对做这个,你可能希望得到一个矩阵R
,这样R[i, j]
就像上面给出的r
一样。您可以在i, j
的循环中执行那,或者您可以使用类似
d = np.array([np.diag(a)])
R = d + d.T - M - M.T
对于您所说的尺寸,我希望整个操作在大约1秒内完成。
考虑到矩阵的大小,我可能会尝试避免使用
的临时工具d = np.array([np.diag(a)])
R = d + d.T
R -= M
R -= M.T