快速反转或点kxnxn矩阵的方法

时间:2012-02-14 21:27:52

标签: matrix numpy scipy

是否有一种使用numpy计算kxnxn矩阵的逆的快速方法(在每个k切片计算逆值)?换句话说,有没有办法矢量化以下代码:

>>>from numpy.linalg import inv
>>>a-random(4*2*2).reshape(4,2,2)
>>>b=a.copy()
>>>for k in range(len(a)):
>>>    b[k,:,:] = inv(a[k,:,:])

1 个答案:

答案 0 :(得分:3)

首先要做的是反过来。我查看了np.linalg.tensorinvnp.linalg.tensorsolve

我认为遗憾的是tensorinv不会给你你想要的东西。它需要数组为“方形”。这排除了你想要做的事情,因为它们对square的定义是np.prod(a[:i]) == np.prod(a[i:]),其中i是0,1或2(一般是数组的一个轴);这可以作为ind的第三个参数tensorinv给出。这意味着如果你有一个长度为M的NxN矩阵的一般数组,你需要有例如(对于i = 1)NxN == NxM,这在一般情况下是不正确的(在您的示例中它实际上是正确的,但无论如何它都没有给出正确答案)。

现在,tensorsolve可能会有所作为。然而,这将涉及a矩阵数组的一些繁重的构造工作,然后作为tensorsolve的第一个参数传递。因为我们希望b成为“矩阵阵列方程”a*b = 1的解决方案(其中1是一个标识矩阵数组),而1将具有相同的形状为ab,我们不能简单地将您在上面定义的a作为tensorsolve的第一个参数。相反,它需要是一个形状(M,N,N,M,N,N)或(M,N,N,N,M,N)或(M,N,N,N,N,M)的阵列)。这是必要的,因为tensorsolve将在最后三个轴上乘以b并对它们求和,以便结果(函数的第二个参数)再次成形(M,N,N) )。

其次,关于点积(你的标题表明这也是你问题的一部分)。这是非常可行的。两个选项。

首先:this blog post by James Hensman提供了一些很好的建议。

第二:我个人更喜欢更清楚地使用np.einsum。 E.g:

a=np.random.random((7,2,2))
b=np.random.random((7,2,2))
np.einsum('ijk,ikl->ijl', a,b)

这将矩阵乘以数组ab中的所有7个“矩阵”。它似乎比上面的博客文章中的数组方法慢了约2倍,但它仍然比使用for循环快70倍,就像在你的例子中一样。事实上,对于较大的数组(例如10000 5x5矩阵),einsum方法似乎稍微快一点(不确定原因)。

希望有所帮助。