【发布时间】:2013-07-29 06:21:44
【问题描述】:
一年多前,我和这里的提问者几乎完全一样: fast way to invert or dot kxnxn matrix
所以我有一个具有维度 (N,M,M) 的索引 a[n,i,j] 的张量,我想为 N 中的每个 n 反转 M*M 方阵部分。
例如,假设我有
In [1]: a = np.arange(12)
a.shape = (3,2,2)
a
Out[1]: array([[[ 0, 1],
[ 2, 3]],
[[ 4, 5],
[ 6, 7]],
[[ 8, 9],
[10, 11]]])
然后 for 循环反转将如下所示:
In [2]: inv_a = np.zeros([3,2,2])
for m in xrange(0,3):
inv_a[m] = np.linalg.inv(a[m])
inv_a
Out[2]: array([[[-1.5, 0.5],
[ 1. , 0. ]],
[[-3.5, 2.5],
[ 3. , -2. ]],
[[-5.5, 4.5],
[ 5. , -4. ]]])
这显然将在 NumPy 2.0 中实现,根据 github 上的this issue...
我想我需要按照 github 问题线程中提到的 seberg 安装开发版本,但是现在有没有其他方法可以以 vectorized 方式执行此操作?
【问题讨论】:
-
答案是否定的,但还不错:Gauss-Jordan matrix inversion is an O(
M^3) operation,所以它将主导性能,除非N>>>M^3。 -
谢谢你的好点,杰米!顺便说一句,当我的代码正常工作时,N 大约在 10^3...10^5 和 M 之间 2...6 并且可能更高...
-
如果主 for 循环是问题所在,也许 Cython 可以提供帮助。在 for 循环的中间会有一个 Python 函数调用,但应该还是会比较快。
-
鉴于这已在即将发布的版本中“修复”,我不知道是否值得尝试过于聪明。但是,您可以将矩阵视为块对角线或带状矩阵。 scipy.linalg 中有用于带状矩阵的例程。由于 M 不是太大,您可以使用它们(例如,solved_banded,如果您的矩阵有更多结构,则可以使用它们)。当然你还得建带状矩阵,带状里面还是会有很多零等等,所以不知道你最后会不会赢。
-
嗯,好点,克雷格...我想我会试试带状矩阵!我想生成非常大的零数组并不是很耗时......
标签: python numpy matrix scipy vectorization