假设我有一个对称的正半定矩阵A(numpy
数组)的“LDL^T”分解,并且我想将所有因子相乘得到A 。LDL的Numpy阵列乘法对称矩阵的分解乘法
什么是最有效的方法来实现这一目标?
目前,我正在做的(D可作为“矢量”): np.dot(np.dot(L, np.diag(D)), L.T)
, 这显然是一个不好的解决方案。
假设我有一个对称的正半定矩阵A(numpy
数组)的“LDL^T”分解,并且我想将所有因子相乘得到A 。LDL的Numpy阵列乘法对称矩阵的分解乘法
什么是最有效的方法来实现这一目标?
目前,我正在做的(D可作为“矢量”): np.dot(np.dot(L, np.diag(D)), L.T)
, 这显然是一个不好的解决方案。
方法#1
我们可以使用elementwise multiplication
,然后matrix-multiplication
。这基本上取代np.dot(L, np.diag(D))
与直接element-wise multiplication
希望有些加速。所以,有了它,执行将成为 -
(L*D).dot(L.T)
方法2
另一种方法可能是用np.einsum
做所有这些事情在一走,像这样 -
np.einsum('ij,j,kj->ik',L,D,L)
运行时间测试
In [303]: L = np.random.randint(0,9,(1000,1000))
In [304]: D = np.random.randint(0,9,(1000))
In [305]: %timeit np.dot(np.dot(L, np.diag(D)), L.T)
1 loops, best of 3: 3.87 s per loop
In [306]: %timeit (L*D).dot(L.T)
1 loops, best of 3: 1.39 s per loop
In [307]: %timeit np.einsum('ij,j,kj->ik',L,D,L)
1 loops, best of 3: 1.71 s per loop
上并不一定有1x1块。我认为方法#1最快(快速检查了一些时间点,但没有正式的基准测试)。我认为元素明智地指的是真正的元素,而不是每个列乘以右手矢量中的相应元素。 – NoBackingDown
感谢您的基准测试。我认为相对表现将取决于维度,第二种方法与第一种方法相比会越来越有利。 – NoBackingDown
@Dominik我很难选择,因为应用程序#1确实是matrix-mult,这个问题实质上是基于它。尽管应用#1的负面影响是创建应用#2闪耀的中间阵列。我猜想在更大的阵列中,考虑到内存效率,'einsum'可能会更好。 – Divakar
@Divakar当然,已经迟到了^^。 – NoBackingDown
请注意,LDL^T在对角线 – percusse