Coverage for /home/martinb/.local/share/virtualenvs/camcops/lib/python3.6/site-packages/scipy/sparse/linalg/isolve/utils.py : 16%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1__docformat__ = "restructuredtext en"
3__all__ = []
6from numpy import asanyarray, asarray, array, matrix, zeros
7from scipy.sparse.sputils import asmatrix
9from scipy.sparse.linalg.interface import aslinearoperator, LinearOperator, \
10 IdentityOperator
12_coerce_rules = {('f','f'):'f', ('f','d'):'d', ('f','F'):'F',
13 ('f','D'):'D', ('d','f'):'d', ('d','d'):'d',
14 ('d','F'):'D', ('d','D'):'D', ('F','f'):'F',
15 ('F','d'):'D', ('F','F'):'F', ('F','D'):'D',
16 ('D','f'):'D', ('D','d'):'D', ('D','F'):'D',
17 ('D','D'):'D'}
20def coerce(x,y):
21 if x not in 'fdFD':
22 x = 'd'
23 if y not in 'fdFD':
24 y = 'd'
25 return _coerce_rules[x,y]
28def id(x):
29 return x
32def make_system(A, M, x0, b):
33 """Make a linear system Ax=b
35 Parameters
36 ----------
37 A : LinearOperator
38 sparse or dense matrix (or any valid input to aslinearoperator)
39 M : {LinearOperator, Nones}
40 preconditioner
41 sparse or dense matrix (or any valid input to aslinearoperator)
42 x0 : {array_like, None}
43 initial guess to iterative method
44 b : array_like
45 right hand side
47 Returns
48 -------
49 (A, M, x, b, postprocess)
50 A : LinearOperator
51 matrix of the linear system
52 M : LinearOperator
53 preconditioner
54 x : rank 1 ndarray
55 initial guess
56 b : rank 1 ndarray
57 right hand side
58 postprocess : function
59 converts the solution vector to the appropriate
60 type and dimensions (e.g. (N,1) matrix)
62 """
63 A_ = A
64 A = aslinearoperator(A)
66 if A.shape[0] != A.shape[1]:
67 raise ValueError('expected square matrix, but got shape=%s' % (A.shape,))
69 N = A.shape[0]
71 b = asanyarray(b)
73 if not (b.shape == (N,1) or b.shape == (N,)):
74 raise ValueError('A and b have incompatible dimensions')
76 if b.dtype.char not in 'fdFD':
77 b = b.astype('d') # upcast non-FP types to double
79 def postprocess(x):
80 if isinstance(b,matrix):
81 x = asmatrix(x)
82 return x.reshape(b.shape)
84 if hasattr(A,'dtype'):
85 xtype = A.dtype.char
86 else:
87 xtype = A.matvec(b).dtype.char
88 xtype = coerce(xtype, b.dtype.char)
90 b = asarray(b,dtype=xtype) # make b the same type as x
91 b = b.ravel()
93 if x0 is None:
94 x = zeros(N, dtype=xtype)
95 else:
96 x = array(x0, dtype=xtype)
97 if not (x.shape == (N,1) or x.shape == (N,)):
98 raise ValueError('A and x have incompatible dimensions')
99 x = x.ravel()
101 # process preconditioner
102 if M is None:
103 if hasattr(A_,'psolve'):
104 psolve = A_.psolve
105 else:
106 psolve = id
107 if hasattr(A_,'rpsolve'):
108 rpsolve = A_.rpsolve
109 else:
110 rpsolve = id
111 if psolve is id and rpsolve is id:
112 M = IdentityOperator(shape=A.shape, dtype=A.dtype)
113 else:
114 M = LinearOperator(A.shape, matvec=psolve, rmatvec=rpsolve,
115 dtype=A.dtype)
116 else:
117 M = aslinearoperator(M)
118 if A.shape != M.shape:
119 raise ValueError('matrix and preconditioner have different shapes')
121 return A, M, x, b, postprocess