我正在尝试执行以下操作,并重复直到收敛:
其中每个 X i是n x p
,并且r
它们在一个r x n x p
名为 的数组中samples
。U
是n x n
,V
是p x p
。(我得到了矩阵正态分布的 MLE 。)尺寸都可能很大;我期待的事情至少在 r = 200
, n = 1000
, p = 1000
.
我当前的代码确实
V = 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)
这行得通,但当然你永远不应该真正找到逆并乘以它。如果我能以某种方式利用 U 和 V 是对称且正定的这一事实,那也很好。我希望能够在迭代中计算 U 和 V 的 Cholesky 因子,但由于总和,我不知道该怎么做。
我可以通过做类似的事情来避免相反的情况
V = sum(np.dot(x.T, scipy.linalg.solve(A, x)) for x in samples)
(或类似利用 psd 的东西),但是有一个 Python 循环,这让 numpy 仙女哭了。
我还可以想象samples
以这样一种方式进行重塑,即我可以获得一个A^-1 x
using solve
for each的数组,x
而无需执行 Python 循环,但这会产生一个很大的辅助数组,这会浪费内存。
是否有一些线性代数或 numpy 技巧可以让我充分利用这三者:没有显式逆,没有 Python 循环,没有大的辅助数组?或者我最好的选择是用一种更快的语言实现一个 Python 循环并调用它?(直接将其移植到 Cython 可能会有所帮助,但仍会涉及大量 Python 方法调用;但直接制作相关的 blas/lapack 例程可能不会太麻烦而没有太多麻烦。)
(事实证明,我实际上并不需要矩阵U
,V
最后 - 只是它们的行列式,或者实际上只是他们的 Kronecker 乘积的行列式。因此,如果有人对如何减少工作并仍然获得决定因素,那将不胜感激。)