我需要反转一个大的,密集的矩阵,我希望使用Scipy的gmres
来做。幸运的是,密集矩阵A
遵循模式,我不需要将矩阵存储在内存中。 LinearOperator
类允许我们构造一个对象,该对象充当GMRES的矩阵,并且可以直接计算矩阵向量乘积A*v
。也就是说,我们编写一个函数mv(v)
,它将向量v
作为输入并返回mv(v) = A*v
。然后,我们可以使用LinearOperator
类来创建A_LinOp = LinearOperator(shape = shape, matvec = mv)
。我们可以将线性运算符放入Scipy gmres
命令中来评估矩阵向量积,而无需将A
完全加载到内存中。
LinearOperator
的文档位于:LinearOperator
Documentation。
这是我的问题:要编写例程来计算矩阵向量积mv(v) = A*v
,我需要另一个输入向量C
。 A
中的条目的格式为A[i,j] = f(C[i] - C[j])
。所以,我真正想要的是mv
有两个输入,一个固定向量输入C
,一个变量输入v
我们要计算A*v
。
MATLAB有类似的设置,写x = gmres(@(v) mv(v,C),b)
,其中b
是问题Ax = b
的右侧,而mv
是一个函数,我们想要计算v
和A*v
的变量输入C
是A
汇总所需的固定已知向量。
我的问题是我无法弄清楚如何允许LinearOperator
类接受两个输入,一个变量和一个“固定”,就像我在MATLAB中一样。
有没有办法在SciPy中进行类似的操作?或者,如果有人知道更好的方法来反转大型密集矩阵(50000, 50000)
,其中条目遵循模式,我将非常感谢任何建议。
谢谢!
编辑:我本应该说明这些信息。矩阵实际上是(以块形式)[A C; C^T 0]
,其中A
是N x N
(N
大)而C
是N x 3
,并且0
为3 x 3
,C^T
为C
的转置。此数组C
与上面提到的数组相同。 A
的条目遵循模式A[i,j] = f(C[i] - C[j])
。
我写mv(v,C)
为A*v[i]
逐行构建i=0,N
,计算总和f(C[i]-C[j)*v[j]
(实际上,我numpy.dot(FC,v)
FC[j] = f(C[i]-C[j])
哪个效果很好)。然后,在最后进行C^T
行的计算。我希望最终用multiprocessing
调用替换大型for循环以并行化for循环,但这是未来需要考虑的事情。我还将研究如何使用Cython来加速计算。
答案 0 :(得分:1)
现在已经很晚了,但如果你还有兴趣......
你的A矩阵必须是非常低的秩,因为它是秩-2矩阵的非线性变换版本。再加上它是对称的。这意味着反转是微不足道的:用例如5个特征值得到截断的特征值分解:A = U * S * U',然后反转:A ^ -1 = U * S ^ -1 * U'。 S是对角线,因此价格便宜。您可以使用eigh获得截断的特征值分解。
负责A.然后其余部分:使用block matrix inversion formula。看起来很讨厌,但我敢打赌100,000,000普鲁士法郎,它比你使用的直接方法快50倍。
答案 1 :(得分:0)
我遇到了相同的情况(比您晚了几年),试图对 LinearOperator 使用多个参数,但又遇到了另一个问题。我发现的解决方案是使用全局变量,以避免将变量作为参数传递给函数。