title: Preconditioned Conjugate Gradient and LinearOperator in python
body: <p>[Homework] I am going to solve the linear system Ax=b by the Preconditioned Conjugate Gradient method, and I use spilu function from scipy.sparse.linalg for the preconditioner. A is a sparse symmetric 162*162 matrix. Since the spilu gives an approximation to the inverse of A, say M approximates A, and so spilu(A) gives M^-1, which is the preconditioner. I find that we can directly gives the preconditioner in the python Conjugate Gradient function, but my code below does not work.</p>
  
  <pre><code>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)
  &lt;ipython-input-84-86f8f91df8d2&gt; in &lt;module&gt;()
  ----&gt; 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
  ---&gt; 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):
  --&gt; 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:
  --&gt; 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' 
  </code></pre>
  
  <p>Also, the question hints I will need to use LinearOperator interface, I do not understand what is exactly LinearOperator doing and why we need it here.</p>
  
  <p>Any suggestion would be appreciated!
  Thanks in advance!</p>