python中预处理的共轭梯度和LinearOperator

时间:2015-09-30 12:16:12

标签: python scipy linear-algebra preconditions

[Homework]我将通过Preconditioned Conjugate Gradient方法解决线性系统Ax = b,并使用scipy.sparse.linalg中的spilu函数作为预处理器。 A是稀疏对称的162 * 162矩阵。由于spilu给出A的倒数的近似值,比如M近似A,所以spilu(A)给出M ^ -1,这是预处理器。我发现我们可以直接在python Conjugate Gradient函数中给出预处理器,但是下面的代码不起作用。

M_inverse=scipy.sparse.linalg.spilu(A)
M2=scipy.sparse.linalg.LinearOperator((162,162),M_inverse.solve)
x3=scipy.sparse.linalg.cg(A,b,M2)
TypeError                                 Traceback (most recent call last)
<ipython-input-84-86f8f91df8d2> in <module>()
----> 1 x3=scipy.sparse.linalg.cg(A,b,M2)

/Users/ruobinghan/anaconda/lib/python3.4/site-packages/scipy/sparse/linalg/isolve/iterative.py in cg(A, b, x0, tol, maxiter, xtype, M, callback)

/Users/ruobinghan/anaconda/lib/python3.4/site-packages/scipy/sparse/linalg/isolve/iterative.py in non_reentrant(func, *a, **kw)
     83     try:
     84         d['__entered'] = True
---> 85         return func(*a, **kw)
     86     finally:
     87         d['__entered'] = False

/Users/ruobinghan/anaconda/lib/python3.4/site-packages/scipy/sparse/linalg/isolve/iterative.py in cg(A, b, x0, tol, maxiter, xtype, M, callback)
    219 @non_reentrant
    220 def cg(A, b, x0=None, tol=1e-5, maxiter=None, xtype=None, M=None, callback=None):
--> 221     A,M,x,b,postprocess = make_system(A,M,x0,b,xtype)
    222 
    223     n = len(b)

/Users/ruobinghan/anaconda/lib/python3.4/site-packages/scipy/sparse/linalg/isolve/utils.py in make_system(A, M, x0, b, xtype)
    108         x = zeros(N, dtype=xtype)
    109     else:
--> 110         x = array(x0, dtype=xtype)
    111         if not (x.shape == (N,1) or x.shape == (N,)):
    112             raise ValueError('A and x have incompatible dimensions')

TypeError: float() argument must be a string or a number, not 'LinearOperator' 

此外,问题提示我将需要使用LinearOperator接口,我不明白LinearOperator究竟在做什么以及为什么我们需要它。

任何建议将不胜感激! 提前谢谢!

1 个答案:

答案 0 :(得分:1)

我认为参数的顺序错误,

x3=scipy.sparse.linalg.cg(A,b,M2)

在错误消息中:

220 def cg(A, b, x0=None, tol=1e-5, maxiter=None, xtype=None, M=None, 
callback=None):
--> 221     A,M,x,b,postprocess = make_system(A,M,x0,b,xtype)

M2代替x0 - 解决方案的初始猜测,但不是预处理器。 在我的主机中,如果订单正确,则class- LinearOperator 运行良好。

正确的版本

x3=scipy.sparse.linalg.cg(A,b,M=M2)

请使用&#34;关键字&#34;尽可能多地争论。