numpy矩阵欺骗 - 逆矩阵和的总和

时间:2013-02-09 00:09:05

标签: python numpy scipy linear-algebra

我正在尝试执行以下操作,并重复直到收敛:

其中每个X i n x pr数组中有r x n x psamplesUn x nVp x pr = 200。 (我正在获得matrix normal distribution的MLE。) 尺寸都可能很大;我期待的事情至少在n = 1000p = 1000V = np.einsum('aji,jk,akl->il', samples, np.linalg.inv(U) / (r*n), samples) U = np.einsum('aij,jk,alk->il', samples, np.linalg.inv(V) / (r*p), samples) 的订单上。

我目前的代码

V = sum(np.dot(x.T, scipy.linalg.solve(A, x)) for x in samples)

这没关系,但当然你永远不应该真正找到反向和乘法的东西。如果我能以某种方式利用U和V是对称和正定的事实,那也是好的。 我希望能够在迭代中计算U和V的Cholesky因子,但由于总和,我不知道如何做到这一点。

我可以通过做

这样的事来避免逆转
samples

(或类似于利用psd-ness的东西),但随后出现了一个Python循环,这让那些笨拙的仙女哭了。

我还可以想象以A^-1 x形式重塑solve,我可以为每x使用U获取V数组,而无需进行Python循环,但这会产生一个大的辅助阵列,浪费内存。

是否有一些线性代数或numpy技巧可以做到最好的三个:没有明确的反转,没有Python循环,没有大的辅助数组?或者我最好用更快的语言实现Python环路并调用它? (直接将它移植到Cython可能会有所帮助,但仍会涉及很多Python方法调用;但是直接制作相关的blas / lapack例程并不会太麻烦。)

(事实证明,我实际上并不需要矩阵{{1}}和{{1}} - 只是他们的决定因素,或者实际上只是他们的Kronecker产品的决定因素。所以如果有人有如何做更少的工作并且仍然得到决定因素的一个聪明的想法,将非常感激。)

1 个答案:

答案 0 :(得分:7)

直到有人提出更有启发性的答案,如果我是你,我会让仙女哭泣......

r, n, p = 200, 400, 400

X = np.random.rand(r, n, p)
U = np.random.rand(n, n)

In [2]: %timeit np.sum(np.dot(x.T, np.linalg.solve(U, x)) for x in X)
1 loops, best of 3: 9.43 s per loop

In [3]: %timeit np.dot(X[0].T, np.linalg.solve(U, X[0]))
10 loops, best of 3: 45.2 ms per loop

因此,拥有一个python循环,并且必须将所有结果加在一起,所需的时间超过了解决200个必须解决的200个系统的200多倍。如果循环和求和是免费的,你得到的改善不到5%。可能还有一些调用python函数开销,但无论你用什么语言编写代码,它仍然可能与解决方程式的实际时间相比可以忽略不计。